Lines 43-48
Link Here
|
43 |
|
43 |
|
44 |
import java.io.File; |
44 |
import java.io.File; |
45 |
import java.io.IOException; |
45 |
import java.io.IOException; |
|
|
46 |
import java.net.MalformedURLException; |
46 |
import java.net.URI; |
47 |
import java.net.URI; |
47 |
import java.net.URISyntaxException; |
48 |
import java.net.URISyntaxException; |
48 |
import java.util.ArrayList; |
49 |
import java.util.ArrayList; |
Lines 55-60
Link Here
|
55 |
import java.util.Properties; |
56 |
import java.util.Properties; |
56 |
import java.util.Set; |
57 |
import java.util.Set; |
57 |
import java.util.TreeSet; |
58 |
import java.util.TreeSet; |
|
|
59 |
import java.util.logging.Logger; |
58 |
import java.util.regex.Matcher; |
60 |
import java.util.regex.Matcher; |
59 |
import java.util.regex.Pattern; |
61 |
import java.util.regex.Pattern; |
60 |
import org.netbeans.api.project.Project; |
62 |
import org.netbeans.api.project.Project; |
Lines 62-69
Link Here
|
62 |
import org.netbeans.api.project.ProjectUtils; |
64 |
import org.netbeans.api.project.ProjectUtils; |
63 |
import org.netbeans.api.project.ant.AntArtifact; |
65 |
import org.netbeans.api.project.ant.AntArtifact; |
64 |
import org.netbeans.api.project.ant.AntArtifactQuery; |
66 |
import org.netbeans.api.project.ant.AntArtifactQuery; |
|
|
67 |
import org.netbeans.api.project.libraries.Library; |
68 |
import org.netbeans.api.project.libraries.LibraryChooser; |
69 |
import org.netbeans.api.project.libraries.LibraryManager; |
65 |
import org.netbeans.api.queries.CollocationQuery; |
70 |
import org.netbeans.api.queries.CollocationQuery; |
66 |
import org.netbeans.modules.project.ant.AntBasedProjectFactorySingleton; |
71 |
import org.netbeans.modules.project.ant.AntBasedProjectFactorySingleton; |
|
|
72 |
import org.netbeans.modules.project.ant.ProjectLibraryProvider; |
67 |
import org.netbeans.modules.project.ant.Util; |
73 |
import org.netbeans.modules.project.ant.Util; |
68 |
import org.netbeans.spi.project.AuxiliaryConfiguration; |
74 |
import org.netbeans.spi.project.AuxiliaryConfiguration; |
69 |
import org.netbeans.spi.project.SubprojectProvider; |
75 |
import org.netbeans.spi.project.SubprojectProvider; |
Lines 72-77
Link Here
|
72 |
import org.openide.filesystems.FileUtil; |
78 |
import org.openide.filesystems.FileUtil; |
73 |
import org.openide.util.Mutex; |
79 |
import org.openide.util.Mutex; |
74 |
import org.openide.util.NbCollections; |
80 |
import org.openide.util.NbCollections; |
|
|
81 |
import org.openide.util.Parameters; |
75 |
import org.openide.xml.XMLUtil; |
82 |
import org.openide.xml.XMLUtil; |
76 |
import org.w3c.dom.Document; |
83 |
import org.w3c.dom.Document; |
77 |
import org.w3c.dom.Element; |
84 |
import org.w3c.dom.Element; |
Lines 332-338
Link Here
|
332 |
relativePath |
339 |
relativePath |
333 |
}; |
340 |
}; |
334 |
} |
341 |
} |
335 |
else if (CollocationQuery.areCollocated(base, path)) { |
342 |
else if (PropertyUtils.relativizeFile(base, path) != null) { |
|
|
343 |
//mkleint: removed CollocationQuery.areCollocated() reference |
344 |
// when AlwaysRelativeCQI gets removed the condition resolves to false more frequently. |
345 |
// that might not be desirable. |
346 |
|
336 |
// Fine, using a relative path to subproject. |
347 |
// Fine, using a relative path to subproject. |
337 |
relativePath = PropertyUtils.relativizeFile(base, path); |
348 |
relativePath = PropertyUtils.relativizeFile(base, path); |
338 |
assert relativePath != null : "These dirs are not really collocated: " + base + " & " + path; |
349 |
assert relativePath != null : "These dirs are not really collocated: " + base + " & " + path; |
Lines 352-357
Link Here
|
352 |
}; |
363 |
}; |
353 |
} |
364 |
} |
354 |
assert !Arrays.asList(values).contains(null) : "values=" + Arrays.toString(values) + " base=" + base + " path=" + path; // #119847 |
365 |
assert !Arrays.asList(values).contains(null) : "values=" + Arrays.toString(values) + " base=" + base + " path=" + path; // #119847 |
|
|
366 |
return setPathPropertyImpl(propertyName, values, propertiesFiles); |
367 |
} |
368 |
|
369 |
/** |
370 |
* Helper method which in project properties file sets up property with |
371 |
* the given name and with (possibly relative) path value. |
372 |
* @return was there any change or not |
373 |
*/ |
374 |
private boolean setPathProperty(String path, String propertyName) { |
375 |
String[] propertiesFiles = new String[] { |
376 |
AntProjectHelper.PROJECT_PROPERTIES_PATH |
377 |
}; |
378 |
String[] values = new String[] { |
379 |
path |
380 |
}; |
381 |
return setPathPropertyImpl(propertyName, values, propertiesFiles); |
382 |
} |
383 |
|
384 |
private boolean setPathPropertyImpl(String propertyName, String[] values, String[] propertiesFiles) { |
355 |
|
385 |
|
356 |
boolean metadataChanged = false; |
386 |
boolean metadataChanged = false; |
357 |
for (int i=0; i<propertiesFiles.length; i++) { |
387 |
for (int i=0; i<propertiesFiles.length; i++) { |
Lines 917-925
Link Here
|
917 |
throw new IllegalArgumentException("Parameter file was not "+ // NOI18N |
947 |
throw new IllegalArgumentException("Parameter file was not "+ // NOI18N |
918 |
"normalized. Was "+file+" instead of "+FileUtil.normalizeFile(file)); // NOI18N |
948 |
"normalized. Was "+file+" instead of "+FileUtil.normalizeFile(file)); // NOI18N |
919 |
} |
949 |
} |
|
|
950 |
return createForeignFileReferenceImpl(file.getAbsolutePath(), expectedArtifactType, true); |
951 |
} |
952 |
|
953 |
/** |
954 |
* Create an Ant-interpretable string referring to a file on disk. Compared |
955 |
* to {@link #createForeignFileReference} the filepath does not have to be |
956 |
* normalized (ie. it can be relative path to project base folder), no |
957 |
* relativization or absolutization of path is done and |
958 |
* reference to file is always stored in project properties. |
959 |
* If the file refers to a known Ant artifact according to |
960 |
* {@link AntArtifactQuery#findArtifactFromFile}, of the expected type |
961 |
* and associated with a particular project, |
962 |
* the behavior is identical to {@link #createForeignFileReference(AntArtifact)}. |
963 |
* <p> |
964 |
* Acquires write access. |
965 |
* @param path a file path to refer to (need not currently exist) |
966 |
* @param expectedArtifactType the required {@link AntArtifact#getType} |
967 |
* @return a string which can refer to that file somehow |
968 |
* |
969 |
* @since org.netbeans.modules.project.ant/1 1.19 |
970 |
*/ |
971 |
public String createForeignFileReferenceAsIs(final String filepath, final String expectedArtifactType) { |
972 |
return createForeignFileReferenceImpl(filepath, expectedArtifactType, false); |
973 |
} |
974 |
|
975 |
private String createForeignFileReferenceImpl(final String path, final String expectedArtifactType, final boolean performHeuristics) { |
976 |
FileObject myProjDirFO = h.getProjectDirectory(); |
977 |
File myProjDir = FileUtil.toFile(myProjDirFO); |
978 |
final File normalizedFile = FileUtil.normalizeFile(PropertyUtils.resolveFile(myProjDir, path)); |
920 |
return ProjectManager.mutex().writeAccess(new Mutex.Action<String>() { |
979 |
return ProjectManager.mutex().writeAccess(new Mutex.Action<String>() { |
921 |
public String run() { |
980 |
public String run() { |
922 |
AntArtifact art = AntArtifactQuery.findArtifactFromFile(file); |
981 |
AntArtifact art = AntArtifactQuery.findArtifactFromFile(normalizedFile); |
923 |
if (art != null && art.getType().equals(expectedArtifactType) && art.getProject() != null) { |
982 |
if (art != null && art.getType().equals(expectedArtifactType) && art.getProject() != null) { |
924 |
try { |
983 |
try { |
925 |
return createForeignFileReference(art); |
984 |
return createForeignFileReference(art); |
Lines 927-952
Link Here
|
927 |
throw new AssertionError(iae); |
986 |
throw new AssertionError(iae); |
928 |
} |
987 |
} |
929 |
} else { |
988 |
} else { |
930 |
String propertiesFile; |
|
|
931 |
String path; |
932 |
File myProjDir = FileUtil.toFile(AntBasedProjectFactorySingleton.getProjectFor(h).getProjectDirectory()); |
989 |
File myProjDir = FileUtil.toFile(AntBasedProjectFactorySingleton.getProjectFor(h).getProjectDirectory()); |
933 |
String fileID = file.getName(); |
990 |
String fileID = normalizedFile.getName(); |
934 |
// if the file is folder then add to ID string also parent folder name, |
991 |
// if the file is folder then add to ID string also parent folder name, |
935 |
// i.e. if external source folder name is "src" the ID will |
992 |
// i.e. if external source folder name is "src" the ID will |
936 |
// be a bit more selfdescribing, e.g. project-src in case |
993 |
// be a bit more selfdescribing, e.g. project-src in case |
937 |
// of ID for ant/project/src directory. |
994 |
// of ID for ant/project/src directory. |
938 |
if (file.isDirectory() && file.getParentFile() != null) { |
995 |
if (normalizedFile.isDirectory() && normalizedFile.getParentFile() != null) { |
939 |
fileID = file.getParentFile().getName()+"-"+file.getName(); |
996 |
fileID = normalizedFile.getParentFile().getName()+"-"+normalizedFile.getName(); |
940 |
} |
997 |
} |
941 |
fileID = PropertyUtils.getUsablePropertyName(fileID); |
998 |
fileID = PropertyUtils.getUsablePropertyName(fileID); |
942 |
String prop = findReferenceID(fileID, "file.reference.", file.getAbsolutePath()); // NOI18N |
999 |
String prop = findReferenceID(fileID, "file.reference.", normalizedFile.getAbsolutePath()); // NOI18N |
943 |
if (prop == null) { |
1000 |
if (prop == null) { |
944 |
prop = generateUniqueID(fileID, "file.reference.", file.getAbsolutePath()); // NOI18N |
1001 |
prop = generateUniqueID(fileID, "file.reference.", normalizedFile.getAbsolutePath()); // NOI18N |
945 |
} |
1002 |
} |
946 |
setPathProperty(myProjDir, file, "file.reference." + prop); |
1003 |
if (performHeuristics) { |
|
|
1004 |
setPathProperty(myProjDir, normalizedFile, "file.reference." + prop); |
1005 |
} else { |
1006 |
setPathProperty(path, "file.reference." + prop); |
1007 |
} |
947 |
return "${file.reference." + prop + '}'; // NOI18N |
1008 |
return "${file.reference." + prop + '}'; // NOI18N |
948 |
} |
1009 |
} |
949 |
} |
1010 |
} |
|
|
1011 |
}); |
1012 |
} |
1013 |
|
1014 |
/** |
1015 |
* Create an Ant-interpretable string referring to a file on disk. Compared |
1016 |
* to {@link #createForeignFileReference} the file path does not have to be |
1017 |
* normalized (ie. it can be relative path to project base folder), no |
1018 |
* relativization or absolutization of path is done and |
1019 |
* reference to file is always stored in project properties. |
1020 |
* <p> |
1021 |
* Acquires write access. |
1022 |
* @param path a file path to refer to (need not currently exist) |
1023 |
* @param property name of the property |
1024 |
* @return a string which can refer to that file somehow |
1025 |
* |
1026 |
* @since org.netbeans.modules.project.ant/1 1.19 |
1027 |
*/ |
1028 |
public String createExtraForeignFileReferenceAsIs(final String path, final String property) { |
1029 |
return ProjectManager.mutex().writeAccess(new Mutex.Action<String>() { |
1030 |
public String run() { |
1031 |
setPathProperty(path, property); |
1032 |
return "${" + property + '}'; // NOI18N |
1033 |
} |
950 |
}); |
1034 |
}); |
951 |
} |
1035 |
} |
952 |
|
1036 |
|
Lines 1127-1132
Link Here
|
1127 |
private static final Pattern FOREIGN_FILE_REFERENCE = Pattern.compile("\\$\\{reference\\.([^.${}]+)\\.([^.${}]+)\\.([\\d&&[^.${}]]+)\\}"); // NOI18N |
1211 |
private static final Pattern FOREIGN_FILE_REFERENCE = Pattern.compile("\\$\\{reference\\.([^.${}]+)\\.([^.${}]+)\\.([\\d&&[^.${}]]+)\\}"); // NOI18N |
1128 |
private static final Pattern FOREIGN_FILE_REFERENCE_OLD = Pattern.compile("\\$\\{reference\\.([^.${}]+)\\.([^.${}]+)\\}"); // NOI18N |
1212 |
private static final Pattern FOREIGN_FILE_REFERENCE_OLD = Pattern.compile("\\$\\{reference\\.([^.${}]+)\\.([^.${}]+)\\}"); // NOI18N |
1129 |
private static final Pattern FOREIGN_PLAIN_FILE_REFERENCE = Pattern.compile("\\$\\{file\\.reference\\.([^${}]+)\\}"); // NOI18N |
1213 |
private static final Pattern FOREIGN_PLAIN_FILE_REFERENCE = Pattern.compile("\\$\\{file\\.reference\\.([^${}]+)\\}"); // NOI18N |
|
|
1214 |
private static final Pattern LIBRARY_REFERENCE = Pattern.compile("\\$\\{libs\\.([^${}]+)\\.[^${}]+\\}"); // NOI18N |
1130 |
|
1215 |
|
1131 |
/** |
1216 |
/** |
1132 |
* Try to find an <code>AntArtifact</code> object corresponding to a given |
1217 |
* Try to find an <code>AntArtifact</code> object corresponding to a given |
Lines 1304-1310
Link Here
|
1304 |
File absolutePath = FileUtil.normalizeFile(PropertyUtils.resolveFile(originalPath, value)); |
1389 |
File absolutePath = FileUtil.normalizeFile(PropertyUtils.resolveFile(originalPath, value)); |
1305 |
|
1390 |
|
1306 |
//TODO: extra base dir relativization: |
1391 |
//TODO: extra base dir relativization: |
1307 |
if (!CollocationQuery.areCollocated(absolutePath, projectDir)) { |
1392 |
|
|
|
1393 |
//mkleint: removed CollocationQuery.areCollocated() reference |
1394 |
// when AlwaysRelativeCQI gets removed the condition resolves to false more frequently. |
1395 |
// that might not be desirable. |
1396 |
String rel = PropertyUtils.relativizeFile(projectDir, absolutePath); |
1397 |
if (rel == null) { |
1308 |
pubRemove.add(key); |
1398 |
pubRemove.add(key); |
1309 |
privAdd.put(key, absolutePath.getAbsolutePath()); |
1399 |
privAdd.put(key, absolutePath.getAbsolutePath()); |
1310 |
} |
1400 |
} |
Lines 1338-1345
Link Here
|
1338 |
} |
1428 |
} |
1339 |
|
1429 |
|
1340 |
//TODO: extra base dir relativization: |
1430 |
//TODO: extra base dir relativization: |
1341 |
if (CollocationQuery.areCollocated(absolutePath, projectDir)) { |
1431 |
|
1342 |
pubAdd.put(key, PropertyUtils.relativizeFile(projectDir, absolutePath)); |
1432 |
//mkleint: removed CollocationQuery.areCollocated() reference |
|
|
1433 |
// when AlwaysRelativeCQI gets removed the condition resolves to false more frequently. |
1434 |
// that might not be desirable. |
1435 |
String rel = PropertyUtils.relativizeFile(projectDir, absolutePath); |
1436 |
if (rel != null) { |
1437 |
pubAdd.put(key, rel); |
1343 |
} |
1438 |
} |
1344 |
} |
1439 |
} |
1345 |
|
1440 |
|
Lines 1357-1363
Link Here
|
1357 |
h.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, pub); |
1452 |
h.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, pub); |
1358 |
h.putProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH, priv); |
1453 |
h.putProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH, priv); |
1359 |
} |
1454 |
} |
|
|
1455 |
|
1456 |
/** |
1457 |
* Create a reference to one volume of a library. |
1458 |
* @param library a library |
1459 |
* @param volumeType a legal volume type for that library |
1460 |
* @return substitutable Ant text suitable for inclusion in a properties file when also loading {@link AntProjectHelper#getProjectLibrariesPropertyProvider} |
1461 |
* @see #findLibrary |
1462 |
* @since org.netbeans.modules.project.ant/1 1.19 |
1463 |
*/ |
1464 |
public String createLibraryReference(Library library, String volumeType) { |
1465 |
if (library.getManager() == LibraryManager.getDefault()) { |
1466 |
if (h.isSharableProject()) { |
1467 |
throw new IllegalArgumentException("Project ["+ // NOI18N |
1468 |
h.getProjectDirectory()+ |
1469 |
"] is sharable and cannot reference global library "+library.getName()); // NOI18N |
1470 |
} |
1471 |
} else { |
1472 |
if (!ProjectLibraryProvider.isReachableLibrary(library, h)) { |
1473 |
throw new IllegalArgumentException("Project ["+ // NOI18N |
1474 |
h.getProjectDirectory()+ |
1475 |
"] cannot reference a library from "+library.getManager().getLocation()); // NOI18N |
1476 |
} |
1477 |
} |
1478 |
return "${libs." + library.getName() + "." + volumeType + "}"; // NOI18N |
1479 |
} |
1480 |
|
1481 |
/** |
1482 |
* Gets a library manager corresponding to library definition file referred to from this project. |
1483 |
* There is no guarantee that the manager is the same object from call to call |
1484 |
* even if the location remain the same; in particular, it is <em>not</em> guaranteed that |
1485 |
* the manager match that returned from {@link Library#getManager} for libraries added |
1486 |
* from {@link #createLibraryReference}. |
1487 |
* @return a library manager associated with project's libraries or null if project is |
1488 |
* not shared (will not include {@link LibraryManager#getDefault}) |
1489 |
* @see #createLibraryReference |
1490 |
* @see #findLibrary |
1491 |
* @since org.netbeans.modules.project.ant/1 1.19 |
1492 |
*/ |
1493 |
public LibraryManager getProjectLibraryManager() { |
1494 |
return ProjectLibraryProvider.getProjectLibraryManager(h); |
1495 |
} |
1496 |
|
1497 |
/** |
1498 |
* Gets a library manager of the given project. |
1499 |
* There is no guarantee that the manager is the same object from call to call |
1500 |
* even if the project is the same; in particular, it is <em>not</em> guaranteed that |
1501 |
* the manager match that returned from {@link Library#getManager} for libraries added |
1502 |
* from {@link #createLibraryReference}. |
1503 |
* @return a library manager associated with project's libraries or null if project is |
1504 |
* not shared (will not include {@link LibraryManager#getDefault}) |
1505 |
* {@link LibraryManager#getDefault}) |
1506 |
* @since org.netbeans.modules.project.ant/1 1.19 |
1507 |
*/ |
1508 |
public static LibraryManager getProjectLibraryManager(Project p) { |
1509 |
AuxiliaryConfiguration aux = p.getLookup().lookup(AuxiliaryConfiguration.class); |
1510 |
if (aux != null) { |
1511 |
File libFile = ProjectLibraryProvider.getLibrariesLocation(aux, |
1512 |
FileUtil.toFile(p.getProjectDirectory())); |
1513 |
if (libFile != null) { |
1514 |
try { |
1515 |
return LibraryManager.forLocation(libFile.toURI().toURL()); |
1516 |
} catch (MalformedURLException e) { |
1517 |
// ok, no project manager |
1518 |
Logger.getLogger(ReferenceHelper.class.getName()).info( |
1519 |
"library manager cannot be found for "+libFile+". "+e.toString()); //NOI18N |
1520 |
} |
1521 |
} |
1522 |
} |
1523 |
return null; |
1524 |
} |
1525 |
|
1526 |
/** |
1527 |
* Copy global IDE library to sharable libraries definition associated with |
1528 |
* this project. Does nothing if project is not sharable. |
1529 |
* When a library with same name already exists in sharable location, the new one |
1530 |
* is copied with generated unique name. |
1531 |
* |
1532 |
* <p>Library creation is done under write access of ProjectManager.mutex(). |
1533 |
* |
1534 |
* @param lib global library; cannot be null |
1535 |
* @return newly created sharable version of library in case of sharable |
1536 |
* project or given global library in case of non-sharable project |
1537 |
* @throws java.io.IOException if there was problem copying files |
1538 |
* @since org.netbeans.modules.project.ant/1 1.19 |
1539 |
*/ |
1540 |
public Library copyLibrary(Library lib) throws IOException { |
1541 |
Parameters.notNull("lib", lib); |
1542 |
if (lib.getManager() != LibraryManager.getDefault()) { |
1543 |
throw new IllegalArgumentException("cannot copy non-global library "+lib.getManager().getLocation()); // NOI18N |
1544 |
} |
1545 |
if (!h.isSharableProject()) { |
1546 |
return lib; |
1547 |
} |
1548 |
File mainPropertiesFile = h.resolveFile(h.getLibrariesLocation()); |
1549 |
return ProjectLibraryProvider.copyLibrary(lib, mainPropertiesFile.toURI().toURL(), true); |
1550 |
} |
1360 |
|
1551 |
|
|
|
1552 |
/** |
1553 |
* Returns library import handler which imports global library to sharable |
1554 |
* one. See {@link LibraryChooser#showDialog} for usage of this handler. |
1555 |
* @return copy handler |
1556 |
* @since org.netbeans.modules.project.ant/1 1.19 |
1557 |
*/ |
1558 |
public LibraryChooser.LibraryImportHandler getLibraryChooserImportHandler() { |
1559 |
return new LibraryChooser.LibraryImportHandler() { |
1560 |
public Library importLibrary(Library library) throws IOException { |
1561 |
return copyLibrary(library); |
1562 |
} |
1563 |
}; |
1564 |
} |
1565 |
/** |
1566 |
* Tries to find a library by name in library manager associated with the project. |
1567 |
* It is <em>not</em> guaranteed that any returned library is an identical object to one which passed in to {@link #createLibraryReference}. |
1568 |
* @param name either a bare {@link Library#getName}, or a reference as created by {@link #createLibraryReference} |
1569 |
* @return the first library to be found matching that name, or null if not found |
1570 |
* @since org.netbeans.modules.project.ant/1 1.19 |
1571 |
*/ |
1572 |
public Library findLibrary(String name) { |
1573 |
Matcher m = LIBRARY_REFERENCE.matcher(name); |
1574 |
if (m.matches()) { |
1575 |
name = m.group(1); |
1576 |
} |
1577 |
LibraryManager mgr = getProjectLibraryManager(); |
1578 |
if (mgr == null) { |
1579 |
return LibraryManager.getDefault().getLibrary(name); |
1580 |
} else { |
1581 |
return mgr.getLibrary(name); |
1582 |
} |
1583 |
} |
1584 |
|
1361 |
/** |
1585 |
/** |
1362 |
* A raw reference descriptor representing a link to a foreign project |
1586 |
* A raw reference descriptor representing a link to a foreign project |
1363 |
* and some build artifact used from it. |
1587 |
* and some build artifact used from it. |
Lines 1638-1644
Link Here
|
1638 |
public String getID() { |
1862 |
public String getID() { |
1639 |
return artifactID; |
1863 |
return artifactID; |
1640 |
} |
1864 |
} |
1641 |
|
1865 |
|
|
|
1866 |
/** |
1867 |
* Get an extra properties used for target execution. |
1868 |
* @return a set of properties (may be empty but not null) |
1869 |
*/ |
1642 |
public Properties getProperties() { |
1870 |
public Properties getProperties() { |
1643 |
return props; |
1871 |
return props; |
1644 |
} |
1872 |
} |