Lines 19-27
Link Here
|
19 |
import java.net.URISyntaxException; |
19 |
import java.net.URISyntaxException; |
20 |
import java.util.ArrayList; |
20 |
import java.util.ArrayList; |
21 |
import java.util.Arrays; |
21 |
import java.util.Arrays; |
|
|
22 |
import java.util.Collections; |
22 |
import java.util.Iterator; |
23 |
import java.util.Iterator; |
23 |
import java.util.List; |
24 |
import java.util.List; |
24 |
import java.util.Map; |
25 |
import java.util.Map; |
|
|
26 |
import java.util.Properties; |
25 |
import java.util.regex.Matcher; |
27 |
import java.util.regex.Matcher; |
26 |
import java.util.regex.Pattern; |
28 |
import java.util.regex.Pattern; |
27 |
import org.netbeans.api.project.Project; |
29 |
import org.netbeans.api.project.Project; |
Lines 84-89
Link Here
|
84 |
*/ |
86 |
*/ |
85 |
static final String REFS_NS = "http://www.netbeans.org/ns/ant-project-references/1"; // NOI18N |
87 |
static final String REFS_NS = "http://www.netbeans.org/ns/ant-project-references/1"; // NOI18N |
86 |
|
88 |
|
|
|
89 |
/** |
90 |
* Newer version of {@link #REFS_NS} supporting Properties and with changed semantics of <script>. |
91 |
*/ |
92 |
static final String REFS_NS2 = "http://www.netbeans.org/ns/ant-project-references/2"; // NOI18N |
93 |
|
87 |
private final AntProjectHelper h; |
94 |
private final AntProjectHelper h; |
88 |
final PropertyEvaluator eval; |
95 |
final PropertyEvaluator eval; |
89 |
private final AuxiliaryConfiguration aux; |
96 |
private final AuxiliaryConfiguration aux; |
Lines 116-128
Link Here
|
116 |
|
123 |
|
117 |
/** |
124 |
/** |
118 |
* Load <references> from project.xml. |
125 |
* Load <references> from project.xml. |
119 |
* @param create if true, create an empty element if it was missing, else leave as null |
126 |
* @return can return null if there are no references stored yet |
120 |
*/ |
127 |
*/ |
121 |
private Element loadReferences(boolean create) { |
128 |
private Element loadReferences() { |
122 |
assert ProjectManager.mutex().isReadAccess() || ProjectManager.mutex().isWriteAccess(); |
129 |
assert ProjectManager.mutex().isReadAccess() || ProjectManager.mutex().isWriteAccess(); |
123 |
Element references = aux.getConfigurationFragment(REFS_NAME, REFS_NS, true); |
130 |
Element references = aux.getConfigurationFragment(REFS_NAME, REFS_NS2, true); |
124 |
if (references == null && create) { |
131 |
if (references == null) { |
125 |
references = XMLUtil.createDocument("ignore", null, null, null).createElementNS(REFS_NS, REFS_NAME); // NOI18N |
132 |
references = aux.getConfigurationFragment(REFS_NAME, REFS_NS, true); |
126 |
} |
133 |
} |
127 |
return references; |
134 |
return references; |
128 |
} |
135 |
} |
Lines 132-180
Link Here
|
132 |
*/ |
139 |
*/ |
133 |
private void storeReferences(Element references) { |
140 |
private void storeReferences(Element references) { |
134 |
assert ProjectManager.mutex().isWriteAccess(); |
141 |
assert ProjectManager.mutex().isWriteAccess(); |
135 |
assert references != null && references.getLocalName().equals(REFS_NAME) && REFS_NS.equals(references.getNamespaceURI()); |
142 |
assert references != null && references.getLocalName().equals(REFS_NAME) && |
|
|
143 |
(REFS_NS.equals(references.getNamespaceURI()) || REFS_NS2.equals(references.getNamespaceURI())); |
136 |
aux.putConfigurationFragment(references, true); |
144 |
aux.putConfigurationFragment(references, true); |
137 |
} |
145 |
} |
138 |
|
146 |
|
|
|
147 |
private void removeOldReferences() { |
148 |
assert ProjectManager.mutex().isWriteAccess(); |
149 |
aux.removeConfigurationFragment(REFS_NS, REFS_NAME, true); |
150 |
} |
151 |
|
139 |
/** |
152 |
/** |
140 |
* Add a reference to an artifact coming from a foreign project. |
153 |
* Add a reference to an artifact coming from a foreign project. |
141 |
* <p> |
154 |
* <p> |
142 |
* Records the name of the foreign project. |
155 |
* For more info see {@link #addReference(AntArtifact, URI)}. |
143 |
* Normally the foreign project name is that project's code name, |
|
|
144 |
* but it may be uniquified if that name is already taken to refer |
145 |
* to a different project with the same code name. |
146 |
* <p> |
147 |
* Adds a project property if necessary to refer to its location of the foreign |
148 |
* project - a shared property if the foreign project |
149 |
* is {@link CollocationQuery collocated} with this one, else a private property. |
150 |
* This property is named <samp>project.<i>foreignProjectName</i></samp>. |
151 |
* Example: <samp>project.mylib=../mylib</samp> |
152 |
* <p> |
153 |
* Adds a project property to refer to the location of the artifact itself. |
154 |
* This property is named <samp>reference.<i>foreignProjectName</i>.<i>targetName</i></samp> |
155 |
* and will use <samp>${project.<i>foreignProjectName</i>}</samp> and be a shared |
156 |
* property - unless the artifact location is an absolute URI, in which case the property |
157 |
* will also be private. |
158 |
* Example: <samp>reference.mylib.jar=${project.mylib}/dist/mylib.jar</samp> |
159 |
* <p> |
160 |
* Also records the artifact type, (relative) script path, and build and |
161 |
* clean target names. |
162 |
* <p> |
163 |
* If the reference already exists (keyed by foreign project object |
164 |
* and target name), nothing is done, unless some other field (script location, |
165 |
* clean target name, or artifact type) needed to be updated, in which case |
166 |
* the new information replaces the old. Similarly, the artifact location |
167 |
* property is updated if necessary. |
168 |
* <p> |
169 |
* Acquires write access. |
170 |
* @param artifact the artifact to add |
156 |
* @param artifact the artifact to add |
171 |
* @return true if a reference or some property was actually added or modified, |
157 |
* @return true if a reference or some property was actually added or modified, |
172 |
* false if everything already existed and was not modified |
158 |
* false if everything already existed and was not modified |
173 |
* @throws IllegalArgumentException if the artifact is not associated with a project |
159 |
* @throws IllegalArgumentException if the artifact is not associated with a project |
|
|
160 |
* @deprecated to add reference use {@link #addReference(AntArtifact, URI)}; |
161 |
* to check whether reference exist or not use {@link #isReferenced(AntArtifact, URI)}. |
162 |
* This method creates reference for the first artifact location only. |
174 |
*/ |
163 |
*/ |
175 |
public boolean addReference(final AntArtifact artifact) throws IllegalArgumentException { |
164 |
public boolean addReference(final AntArtifact artifact) throws IllegalArgumentException { |
176 |
return ((Boolean)ProjectManager.mutex().writeAccess(new Mutex.Action() { |
165 |
Object ret[] = addReference0(artifact, artifact.getArtifactLocations()[0]); |
|
|
166 |
return ((Boolean)ret[0]).booleanValue(); |
167 |
} |
168 |
|
169 |
// @return array of two elements: [Boolean - any modification, String - reference] |
170 |
private Object[] addReference0(final AntArtifact artifact, final URI location) throws IllegalArgumentException { |
171 |
return ((List)ProjectManager.mutex().writeAccess(new Mutex.Action() { |
177 |
public Object run() { |
172 |
public Object run() { |
|
|
173 |
int index = findLocationIndex(artifact, location); |
178 |
Project forProj = artifact.getProject(); |
174 |
Project forProj = artifact.getProject(); |
179 |
if (forProj == null) { |
175 |
if (forProj == null) { |
180 |
throw new IllegalArgumentException("No project associated with " + artifact); // NOI18N |
176 |
throw new IllegalArgumentException("No project associated with " + artifact); // NOI18N |
Lines 187-236
Link Here
|
187 |
if (forProjName == null) { |
183 |
if (forProjName == null) { |
188 |
forProjName = generateUniqueID(projName, "project.", forProjDir.getAbsolutePath()); |
184 |
forProjName = generateUniqueID(projName, "project.", forProjDir.getAbsolutePath()); |
189 |
} |
185 |
} |
|
|
186 |
RawReference ref; |
190 |
File scriptFile = artifact.getScriptLocation(); |
187 |
File scriptFile = artifact.getScriptLocation(); |
191 |
URI scriptLocation; |
188 |
if (canUseVersion10(artifact, forProjDir)) { |
192 |
String rel = PropertyUtils.relativizeFile(forProjDir, scriptFile); |
189 |
String rel = PropertyUtils.relativizeFile(forProjDir, scriptFile); |
|
|
190 |
URI scriptLocation; |
193 |
try { |
191 |
try { |
194 |
scriptLocation = new URI(null, null, rel, null); |
192 |
scriptLocation = new URI(null, null, rel, null); |
195 |
} catch (URISyntaxException ex) { |
193 |
} catch (URISyntaxException ex) { |
196 |
scriptLocation = forProjDir.toURI().relativize(scriptFile.toURI()); |
194 |
scriptLocation = forProjDir.toURI().relativize(scriptFile.toURI()); |
197 |
} |
195 |
} |
198 |
RawReference ref = new RawReference(forProjName, artifact.getType(), scriptLocation, artifact.getTargetName(), artifact.getCleanTargetName(), artifact.getID()); |
196 |
ref = new RawReference(forProjName, artifact.getType(), scriptLocation, artifact.getTargetName(), artifact.getCleanTargetName(), artifact.getID()); |
199 |
Element references = loadReferences(true); |
197 |
} else { |
200 |
boolean success; |
198 |
String scriptLocation; |
201 |
try { |
199 |
if (scriptFile.getAbsolutePath().startsWith(forProjDir.getAbsolutePath())) { |
202 |
success = addRawReference(ref, references); |
200 |
String rel = PropertyUtils.relativizeFile(forProjDir, scriptFile); |
203 |
} catch (IllegalArgumentException e) { |
201 |
assert rel != null : "Relativization must succeed for files: "+forProjDir+ " "+scriptFile; |
204 |
ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); |
202 |
scriptLocation = "${project."+forProjName+"}/"+rel; |
205 |
return Boolean.FALSE; |
203 |
} else { |
206 |
} |
204 |
scriptLocation = "build.script.reference." + forProjName; |
207 |
if (success) { |
205 |
setPathProperty(forProjDir, scriptFile, scriptLocation); |
208 |
storeReferences(references); |
206 |
scriptLocation = "${"+scriptLocation+"}"; |
|
|
207 |
} |
208 |
ref = new RawReference(forProjName, artifact.getType(), scriptLocation, |
209 |
artifact.getTargetName(), artifact.getCleanTargetName(), |
210 |
artifact.getID(), artifact.getProperties()); |
209 |
} |
211 |
} |
|
|
212 |
boolean success = addRawReference0(ref); |
210 |
// Set up ${project.whatever}. |
213 |
// Set up ${project.whatever}. |
211 |
FileObject myProjDirFO = AntBasedProjectFactorySingleton.getProjectFor(h).getProjectDirectory(); |
214 |
FileObject myProjDirFO = AntBasedProjectFactorySingleton.getProjectFor(h).getProjectDirectory(); |
212 |
File myProjDir = FileUtil.toFile(myProjDirFO); |
215 |
File myProjDir = FileUtil.toFile(myProjDirFO); |
213 |
String forProjPath; |
216 |
if (setPathProperty(myProjDir, forProjDir, "project." + forProjName)) { |
214 |
String propertiesFile; |
|
|
215 |
if (CollocationQuery.areCollocated(myProjDir, forProjDir)) { |
216 |
// Fine, using a relative path to subproject. |
217 |
forProjPath = PropertyUtils.relativizeFile(myProjDir, forProjDir); |
218 |
assert forProjPath != null : "These dirs are not really collocated: " + myProjDir + " & " + forProjDir; |
219 |
propertiesFile = AntProjectHelper.PROJECT_PROPERTIES_PATH; |
220 |
} else { |
221 |
// Use an absolute path. |
222 |
forProjPath = forProjDir.getAbsolutePath(); |
223 |
propertiesFile = AntProjectHelper.PRIVATE_PROPERTIES_PATH; |
224 |
} |
225 |
EditableProperties props = h.getProperties(propertiesFile); |
226 |
String forProjPathProp = "project." + forProjName; // NOI18N |
227 |
if (!forProjPath.equals(props.getProperty(forProjPathProp))) { |
228 |
props.put(forProjPathProp, forProjPath); |
229 |
h.putProperties(propertiesFile, props); |
230 |
success = true; |
217 |
success = true; |
231 |
} |
218 |
} |
232 |
// Set up ${reference.whatever.whatever}. |
219 |
// Set up ${reference.whatever.whatever}. |
233 |
URI artFile = artifact.getArtifactLocation(); |
220 |
String propertiesFile; |
|
|
221 |
String forProjPathProp = "project." + forProjName; // NOI18N |
222 |
URI artFile = location; |
234 |
String refPath; |
223 |
String refPath; |
235 |
if (artFile.isAbsolute()) { |
224 |
if (artFile.isAbsolute()) { |
236 |
refPath = new File(artFile).getAbsolutePath(); |
225 |
refPath = new File(artFile).getAbsolutePath(); |
Lines 239-252
Link Here
|
239 |
refPath = "${" + forProjPathProp + "}/" + artFile.getPath(); // NOI18N |
228 |
refPath = "${" + forProjPathProp + "}/" + artFile.getPath(); // NOI18N |
240 |
propertiesFile = AntProjectHelper.PROJECT_PROPERTIES_PATH; |
229 |
propertiesFile = AntProjectHelper.PROJECT_PROPERTIES_PATH; |
241 |
} |
230 |
} |
242 |
props = h.getProperties(propertiesFile); |
231 |
EditableProperties props = h.getProperties(propertiesFile); |
243 |
String refPathProp = "reference." + forProjName + '.' + getUsableReferenceID(artifact.getID()); // NOI18N |
232 |
String refPathProp = "reference." + forProjName + '.' + getUsableReferenceID(artifact.getID()); // NOI18N |
|
|
233 |
if (index > 0) { |
234 |
refPathProp += "."+index; |
235 |
} |
244 |
if (!refPath.equals(props.getProperty(refPathProp))) { |
236 |
if (!refPath.equals(props.getProperty(refPathProp))) { |
245 |
props.put(refPathProp, refPath); |
237 |
props.put(refPathProp, refPath); |
246 |
h.putProperties(propertiesFile, props); |
238 |
h.putProperties(propertiesFile, props); |
247 |
success = true; |
239 |
success = true; |
248 |
} |
240 |
} |
249 |
return Boolean.valueOf(success); |
241 |
ArrayList l = new ArrayList(); |
|
|
242 |
l.add(Boolean.valueOf(success)); |
243 |
l.add("${"+refPathProp+"}"); // NOI18N |
244 |
return l; |
245 |
} |
246 |
})).toArray(new Object[2]); |
247 |
} |
248 |
|
249 |
private int findLocationIndex(final AntArtifact artifact, final URI location) throws IllegalArgumentException { |
250 |
if (location == null) { |
251 |
throw new IllegalArgumentException("location cannot be null"); |
252 |
} |
253 |
URI uris[] = artifact.getArtifactLocations(); |
254 |
for (int i=0; i<uris.length; i++) { |
255 |
if (uris[i].equals(location)) { |
256 |
return i; |
257 |
} |
258 |
} |
259 |
throw new IllegalArgumentException("location ("+location+") must be in AntArtifact's locations ("+artifact+")"); |
260 |
} |
261 |
|
262 |
/** |
263 |
* Test whether the artifact can be stored as /1 artifact or not. |
264 |
*/ |
265 |
private static boolean canUseVersion10(AntArtifact aa, File projectDirectory) { |
266 |
// is there multiple outputs? |
267 |
if (aa.getArtifactLocations().length > 1) { |
268 |
return false; |
269 |
} |
270 |
// has some properties? |
271 |
if (aa.getProperties().keySet().size() > 0) { |
272 |
return false; |
273 |
} |
274 |
// does Ant script lies under project directory? |
275 |
if (!aa.getScriptLocation().getAbsolutePath().startsWith(projectDirectory.getAbsolutePath())) { |
276 |
return false; |
277 |
} |
278 |
return true; |
279 |
} |
280 |
|
281 |
/** |
282 |
* Helper method which checks collocation status of two files and based on |
283 |
* that it will in private or project properties file set up property with |
284 |
* the given name and with absolute or relative path value. |
285 |
* @return was there any change or not |
286 |
*/ |
287 |
private boolean setPathProperty(File base, File path, String propertyName) { |
288 |
String value; |
289 |
String propertiesFile; |
290 |
if (CollocationQuery.areCollocated(base, path)) { |
291 |
// Fine, using a relative path to subproject. |
292 |
value = PropertyUtils.relativizeFile(base, path); |
293 |
assert value != null : "These dirs are not really collocated: " + base + " & " + path; |
294 |
propertiesFile = AntProjectHelper.PROJECT_PROPERTIES_PATH; |
295 |
} else { |
296 |
// Use an absolute path. |
297 |
value = path.getAbsolutePath(); |
298 |
propertiesFile = AntProjectHelper.PRIVATE_PROPERTIES_PATH; |
299 |
} |
300 |
EditableProperties props = h.getProperties(propertiesFile); |
301 |
if (!value.equals(props.getProperty(propertyName))) { |
302 |
props.put(propertyName, value); |
303 |
h.putProperties(propertiesFile, props); |
304 |
// check presence of this property in opposite property file and |
305 |
// remove it if necessary |
306 |
propertiesFile = (propertiesFile == AntProjectHelper.PROJECT_PROPERTIES_PATH ? |
307 |
AntProjectHelper.PRIVATE_PROPERTIES_PATH : AntProjectHelper.PROJECT_PROPERTIES_PATH); |
308 |
props = h.getProperties(propertiesFile); |
309 |
if (props.remove(propertyName) != null) { |
310 |
h.putProperties(propertiesFile, props); |
311 |
} |
312 |
return true; |
313 |
} else { |
314 |
return false; |
315 |
} |
316 |
|
317 |
} |
318 |
|
319 |
/** |
320 |
* Add a reference to an artifact's location coming from a foreign project. |
321 |
* <p> |
322 |
* Records the name of the foreign project. |
323 |
* Normally the foreign project name is that project's code name, |
324 |
* but it may be uniquified if that name is already taken to refer |
325 |
* to a different project with the same code name. |
326 |
* <p> |
327 |
* Adds a project property if necessary to refer to its location of the foreign |
328 |
* project - a shared property if the foreign project |
329 |
* is {@link CollocationQuery collocated} with this one, else a private property. |
330 |
* This property is named <samp>project.<i>foreignProjectName</i></samp>. |
331 |
* Example: <samp>project.mylib=../mylib</samp> |
332 |
* <p> |
333 |
* Adds a project property to refer to the artifact's location. |
334 |
* This property is named <samp>reference.<i>foreignProjectName</i>.<i>targetName</i></samp> |
335 |
* and will use <samp>${project.<i>foreignProjectName</i>}</samp> and be a shared |
336 |
* property - unless the artifact location is an absolute URI, in which case the property |
337 |
* will also be private. |
338 |
* Example: <samp>reference.mylib.jar=${project.mylib}/dist/mylib.jar</samp> |
339 |
* <p> |
340 |
* Also records the artifact type, (relative) script path, and build and |
341 |
* clean target names. |
342 |
* <p> |
343 |
* If the reference already exists (keyed by foreign project object |
344 |
* and target name), nothing is done, unless some other field (script location, |
345 |
* clean target name, or artifact type) needed to be updated, in which case |
346 |
* the new information replaces the old. Similarly, the artifact location |
347 |
* property is updated if necessary. |
348 |
* <p> |
349 |
* Acquires write access. |
350 |
* @param artifact the artifact to add |
351 |
* @param location the artifact's location to create reference to |
352 |
* @return name of reference which was created or already existed |
353 |
* @throws IllegalArgumentException if the artifact is not associated with a project |
354 |
* or if the location is not artifact's location |
355 |
* @since X.XX |
356 |
*/ |
357 |
public String addReference(final AntArtifact artifact, URI location) throws IllegalArgumentException { |
358 |
Object ret[] = addReference0(artifact, location); |
359 |
return (String)ret[1]; |
360 |
} |
361 |
|
362 |
/** |
363 |
* Tests whether reference for artifact's location was already created by |
364 |
* {@link #addReference(AntArtifact, URI)} for this project or not. This |
365 |
* method returns false also in case when reference exist but needs to be |
366 |
* updated. |
367 |
* <p> |
368 |
* Acquires read access. |
369 |
* @param artifact the artifact to add |
370 |
* @param location the artifact's location to create reference to |
371 |
* @return true if already referenced |
372 |
* @throws IllegalArgumentException if the artifact is not associated with a project |
373 |
* or if the location is not artifact's location |
374 |
* @since X.XX |
375 |
*/ |
376 |
public boolean isReferenced(final AntArtifact artifact, final URI location) throws IllegalArgumentException { |
377 |
return ((Boolean)ProjectManager.mutex().readAccess(new Mutex.Action() { |
378 |
public Object run() { |
379 |
int index = findLocationIndex(artifact, location); |
380 |
Project forProj = artifact.getProject(); |
381 |
if (forProj == null) { |
382 |
throw new IllegalArgumentException("No project associated with " + artifact); // NOI18N |
383 |
} |
384 |
File forProjDir = FileUtil.toFile(forProj.getProjectDirectory()); |
385 |
assert forProjDir != null : forProj.getProjectDirectory(); |
386 |
String projName = getUsableReferenceID(ProjectUtils.getInformation(forProj).getName()); |
387 |
String forProjName = findReferenceID(projName, "project.", forProjDir.getAbsolutePath()); |
388 |
if (forProjName == null) { |
389 |
return Boolean.FALSE; |
390 |
} |
391 |
RawReference ref = getRawReference(forProjName, getUsableReferenceID(artifact.getID())); |
392 |
if (ref == null) { |
393 |
return Boolean.FALSE; |
394 |
} |
395 |
File script = h.resolveFile(eval.evaluate(ref.getScriptLocationValue())); |
396 |
if (!artifact.getType().equals(ref.getArtifactType()) || |
397 |
!artifact.getID().equals(ref.getID()) || |
398 |
!artifact.getScriptLocation().equals(script) || |
399 |
!artifact.getProperties().equals(ref.getProperties()) || |
400 |
!artifact.getTargetName().equals(ref.getTargetName()) || |
401 |
!artifact.getCleanTargetName().equals(ref.getCleanTargetName())) { |
402 |
return Boolean.FALSE; |
403 |
} |
404 |
|
405 |
String reference = "reference." + forProjName + '.' + getUsableReferenceID(artifact.getID()); // NOI18N |
406 |
if (index > 0) { |
407 |
reference += "."+index; |
408 |
} |
409 |
return Boolean.valueOf(eval.getProperty(reference) != null); |
250 |
} |
410 |
} |
251 |
})).booleanValue(); |
411 |
})).booleanValue(); |
252 |
} |
412 |
} |
Lines 273-297
Link Here
|
273 |
public boolean addRawReference(final RawReference ref) { |
433 |
public boolean addRawReference(final RawReference ref) { |
274 |
return ((Boolean)ProjectManager.mutex().writeAccess(new Mutex.Action() { |
434 |
return ((Boolean)ProjectManager.mutex().writeAccess(new Mutex.Action() { |
275 |
public Object run() { |
435 |
public Object run() { |
276 |
Element references = loadReferences(true); |
|
|
277 |
boolean success; |
278 |
try { |
436 |
try { |
279 |
success = addRawReference(ref, references); |
437 |
return Boolean.valueOf(addRawReference0(ref)); |
280 |
} catch (IllegalArgumentException e) { |
438 |
} catch (IllegalArgumentException e) { |
281 |
ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); |
439 |
ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); |
282 |
return Boolean.FALSE; |
440 |
return Boolean.FALSE; |
283 |
} |
441 |
} |
284 |
if (success) { |
442 |
} |
|
|
443 |
})).booleanValue(); |
444 |
} |
445 |
|
446 |
private boolean addRawReference0(final RawReference ref) throws IllegalArgumentException { |
447 |
Element references = loadReferences(); |
448 |
if (references == null) { |
449 |
references = XMLUtil.createDocument("ignore", null, null, null).createElementNS(ref.getNS(), REFS_NAME); // NOI18N |
450 |
} |
451 |
boolean modified = false; |
452 |
if (references.getNamespaceURI().equals(REFS_NS) && ref.getNS().equals(REFS_NS2)) { |
453 |
// upgrade all references to version /2 here: |
454 |
references = upgradeTo20(references); |
455 |
removeOldReferences(); |
456 |
modified = true; |
457 |
} |
458 |
modified = updateRawReferenceElement(ref, references); |
459 |
if (modified) { |
285 |
storeReferences(references); |
460 |
storeReferences(references); |
286 |
return Boolean.TRUE; |
|
|
287 |
} else { |
288 |
return Boolean.FALSE; |
289 |
} |
461 |
} |
|
|
462 |
return modified; |
290 |
} |
463 |
} |
291 |
})).booleanValue(); |
464 |
|
|
|
465 |
private Element upgradeTo20(Element references) { |
466 |
Element references20 = XMLUtil.createDocument("ignore", null, null, null).createElementNS(REFS_NS2, REFS_NAME); // NOI18N |
467 |
RawReference rr[] = getRawReferences(references); |
468 |
for (int i=0; i<rr.length; i++) { |
469 |
rr[i].upgrade(); |
470 |
updateRawReferenceElement(rr[i], references20); |
471 |
} |
472 |
return references20; |
292 |
} |
473 |
} |
293 |
|
474 |
|
294 |
private static boolean addRawReference(RawReference ref, Element references) throws IllegalArgumentException { |
475 |
private static boolean updateRawReferenceElement(RawReference ref, Element references) throws IllegalArgumentException { |
295 |
// Linear search; always keeping references sorted first by foreign project |
476 |
// Linear search; always keeping references sorted first by foreign project |
296 |
// name, then by target name. |
477 |
// name, then by target name. |
297 |
Element nextRefEl = null; |
478 |
Element nextRefEl = null; |
Lines 314-320
Link Here
|
314 |
if (testRef.getID().equals(ref.getID())) { |
495 |
if (testRef.getID().equals(ref.getID())) { |
315 |
// Key match, check if it needs to be updated. |
496 |
// Key match, check if it needs to be updated. |
316 |
if (testRef.getArtifactType().equals(ref.getArtifactType()) && |
497 |
if (testRef.getArtifactType().equals(ref.getArtifactType()) && |
317 |
testRef.getScriptLocation().equals(ref.getScriptLocation()) && |
498 |
testRef.getScriptLocationValue().equals(ref.getScriptLocationValue()) && |
|
|
499 |
testRef.getProperties().equals(ref.getProperties()) && |
318 |
testRef.getTargetName().equals(ref.getTargetName()) && |
500 |
testRef.getTargetName().equals(ref.getTargetName()) && |
319 |
testRef.getCleanTargetName().equals(ref.getCleanTargetName())) { |
501 |
testRef.getCleanTargetName().equals(ref.getCleanTargetName())) { |
320 |
// Match on other fields. Return without changing anything. |
502 |
// Match on other fields. Return without changing anything. |
Lines 333-339
Link Here
|
333 |
} |
515 |
} |
334 |
} |
516 |
} |
335 |
// Need to insert a new record before nextRef. |
517 |
// Need to insert a new record before nextRef. |
336 |
Element newRefEl = ref.toXml(references.getOwnerDocument()); |
518 |
Element newRefEl = ref.toXml(references.getNamespaceURI(), references.getOwnerDocument()); |
337 |
// Note: OK if nextRefEl == null, that means insert as last child. |
519 |
// Note: OK if nextRefEl == null, that means insert as last child. |
338 |
references.insertBefore(newRefEl, nextRefEl); |
520 |
references.insertBefore(newRefEl, nextRefEl); |
339 |
return true; |
521 |
return true; |
Lines 355-379
Link Here
|
355 |
* @param id the ID of the build artifact (usually build target name) |
537 |
* @param id the ID of the build artifact (usually build target name) |
356 |
* @return true if a reference or some property was actually removed, |
538 |
* @return true if a reference or some property was actually removed, |
357 |
* false if the reference was not there and no property was removed |
539 |
* false if the reference was not there and no property was removed |
|
|
540 |
* @deprecated use {@link #destroyReference} instead; was unused anyway |
358 |
*/ |
541 |
*/ |
359 |
public boolean removeReference(final String foreignProjectName, final String id) { |
542 |
public boolean removeReference(final String foreignProjectName, final String id) { |
360 |
return removeReference(foreignProjectName, id, false); |
543 |
return removeReference(foreignProjectName, id, false, null); |
361 |
} |
544 |
} |
362 |
|
545 |
|
363 |
private boolean removeReference(final String foreignProjectName, final String id, final boolean escaped) { |
546 |
private boolean removeReference(final String foreignProjectName, final String id, final boolean escaped, final String reference) { |
364 |
return ((Boolean)ProjectManager.mutex().writeAccess(new Mutex.Action() { |
547 |
return ((Boolean)ProjectManager.mutex().writeAccess(new Mutex.Action() { |
365 |
public Object run() { |
548 |
public Object run() { |
366 |
Element references = loadReferences(true); |
|
|
367 |
boolean success; |
549 |
boolean success; |
368 |
try { |
550 |
try { |
369 |
success = removeRawReference(foreignProjectName, id, references, escaped); |
551 |
success = removeRawReference0(foreignProjectName, id, escaped); |
370 |
} catch (IllegalArgumentException e) { |
552 |
} catch (IllegalArgumentException e) { |
371 |
ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); |
553 |
ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); |
372 |
return Boolean.FALSE; |
554 |
return Boolean.FALSE; |
373 |
} |
555 |
} |
374 |
if (success) { |
|
|
375 |
storeReferences(references); |
376 |
} |
377 |
// Note: try to delete obsoleted properties from both project.properties |
556 |
// Note: try to delete obsoleted properties from both project.properties |
378 |
// and private.properties, just in case. |
557 |
// and private.properties, just in case. |
379 |
String[] PROPS_PATHS = { |
558 |
String[] PROPS_PATHS = { |
Lines 382-388
Link Here
|
382 |
}; |
561 |
}; |
383 |
// Check whether there are any other references using foreignProjectName. |
562 |
// Check whether there are any other references using foreignProjectName. |
384 |
// If not, we can delete ${project.foreignProjectName}. |
563 |
// If not, we can delete ${project.foreignProjectName}. |
385 |
RawReference[] refs = getRawReferences(references); |
564 |
RawReference[] refs = new RawReference[0]; |
|
|
565 |
Element references = loadReferences(); |
566 |
if (references != null) { |
567 |
refs = getRawReferences(references); |
568 |
} |
386 |
boolean deleteProjProp = true; |
569 |
boolean deleteProjProp = true; |
387 |
for (int i = 0; i < refs.length; i++) { |
570 |
for (int i = 0; i < refs.length; i++) { |
388 |
if (refs[i].getForeignProjectName().equals(foreignProjectName)) { |
571 |
if (refs[i].getForeignProjectName().equals(foreignProjectName)) { |
Lines 401-407
Link Here
|
401 |
} |
584 |
} |
402 |
} |
585 |
} |
403 |
} |
586 |
} |
404 |
String refProp = "reference." + foreignProjectName + '.' + getUsableReferenceID(id); // NOI18N |
587 |
|
|
|
588 |
String refProp = reference; |
589 |
if (refProp == null) { |
590 |
refProp = "reference." + foreignProjectName + '.' + getUsableReferenceID(id); // NOI18N |
591 |
} |
592 |
// remove also build script property if exist any: |
593 |
String buildScriptProperty = "build.script.reference." + foreignProjectName; |
405 |
for (int i = 0; i < PROPS_PATHS.length; i++) { |
594 |
for (int i = 0; i < PROPS_PATHS.length; i++) { |
406 |
EditableProperties props = h.getProperties(PROPS_PATHS[i]); |
595 |
EditableProperties props = h.getProperties(PROPS_PATHS[i]); |
407 |
if (props.containsKey(refProp)) { |
596 |
if (props.containsKey(refProp)) { |
Lines 409-414
Link Here
|
409 |
h.putProperties(PROPS_PATHS[i], props); |
598 |
h.putProperties(PROPS_PATHS[i], props); |
410 |
success = true; |
599 |
success = true; |
411 |
} |
600 |
} |
|
|
601 |
if (props.containsKey(buildScriptProperty)) { |
602 |
props.remove(buildScriptProperty); |
603 |
h.putProperties(PROPS_PATHS[i], props); |
604 |
success = true; |
605 |
} |
412 |
} |
606 |
} |
413 |
return Boolean.valueOf(success); |
607 |
return Boolean.valueOf(success); |
414 |
} |
608 |
} |
Lines 424-431
Link Here
|
424 |
* @param fileReference file reference as created by |
618 |
* @param fileReference file reference as created by |
425 |
* {@link #createForeignFileReference(File, String)} |
619 |
* {@link #createForeignFileReference(File, String)} |
426 |
* @return true if the reference was actually removed; otherwise false |
620 |
* @return true if the reference was actually removed; otherwise false |
|
|
621 |
* @deprecated use {@link #destroyReference} instead; was unused anyway |
427 |
*/ |
622 |
*/ |
428 |
public boolean removeReference(final String fileReference) { |
623 |
public boolean removeReference(final String fileReference) { |
|
|
624 |
return removeFileReference(fileReference); |
625 |
} |
626 |
|
627 |
private boolean removeFileReference(final String fileReference) { |
429 |
return ((Boolean)ProjectManager.mutex().writeAccess(new Mutex.Action() { |
628 |
return ((Boolean)ProjectManager.mutex().writeAccess(new Mutex.Action() { |
430 |
public Object run() { |
629 |
public Object run() { |
431 |
boolean success = false; |
630 |
boolean success = false; |
Lines 468-492
Link Here
|
468 |
public boolean removeRawReference(final String foreignProjectName, final String id) { |
667 |
public boolean removeRawReference(final String foreignProjectName, final String id) { |
469 |
return ((Boolean)ProjectManager.mutex().writeAccess(new Mutex.Action() { |
668 |
return ((Boolean)ProjectManager.mutex().writeAccess(new Mutex.Action() { |
470 |
public Object run() { |
669 |
public Object run() { |
471 |
Element references = loadReferences(true); |
|
|
472 |
boolean success; |
473 |
try { |
670 |
try { |
474 |
success = removeRawReference(foreignProjectName, id, references, false); |
671 |
return Boolean.valueOf(removeRawReference0(foreignProjectName, id, false)); |
475 |
} catch (IllegalArgumentException e) { |
672 |
} catch (IllegalArgumentException e) { |
476 |
ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); |
673 |
ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); |
477 |
return Boolean.FALSE; |
674 |
return Boolean.FALSE; |
478 |
} |
675 |
} |
|
|
676 |
} |
677 |
})).booleanValue(); |
678 |
} |
679 |
|
680 |
private boolean removeRawReference0(final String foreignProjectName, final String id, boolean escaped) throws IllegalArgumentException { |
681 |
Element references = loadReferences(); |
682 |
if (references == null) { |
683 |
return false; |
684 |
} |
685 |
boolean success = removeRawReferenceElement(foreignProjectName, id, references, escaped); |
479 |
if (success) { |
686 |
if (success) { |
480 |
storeReferences(references); |
687 |
storeReferences(references); |
481 |
return Boolean.TRUE; |
|
|
482 |
} else { |
483 |
return Boolean.FALSE; |
484 |
} |
688 |
} |
485 |
} |
689 |
return success; |
486 |
})).booleanValue(); |
|
|
487 |
} |
690 |
} |
488 |
|
691 |
|
489 |
private static boolean removeRawReference(String foreignProjectName, String id, Element references, boolean escaped) throws IllegalArgumentException { |
692 |
private static boolean removeRawReferenceElement(String foreignProjectName, String id, Element references, boolean escaped) throws IllegalArgumentException { |
490 |
// As with addRawReference, do a linear search through. |
693 |
// As with addRawReference, do a linear search through. |
491 |
List/*<Element>*/subEls = Util.findSubElements(references); |
694 |
List/*<Element>*/subEls = Util.findSubElements(references); |
492 |
Iterator it = subEls.iterator(); |
695 |
Iterator it = subEls.iterator(); |
Lines 530-536
Link Here
|
530 |
public RawReference[] getRawReferences() { |
733 |
public RawReference[] getRawReferences() { |
531 |
return (RawReference[])ProjectManager.mutex().readAccess(new Mutex.Action() { |
734 |
return (RawReference[])ProjectManager.mutex().readAccess(new Mutex.Action() { |
532 |
public Object run() { |
735 |
public Object run() { |
533 |
Element references = loadReferences(false); |
736 |
Element references = loadReferences(); |
534 |
if (references != null) { |
737 |
if (references != null) { |
535 |
try { |
738 |
try { |
536 |
return getRawReferences(references); |
739 |
return getRawReferences(references); |
Lines 573-579
Link Here
|
573 |
RawReference getRawReference(final String foreignProjectName, final String id, final boolean escaped) { |
776 |
RawReference getRawReference(final String foreignProjectName, final String id, final boolean escaped) { |
574 |
return (RawReference)ProjectManager.mutex().readAccess(new Mutex.Action() { |
777 |
return (RawReference)ProjectManager.mutex().readAccess(new Mutex.Action() { |
575 |
public Object run() { |
778 |
public Object run() { |
576 |
Element references = loadReferences(false); |
779 |
Element references = loadReferences(); |
577 |
if (references != null) { |
780 |
if (references != null) { |
578 |
try { |
781 |
try { |
579 |
return getRawReference(foreignProjectName, id, references, escaped); |
782 |
return getRawReference(foreignProjectName, id, references, escaped); |
Lines 638-652
Link Here
|
638 |
String propertiesFile; |
841 |
String propertiesFile; |
639 |
String path; |
842 |
String path; |
640 |
File myProjDir = FileUtil.toFile(AntBasedProjectFactorySingleton.getProjectFor(h).getProjectDirectory()); |
843 |
File myProjDir = FileUtil.toFile(AntBasedProjectFactorySingleton.getProjectFor(h).getProjectDirectory()); |
641 |
if (CollocationQuery.areCollocated(myProjDir, file)) { |
|
|
642 |
propertiesFile = AntProjectHelper.PROJECT_PROPERTIES_PATH; |
643 |
path = PropertyUtils.relativizeFile(myProjDir, file); |
644 |
assert path != null : "expected relative path from " + myProjDir + " to " + file; |
645 |
} else { |
646 |
propertiesFile = AntProjectHelper.PRIVATE_PROPERTIES_PATH; |
647 |
path = file.getAbsolutePath(); |
648 |
} |
649 |
EditableProperties props = h.getProperties(propertiesFile); |
650 |
String fileID = file.getName(); |
844 |
String fileID = file.getName(); |
651 |
// if the file is folder then add to ID string also parent folder name, |
845 |
// if the file is folder then add to ID string also parent folder name, |
652 |
// i.e. if external source folder name is "src" the ID will |
846 |
// i.e. if external source folder name is "src" the ID will |
Lines 660-669
Link Here
|
660 |
if (prop == null) { |
854 |
if (prop == null) { |
661 |
prop = generateUniqueID(fileID, "file.reference.", file.getAbsolutePath()); // NOI18N |
855 |
prop = generateUniqueID(fileID, "file.reference.", file.getAbsolutePath()); // NOI18N |
662 |
} |
856 |
} |
663 |
if (!path.equals(props.getProperty("file.reference." + prop))) { // NOI18N |
857 |
setPathProperty(myProjDir, file, "file.reference." + prop); |
664 |
props.put("file.reference." + prop, path); // NOI18N |
|
|
665 |
h.putProperties(propertiesFile, props); |
666 |
} |
667 |
return "${file.reference." + prop + '}'; // NOI18N |
858 |
return "${file.reference." + prop + '}'; // NOI18N |
668 |
} |
859 |
} |
669 |
} |
860 |
} |
Lines 742-752
Link Here
|
742 |
* @param artifact a known build artifact to refer to |
933 |
* @param artifact a known build artifact to refer to |
743 |
* @return a string which can refer to that artifact file somehow |
934 |
* @return a string which can refer to that artifact file somehow |
744 |
* @throws IllegalArgumentException if the artifact is not associated with a project |
935 |
* @throws IllegalArgumentException if the artifact is not associated with a project |
|
|
936 |
* @deprecated use {@link #addReference(AntArtifact, URI)} instead |
745 |
*/ |
937 |
*/ |
746 |
public String createForeignFileReference(AntArtifact artifact) throws IllegalArgumentException { |
938 |
public String createForeignFileReference(AntArtifact artifact) throws IllegalArgumentException { |
747 |
addReference(artifact); |
939 |
Object ret[] = addReference0(artifact, artifact.getArtifactLocations()[0]); |
748 |
String projID = findReferenceID(artifact); |
940 |
return (String)ret[1]; |
749 |
return "${reference." + projID + '.' + getUsableReferenceID(artifact.getID()) + '}'; // NOI18N |
|
|
750 |
} |
941 |
} |
751 |
|
942 |
|
752 |
/** |
943 |
/** |
Lines 758-764
Link Here
|
758 |
} |
949 |
} |
759 |
|
950 |
|
760 |
|
951 |
|
761 |
private static final Pattern FOREIGN_FILE_REFERENCE = Pattern.compile("\\$\\{reference\\.([^.${}]+)\\.([^.${}]+)\\}"); // NOI18N |
952 |
private static final Pattern FOREIGN_FILE_REFERENCE = Pattern.compile("\\$\\{reference\\.([^.${}]+)\\.([^.${}]+)\\.([\\d&&[^.${}]]+)\\}"); // NOI18N |
|
|
953 |
private static final Pattern FOREIGN_FILE_REFERENCE_OLD = Pattern.compile("\\$\\{reference\\.([^.${}]+)\\.([^.${}]+)\\}"); // NOI18N |
762 |
private static final Pattern FOREIGN_PLAIN_FILE_REFERENCE = Pattern.compile("\\$\\{file\\.reference\\.([^${}]+)\\}"); // NOI18N |
954 |
private static final Pattern FOREIGN_PLAIN_FILE_REFERENCE = Pattern.compile("\\$\\{file\\.reference\\.([^${}]+)\\}"); // NOI18N |
763 |
|
955 |
|
764 |
/** |
956 |
/** |
Lines 769-797
Link Here
|
769 |
* <p>Acquires read access. |
961 |
* <p>Acquires read access. |
770 |
* @param reference a reference string as present in an Ant property |
962 |
* @param reference a reference string as present in an Ant property |
771 |
* @return a corresponding Ant artifact object if there is one, else null |
963 |
* @return a corresponding Ant artifact object if there is one, else null |
|
|
964 |
* @deprecated use {@link #findArtifactAndLocation} instead |
772 |
*/ |
965 |
*/ |
773 |
public AntArtifact getForeignFileReferenceAsArtifact(final String reference) { |
966 |
public AntArtifact getForeignFileReferenceAsArtifact(final String reference) { |
774 |
return (AntArtifact)ProjectManager.mutex().readAccess(new Mutex.Action() { |
967 |
Object ret[] = findArtifactAndLocation(reference); |
|
|
968 |
return (AntArtifact)ret[0]; |
969 |
} |
970 |
|
971 |
/** |
972 |
* Try to find an <code>AntArtifact</code> object and location corresponding |
973 |
* to a given reference. If the supplied string is not a recognized |
974 |
* reference to a build artifact, returns null. |
975 |
* <p> |
976 |
* Acquires read access. |
977 |
* @param reference a reference string as present in an Ant property and as |
978 |
* created by {@link #addReference(AntArtifact, URI)} |
979 |
* @return always returns array of two items. The items may be null. First |
980 |
* one is instance of AntArtifact and second is instance of URI and is |
981 |
* AntArtifact's location |
982 |
* @since X.XX |
983 |
*/ |
984 |
public Object[] findArtifactAndLocation(final String reference) { |
985 |
return ((List)ProjectManager.mutex().readAccess(new Mutex.Action() { |
775 |
public Object run() { |
986 |
public Object run() { |
|
|
987 |
ArrayList l = new ArrayList(); |
988 |
AntArtifact aa = null; |
776 |
Matcher m = FOREIGN_FILE_REFERENCE.matcher(reference); |
989 |
Matcher m = FOREIGN_FILE_REFERENCE.matcher(reference); |
777 |
if (m.matches()) { |
990 |
boolean matches = m.matches(); |
|
|
991 |
int index = 0; |
992 |
if (!matches) { |
993 |
m = FOREIGN_FILE_REFERENCE_OLD.matcher(reference); |
994 |
matches = m.matches(); |
995 |
} else { |
996 |
try { |
997 |
index = Integer.parseInt(m.group(3)); |
998 |
} catch (NumberFormatException ex) { |
999 |
ErrorManager.getDefault().log(ErrorManager.INFORMATIONAL, |
1000 |
"Could not parse reference ("+reference+") for the jar index. " + // NOI18N |
1001 |
"Expected number: "+m.group(3)); // NOI18N |
1002 |
matches = false; |
1003 |
} |
1004 |
} |
1005 |
if (matches) { |
778 |
RawReference ref = getRawReference(m.group(1), m.group(2), true); |
1006 |
RawReference ref = getRawReference(m.group(1), m.group(2), true); |
779 |
if (ref != null) { |
1007 |
if (ref != null) { |
780 |
return ref.toAntArtifact(ReferenceHelper.this); |
1008 |
aa = ref.toAntArtifact(ReferenceHelper.this); |
781 |
} |
1009 |
} |
782 |
} |
1010 |
} |
783 |
return null; |
1011 |
if (aa == null) { |
|
|
1012 |
l.add(null); |
1013 |
l.add(null); |
1014 |
return l; |
784 |
} |
1015 |
} |
785 |
}); |
1016 |
assert index <= aa.getArtifactLocations().length; |
|
|
1017 |
URI uri = aa.getArtifactLocations()[index]; |
1018 |
l.add(aa); |
1019 |
l.add(uri); |
1020 |
return l; |
1021 |
} |
1022 |
})).toArray(new Object[2]); |
1023 |
} |
1024 |
|
1025 |
/** |
1026 |
* Remove a reference to a foreign file from the project. |
1027 |
* See {@link #destroyReference} for more information. |
1028 |
* @param reference an Ant-interpretable foreign file reference as created e.g. |
1029 |
* by {@link #createForeignFileReference(File,String)} or |
1030 |
* by {@link #createForeignFileReference(AntArtifact)} |
1031 |
* @deprecated use {@link #destroyReference} instead which does exactly |
1032 |
* the same but has more appropriate name |
1033 |
*/ |
1034 |
public void destroyForeignFileReference(String reference) { |
1035 |
destroyReference(reference); |
786 |
} |
1036 |
} |
787 |
|
1037 |
|
788 |
/** |
1038 |
/** |
789 |
* Remove a reference to a foreign file from the project. |
1039 |
* Remove a reference to a foreign file from the project. |
790 |
* If the passed string consists of an Ant property reference corresponding to |
1040 |
* If the passed string consists of an Ant property reference corresponding to |
791 |
* a known inter-project reference created by |
1041 |
* a known inter-project reference created by |
792 |
* {@link #createForeignFileReference(AntArtifact)} or file reference created by |
1042 |
* {@link #addReference(AntArtifact, URI)} or file reference created by |
793 |
* {@link #createForeignFileReference(File, String)}, that reference is removed using |
1043 |
* {@link #createForeignFileReference(File, String)}, that reference is removed. |
794 |
* {@link #removeReference(String, String)} or {@link #removeReference(String)}. |
|
|
795 |
* Since this would break any other identical foreign |
1044 |
* Since this would break any other identical foreign |
796 |
* file references present in the project, you should first confirm that this |
1045 |
* file references present in the project, you should first confirm that this |
797 |
* reference was the last one of its kind (by string match). |
1046 |
* reference was the last one of its kind (by string match). |
Lines 803-822
Link Here
|
803 |
* @param reference an Ant-interpretable foreign file reference as created e.g. |
1052 |
* @param reference an Ant-interpretable foreign file reference as created e.g. |
804 |
* by {@link #createForeignFileReference(File,String)} or |
1053 |
* by {@link #createForeignFileReference(File,String)} or |
805 |
* by {@link #createForeignFileReference(AntArtifact)} |
1054 |
* by {@link #createForeignFileReference(AntArtifact)} |
|
|
1055 |
* @return true if reference was really destroyed or not |
1056 |
* @since X.XX |
806 |
*/ |
1057 |
*/ |
807 |
public void destroyForeignFileReference(String reference) { |
1058 |
public boolean destroyReference(String reference) { |
808 |
Matcher m = FOREIGN_FILE_REFERENCE.matcher(reference); |
1059 |
Matcher m = FOREIGN_FILE_REFERENCE.matcher(reference); |
809 |
if (m.matches()) { |
1060 |
boolean matches = m.matches(); |
|
|
1061 |
if (!matches) { |
1062 |
m = FOREIGN_FILE_REFERENCE_OLD.matcher(reference); |
1063 |
matches = m.matches(); |
1064 |
} |
1065 |
if (matches) { |
810 |
String forProjName = m.group(1); |
1066 |
String forProjName = m.group(1); |
811 |
String id = m.group(2); |
1067 |
String id = m.group(2); |
812 |
removeReference(forProjName, id, true); |
1068 |
return removeReference(forProjName, id, true, reference.substring(2, reference.length()-1)); |
813 |
return; |
|
|
814 |
} |
1069 |
} |
815 |
m = FOREIGN_PLAIN_FILE_REFERENCE.matcher(reference); |
1070 |
m = FOREIGN_PLAIN_FILE_REFERENCE.matcher(reference); |
816 |
if (m.matches()) { |
1071 |
if (m.matches()) { |
817 |
removeReference(reference); |
1072 |
return removeFileReference(reference); |
818 |
return; |
|
|
819 |
} |
1073 |
} |
|
|
1074 |
return false; |
820 |
} |
1075 |
} |
821 |
|
1076 |
|
822 |
/** |
1077 |
/** |
Lines 847-856
Link Here
|
847 |
|
1102 |
|
848 |
private final String foreignProjectName; |
1103 |
private final String foreignProjectName; |
849 |
private final String artifactType; |
1104 |
private final String artifactType; |
850 |
private final URI scriptLocation; |
1105 |
private URI scriptLocation; |
|
|
1106 |
// introduced in /2 version |
1107 |
private String newScriptLocation; |
851 |
private final String targetName; |
1108 |
private final String targetName; |
852 |
private final String cleanTargetName; |
1109 |
private final String cleanTargetName; |
853 |
private final String artifactID; |
1110 |
private final String artifactID; |
|
|
1111 |
private final Properties props; |
854 |
|
1112 |
|
855 |
/** |
1113 |
/** |
856 |
* Create a raw reference descriptor. |
1114 |
* Create a raw reference descriptor. |
Lines 864-878
Link Here
|
864 |
* @throws IllegalArgumentException if the script location is given an absolute URI |
1122 |
* @throws IllegalArgumentException if the script location is given an absolute URI |
865 |
*/ |
1123 |
*/ |
866 |
public RawReference(String foreignProjectName, String artifactType, URI scriptLocation, String targetName, String cleanTargetName, String artifactID) throws IllegalArgumentException { |
1124 |
public RawReference(String foreignProjectName, String artifactType, URI scriptLocation, String targetName, String cleanTargetName, String artifactID) throws IllegalArgumentException { |
|
|
1125 |
this(foreignProjectName, artifactType, scriptLocation, null, targetName, cleanTargetName, artifactID, new Properties()); |
1126 |
} |
1127 |
|
1128 |
/** |
1129 |
* Create a raw reference descriptor. |
1130 |
* As this is basically just a struct, does no real work. |
1131 |
* @param foreignProjectName the name of the foreign project (usually its code name) |
1132 |
* @param artifactType the {@link AntArtifact#getType type} of the build artifact |
1133 |
* @param newScriptLocation absolute path to the build script; can contain Ant-like properties |
1134 |
* @param targetName the Ant target name |
1135 |
* @param cleanTargetName the Ant clean target name |
1136 |
* @param artifactID the {@link AntArtifact#getID ID} of the build artifact |
1137 |
* @param props optional properties to be used for target execution; never null |
1138 |
* @throws IllegalArgumentException if the script location is given an absolute URI |
1139 |
* @since X.XX |
1140 |
*/ |
1141 |
public RawReference(String foreignProjectName, String artifactType, String newScriptLocation, String targetName, String cleanTargetName, String artifactID, Properties props) throws IllegalArgumentException { |
1142 |
this(foreignProjectName, artifactType, null, newScriptLocation, targetName, cleanTargetName, artifactID, props); |
1143 |
} |
1144 |
|
1145 |
private RawReference(String foreignProjectName, String artifactType, URI scriptLocation, String newScriptLocation, String targetName, String cleanTargetName, String artifactID, Properties props) throws IllegalArgumentException { |
867 |
this.foreignProjectName = foreignProjectName; |
1146 |
this.foreignProjectName = foreignProjectName; |
868 |
this.artifactType = artifactType; |
1147 |
this.artifactType = artifactType; |
869 |
if (scriptLocation.isAbsolute()) { |
1148 |
if (scriptLocation != null && scriptLocation.isAbsolute()) { |
870 |
throw new IllegalArgumentException("Cannot use an absolute URI " + scriptLocation + " for script location"); // NOI18N |
1149 |
throw new IllegalArgumentException("Cannot use an absolute URI " + scriptLocation + " for script location"); // NOI18N |
871 |
} |
1150 |
} |
872 |
this.scriptLocation = scriptLocation; |
1151 |
this.scriptLocation = scriptLocation; |
|
|
1152 |
this.newScriptLocation = newScriptLocation; |
873 |
this.targetName = targetName; |
1153 |
this.targetName = targetName; |
874 |
this.cleanTargetName = cleanTargetName; |
1154 |
this.cleanTargetName = cleanTargetName; |
875 |
this.artifactID = artifactID; |
1155 |
this.artifactID = artifactID; |
|
|
1156 |
this.props = props; |
876 |
} |
1157 |
} |
877 |
|
1158 |
|
878 |
private static final List/*<String>*/ SUB_ELEMENT_NAMES = Arrays.asList(new String[] { |
1159 |
private static final List/*<String>*/ SUB_ELEMENT_NAMES = Arrays.asList(new String[] { |
Lines 889-894
Link Here
|
889 |
* @throws IllegalArgumentException if anything is missing or duplicated or malformed etc. |
1170 |
* @throws IllegalArgumentException if anything is missing or duplicated or malformed etc. |
890 |
*/ |
1171 |
*/ |
891 |
static RawReference create(Element xml) throws IllegalArgumentException { |
1172 |
static RawReference create(Element xml) throws IllegalArgumentException { |
|
|
1173 |
if (REFS_NS.equals(xml.getNamespaceURI())) { |
1174 |
return create1(xml); |
1175 |
} else { |
1176 |
return create2(xml); |
1177 |
} |
1178 |
} |
1179 |
|
1180 |
private static RawReference create1(Element xml) throws IllegalArgumentException { |
892 |
if (!REF_NAME.equals(xml.getLocalName()) || !REFS_NS.equals(xml.getNamespaceURI())) { |
1181 |
if (!REF_NAME.equals(xml.getLocalName()) || !REFS_NS.equals(xml.getNamespaceURI())) { |
893 |
throw new IllegalArgumentException("bad element name: " + xml); // NOI18N |
1182 |
throw new IllegalArgumentException("bad element name: " + xml); // NOI18N |
894 |
} |
1183 |
} |
Lines 921-947
Link Here
|
921 |
return new RawReference(values[0], values[1], scriptLocation, values[3], values[4], values[5]); |
1210 |
return new RawReference(values[0], values[1], scriptLocation, values[3], values[4], values[5]); |
922 |
} |
1211 |
} |
923 |
|
1212 |
|
|
|
1213 |
private static RawReference create2(Element xml) throws IllegalArgumentException { |
1214 |
if (!REF_NAME.equals(xml.getLocalName()) || !REFS_NS2.equals(xml.getNamespaceURI())) { |
1215 |
throw new IllegalArgumentException("bad element name: " + xml); // NOI18N |
1216 |
} |
1217 |
List nl = Util.findSubElements(xml); |
1218 |
if (nl.size() < 6) { |
1219 |
throw new IllegalArgumentException("missing or extra data: " + xml); // NOI18N |
1220 |
} |
1221 |
String[] values = new String[6]; |
1222 |
for (int i = 0; i < 6; i++) { |
1223 |
Element el = (Element)nl.get(i); |
1224 |
if (!REFS_NS2.equals(el.getNamespaceURI())) { |
1225 |
throw new IllegalArgumentException("bad subelement ns: " + el); // NOI18N |
1226 |
} |
1227 |
String elName = el.getLocalName(); |
1228 |
int idx = SUB_ELEMENT_NAMES.indexOf(elName); |
1229 |
if (idx == -1) { |
1230 |
throw new IllegalArgumentException("bad subelement name: " + elName); // NOI18N |
1231 |
} |
1232 |
String val = Util.findText(el); |
1233 |
if (val == null) { |
1234 |
throw new IllegalArgumentException("empty subelement: " + el); // NOI18N |
1235 |
} |
1236 |
if (values[idx] != null) { |
1237 |
throw new IllegalArgumentException("duplicate " + elName + ": " + values[idx] + " and " + val); // NOI18N |
1238 |
} |
1239 |
values[idx] = val; |
1240 |
} |
1241 |
Properties props = new Properties(); |
1242 |
if (nl.size() == 7) { |
1243 |
Element el = (Element)nl.get(6); |
1244 |
if (!REFS_NS2.equals(el.getNamespaceURI())) { |
1245 |
throw new IllegalArgumentException("bad subelement ns: " + el); // NOI18N |
1246 |
} |
1247 |
if (!"properties".equals(el.getLocalName())) { // NOI18N |
1248 |
throw new IllegalArgumentException("bad subelement. expected 'properties': " + el); // NOI18N |
1249 |
} |
1250 |
Iterator it = Util.findSubElements(el).iterator(); |
1251 |
while (it.hasNext()) { |
1252 |
el = (Element)it.next(); |
1253 |
String key = el.getAttribute("name"); |
1254 |
String value = Util.findText(el); |
1255 |
props.setProperty(key, value); |
1256 |
} |
1257 |
} |
1258 |
assert !Arrays.asList(values).contains(null); |
1259 |
return new RawReference(values[0], values[1], values[2], values[3], values[4], values[5], props); |
1260 |
} |
1261 |
|
924 |
/** |
1262 |
/** |
925 |
* Write a RawReference as an XML <reference> fragment. |
1263 |
* Write a RawReference as an XML <reference> fragment. |
926 |
*/ |
1264 |
*/ |
927 |
Element toXml(Document ownerDocument) { |
1265 |
Element toXml(String namespace, Document ownerDocument) { |
928 |
Element el = ownerDocument.createElementNS(REFS_NS, REF_NAME); |
1266 |
Element el = ownerDocument.createElementNS(namespace, REF_NAME); |
929 |
String[] values = { |
1267 |
String[] values = { |
930 |
foreignProjectName, |
1268 |
foreignProjectName, |
931 |
artifactType, |
1269 |
artifactType, |
932 |
scriptLocation.toString(), |
1270 |
newScriptLocation != null ? newScriptLocation : scriptLocation.toString(), |
933 |
targetName, |
1271 |
targetName, |
934 |
cleanTargetName, |
1272 |
cleanTargetName, |
935 |
artifactID, |
1273 |
artifactID, |
936 |
}; |
1274 |
}; |
937 |
for (int i = 0; i < 6; i++) { |
1275 |
for (int i = 0; i < 6; i++) { |
938 |
Element subel = ownerDocument.createElementNS(REFS_NS, (String)SUB_ELEMENT_NAMES.get(i)); |
1276 |
Element subel = ownerDocument.createElementNS(namespace, (String)SUB_ELEMENT_NAMES.get(i)); |
939 |
subel.appendChild(ownerDocument.createTextNode(values[i])); |
1277 |
subel.appendChild(ownerDocument.createTextNode(values[i])); |
940 |
el.appendChild(subel); |
1278 |
el.appendChild(subel); |
941 |
} |
1279 |
} |
|
|
1280 |
if (props.keySet().size() > 0) { |
1281 |
assert namespace.equals(REFS_NS2) : "can happen only in /2"; // NOI18N |
1282 |
Element propEls = ownerDocument.createElementNS(namespace, "properties"); // NOI18N |
1283 |
el.appendChild(propEls); |
1284 |
List keys = new ArrayList(props.keySet()); |
1285 |
Collections.sort(keys); |
1286 |
Iterator it = keys.iterator(); |
1287 |
while (it.hasNext()) { |
1288 |
String key = (String)it.next(); |
1289 |
Element propEl = ownerDocument.createElementNS(namespace, "property"); // NOI18N |
1290 |
propEl.appendChild(ownerDocument.createTextNode(props.getProperty(key))); |
1291 |
propEl.setAttribute("name", key); // NOI18N |
1292 |
propEls.appendChild(propEl); |
1293 |
} |
1294 |
} |
942 |
return el; |
1295 |
return el; |
943 |
} |
1296 |
} |
944 |
|
1297 |
|
|
|
1298 |
private String getNS() { |
1299 |
if (newScriptLocation != null) { |
1300 |
return REFS_NS2; |
1301 |
} else { |
1302 |
return REFS_NS; |
1303 |
} |
1304 |
} |
1305 |
|
945 |
/** |
1306 |
/** |
946 |
* Get the name of the foreign project as referred to from this project. |
1307 |
* Get the name of the foreign project as referred to from this project. |
947 |
* Usually this will be the code name of the foreign project, but it may |
1308 |
* Usually this will be the code name of the foreign project, but it may |
Lines 968-979
Link Here
|
968 |
* project directory. |
1329 |
* project directory. |
969 |
* This is the script which would be called to build the desired artifact. |
1330 |
* This is the script which would be called to build the desired artifact. |
970 |
* @return the script location |
1331 |
* @return the script location |
|
|
1332 |
* @deprecated use {@link #getScriptLocationValue} instead; may return null now |
971 |
*/ |
1333 |
*/ |
972 |
public URI getScriptLocation() { |
1334 |
public URI getScriptLocation() { |
973 |
return scriptLocation; |
1335 |
return scriptLocation; |
974 |
} |
1336 |
} |
975 |
|
1337 |
|
976 |
/** |
1338 |
/** |
|
|
1339 |
* Get absolute path location of the foreign project's build script. |
1340 |
* This is the script which would be called to build the desired artifact. |
1341 |
* @return absolute path possibly containing Ant properties |
1342 |
*/ |
1343 |
public String getScriptLocationValue() { |
1344 |
if (newScriptLocation != null) { |
1345 |
return newScriptLocation; |
1346 |
} else { |
1347 |
return "${project."+foreignProjectName+"}/"+scriptLocation.toString(); |
1348 |
} |
1349 |
} |
1350 |
|
1351 |
/** |
977 |
* Get the Ant target name to build the artifact. |
1352 |
* Get the Ant target name to build the artifact. |
978 |
* @return the target name |
1353 |
* @return the target name |
979 |
*/ |
1354 |
*/ |
Lines 998-1003
Link Here
|
998 |
return artifactID; |
1373 |
return artifactID; |
999 |
} |
1374 |
} |
1000 |
|
1375 |
|
|
|
1376 |
public Properties getProperties() { |
1377 |
return props; |
1378 |
} |
1379 |
|
1001 |
/** |
1380 |
/** |
1002 |
* Attempt to convert this reference to a live artifact object. |
1381 |
* Attempt to convert this reference to a live artifact object. |
1003 |
* This involves finding the referenced foreign project on disk |
1382 |
* This involves finding the referenced foreign project on disk |
Lines 1046-1053
Link Here
|
1046 |
}); |
1425 |
}); |
1047 |
} |
1426 |
} |
1048 |
|
1427 |
|
|
|
1428 |
private void upgrade() { |
1429 |
assert newScriptLocation == null && scriptLocation != null : "was already upgraded "+this; |
1430 |
newScriptLocation = "${project."+foreignProjectName+"}/" +scriptLocation.toString(); // NOI18N |
1431 |
scriptLocation = null; |
1432 |
} |
1433 |
|
1049 |
public String toString() { |
1434 |
public String toString() { |
1050 |
return "ReferenceHelper.RawReference<" + foreignProjectName + "," + artifactType + "," + scriptLocation + "," + targetName + "," + cleanTargetName + "," + artifactID + ">"; // NOI18N |
1435 |
return "ReferenceHelper.RawReference<" + foreignProjectName + "," + |
|
|
1436 |
artifactType + "," + newScriptLocation != null ? newScriptLocation : scriptLocation + |
1437 |
"," + targetName + "," + cleanTargetName + "," + artifactID + ">"; // NOI18N |
1051 |
} |
1438 |
} |
1052 |
|
1439 |
|
1053 |
} |
1440 |
} |