Commit patch of the Felix-413 issue.
Add the licence header.
Improve javadoc, comments, and error messages.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@590935 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/maven-obr-plugin/src/main/java/org/apache/felix/sandbox/obr/plugin/ObrCleanRepo.java b/maven-obr-plugin/src/main/java/org/apache/felix/sandbox/obr/plugin/ObrCleanRepo.java
new file mode 100644
index 0000000..e3446a2
--- /dev/null
+++ b/maven-obr-plugin/src/main/java/org/apache/felix/sandbox/obr/plugin/ObrCleanRepo.java
@@ -0,0 +1,271 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.sandbox.obr.plugin;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Properties;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Result;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+/**
+ * Clean an OBR repository by finding and removing missing resources.
+ * @goal clean
+ * @phase install
+ * @requiresDependencyResolution compile
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ObrCleanRepo extends AbstractMojo {
+
+ /**
+ * OBR Repository.
+ *
+ * @parameter expression="${obrRepository}"
+ */
+ private String obrRepository;
+
+ /**
+ * Local Repository.
+ *
+ * @parameter expression="${localRepository}"
+ * @required
+ * @readonly
+ */
+ private ArtifactRepository localRepository;
+
+ public void execute() throws MojoExecutionException {
+ // If no OBR repository, return
+ if ("NONE".equalsIgnoreCase(obrRepository)) {
+ return;
+ }
+
+ try {
+ // Compute local repository location
+ String localRepoPath = localRepository.getBasedir();
+ PathFile repositoryXml = normalizeRepositoryPath(obrRepository, localRepoPath);
+
+ // Check if the file exist
+ if (!repositoryXml.isExists()) {
+ getLog().error("The repository file " + repositoryXml.getAbsoluteFilename() + " does not exist");
+ return;
+ }
+
+ Document doc = parseFile(repositoryXml.getFile(), initConstructor());
+ Node finalDocument = cleanDocument(doc.getDocumentElement()); //Analyze existing repository.
+
+ if (finalDocument == null) {
+ getLog().info("Nothing to clean in " + repositoryXml.getAbsoluteFilename());
+ } else {
+ getLog().info("Cleaning...");
+ writeToFile(repositoryXml.getUri(), finalDocument); // Write the new file
+ getLog().info("Repository " + repositoryXml.getAbsoluteFilename() + " updated");
+ }
+ } catch (Exception e) {
+ getLog().error("Exception while cleaning the OBR repository file : " + e.getLocalizedMessage(), e);
+ }
+ }
+
+ /**
+ * Analyze the given XML tree (DOM of the repository file) and remove missing resources.
+ * @param elem : the input XML tree
+ * @return the cleaned XML tree
+ */
+ private Element cleanDocument(Element elem) {
+ NodeList nodes = elem.getElementsByTagName("resource");
+ List toRemove = new ArrayList();
+
+ // First, look for missing resources
+ for (int i = 0; i < nodes.getLength(); i++) {
+ Element n = (Element) nodes.item(i);
+ String value = n.getAttribute("uri");
+
+ String localRepoPath = localRepository.getBasedir();
+ File file = new File(localRepoPath, value);
+
+ if (!file.exists()) {
+ getLog().info(
+ "The bundle " + n.getAttribute("presentationname") + " - " + n.getAttribute("version")
+ + " will be removed");
+ toRemove.add(n);
+ }
+ }
+
+ if (toRemove.size() > 0) {
+ // Then remove missing resources.
+ for (int i = 0; i < toRemove.size(); i++) {
+ elem.removeChild((Node) toRemove.get(i));
+ }
+
+ // If we have to remove resources, we need to update 'lastmodified' attribute
+ SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss.SSS");
+ Date d = new Date();
+ d.setTime(System.currentTimeMillis());
+ elem.setAttribute("lastmodified", format.format(d));
+ return elem;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Initialize the document builder from Xerces.
+ * @return DocumentBuilder ready to create new document
+ * @throws MojoExecutionException : occurs when the instantiation of the document builder fails
+ */
+ private DocumentBuilder initConstructor() throws MojoExecutionException {
+ DocumentBuilder constructor = null;
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ try {
+ constructor = factory.newDocumentBuilder();
+ } catch (ParserConfigurationException e) {
+ getLog().error("Unable to create a new xml document");
+ throw new MojoExecutionException("Cannot create the Document Builder : " + e.getMessage());
+ }
+ return constructor;
+ }
+
+ /**
+ * Open an XML file.
+ * @param filename : XML file path
+ * @param constructor DocumentBuilder get from xerces
+ * @return Document which describes this file
+ * @throws MojoExecutionException occurs when the given file cannot be opened or is a valid XML file.
+ */
+ private Document parseFile(File file, DocumentBuilder constructor) throws MojoExecutionException {
+ if (constructor == null) {
+ return null;
+ }
+ // The document is the root of the DOM tree.
+ getLog().info("Parsing " + file.getAbsolutePath());
+ Document doc = null;
+ try {
+ doc = constructor.parse(file);
+ } catch (SAXException e) {
+ getLog().error("Cannot parse " + file.getAbsolutePath() + " : " + e.getMessage());
+ throw new MojoExecutionException("Cannot parse " + file.getAbsolutePath() + " : " + e.getMessage());
+ } catch (IOException e) {
+ getLog().error("Cannot open " + file.getAbsolutePath() + " : " + e.getMessage());
+ throw new MojoExecutionException("Cannot open " + file.getAbsolutePath() + " : " + e.getMessage());
+ }
+ return doc;
+ }
+
+ /**
+ * write a Node in a xml file.
+ * @param outputFilename URI to the output file
+ * @param treeToBeWrite Node root of the tree to be write in file
+ * @throws MojoExecutionException if the plugin failed
+ */
+ private void writeToFile(URI outputFilename, Node treeToBeWrite) throws MojoExecutionException {
+ // init the transformer
+ Transformer transformer = null;
+ TransformerFactory tfabrique = TransformerFactory.newInstance();
+ try {
+ transformer = tfabrique.newTransformer();
+ } catch (TransformerConfigurationException e) {
+ getLog().error("Unable to write to file: " + outputFilename.toString());
+ throw new MojoExecutionException("Unable to write to file: " + outputFilename.toString() + " : " + e.getMessage());
+ }
+ Properties proprietes = new Properties();
+ proprietes.put("method", "xml");
+ proprietes.put("version", "1.0");
+ proprietes.put("encoding", "ISO-8859-1");
+ proprietes.put("standalone", "yes");
+ proprietes.put("indent", "yes");
+ proprietes.put("omit-xml-declaration", "no");
+ transformer.setOutputProperties(proprietes);
+
+ DOMSource input = new DOMSource(treeToBeWrite);
+
+ File fichier = new File(outputFilename);
+ FileOutputStream flux = null;
+ try {
+ flux = new FileOutputStream(fichier);
+ } catch (FileNotFoundException e) {
+ getLog().error("Unable to write to file: " + fichier.getName());
+ throw new MojoExecutionException("Unable to write to file: " + fichier.getName() + " : " + e.getMessage());
+ }
+ Result output = new StreamResult(flux);
+ try {
+ transformer.transform(input, output);
+ } catch (TransformerException e) {
+ throw new MojoExecutionException("Unable to write to file: " + outputFilename.toString() + " : " + e.getMessage());
+ }
+
+ try {
+ flux.flush();
+ flux.close();
+ } catch (IOException e) {
+ throw new MojoExecutionException("IOException when closing file : " + e.getMessage());
+ }
+
+ }
+
+ private static PathFile normalizeRepositoryPath(String obrPath, String mavenPath) {
+ if (null == obrPath || obrPath.length() == 0) {
+ obrPath = mavenPath + File.separatorChar + "repository.xml";
+ } else if (!obrPath.endsWith(".xml")) {
+ obrPath = obrPath + File.separatorChar + "repository.xml";
+ }
+
+ URI uri;
+ try {
+ uri = new URI(obrPath);
+ } catch (URISyntaxException e) {
+ uri = null;
+ }
+
+ if (null == uri || !uri.isAbsolute()) {
+ File file = new File(obrPath);
+ if (!file.isAbsolute()) {
+ file = new File(mavenPath, obrPath);
+ }
+
+ uri = file.toURI();
+ }
+
+ return new PathFile(uri.toASCIIString());
+ }
+}
diff --git a/maven-obr-plugin/src/main/java/org/apache/felix/sandbox/obr/plugin/ObrUpdate.java b/maven-obr-plugin/src/main/java/org/apache/felix/sandbox/obr/plugin/ObrUpdate.java
index 6bb0da4..4809951 100644
--- a/maven-obr-plugin/src/main/java/org/apache/felix/sandbox/obr/plugin/ObrUpdate.java
+++ b/maven-obr-plugin/src/main/java/org/apache/felix/sandbox/obr/plugin/ObrUpdate.java
@@ -216,7 +216,7 @@
if (!walkOnTree(m_root)) {
// the correct resource node was not found, we must create it
- // we calcul the new id
+ // we compute the new id
int id = -1;
for (int i = 1; i < m_idTab.length; i++) {
if (!m_idTab[i]) {
@@ -252,7 +252,7 @@
}
/**
- * Parse the reporitory descriptor file.
+ * Parse the repository descriptor file.
*
* @return 0 if the bundle is already in the descriptor, else -1
* @throws MojoExecutionException if the plugin failed
@@ -293,7 +293,6 @@
m_root = (Element) m_repoDoc.getDocumentElement();
return 0;
-
}
/**