import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Task; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.Namespace; import org.dom4j.QName; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; /** * Update dendences in project xml on all modules in nbm form locatated is the specified folder * @author pzajac */ public class UpdateFeatureDeps extends Task { private static final String NBM_EXT = ".nbm"; private static final String PRJ_NAME_SPACE = "http://www.netbeans.org/ns/project/1"; private static final String DATA_NAME_SPACE = "http://www.netbeans.org/ns/nb-module-project/3"; private File nbmFolder; private File projectXmlFile; private String cnd; /** entries for unit testing in order to avoid scanning modules */ /** Creates a new instance of FixTestClassPath */ public UpdateFeatureDeps() { } public void setProjectXml(File projectXml) { projectXmlFile = projectXml; } public void setNbmFolder(File file) { nbmFolder = file; } public void execute() throws BuildException { // read project xml try { // test mode doesn't override project.xml if (projectXmlFile == null || !projectXmlFile.isFile()) { throw new BuildException("project.xml file doesn't exist."); } if (nbmFolder == null || !nbmFolder.isDirectory()) { throw new BuildException("nbmfolder doesn't exist or is not folder: " + nbmFolder); } // start parse project xml SAXReader reader = new SAXReader(); Document doc = reader.read(projectXmlFile); Element rootElement = doc.getRootElement(); Element data = getDel(getPel(rootElement, "configuration"), "data"); Element dataEl = getDel(data,"module-dependencies"); cnd = getDel(data,"code-name-base").getText(); if (dataEl == null) { throw new BuildException("No module dependencies tag in " + projectXmlFile); } // remove all current dependecies dataEl.clearContent(); // add new dependencies for (File file : nbmFolder.listFiles()) { if (file.isFile() && file.getName().endsWith(NBM_EXT)) { // create dependency from nbm file ZipFile zf = new ZipFile(file); try { String name = file.getName(); String cnb = name.replace(NBM_EXT,""); System.out.println("cnb:" + cnb); ZipEntry entry = zf.getEntry("netbeans/config/Modules/" + cnb + ".xml"); InputStream is = zf.getInputStream(entry); try { Document moduleDoc = reader.read(is); List elements = moduleDoc.selectNodes("//module/param"); String specVersion = null; String release = null; for (Object elObj : elements) { Element el = (Element) elObj; String nameVal = el.attributeValue("name"); if ("specversion".equals(nameVal)) { specVersion = el.getTextTrim(); } if ("release".equals(nameVal)) { release = el.getTextTrim(); } } addDepEntry(cnb, specVersion, release, dataEl); } finally { is.close(); } } finally { zf.close(); } } } // store project.properties and project.xml FileWriter fileWriter = new FileWriter( projectXmlFile ); try { XMLWriter writer = new XMLWriter(fileWriter,OutputFormat.createPrettyPrint() ); writer.write( doc ); writer.close(); } finally { fileWriter.close(); } } catch (IOException ioe) { throw new BuildException(ioe); } catch (DocumentException de) { throw new BuildException(de); } } private void addDepEntry(String name, String specVersion, String releaseVersion, Element dataEl) { name = name.replace('-', '.'); if (!cnd.equals(name)) { Element depEl = addDel(dataEl,"dependency"); Element cndEl = addDel(depEl,"code-name-base"); cndEl.setText(name); Element runEl = addDel(depEl,"run-dependency"); if (releaseVersion != null) { Element relEl = addDel(runEl,"release-version"); relEl.setText(releaseVersion); } Element specEl = addDel(runEl,"specification-version"); specEl.setText( specVersion); } } private Element getPel(Element el,String name) { return el.element(QName.get(name, Namespace.get(PRJ_NAME_SPACE))); } private Element getDel(Element el,String name) { return el.element(QName.get(name, Namespace.get(DATA_NAME_SPACE))); } private Element addDel(Element dataEl, String name) { return dataEl.addElement(QName.get(name, Namespace.get(DATA_NAME_SPACE))); } }