Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright (c) OSGi Alliance (2002, 2013). All Rights Reserved.
   * 
   * 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.osgi.util.xml;
 
 import java.net.URL;
 import java.util.List;
A BundleActivator class that allows any JAXP compliant XML Parser to register itself as an OSGi parser service. Multiple JAXP compliant parsers can concurrently register by using this BundleActivator class. Bundles who wish to use an XML parser can then use the framework's service registry to locate available XML Parsers with the desired characteristics such as validating and namespace-aware.

The services that this bundle activator enables a bundle to provide are:

The algorithm to find the implementations of the abstract parsers is derived from the JAR file specifications, specifically the Services API.

An XMLParserActivator assumes that it can find the class file names of the factory classes in the following files:

  • /META-INF/services/javax.xml.parsers.SAXParserFactory is a file contained in a jar available to the runtime which contains the implementation class name(s) of the SAXParserFactory.
  • /META-INF/services/javax.xml.parsers.DocumentBuilderFactory is a file contained in a jar available to the runtime which contains the implementation class name(s) of the DocumentBuilderFactory

If either of the files does not exist, XMLParserActivator assumes that the parser does not support that parser type.

XMLParserActivator attempts to instantiate both the SAXParserFactory and the DocumentBuilderFactory. It registers each factory with the framework along with service properties:

  • PARSER_VALIDATING- indicates if this factory supports validating parsers. It's value is a Boolean.
  • PARSER_NAMESPACEAWARE- indicates if this factory supports namespace aware parsers It's value is a Boolean.

Individual parser implementations may have additional features, properties, or attributes which could be used to select a parser with a filter. These can be added by extending this class and overriding the setSAXProperties and setDOMProperties methods.

