package org.apache.maven.artifact.repository.layout; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.StringTokenizer; import java.io.InputStream; import java.io.File; import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; import org.jdom.input.SAXBuilder; import org.xml.sax.InputSource; public class MavenJPackageDepmap { private static MavenJPackageDepmap instance; private static Hashtable jppArtifactMap; /** * * @author Stanislav Ochotnicky * * 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 = ""; String endTag = ""; 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 MavenJPackageDepmap() { jppArtifactMap = new Hashtable(); buildJppArtifactMap(); } public static MavenJPackageDepmap getInstance() { if (instance == null) { instance = new MavenJPackageDepmap(); } return instance; } public Hashtable getMappedInfo(Hashtable mavenDep) { return getMappedInfo((String) mavenDep.get("group"), (String) mavenDep.get("artifact"), (String) mavenDep.get("version")); } public Hashtable getMappedInfo(String groupId, String artifactId, String version) { Hashtable jppDep; String idToCheck, jppCombination; if (System.getProperty("maven2.ignore.versions") == null && System.getProperty("maven2.jpp.mode") == null) { idToCheck = groupId+","+artifactId+","+version; } else { idToCheck = groupId+","+artifactId; } jppCombination = (String) jppArtifactMap.get(idToCheck); //System.err.println("*** " + groupId+","+artifactId+","+version + " => " + jppCombination); jppDep = new Hashtable(); if (jppCombination != null && jppCombination != "") { StringTokenizer st = new StringTokenizer(jppCombination, ","); jppDep.put("group", st.nextToken()); jppDep.put("artifact",st.nextToken()); jppDep.put("version",st.nextToken()); } else { jppDep.put("group", groupId); jppDep.put("artifact", artifactId); jppDep.put("version", version); } return jppDep; } /** * Returns whether or not the given dependency should be dropped. */ public boolean shouldEliminate(String groupId, String artifactId, String version) { String idToCheck; if (System.getProperty("maven2.ignore.versions") == null && System.getProperty("maven2.jpp.mode") == null) { idToCheck = groupId+","+artifactId+","+version; } else { idToCheck = groupId+","+artifactId; } return jppArtifactMap.get(idToCheck) != null && jppArtifactMap.get(idToCheck).equals(""); } private static void buildJppArtifactMap() { try{ if (System.getProperty("maven2.ignore.versions") != null || System.getProperty("maven2.jpp.mode") != null) { debug("Processing file: /usr/share/java-utils/xml/maven2-versionless-depmap.xml"); processDepmapFile(new FileInputStream("/etc/maven/maven2-versionless-depmap.xml")); } } catch (FileNotFoundException e) { System.err.println("WARNING: Unable to find versionless map" ); e.printStackTrace(); } catch (IOException e) { System.err.println("WARNING: I/O exception occured when opening versionless map file"); e.printStackTrace(); } // process fragments in etc File fragmentDir = new File("/etc/maven/fragments"); String flist[] = fragmentDir.list(); if (flist != null) { java.util.Arrays.sort(flist); for (String fragFilename : flist) { try { processDepmapFile(new WrapFragmentStream("/etc/maven/fragments/" + fragFilename)); } catch (IOException e) { System.err.println("WARNING: I/O exception occured when opening etc map file" + fragFilename); e.printStackTrace(); } } } // process fragments is usr. Once packages are rebuilt, we can skip // fragments in /etc fragmentDir = new File("/usr/share/maven-fragments"); flist = fragmentDir.list(); if (flist != null) { java.util.Arrays.sort(flist); for (String fragFilename : flist) { try { processDepmapFile(new WrapFragmentStream("/usr/share/maven-fragments/" + fragFilename)); } catch (IOException e) { System.err.println("WARNING: I/O exception occured when opening usr map file" + fragFilename); e.printStackTrace(); } } } String customFileName = System.getProperty("maven2.jpp.depmap.file", null); try { if (customFileName != null) { debug("Processing file: " + customFileName); processDepmapFile(new FileInputStream(customFileName)); } } catch (FileNotFoundException e) { System.err.println("ERROR: Unable to find custom map file: " + customFileName); e.printStackTrace(); } catch (IOException e) { System.err.println("ERROR: I/O exception occured when opening map file"); e.printStackTrace(); } } private static void processDepmapFile(InputStream file) { Document mapDocument; try { mapDocument = (new SAXBuilder()).build(new InputSource(file)); } catch (IOException ioe) { System.err.println("ERROR: I/O exception occured when opening map file"); ioe.printStackTrace(); return; } catch (JDOMException jde) { System.err.println("ERROR: Unable to instantiate parser"); jde.printStackTrace(); return; } List l = mapDocument.getRootElement().getChildren("dependency"); Iterator i = l.iterator(); while (i.hasNext()) { Element depElement = (Element) i.next(); Element mElem = depElement.getChild("maven"); Element jppElem = depElement.getChild("jpp"); String mG = mElem.getChildText("groupId"); String mA = mElem.getChildText("artifactId"); String mV = mElem.getChildText("version"); // jppElem == null => drop this dependency if (jppElem != null) { String jppG = jppElem.getChildText("groupId"); String jppA = jppElem.getChildText("artifactId"); String jppV = jppElem.getChildText("version"); if (System.getProperty("maven2.ignore.versions") == null && System.getProperty("maven2.jpp.mode") == null) { debug("*** Adding: " + mG+","+mA+","+mV + " => " + jppG+","+jppA+","+jppV + " to map..."); jppArtifactMap.put(mG+","+mA+","+mV, jppG+","+jppA+","+jppV); } else { debug("*** Adding: " + mG+","+mA + " => " + jppG+","+jppA+","+jppV + " to map..."); jppArtifactMap.put(mG+","+mA, jppG+","+jppA+","+jppV); } } else { debug("*** Adding: " + mG+","+mA+"," + " => " + "JPP/maven2,empty-dep,"+mV + " to map..."); jppArtifactMap.put(mG+","+mA, "JPP/maven2,empty-dep,"+mV); } } } private static void debug(String msg) { if (System.getProperty("maven2.jpp.debug") != null) System.err.println(msg); } }