[KARAF-2888] Refactor repository validation so that we use a single pass, cache the created Schema
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/1306af5f Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/1306af5f Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/1306af5f Branch: refs/heads/master Commit: 1306af5f222e8bf8925d0e42b0062ec3d367c1d3 Parents: a9b763f Author: Guillaume Nodet <gno...@gmail.com> Authored: Fri Apr 11 11:14:16 2014 +0200 Committer: Guillaume Nodet <gno...@gmail.com> Committed: Fri Apr 11 19:20:03 2014 +0200 ---------------------------------------------------------------------- features/pom.xml | 4 + .../org/apache/karaf/features/Repository.java | 3 +- .../karaf/features/internal/model/JaxbUtil.java | 149 ++++++++++++++----- .../internal/service/BootFeaturesInstaller.java | 2 +- .../internal/service/FeatureValidationUtil.java | 80 +--------- .../internal/service/FeaturesServiceImpl.java | 4 +- .../internal/service/RepositoryImpl.java | 15 +- .../service/FeaturesValidationTest.java | 49 +++++- .../karaf/tooling/features/CreateKarMojo.java | 23 ++- .../features/GenerateDescriptorMojo.java | 9 +- .../karaf/tooling/features/InstallKarsMojo.java | 9 +- .../features/GenerateDescriptorMojoTest.java | 9 +- .../java/org/apache/karaf/util/XmlUtils.java | 64 +++++--- 13 files changed, 231 insertions(+), 189 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/karaf/blob/1306af5f/features/pom.xml ---------------------------------------------------------------------- diff --git a/features/pom.xml b/features/pom.xml index 5013057..d722ada 100644 --- a/features/pom.xml +++ b/features/pom.xml @@ -129,12 +129,16 @@ org.apache.felix.resolver, org.apache.felix.utils.version, org.apache.felix.utils.manifest, + org.apache.karaf.util, org.apache.karaf.util.collections, org.apache.karaf.util.json, org.apache.karaf.util.tracker, org.osgi.service.resolver, org.osgi.service.repository </Private-Package> + <Embed-Dependency> + org.apache.karaf.util;inline="org/apache/karaf/util/XmlUtils*.class" + </Embed-Dependency> <Bundle-Activator> org.apache.karaf.features.internal.osgi.Activator </Bundle-Activator> http://git-wip-us.apache.org/repos/asf/karaf/blob/1306af5f/features/src/main/java/org/apache/karaf/features/Repository.java ---------------------------------------------------------------------- diff --git a/features/src/main/java/org/apache/karaf/features/Repository.java b/features/src/main/java/org/apache/karaf/features/Repository.java index 6ee96da..3ea12ec 100644 --- a/features/src/main/java/org/apache/karaf/features/Repository.java +++ b/features/src/main/java/org/apache/karaf/features/Repository.java @@ -16,6 +16,7 @@ */ package org.apache.karaf.features; +import java.io.IOException; import java.net.URI; /** @@ -23,7 +24,7 @@ import java.net.URI; */ public interface Repository { - String getName(); + String getName() throws IOException; URI getURI(); http://git-wip-us.apache.org/repos/asf/karaf/blob/1306af5f/features/src/main/java/org/apache/karaf/features/internal/model/JaxbUtil.java ---------------------------------------------------------------------- diff --git a/features/src/main/java/org/apache/karaf/features/internal/model/JaxbUtil.java b/features/src/main/java/org/apache/karaf/features/internal/model/JaxbUtil.java index 39c057a..2036452 100644 --- a/features/src/main/java/org/apache/karaf/features/internal/model/JaxbUtil.java +++ b/features/src/main/java/org/apache/karaf/features/internal/model/JaxbUtil.java @@ -23,19 +23,27 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.Writer; +import java.net.URL; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import javax.xml.XMLConstants; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; -import javax.xml.bind.ValidationEvent; -import javax.xml.bind.ValidationEventHandler; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; -import javax.xml.stream.XMLInputFactory; +import javax.xml.namespace.QName; +import javax.xml.transform.dom.DOMSource; import javax.xml.transform.sax.SAXSource; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; import org.apache.karaf.features.FeaturesNamespaces; +import org.apache.karaf.util.XmlUtils; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXException; @@ -45,7 +53,6 @@ import org.xml.sax.helpers.XMLFilterImpl; public class JaxbUtil { - public static final XMLInputFactory XMLINPUT_FACTORY = XMLInputFactory.newInstance(); private static final JAXBContext FEATURES_CONTEXT; static { try { @@ -75,45 +82,113 @@ public class JaxbUtil { /** * Read in a Features from the input stream. * - * @param in input stream to read + * @param uri uri to read * @param validate whether to validate the input. * @return a Features read from the input stream - * @throws ParserConfigurationException is the SAX parser can not be configured - * @throws SAXException if there is an xml problem - * @throws JAXBException if the xml cannot be marshalled into a T. */ - public static Features unmarshal(InputStream in, boolean validate) { - InputSource inputSource = new InputSource(in); + public static Features unmarshal(String uri, boolean validate) { + if (validate) { + return unmarshalValidate(uri, null); + } else { + return unmarshalNoValidate(uri, null); + } + } + + public static Features unmarshal(String uri, InputStream stream, boolean validate) { + if (validate) { + return unmarshalValidate(uri, stream); + } else { + return unmarshalNoValidate(uri, stream); + } + } - SAXParserFactory factory = SAXParserFactory.newInstance(); - factory.setNamespaceAware(true); - factory.setValidating(validate); - SAXParser parser; + private static Features unmarshalValidate(String uri, InputStream stream) { try { - parser = factory.newSAXParser(); - - - Unmarshaller unmarshaller = FEATURES_CONTEXT.createUnmarshaller(); - unmarshaller.setEventHandler(new ValidationEventHandler() { - public boolean handleEvent(ValidationEvent validationEvent) { - System.out.println(validationEvent); - return false; + Document doc; + if (stream != null) { + doc = XmlUtils.parse(stream); + doc.setDocumentURI(uri); + } else { + doc = XmlUtils.parse(uri); } - }); - XMLFilter xmlFilter = new NoSourceAndNamespaceFilter(parser.getXMLReader()); - xmlFilter.setContentHandler(unmarshaller.getUnmarshallerHandler()); + Schema schema = getSchema(doc.getDocumentElement().getNamespaceURI()); + try { + schema.newValidator().validate(new DOMSource(doc)); + } catch (SAXException e) { + throw new IllegalArgumentException("Unable to validate " + uri, e); + } - SAXSource source = new SAXSource(xmlFilter, inputSource); + fixDom(doc, doc.getDocumentElement()); + Unmarshaller unmarshaller = FEATURES_CONTEXT.createUnmarshaller(); + return (Features) unmarshaller.unmarshal(new DOMSource(doc)); - return (Features)unmarshaller.unmarshal(source); - - } catch (ParserConfigurationException e) { - throw new RuntimeException(e); - } catch (JAXBException e) { - throw new RuntimeException(e); - } catch (SAXException e) { - throw new RuntimeException(e); + + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new RuntimeException("Unable to load " + uri, e); + } + } + + private static Map<String, Schema> schemas = new ConcurrentHashMap<String, Schema>(); + private static Schema getSchema(String namespace) throws SAXException { + Schema schema = schemas.get(namespace); + if (schema == null) { + String schemaLocation; + if (FeaturesNamespaces.URI_1_0_0.equals(namespace)) { + schemaLocation = "/org/apache/karaf/features/karaf-features-1.0.0.xsd"; + } else if (FeaturesNamespaces.URI_1_1_0.equals(namespace)) { + schemaLocation = "/org/apache/karaf/features/karaf-features-1.1.0.xsd"; + } else if (FeaturesNamespaces.URI_1_2_0.equals(namespace)) { + schemaLocation = "/org/apache/karaf/features/karaf-features-1.2.0.xsd"; + } else if (FeaturesNamespaces.URI_1_3_0.equals(namespace)) { + schemaLocation = "/org/apache/karaf/features/karaf-features-1.3.0.xsd"; + } else { + throw new IllegalArgumentException("Unsupported namespace: " + namespace); + } + + SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + // root element has namespace - we can use schema validation + URL url = JaxbUtil.class.getResource(schemaLocation); + if (url == null) { + throw new IllegalStateException("Could not find resource: " + schemaLocation); + } + schema = factory.newSchema(new StreamSource(url.toExternalForm())); + schemas.put(namespace, schema); + } + return schema; + } + + + private static void fixDom(Document doc, Node node) { + if (node.getNamespaceURI() != null && !FeaturesNamespaces.URI_CURRENT.equals(node.getNamespaceURI())) { + doc.renameNode(node, FeaturesNamespaces.URI_CURRENT, node.getLocalName()); + } + NodeList children = node.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + fixDom(doc, children.item(i)); + } + } + + private static Features unmarshalNoValidate(String uri, InputStream stream) { + try { + Unmarshaller unmarshaller = FEATURES_CONTEXT.createUnmarshaller(); + XMLFilter xmlFilter = new NoSourceAndNamespaceFilter(XmlUtils.xmlReader()); + xmlFilter.setContentHandler(unmarshaller.getUnmarshallerHandler()); + + + InputSource is = new InputSource(uri); + if (stream != null) { + is.setByteStream(stream); + } + SAXSource source = new SAXSource(xmlFilter, new InputSource(uri)); + return (Features) unmarshaller.unmarshal(source); + + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new RuntimeException("Unable to load " + uri, e); } } http://git-wip-us.apache.org/repos/asf/karaf/blob/1306af5f/features/src/main/java/org/apache/karaf/features/internal/service/BootFeaturesInstaller.java ---------------------------------------------------------------------- diff --git a/features/src/main/java/org/apache/karaf/features/internal/service/BootFeaturesInstaller.java b/features/src/main/java/org/apache/karaf/features/internal/service/BootFeaturesInstaller.java index eaa9ba0..5b362b8 100644 --- a/features/src/main/java/org/apache/karaf/features/internal/service/BootFeaturesInstaller.java +++ b/features/src/main/java/org/apache/karaf/features/internal/service/BootFeaturesInstaller.java @@ -89,7 +89,7 @@ public class BootFeaturesInstaller { try { featuresService.addRepository(URI.create(repo)); } catch (Exception e) { - LOGGER.error("Error installing boot feature repository " + repo); + LOGGER.error("Error installing boot feature repository " + repo, e); } } } http://git-wip-us.apache.org/repos/asf/karaf/blob/1306af5f/features/src/main/java/org/apache/karaf/features/internal/service/FeatureValidationUtil.java ---------------------------------------------------------------------- diff --git a/features/src/main/java/org/apache/karaf/features/internal/service/FeatureValidationUtil.java b/features/src/main/java/org/apache/karaf/features/internal/service/FeatureValidationUtil.java index 8fb161e..6903dc0 100644 --- a/features/src/main/java/org/apache/karaf/features/internal/service/FeatureValidationUtil.java +++ b/features/src/main/java/org/apache/karaf/features/internal/service/FeatureValidationUtil.java @@ -15,38 +15,15 @@ */ package org.apache.karaf.features.internal.service; -import java.io.IOException; -import java.io.InputStream; import java.net.URI; -import java.net.URLConnection; -import javax.xml.XMLConstants; -import javax.xml.namespace.QName; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamSource; -import javax.xml.validation.Schema; -import javax.xml.validation.SchemaFactory; -import javax.xml.validation.Validator; - -import org.apache.karaf.features.FeaturesNamespaces; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.w3c.dom.Document; -import org.xml.sax.SAXException; +import org.apache.karaf.features.internal.model.JaxbUtil; /** * Utility class which fires XML Schema validation. */ public class FeatureValidationUtil { - public static final QName FEATURES_0_0 = new QName("features"); - public static final QName FEATURES_1_0 = new QName("http://karaf.apache.org/xmlns/features/v1.0.0", "features"); - public static final QName FEATURES_1_1 = new QName("http://karaf.apache.org/xmlns/features/v1.1.0", "features"); - public static final QName FEATURES_1_2 = new QName("http://karaf.apache.org/xmlns/features/v1.2.0", "features"); - private static final Logger LOGGER = LoggerFactory.getLogger(FeatureValidationUtil.class); - /** * Runs schema validation. * @@ -54,60 +31,7 @@ public class FeatureValidationUtil { * @throws Exception When validation fails. */ public static void validate(URI uri) throws Exception { - Document doc = load(uri); - - QName name = new QName(doc.getDocumentElement().getNamespaceURI(), doc.getDocumentElement().getLocalName()); - - if (FeaturesNamespaces.FEATURES_0_0_0.equals(name)) { - LOGGER.warn("Old style feature file without namespace found (URI: {}). This format is deprecated and support for it will soon be removed", uri); - return; - } else if (FeaturesNamespaces.FEATURES_1_0_0.equals(name)) { - validate(doc, "/org/apache/karaf/features/karaf-features-1.0.0.xsd"); - } else if (FeaturesNamespaces.FEATURES_1_1_0.equals(name)) { - validate(doc, "/org/apache/karaf/features/karaf-features-1.1.0.xsd"); - } else if (FeaturesNamespaces.FEATURES_1_2_0.equals(name)) { - validate(doc, "/org/apache/karaf/features/karaf-features-1.2.0.xsd"); - } else if (FeaturesNamespaces.FEATURES_1_3_0.equals(name)) { - validate(doc, "/org/apache/karaf/features/karaf-features-1.3.0.xsd"); - } - else { - throw new IllegalArgumentException("Unrecognized root element: " + name); - } - } - - private static Document load(URI uri) throws IOException, SAXException, ParserConfigurationException { - InputStream stream = null; - try { - URLConnection conn; - try { - conn = uri.toURL().openConnection(); - } catch (IllegalArgumentException e) { - throw new IllegalArgumentException("invalid URI: " + uri, e); - } - conn.setDefaultUseCaches(false); - stream = conn.getInputStream(); - // load document and check the root element for namespace declaration - DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance(); - dFactory.setNamespaceAware(true); - return dFactory.newDocumentBuilder().parse(stream); - } finally { - if (stream != null) { - stream.close(); - } - } - } - - private static void validate(Document doc, String schemaLocation) throws SAXException { - SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); - // root element has namespace - we can use schema validation - Schema schema = factory.newSchema(new StreamSource(FeatureValidationUtil.class.getResourceAsStream(schemaLocation))); - // create schema by reading it from an XSD file: - Validator validator = schema.newValidator(); - try { - validator.validate(new DOMSource(doc)); - } catch (Exception e) { - throw new IllegalArgumentException("Unable to validate " + doc.getDocumentURI(), e); - } + JaxbUtil.unmarshal(uri.toASCIIString(), true); } } http://git-wip-us.apache.org/repos/asf/karaf/blob/1306af5f/features/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java ---------------------------------------------------------------------- diff --git a/features/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java b/features/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java index 0bd1e67..65223d5 100644 --- a/features/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java +++ b/features/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java @@ -281,10 +281,8 @@ public class FeaturesServiceImpl implements FeaturesService { // public Repository loadRepository(URI uri) throws Exception { - // TODO: merge validation and loading by loading the DOM, validating, unmarshalling - FeatureValidationUtil.validate(uri); RepositoryImpl repo = new RepositoryImpl(uri); - repo.load(); + repo.load(true); return repo; } http://git-wip-us.apache.org/repos/asf/karaf/blob/1306af5f/features/src/main/java/org/apache/karaf/features/internal/service/RepositoryImpl.java ---------------------------------------------------------------------- diff --git a/features/src/main/java/org/apache/karaf/features/internal/service/RepositoryImpl.java b/features/src/main/java/org/apache/karaf/features/internal/service/RepositoryImpl.java index 4bf1502..56e5102 100644 --- a/features/src/main/java/org/apache/karaf/features/internal/service/RepositoryImpl.java +++ b/features/src/main/java/org/apache/karaf/features/internal/service/RepositoryImpl.java @@ -42,13 +42,8 @@ public class RepositoryImpl implements Repository { return uri; } - public String getName() { - // TODO: catching this exception is ugly - try { - load(); - } catch (IOException e) { - throw new RuntimeException("Unable to load repository", e); - } + public String getName() throws IOException { + load(); return features.getName(); } @@ -70,6 +65,10 @@ public class RepositoryImpl implements Repository { public void load() throws IOException { + load(false); + } + + public void load(boolean validate) throws IOException { if (features == null) { try { InputStream inputStream = uri.toURL().openStream(); @@ -83,7 +82,7 @@ public class RepositoryImpl implements Repository { } }; try { - features = JaxbUtil.unmarshal(inputStream, false); + features = JaxbUtil.unmarshal(uri.toASCIIString(), inputStream, validate); } finally { inputStream.close(); } http://git-wip-us.apache.org/repos/asf/karaf/blob/1306af5f/features/src/test/java/org/apache/karaf/features/internal/service/FeaturesValidationTest.java ---------------------------------------------------------------------- diff --git a/features/src/test/java/org/apache/karaf/features/internal/service/FeaturesValidationTest.java b/features/src/test/java/org/apache/karaf/features/internal/service/FeaturesValidationTest.java index f3ca2e6..9e33ee3 100644 --- a/features/src/test/java/org/apache/karaf/features/internal/service/FeaturesValidationTest.java +++ b/features/src/test/java/org/apache/karaf/features/internal/service/FeaturesValidationTest.java @@ -16,20 +16,29 @@ */ package org.apache.karaf.features.internal.service; +import java.io.InputStream; +import java.net.URL; + +import org.apache.karaf.features.Repository; +import org.apache.karaf.features.internal.model.Features; +import org.apache.karaf.features.internal.model.JaxbUtil; import org.junit.Test; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; public class FeaturesValidationTest { @Test - public void testNoNs() throws Exception { - FeatureValidationUtil.validate(getClass().getResource("f01.xml").toURI()); + public void testNs10() throws Exception { + FeatureValidationUtil.validate(getClass().getResource("f02.xml").toURI()); } @Test - public void testNs10() throws Exception { - FeatureValidationUtil.validate(getClass().getResource("f02.xml").toURI()); + public void testNs10Unmarshall() throws Exception { + URL url = getClass().getResource("f02.xml"); + Features features = JaxbUtil.unmarshal(url.toExternalForm(), true); + assertNotNull(features); } @Test @@ -38,13 +47,22 @@ public class FeaturesValidationTest { } @Test + public void testNs10NoNameUnmarshall() throws Exception { + URL url = getClass().getResource("f03.xml"); + Features features = JaxbUtil.unmarshal(url.toExternalForm(), true); + assertNotNull(features); + } + + @Test public void testNs11() throws Exception { FeatureValidationUtil.validate(getClass().getResource("f04.xml").toURI()); } @Test - public void testNs12() throws Exception { - FeatureValidationUtil.validate(getClass().getResource("f06.xml").toURI()); + public void testNs11Unmarshall() throws Exception { + URL url = getClass().getResource("f04.xml"); + Features features = JaxbUtil.unmarshal(url.toExternalForm(), true); + assertNotNull(features); } @Test @@ -58,8 +76,27 @@ public class FeaturesValidationTest { } @Test + public void testNs12() throws Exception { + FeatureValidationUtil.validate(getClass().getResource("f06.xml").toURI()); + } + + @Test + public void testNs12Unmarshall() throws Exception { + URL url = getClass().getResource("f06.xml"); + Features features = JaxbUtil.unmarshal(url.toExternalForm(), true); + assertNotNull(features); + } + + @Test public void testNs13() throws Exception { FeatureValidationUtil.validate(getClass().getResource("f07.xml").toURI()); } + @Test + public void testNs13Unmarshall() throws Exception { + URL url = getClass().getResource("f07.xml"); + Features features = JaxbUtil.unmarshal(url.toExternalForm(), true); + assertNotNull(features); + } + } http://git-wip-us.apache.org/repos/asf/karaf/blob/1306af5f/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/CreateKarMojo.java ---------------------------------------------------------------------- diff --git a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/CreateKarMojo.java b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/CreateKarMojo.java index c30f7c0..71ff485 100644 --- a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/CreateKarMojo.java +++ b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/CreateKarMojo.java @@ -212,23 +212,18 @@ public class CreateKarMojo extends MojoSupport { private List<Artifact> readResources(File featuresFile) throws MojoExecutionException { List<Artifact> resources = new ArrayList<Artifact>(); try { - InputStream in = new FileInputStream(featuresFile); - try { - Features features = JaxbUtil.unmarshal(in, false); - for (Feature feature : features.getFeature()) { - for (BundleInfo bundle : feature.getBundles()) { - if (ignoreDependencyFlag || (!ignoreDependencyFlag && !bundle.isDependency())) { - resources.add(resourceToArtifact(bundle.getLocation(), false)); - } - } - for (ConfigFileInfo configFile : feature.getConfigurationFiles()) { - resources.add(resourceToArtifact(configFile.getLocation(), false)); + Features features = JaxbUtil.unmarshal(featuresFile.toURI().toASCIIString(), false); + for (Feature feature : features.getFeature()) { + for (BundleInfo bundle : feature.getBundles()) { + if (ignoreDependencyFlag || (!ignoreDependencyFlag && !bundle.isDependency())) { + resources.add(resourceToArtifact(bundle.getLocation(), false)); } } - return resources; - } finally { - in.close(); + for (ConfigFileInfo configFile : feature.getConfigurationFiles()) { + resources.add(resourceToArtifact(configFile.getLocation(), false)); + } } + return resources; } catch (MojoExecutionException e) { throw e; } catch (Exception e) { http://git-wip-us.apache.org/repos/asf/karaf/blob/1306af5f/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/GenerateDescriptorMojo.java ---------------------------------------------------------------------- diff --git a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/GenerateDescriptorMojo.java b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/GenerateDescriptorMojo.java index 1aff2c6..3cdae4a 100644 --- a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/GenerateDescriptorMojo.java +++ b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/GenerateDescriptorMojo.java @@ -401,14 +401,7 @@ public class GenerateDescriptorMojo extends AbstractLogEnabled implements Mojo { } private Features readFeaturesFile(File featuresFile) throws XMLStreamException, JAXBException, IOException { - Features features; - InputStream in = new FileInputStream(featuresFile); - try { - features = JaxbUtil.unmarshal(in, false); - } finally { - in.close(); - } - return features; + return JaxbUtil.unmarshal(featuresFile.toURI().toASCIIString(), false); } public void setLog(Log log) { http://git-wip-us.apache.org/repos/asf/karaf/blob/1306af5f/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/InstallKarsMojo.java ---------------------------------------------------------------------- diff --git a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/InstallKarsMojo.java b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/InstallKarsMojo.java index c1a6c5f..f58ca37 100644 --- a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/InstallKarsMojo.java +++ b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/InstallKarsMojo.java @@ -425,14 +425,7 @@ public class InstallKarsMojo extends MojoSupport { } else { repoFile = new File(uri); } - InputStream in = new FileInputStream(repoFile); - Features features; - try { - features = JaxbUtil.unmarshal(in, false); - } finally { - in.close(); - } - return features; + return JaxbUtil.unmarshal(repoFile.toURI().toASCIIString(), false); } public void installFeature(org.apache.karaf.features.Feature feature) throws Exception { http://git-wip-us.apache.org/repos/asf/karaf/blob/1306af5f/tooling/karaf-maven-plugin/src/test/java/org/apache/karaf/tooling/features/GenerateDescriptorMojoTest.java ---------------------------------------------------------------------- diff --git a/tooling/karaf-maven-plugin/src/test/java/org/apache/karaf/tooling/features/GenerateDescriptorMojoTest.java b/tooling/karaf-maven-plugin/src/test/java/org/apache/karaf/tooling/features/GenerateDescriptorMojoTest.java index 4b12fda..0eecbd0 100644 --- a/tooling/karaf-maven-plugin/src/test/java/org/apache/karaf/tooling/features/GenerateDescriptorMojoTest.java +++ b/tooling/karaf-maven-plugin/src/test/java/org/apache/karaf/tooling/features/GenerateDescriptorMojoTest.java @@ -23,6 +23,7 @@ import static org.junit.Assert.*; import java.io.ByteArrayOutputStream; import java.io.InputStream; +import java.net.URL; import java.util.List; import javax.xml.bind.JAXBException; @@ -41,9 +42,9 @@ public class GenerateDescriptorMojoTest { @Test public void testReadXml100() throws JAXBException, SAXException, ParserConfigurationException, XMLStreamException { - InputStream in = getClass().getClassLoader().getResourceAsStream("input-features-1.0.0.xml"); + URL url = getClass().getClassLoader().getResource("input-features-1.0.0.xml"); - Features featuresRoot = JaxbUtil.unmarshal(in, false); + Features featuresRoot = JaxbUtil.unmarshal(url.toExternalForm(), false); assertEquals(featuresRoot.getRepository().size(), 1); @@ -61,9 +62,9 @@ public class GenerateDescriptorMojoTest { @Test public void testReadXml1() throws Exception { - InputStream in = getClass().getClassLoader().getResourceAsStream("input-features-1.1.0.xml"); + URL url = getClass().getClassLoader().getResource("input-features-1.1.0.xml"); - Features featuresRoot = JaxbUtil.unmarshal(in, false); + Features featuresRoot = JaxbUtil.unmarshal(url.toExternalForm(), false); List<Feature> featuresList = featuresRoot.getFeature(); http://git-wip-us.apache.org/repos/asf/karaf/blob/1306af5f/util/src/main/java/org/apache/karaf/util/XmlUtils.java ---------------------------------------------------------------------- diff --git a/util/src/main/java/org/apache/karaf/util/XmlUtils.java b/util/src/main/java/org/apache/karaf/util/XmlUtils.java index cbcb593..adfc2e6 100644 --- a/util/src/main/java/org/apache/karaf/util/XmlUtils.java +++ b/util/src/main/java/org/apache/karaf/util/XmlUtils.java @@ -16,17 +16,25 @@ */ package org.apache.karaf.util; -import com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl; -import org.w3c.dom.Document; -import org.xml.sax.ErrorHandler; -import org.xml.sax.SAXException; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.*; -import java.io.File; -import java.io.IOException; +import javax.xml.parsers.SAXParserFactory; +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; + +import org.w3c.dom.Document; +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; /** * Utils class to manipulate XML document in a thread safe way. @@ -35,6 +43,7 @@ public class XmlUtils { private static final ThreadLocal<DocumentBuilderFactory> DOCUMENT_BUILDER_FACTORY = new ThreadLocal<DocumentBuilderFactory>(); private static final ThreadLocal<TransformerFactory> TRANSFORMER_FACTORY = new ThreadLocal<TransformerFactory>(); + private static final ThreadLocal<SAXParserFactory> SAX_PARSER_FACTORY = new ThreadLocal<SAXParserFactory>(); public static Document parse(String uri) throws TransformerException, IOException, SAXException, ParserConfigurationException { DocumentBuilder db = documentBuilder(); @@ -45,6 +54,15 @@ public class XmlUtils { } } + public static Document parse(InputStream stream) throws TransformerException, IOException, SAXException, ParserConfigurationException { + DocumentBuilder db = documentBuilder(); + try { + return db.parse(stream); + } finally { + db.reset(); + } + } + public static Document parse(File f) throws TransformerException, IOException, SAXException, ParserConfigurationException { DocumentBuilder db = documentBuilder(); try { @@ -82,36 +100,40 @@ public class XmlUtils { } } - private static DocumentBuilder documentBuilder() throws ParserConfigurationException { - DocumentBuilderFactory dbf; - if (DOCUMENT_BUILDER_FACTORY.get() == null) { + public static XMLReader xmlReader() throws ParserConfigurationException, SAXException { + SAXParserFactory spf = SAX_PARSER_FACTORY.get(); + if (spf == null) { + spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + SAX_PARSER_FACTORY.set(spf); + } + return spf.newSAXParser().getXMLReader(); + } + + public static DocumentBuilder documentBuilder() throws ParserConfigurationException { + DocumentBuilderFactory dbf = DOCUMENT_BUILDER_FACTORY.get(); + if (dbf == null) { dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); DOCUMENT_BUILDER_FACTORY.set(dbf); - } else { - dbf = DOCUMENT_BUILDER_FACTORY.get(); } return dbf.newDocumentBuilder(); } - private static Transformer transformer() throws TransformerConfigurationException { - TransformerFactory tf; - if (TRANSFORMER_FACTORY.get() == null) { + public static Transformer transformer() throws TransformerConfigurationException { + TransformerFactory tf = TRANSFORMER_FACTORY.get(); + if (tf == null) { tf = TransformerFactory.newInstance(); TRANSFORMER_FACTORY.set(tf); - } else { - tf = TRANSFORMER_FACTORY.get(); } return tf.newTransformer(); } private static Transformer transformer(Source xsltSource) throws TransformerConfigurationException { - TransformerFactory tf; - if (TRANSFORMER_FACTORY.get() == null) { + TransformerFactory tf = TRANSFORMER_FACTORY.get(); + if (tf == null) { tf = TransformerFactory.newInstance(); TRANSFORMER_FACTORY.set(tf); - } else { - tf = TRANSFORMER_FACTORY.get(); } return tf.newTransformer(xsltSource); }