|
25 | 25 | package com.cloudbees.hudson.plugins.folder; |
26 | 26 |
|
27 | 27 | import com.cloudbees.hudson.plugins.folder.computed.ComputedFolder; |
| 28 | +import edu.umd.cs.findbugs.annotations.CheckForNull; |
| 29 | +import edu.umd.cs.findbugs.annotations.NonNull; |
28 | 30 | import hudson.Util; |
29 | | -import hudson.model.AbstractItem; |
30 | 31 | import hudson.model.Action; |
31 | 32 | import hudson.model.Item; |
32 | | -import hudson.model.ItemGroup; |
33 | 33 | import hudson.model.JobProperty; |
34 | 34 | import hudson.model.TopLevelItem; |
35 | | -import java.io.Closeable; |
36 | | -import java.io.IOException; |
37 | | -import java.util.Map; |
38 | | -import java.util.WeakHashMap; |
39 | 35 | import java.util.logging.Logger; |
40 | | -import edu.umd.cs.findbugs.annotations.CheckForNull; |
41 | | -import edu.umd.cs.findbugs.annotations.NonNull; |
42 | 36 | import jenkins.model.TransientActionFactory; |
43 | 37 |
|
44 | 38 | /** |
|
52 | 46 | * <ul> |
53 | 47 | * <li>See the notes on {@link #itemNameFromItem(AbstractFolder, TopLevelItem)} and |
54 | 48 | * {@link #dirNameFromItem(AbstractFolder, TopLevelItem)} regarding the constraints on how to name things</li> |
55 | | - * <li>There are some items which need the {@link Item#getRootDir()} during construction (those are bold evil item types |
56 | | - * that leak side-effects, you should fix them if you find them). While you wait for them to be fixed you will need |
57 | | - * to work-around the issue by ensuring that you call {@link #beforeCreateItem(AbstractFolder, String, String)} |
58 | | - * passing the {@link Item#getName()} you want the item to have <strong>and</strong> the ideal unmangled name |
59 | | - * <strong>before</strong> you call {@code new ChildItemType(parent,name)} and then call |
60 | | - * {@link #afterItemCreated(Trace)} when the constructor has returned. Then insure that your |
61 | | - * {@link #itemNameFromItem(AbstractFolder, TopLevelItem)} and {@link #dirNameFromItem(AbstractFolder, TopLevelItem)} |
62 | | - * fall back to {@link #idealNameFromItem(AbstractFolder, TopLevelItem)} when the magic property they are looking |
63 | | - * for is missing.</li> |
64 | 49 | * </ul> |
65 | 50 | * |
66 | 51 | * For a valid implementation, the |
|
82 | 67 | public abstract class ChildNameGenerator<P extends AbstractFolder<I>, I extends TopLevelItem> { |
83 | 68 | private static final Logger LOGGER = Logger.getLogger(ChildNameGenerator.class.getName()); |
84 | 69 |
|
85 | | - private static final Map<Trace,String> idealNames = new WeakHashMap<>(); |
86 | | - |
87 | | - /** |
88 | | - * Work-around helper method to "fix" {@link Item} constructors that have on-disk side-effects and therefore |
89 | | - * need {@link Item#getRootDir()} to work during the constructor. |
90 | | - * @param project the {@link AbstractFolder}. |
91 | | - * @param itemName the name that will be returned by {@link Item#getName()} when the item is constructed. This is |
92 | | - * the second parameter of {@link AbstractItem#AbstractItem(ItemGroup, String)}. This one would be |
93 | | - * the one with URL path segment escaping. |
94 | | - * @param idealName the original name before whatever URL path segment escaping you applied |
95 | | - * @return the {@link Trace} to keep track of when we can remove the memory of the creation process. Please |
96 | | - * {@link Trace#close()} the trace after the item is created. |
97 | | - */ |
98 | | - @NonNull |
99 | | - public static Trace beforeCreateItem(@NonNull AbstractFolder<?> project, |
100 | | - @NonNull String itemName, |
101 | | - @NonNull String idealName) { |
102 | | - final Trace trace = new Trace(project, itemName); |
103 | | - synchronized (idealNames) { |
104 | | - idealNames.put(trace, idealName); |
105 | | - } |
106 | | - return trace; |
107 | | - } |
108 | | - |
109 | | - /** |
110 | | - * Clean up for a creation {@link Trace}. Not strictly required, but nice implementations will do this via {@link Trace#close()}. |
111 | | - * @param trace the trace. |
112 | | - */ |
113 | | - private static void afterItemCreated(@NonNull Trace trace) { |
114 | | - synchronized (idealNames) { |
115 | | - idealNames.remove(trace); |
116 | | - } |
117 | | - } |
118 | | - |
119 | | - /** |
120 | | - * Looks up the {@link Item} to see if we stored the ideal name before invoking the constructor that is having |
121 | | - * on-disk side-effects before the object has escaped {@link #beforeCreateItem(AbstractFolder, String, String)} |
122 | | - * @param parent the parent within which the item is being created. |
123 | | - * @param item the partially created item. |
124 | | - * @return the ideal name of the item. |
125 | | - */ |
126 | | - @CheckForNull |
127 | | - protected final String idealNameFromItem(@NonNull P parent, @NonNull I item) { |
128 | | - String itemName = item.getName(); |
129 | | - if (itemName == null) { |
130 | | - return null; |
131 | | - } |
132 | | - synchronized (idealNames) { |
133 | | - return idealNames.get(new Trace(parent, itemName)); |
134 | | - } |
135 | | - } |
136 | | - |
137 | 70 | /** |
138 | 71 | * Infers the {@link Item#getName()} from the {@link Item} instance itself. |
139 | 72 | * |
@@ -229,66 +162,4 @@ final String dirName(@NonNull P parent, @NonNull I item) { |
229 | 162 | */ |
230 | 163 | @NonNull |
231 | 164 | public abstract String dirNameFromLegacy(@NonNull P parent, @NonNull String legacyDirName); |
232 | | - |
233 | | - /** |
234 | | - * Traces the creation of a new {@link Item} in a folder. Use |
235 | | - * {@link ChildNameGenerator#beforeCreateItem(AbstractFolder, String, String)} to get the instance. |
236 | | - */ |
237 | | - public static final class Trace implements Closeable { |
238 | | - /** |
239 | | - * The folder. |
240 | | - */ |
241 | | - @NonNull |
242 | | - private final AbstractFolder<?> folder; |
243 | | - /** |
244 | | - * The {@link Item#getName()} that we expect to be created in the very near future. |
245 | | - */ |
246 | | - @NonNull |
247 | | - private final String itemName; |
248 | | - |
249 | | - /** |
250 | | - * Constructor. |
251 | | - * @param folder the folder. |
252 | | - * @param itemName the item name |
253 | | - */ |
254 | | - private Trace(@NonNull AbstractFolder<?> folder, @NonNull String itemName) { |
255 | | - this.folder = folder; |
256 | | - this.itemName = itemName; |
257 | | - } |
258 | | - |
259 | | - /** |
260 | | - * {@inheritDoc} |
261 | | - */ |
262 | | - @Override |
263 | | - public boolean equals(Object o) { |
264 | | - if (this == o) { |
265 | | - return true; |
266 | | - } |
267 | | - if (o == null || getClass() != o.getClass()) { |
268 | | - return false; |
269 | | - } |
270 | | - |
271 | | - Trace that = (Trace) o; |
272 | | - |
273 | | - return folder == that.folder && itemName.equals(that.itemName); |
274 | | - } |
275 | | - |
276 | | - /** |
277 | | - * {@inheritDoc} |
278 | | - */ |
279 | | - @Override |
280 | | - public int hashCode() { |
281 | | - int result = folder.hashCode(); |
282 | | - result = 31 * result + itemName.hashCode(); |
283 | | - return result; |
284 | | - } |
285 | | - |
286 | | - /** |
287 | | - * {@inheritDoc} |
288 | | - */ |
289 | | - @Override |
290 | | - public void close() { |
291 | | - afterItemCreated(this); |
292 | | - } |
293 | | - } |
294 | 165 | } |
0 commit comments