/**
* Licensed 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.aries.cdi.container.internal.model;
import static org.apache.aries.cdi.container.internal.util.Reflection.cast;
import static org.osgi.service.cdi.CdiConstants.REQUIREMENT_BEANS_ATTRIBUTE;
import static org.osgi.service.cdi.CdiConstants.REQUIREMENT_OSGI_BEANS_ATTRIBUTE;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.apache.aries.cdi.container.internal.util.Throw;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
public abstract class AbstractModelBuilder {
public BeansModel build() {
List<URL> beanDescriptorURLs = new ArrayList<URL>();
List<URL> osgiBeanDescriptorURLs = new ArrayList<URL>();
Map<String, Object> attributes = getAttributes();
List<String> beanDescriptorPaths = cast(attributes.get(REQUIREMENT_BEANS_ATTRIBUTE));
if (beanDescriptorPaths != null) {
for (String descriptorPath : beanDescriptorPaths) {
URL url = getResource(descriptorPath);
if (url != null) {
beanDescriptorURLs.add(url);
}
}
}
List<String> osgiBeansDescriptorPaths = cast(attributes.get(REQUIREMENT_OSGI_BEANS_ATTRIBUTE));
if (osgiBeansDescriptorPaths == null) {
osgiBeansDescriptorPaths = getDefaultResources();
}
if (osgiBeansDescriptorPaths != null) {
for (String descriptorPath : osgiBeansDescriptorPaths) {
URL url = getResource(descriptorPath);
if (url != null) {
osgiBeanDescriptorURLs.add(url);
}
}
}
return parse(osgiBeanDescriptorURLs, beanDescriptorURLs);
}
abstract Map<String, Object> getAttributes();
abstract ClassLoader getClassLoader();
abstract URL getResource(String resource);
abstract List<String> getDefaultResources();
private OSGiBeansHandler getHandler(List<URL> beanDescriptorURLs) {
return new OSGiBeansHandler(beanDescriptorURLs);
}
private BeansModel parse(List<URL> osgiBeansDescriptorURLs, List<URL> beanDescriptorURLs) {
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setValidating(false);
factory.setNamespaceAware(true);
if (osgiBeansDescriptorURLs.isEmpty()) {
throw new IllegalArgumentException("Missing osgi-beans descriptors");
}
SAXParser parser;
try {
parser = factory.newSAXParser();
}
catch (ParserConfigurationException | SAXException e) {
return Throw.exception(e);
}
OSGiBeansHandler handler = getHandler(beanDescriptorURLs);
for (URL osgiBeansDescriptorURL: osgiBeansDescriptorURLs) {
try (InputStream inputStream = osgiBeansDescriptorURL.openStream()) {
InputSource source = new InputSource(inputStream);
if (source.getByteStream().available() == 0) {
throw new IllegalArgumentException(
"Specified osgi-beans descriptor is empty: " + osgiBeansDescriptorURL);
}
try {
parser.setProperty(
"http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema");
parser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaSource", loadXsds());
}
catch (IllegalArgumentException | SAXNotRecognizedException | SAXNotSupportedException e) {
// No op, we just don't validate the XML
}
parser.parse(source, handler);
}
catch (IOException | SAXException e) {
return Throw.exception(e);
}
}
return handler.createBeansModel();
}
private InputSource loadXsd(String name) {
InputStream in = getClassLoader().getResourceAsStream(name);
if (in == null) {
return null;
}
else {
return new InputSource(in);
}
}
private InputSource[] loadXsds() {
List<InputSource> xsds = new ArrayList<InputSource>();
for (XmlSchema schema : XmlSchema.values()) {
InputSource source = loadXsd(schema.getFileName());
if (source != null) {
xsds.add(source);
}
}
return xsds.toArray(new InputSource[0]);
}
}