2010-12-21 14:25:37 +00:00
|
|
|
package org.apache.maven.artifact.repository;
|
|
|
|
|
2011-06-10 08:33:20 +00:00
|
|
|
import java.io.File;
|
|
|
|
import java.io.FileInputStream;
|
2010-12-21 14:25:37 +00:00
|
|
|
import java.io.FileNotFoundException;
|
|
|
|
import java.io.IOException;
|
2011-06-10 08:33:20 +00:00
|
|
|
import java.io.InputStream;
|
2012-10-18 13:51:02 +00:00
|
|
|
import java.util.ArrayList;
|
2010-12-21 14:25:37 +00:00
|
|
|
import java.util.Hashtable;
|
2012-10-18 13:51:02 +00:00
|
|
|
import java.util.List;
|
2010-12-21 14:25:37 +00:00
|
|
|
import java.util.StringTokenizer;
|
|
|
|
|
|
|
|
import javax.xml.parsers.DocumentBuilder;
|
|
|
|
import javax.xml.parsers.DocumentBuilderFactory;
|
|
|
|
import javax.xml.parsers.ParserConfigurationException;
|
|
|
|
|
2011-06-10 08:33:20 +00:00
|
|
|
import org.w3c.dom.Document;
|
|
|
|
import org.w3c.dom.Element;
|
|
|
|
import org.w3c.dom.NodeList;
|
2010-12-21 14:25:37 +00:00
|
|
|
import org.xml.sax.SAXException;
|
|
|
|
|
|
|
|
public class MavenJPackageDepmap {
|
|
|
|
|
2011-06-10 08:33:20 +00:00
|
|
|
private static class ArtifactDefinition {
|
|
|
|
String groupId = null;
|
|
|
|
String artifactId = null;
|
|
|
|
String version = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @author Stanislav Ochotnicky <sochotnicky@redhat.com>
|
|
|
|
*
|
|
|
|
* This class is used to wrap around fragments that are mapping
|
|
|
|
* artifacts to jar files in our _javadir. These used to be
|
|
|
|
* processed in a macro after every package installation. Fragments
|
|
|
|
* themselves are not proper xml files (they have no root element)
|
|
|
|
* so we have to fix them by wrapping them in one root element.
|
|
|
|
*/
|
|
|
|
private static class WrapFragmentStream extends InputStream {
|
|
|
|
String startTag = "<deps>";
|
|
|
|
String endTag = "</deps>";
|
|
|
|
byte fragmentContent[];
|
|
|
|
int position;
|
|
|
|
|
|
|
|
WrapFragmentStream(String fragmentPath) throws IOException {
|
|
|
|
FileInputStream fin = new FileInputStream(fragmentPath);
|
|
|
|
int nBytes = fin.available();
|
|
|
|
byte tmpContent[] = new byte[nBytes];
|
|
|
|
fin.read(tmpContent);
|
|
|
|
fin.close();
|
|
|
|
byte startBytes[] = startTag.getBytes();
|
|
|
|
byte endBytes[] = endTag.getBytes();
|
|
|
|
fragmentContent = new byte[nBytes + startBytes.length
|
|
|
|
+ endBytes.length];
|
|
|
|
System.arraycopy(startBytes, 0, fragmentContent, 0,
|
|
|
|
startBytes.length);
|
|
|
|
System.arraycopy(tmpContent, 0, fragmentContent, startBytes.length,
|
|
|
|
tmpContent.length);
|
|
|
|
System.arraycopy(endBytes, 0, fragmentContent, startBytes.length
|
|
|
|
+ tmpContent.length, endBytes.length);
|
|
|
|
position = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int read() throws IOException {
|
|
|
|
if (position < fragmentContent.length) {
|
|
|
|
return fragmentContent[position++];
|
|
|
|
} else {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static MavenJPackageDepmap instance;
|
|
|
|
private static Hashtable<String, String> jppArtifactMap;
|
2012-10-18 13:51:02 +00:00
|
|
|
private static Hashtable<String, ArrayList<String>> jppUnversionedArtifactMap;
|
2011-06-10 08:33:20 +00:00
|
|
|
|
|
|
|
private MavenJPackageDepmap() {
|
|
|
|
jppArtifactMap = new Hashtable<String, String>();
|
2012-10-18 13:51:02 +00:00
|
|
|
jppUnversionedArtifactMap = new Hashtable<String, ArrayList<String>>();
|
2011-06-10 08:33:20 +00:00
|
|
|
buildJppArtifactMap();
|
|
|
|
}
|
|
|
|
|
|
|
|
public static MavenJPackageDepmap getInstance() {
|
|
|
|
if (instance == null) {
|
|
|
|
instance = new MavenJPackageDepmap();
|
|
|
|
}
|
|
|
|
|
|
|
|
return instance;
|
|
|
|
}
|
|
|
|
|
2012-10-18 13:51:02 +00:00
|
|
|
/**
|
|
|
|
* This function can be used to query exact version of an artifact.
|
|
|
|
*
|
|
|
|
* @param groupId
|
|
|
|
* @param artifactId
|
|
|
|
* @param version
|
|
|
|
* @return Hashtable mapping for groupId, artifactId and version or null if
|
|
|
|
* exact mapping not found
|
|
|
|
*/
|
2011-06-10 08:33:20 +00:00
|
|
|
public Hashtable<String, String> getMappedInfo(String groupId,
|
|
|
|
String artifactId, String version) {
|
|
|
|
|
|
|
|
Hashtable<String, String> jppDep;
|
|
|
|
String idToCheck, jppCombination;
|
|
|
|
|
2012-10-18 13:51:02 +00:00
|
|
|
idToCheck = groupId + "," + artifactId + "," + version;
|
2011-06-10 08:33:20 +00:00
|
|
|
|
|
|
|
jppCombination = (String) jppArtifactMap.get(idToCheck);
|
2012-10-18 13:51:02 +00:00
|
|
|
jppDep = null;
|
2011-06-10 08:33:20 +00:00
|
|
|
if (jppCombination != null && jppCombination != "") {
|
|
|
|
StringTokenizer st = new StringTokenizer(jppCombination, ",");
|
2012-10-18 13:51:02 +00:00
|
|
|
jppDep = new Hashtable<String, String>();
|
2011-06-10 08:33:20 +00:00
|
|
|
jppDep.put("group", st.nextToken());
|
|
|
|
jppDep.put("artifact", st.nextToken());
|
|
|
|
jppDep.put("version", st.nextToken());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return jppDep;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2012-10-18 13:51:02 +00:00
|
|
|
* This function can be used to query for all possible artifact resolutions.
|
|
|
|
* It works with multiple duplicate gid:aid mappings, but only one should
|
|
|
|
* have unversioned files (default version) to work properly later
|
|
|
|
*
|
|
|
|
* @param groupId
|
|
|
|
* @param artifactId
|
|
|
|
* @param version
|
|
|
|
* @return
|
2011-06-10 08:33:20 +00:00
|
|
|
*/
|
2012-10-18 13:51:02 +00:00
|
|
|
public ArrayList<Hashtable<String, String>> getUnversionedMappedInfo(
|
|
|
|
String groupId, String artifactId, String version) {
|
|
|
|
|
|
|
|
Hashtable<String, String> jppDep;
|
2011-06-10 08:33:20 +00:00
|
|
|
String idToCheck;
|
2012-10-18 13:51:02 +00:00
|
|
|
List<String> maps;
|
2011-06-10 08:33:20 +00:00
|
|
|
|
2012-10-18 13:51:02 +00:00
|
|
|
idToCheck = groupId + "," + artifactId;
|
2011-06-10 08:33:20 +00:00
|
|
|
|
2012-10-18 13:51:02 +00:00
|
|
|
maps = jppUnversionedArtifactMap.get(idToCheck);
|
|
|
|
ArrayList<Hashtable<String, String>> ret = new ArrayList<Hashtable<String, String>>();
|
|
|
|
if (maps != null) {
|
|
|
|
for (String jppPart : maps) {
|
|
|
|
jppDep = new Hashtable<String, String>();
|
|
|
|
StringTokenizer st = new StringTokenizer(jppPart, ",");
|
2011-06-10 08:33:20 +00:00
|
|
|
|
2012-10-18 13:51:02 +00:00
|
|
|
jppDep.put("group", st.nextToken());
|
|
|
|
jppDep.put("artifact", st.nextToken());
|
|
|
|
jppDep.put("version", st.nextToken());
|
|
|
|
|
|
|
|
// we add to index 0 to make it reversed order for compatibility
|
|
|
|
// with older code
|
|
|
|
ret.add(0, jppDep);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ret;
|
2011-06-10 08:33:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private static void buildJppArtifactMap() {
|
|
|
|
|
2012-10-18 13:51:02 +00:00
|
|
|
processDepmapFile("/etc/maven/maven2-versionless-depmap.xml");
|
2011-06-10 08:33:20 +00:00
|
|
|
|
|
|
|
// process fragments in etc
|
|
|
|
File fragmentDir = new File("/etc/maven/fragments");
|
|
|
|
String flist[] = fragmentDir.list();
|
2011-06-22 15:06:41 +00:00
|
|
|
if (flist != null) {
|
|
|
|
java.util.Arrays.sort(flist);
|
2011-06-10 08:33:20 +00:00
|
|
|
for (String fragFilename : flist)
|
|
|
|
processDepmapFile("/etc/maven/fragments/" + fragFilename);
|
2011-06-22 15:06:41 +00:00
|
|
|
}
|
2011-06-10 08:33:20 +00:00
|
|
|
|
|
|
|
// process fragments is usr. Once packages are rebuilt, we can skip
|
|
|
|
// fragments in /etc
|
|
|
|
fragmentDir = new File("/usr/share/maven-fragments");
|
|
|
|
flist = fragmentDir.list();
|
2011-06-22 15:06:41 +00:00
|
|
|
if (flist != null) {
|
|
|
|
java.util.Arrays.sort(flist);
|
2011-06-10 08:33:20 +00:00
|
|
|
for (String fragFilename : flist)
|
|
|
|
processDepmapFile("/usr/share/maven-fragments/" + fragFilename);
|
2011-06-22 15:06:41 +00:00
|
|
|
}
|
2011-06-10 08:33:20 +00:00
|
|
|
|
|
|
|
String customFileName = System.getProperty("maven.local.depmap.file",
|
|
|
|
null);
|
|
|
|
if (customFileName != null) {
|
|
|
|
processDepmapFile(customFileName);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void processDepmapFile(String fileName) {
|
|
|
|
|
|
|
|
Document mapDocument;
|
|
|
|
debug("Loading depmap file: " + fileName);
|
|
|
|
try {
|
|
|
|
DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance();
|
|
|
|
fact.setNamespaceAware(true);
|
|
|
|
DocumentBuilder builder = fact.newDocumentBuilder();
|
|
|
|
// we can wrap even old depmaps, no harm done
|
|
|
|
WrapFragmentStream wfs = new WrapFragmentStream(fileName);
|
|
|
|
mapDocument = builder.parse(wfs);
|
|
|
|
wfs.close();
|
|
|
|
} catch (FileNotFoundException fnfe) {
|
|
|
|
System.err.println("ERROR: Unable to find map file: " + fileName);
|
|
|
|
fnfe.printStackTrace();
|
|
|
|
return;
|
|
|
|
} catch (IOException ioe) {
|
|
|
|
System.err
|
|
|
|
.println("ERROR: I/O exception occured when opening map file");
|
|
|
|
ioe.printStackTrace();
|
|
|
|
return;
|
|
|
|
} catch (ParserConfigurationException pce) {
|
|
|
|
System.err
|
|
|
|
.println("ERROR: Parsing of depmap file failed - configuration");
|
|
|
|
pce.printStackTrace();
|
|
|
|
return;
|
|
|
|
} catch (SAXException se) {
|
|
|
|
System.err.println("ERROR: Parsing of depmap file failed");
|
|
|
|
se.printStackTrace();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
NodeList depNodes = (NodeList) mapDocument
|
|
|
|
.getElementsByTagName("dependency");
|
|
|
|
|
|
|
|
for (int i = 0; i < depNodes.getLength(); i++) {
|
|
|
|
Element depNode = (Element) depNodes.item(i);
|
|
|
|
|
|
|
|
NodeList mavenNodeList = (NodeList) depNode
|
|
|
|
.getElementsByTagName("maven");
|
|
|
|
if (mavenNodeList.getLength() != 1) {
|
|
|
|
debug("Number of maven sub-elements is not 1. Bailing from depmap generation");
|
|
|
|
debug("Maven node: " + depNode.getTextContent());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
ArtifactDefinition mavenAD = getArtifactDefinition((Element) mavenNodeList
|
|
|
|
.item(0));
|
|
|
|
|
|
|
|
ArtifactDefinition jppAD = null;
|
|
|
|
NodeList jppNodeList = (NodeList) depNode
|
|
|
|
.getElementsByTagName("jpp");
|
|
|
|
|
|
|
|
if (jppNodeList.getLength() == 1) {
|
|
|
|
jppAD = getArtifactDefinition((Element) jppNodeList.item(0));
|
2012-10-18 13:51:02 +00:00
|
|
|
debug("*** Adding: " + mavenAD.groupId + ","
|
|
|
|
+ mavenAD.artifactId + " => " + jppAD.groupId + ","
|
|
|
|
+ jppAD.artifactId + "," + jppAD.version + " to map...");
|
|
|
|
|
|
|
|
jppArtifactMap.put(mavenAD.groupId + "," + mavenAD.artifactId
|
|
|
|
+ "," + mavenAD.version, jppAD.groupId + ","
|
|
|
|
+ jppAD.artifactId + "," + jppAD.version);
|
|
|
|
ArrayList<String> maps = jppUnversionedArtifactMap
|
|
|
|
.get(mavenAD.groupId + "," + mavenAD.artifactId);
|
|
|
|
if (maps == null) {
|
|
|
|
maps = new ArrayList<String>();
|
2011-06-10 08:33:20 +00:00
|
|
|
}
|
2012-10-18 13:51:02 +00:00
|
|
|
|
|
|
|
maps.add(jppAD.groupId + "," + jppAD.artifactId + ","
|
|
|
|
+ jppAD.version);
|
|
|
|
|
|
|
|
jppUnversionedArtifactMap.put(mavenAD.groupId + ","
|
|
|
|
+ mavenAD.artifactId, maps);
|
2011-06-10 08:33:20 +00:00
|
|
|
} else {
|
2011-06-22 09:56:09 +00:00
|
|
|
debug("Number of jpp sub-elements is not 1. Dropping dependency for "
|
|
|
|
+ mavenAD.groupId + ":" + mavenAD.artifactId);
|
2012-10-18 13:51:02 +00:00
|
|
|
jppArtifactMap.put(mavenAD.groupId + "," + mavenAD.artifactId
|
|
|
|
+ "," + mavenAD.version, "JPP/maven,empty-dep,"
|
|
|
|
+ mavenAD.version);
|
|
|
|
ArrayList<String> maps = new ArrayList<String>();
|
|
|
|
maps.add("JPP/maven,empty-dep," + mavenAD.version);
|
|
|
|
jppUnversionedArtifactMap.put(mavenAD.groupId + ","
|
|
|
|
+ mavenAD.artifactId, maps);
|
2011-06-10 08:33:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static ArtifactDefinition getArtifactDefinition(Element element) {
|
|
|
|
ArtifactDefinition ad = new ArtifactDefinition();
|
|
|
|
|
|
|
|
NodeList nodes = element.getElementsByTagName("groupId");
|
|
|
|
if (nodes.getLength() != 1) {
|
|
|
|
debug("groupId definition not found in depmap");
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
ad.groupId = nodes.item(0).getTextContent();
|
|
|
|
|
|
|
|
nodes = element.getElementsByTagName("artifactId");
|
|
|
|
if (nodes.getLength() != 1) {
|
|
|
|
debug("artifactId definition not found in depmap");
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
ad.artifactId = nodes.item(0).getTextContent();
|
|
|
|
|
|
|
|
nodes = element.getElementsByTagName("version");
|
|
|
|
if (nodes.getLength() != 1) {
|
|
|
|
ad.version = "DUMMY_VER";
|
|
|
|
} else {
|
|
|
|
ad.version = nodes.item(0).getTextContent();
|
|
|
|
}
|
|
|
|
return ad;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void debug(String msg) {
|
|
|
|
if (System.getProperty("maven.local.debug") != null)
|
|
|
|
System.err.println(msg);
|
|
|
|
}
|
2010-12-21 14:25:37 +00:00
|
|
|
}
|