Author(s):
$Id: c73b3c06188fd8154bea38524e1ee7a15c5ac836 $
ThreadSafe:
 
 public class XMLParserActivator implements BundleActivatorServiceFactory {
Context of this bundle
 
 	private volatile BundleContext	context;
Filename containing the SAX Parser Factory Class name. Also used as the basis for the SERVICE_PID registration property.
	public static final String		SAXFACTORYNAME"javax.xml.parsers.SAXParserFactory";
Filename containing the DOM Parser Factory Class name. Also used as the basis for the SERVICE_PID registration property.
	public static final String		DOMFACTORYNAME"javax.xml.parsers.DocumentBuilderFactory";
Path to the factory class name files
	private static final String		PARSERCLASSFILEPATH"/META-INF/services/";
Fully qualified path name of SAX Parser Factory Class Name file
	public static final String		SAXCLASSFILE + ;
Fully qualified path name of DOM Parser Factory Class Name file
	public static final String		DOMCLASSFILE + ;
SAX Factory Service Description
	private static final String		SAXFACTORYDESCRIPTION"A JAXP Compliant SAX Parser";
DOM Factory Service Description
	private static final String		DOMFACTORYDESCRIPTION"A JAXP Compliant DOM Parser";
Service property specifying if factory is configured to support validating parsers. The value is of type Boolean.
	public static final String		PARSER_VALIDATING"parser.validating";
Service property specifying if factory is configured to support namespace aware parsers. The value is of type Boolean.
	public static final String		PARSER_NAMESPACEAWARE"parser.namespaceAware";
Key for parser factory name property - this must be saved in the parsers properties hashtable so that the parser factory can be instantiated from a ServiceReference
	private static final String		FACTORYNAMEKEY"parser.factoryname";

Called when this bundle is started so the Framework can perform the bundle-specific activities necessary to start this bundle. This method can be used to register services or to allocate any resources that this bundle needs.

This method must complete and return to its caller in a timely manner.

This method attempts to register a SAX and DOM parser with the Framework's service registry.

Parameters:
context The execution context of the bundle being started.
Throws:
java.lang.Exception If this method throws an exception, this bundle is marked as stopped and the Framework will remove this bundle's listeners, unregister all services registered by this bundle, and release all services used by this bundle.
	public void start(BundleContext contextthrows Exception {
		this. = context;
		Bundle parserBundle = context.getBundle();
		// check for sax parsers
		// check for dom parsers
	}

This method has nothing to do as all active service registrations will automatically get unregistered when the bundle stops.

Parameters:
context The execution context of the bundle being stopped.
Throws:
java.lang.Exception If this method throws an exception, the bundle is still marked as stopped, and the Framework will remove the bundle's listeners, unregister all services registered by the bundle, and release all services used by the bundle.
	public void stop(BundleContext contextthrows Exception {
		// framework will automatically unregister the parser services
	}

Given the URL for a file, reads and returns the parser class names. There may be multiple classes specified in this file, one per line. There may also be comment lines in the file, which begin with "#".

Parameters:
parserUrl The URL of the service file containing the parser class names
Returns:
A List of strings containing the parser class names.
Throws:
java.io.IOException if there is a problem reading the URL input stream
	private List getParserFactoryClassNames(URL parserUrlthrows IOException {
		if (parserUrl == null) {
		}
		List v = new ArrayList(1);
		String parserFactoryClassName = null;
		InputStream is = parserUrl.openStream();
		while (true) {
			parserFactoryClassName = br.readLine();
			if (parserFactoryClassName == null) {
				break// end of file reached
			}
			String pfcName = parserFactoryClassName.trim();
			if (pfcName.length() == 0) {
				continue// blank line
			}
			int commentIdx = pfcName.indexOf("#");
			if (commentIdx == 0) { // comment line
				continue;
else
				if (commentIdx < 0) { // no comment on this line
					v.add(pfcName);
else {
					v.add(pfcName.substring(0, commentIdx).trim());
				}
		}
		return v;
	}

Register SAX Parser Factory Services with the framework.

Parameters:
parserFactoryClassNames - a List of String objects containing the names of the parser Factory Classes
Throws:
javax.xml.parsers.FactoryConfigurationError if thrown from getFactory
	private void registerSAXParsers(List parserFactoryClassNamesthrows FactoryConfigurationError {
		Iterator e = parserFactoryClassNames.iterator();
		int index = 0;
		while (e.hasNext()) {
			String parserFactoryClassName = (Stringe.next();
			// create a sax parser factory just to get it's default
			// properties. It will never be used since
			// this class will operate as a service factory and give each
			// service requestor it's own SaxParserFactory
			SAXParserFactory factory = (SAXParserFactorygetFactory(parserFactoryClassName);
			Hashtable properties = new Hashtable(7);
			// figure out the default properties of the parser
			setDefaultSAXProperties(factorypropertiesindex);
			// store the parser factory class name in the properties so that
			// it can be retrieved when getService is called
			// to return a parser factory
			properties.put(parserFactoryClassName);
			// register the factory as a service
			index++;
		}
	}

Set the SAX Parser Service Properties. By default, the following properties are set:

  • SERVICE_DESCRIPTION
  • SERVICE_PID
  • PARSER_VALIDATING- instantiates a parser and queries it to find out whether it is validating or not
  • PARSER_NAMESPACEAWARE- instantiates a parser and queries it to find out whether it is namespace aware or not
    • Parameters:
      factory The SAXParserFactory object
      props Hashtable of service properties.
	private void setDefaultSAXProperties(SAXParserFactory factoryHashtable propsint index) {
		props.put(. + "." + .getBundle().getBundleId() + "." + index);
		setSAXProperties(factoryprops);
	}

Set the customizable SAX Parser Service Properties.

This method attempts to instantiate a validating parser and a namespace aware parser to determine if the parser can support those features. The appropriate properties are then set in the specified properties object.

This method can be overridden to add additional SAX2 features and properties. If you want to be able to filter searches of the OSGi service registry, this method must put a key, value pair into the properties object for each feature or property. For example, properties.put("http://www.acme.com/features/foo", Boolean.TRUE);

Parameters:
factory - the SAXParserFactory object
properties - the properties object for the service
	public void setSAXProperties(SAXParserFactory factoryHashtable properties) {
		// check if this parser can be configured to validate
		boolean validating = true;
		factory.setValidating(true);
		factory.setNamespaceAware(false);
		try {
			factory.newSAXParser();
catch (Exception pce_val) {
			validating = false;
		}
		// check if this parser can be configured to be namespaceaware
		boolean namespaceaware = true;
		factory.setValidating(false);
		factory.setNamespaceAware(true);
		try {
			factory.newSAXParser();
catch (Exception pce_nsa) {
			namespaceaware = false;
		}
		// set the factory values
		factory.setValidating(validating);
		factory.setNamespaceAware(namespaceaware);
		// set the OSGi service properties
		properties.put(new Boolean(namespaceaware));
		properties.put(new Boolean(validating));
	}

Register DOM Parser Factory Services with the framework.

Parameters:
parserFactoryClassNames - a List of String objects containing the names of the parser Factory Classes
Throws:
javax.xml.parsers.FactoryConfigurationError if thrown from getFactory
	private void registerDOMParsers(List parserFactoryClassNamesthrows FactoryConfigurationError {
		Iterator e = parserFactoryClassNames.iterator();
		int index = 0;
		while (e.hasNext()) {
			String parserFactoryClassName = (Stringe.next();
			// create a dom parser factory just to get it's default
			// properties. It will never be used since
			// this class will operate as a service factory and give each
			// service requestor it's own DocumentBuilderFactory
			DocumentBuilderFactory factory = (DocumentBuilderFactorygetFactory(parserFactoryClassName);
			Hashtable properties = new Hashtable(7);
			// figure out the default properties of the parser
			setDefaultDOMProperties(factorypropertiesindex);
			// store the parser factory class name in the properties so that
			// it can be retrieved when getService is called
			// to return a parser factory
			properties.put(parserFactoryClassName);
			// register the factory as a service
			index++;
		}
	}

Set the DOM parser service properties. By default, the following properties are set:
  • SERVICE_DESCRIPTION
  • SERVICE_PID
  • PARSER_VALIDATING
  • PARSER_NAMESPACEAWARE
    • Parameters:
      factory The DocumentBuilderFactory object
      props Hashtable of service properties.
	private void setDefaultDOMProperties(DocumentBuilderFactory factoryHashtable propsint index) {
		props.put(. + "." + .getBundle().getBundleId() + "." + index);
		setDOMProperties(factoryprops);
	}

Set the customizable DOM Parser Service Properties.

This method attempts to instantiate a validating parser and a namespace aware parser to determine if the parser can support those features. The appropriate properties are then set in the specified props object.

This method can be overridden to add additional DOM2 features and properties. If you want to be able to filter searches of the OSGi service registry, this method must put a key, value pair into the properties object for each feature or property. For example, properties.put("http://www.acme.com/features/foo", Boolean.TRUE);

Parameters:
factory - the DocumentBuilderFactory object
props - Hashtable of service properties.
	public void setDOMProperties(DocumentBuilderFactory factoryHashtable props) {
		// check if this parser can be configured to validate
		boolean validating = true;
		factory.setValidating(true);
		factory.setNamespaceAware(false);
		try {
catch (Exception pce_val) {
			validating = false;
		}
		// check if this parser can be configured to be namespaceaware
		boolean namespaceaware = true;
		factory.setValidating(false);
		factory.setNamespaceAware(true);
		try {
catch (Exception pce_nsa) {
			namespaceaware = false;
		}
		// set the factory values
		factory.setValidating(validating);
		factory.setNamespaceAware(namespaceaware);
		// set the OSGi service properties
		props.put(new Boolean(validating));
		props.put(new Boolean(namespaceaware));
	}

Given a parser factory class name, instantiate that class.

Parameters:
parserFactoryClassName A String object containing the name of the parser factory class
Returns:
a parserFactoryClass Object
Pre:
parserFactoryClassName!=null
	private Object getFactory(String parserFactoryClassNamethrows FactoryConfigurationError {
		try {
			return .getBundle().loadClass(parserFactoryClassName).newInstance();
catch (RuntimeException e) {
			throw e;
catch (Exception e) {
		}
	}

Creates a new XML Parser Factory object.

A unique XML Parser Factory object is returned for each call to this method.

The returned XML Parser Factory object will be configured for validating and namespace aware support as specified in the service properties of the specified ServiceRegistration object. This method can be overridden to configure additional features in the returned XML Parser Factory object.

Parameters:
bundle The bundle using the service.
registration The ServiceRegistration object for the service.
Returns:
A new, configured XML Parser Factory object or null if a configuration error was encountered
	public Object getService(Bundle bundleServiceRegistration registration) {
		ServiceReference sref = registration.getReference();
		String parserFactoryClassName = (Stringsref.getProperty();
		// need to set factory properties
		Object factory = getFactory(parserFactoryClassName);
		if (factory instanceof SAXParserFactory) {
else {
			if (factory instanceof DocumentBuilderFactory) {
			}
		}
		return factory;
	}

Releases a XML Parser Factory object.

Parameters:
bundle The bundle releasing the service.
registration The ServiceRegistration object for the service.
service The XML Parser Factory object returned by a previous call to the getService method.
	public void ungetService(Bundle bundleServiceRegistration registrationObject service) {
	}
New to GrepCode? Check out our FAQ X