Author: fmeschbe Date: Mon Oct 1 07:08:33 2007 New Revision: 580966 URL: http://svn.apache.org/viewvc?rev=580966&view=rev Log: FELIX-110 completion of the current Felix SCR implementation to take into account components <properties> elements
Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/BundleComponentActivator.java felix/trunk/scr/src/main/java/org/apache/felix/scr/XmlHandler.java Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/BundleComponentActivator.java URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/BundleComponentActivator.java?rev=580966&r1=580965&r2=580966&view=diff ============================================================================== --- felix/trunk/scr/src/main/java/org/apache/felix/scr/BundleComponentActivator.java (original) +++ felix/trunk/scr/src/main/java/org/apache/felix/scr/BundleComponentActivator.java Mon Oct 1 07:08:33 2007 @@ -1,4 +1,4 @@ -/* +/* * 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 @@ -77,7 +77,7 @@ * register components with to ensure uniqueness of component names * and to ensure configuration updates. * @param context The bundle context owning the components - * + * * @throws ComponentException if any error occurrs initializing this class */ BundleComponentActivator( ComponentRegistry componentRegistry, ComponentActorThread componentActor, @@ -114,16 +114,16 @@ /** * Gets the MetaData location, parses the meta data and requests the processing * of binder instances - * + * * @param descriptorLocations A comma separated list of locations of * component descriptors. This must not be <code>null</code>. - * + * * @throws IllegalStateException If the bundle has already been uninstalled. */ private void initialize( String descriptorLocations ) { - // 112.4.1: The value of the the header is a comma separated list of XML entries within the Bundle + // 112.4.1: The value of the the header is a comma separated list of XML entries within the Bundle StringTokenizer st = new StringTokenizer( descriptorLocations, ", " ); while ( st.hasMoreTokens() ) @@ -146,7 +146,7 @@ stream = descriptorURL.openStream(); BufferedReader in = new BufferedReader( new InputStreamReader( stream ) ); - XmlHandler handler = new XmlHandler(); + XmlHandler handler = new XmlHandler( m_context.getBundle() ); KXml2SAXParser parser; parser = new KXml2SAXParser( in ); @@ -334,8 +334,8 @@ * then starting a thread to actually enable all components found. * <p> * If no component matching the given name is found the thread is not - * started and the method does nothing. - * + * started and the method does nothing. + * * @param name The name of the component to enable or <code>null</code> to * enable all components. */ @@ -367,8 +367,8 @@ * then starting a thread to actually disable all components found. * <p> * If no component matching the given name is found the thread is not - * started and the method does nothing. - * + * started and the method does nothing. + * * @param name The name of the component to disable or <code>null</code> to * disable all components. */ @@ -401,10 +401,10 @@ * an array containing a single component manager matching the name is * returned if one is registered. Finally, if no component manager with the * given name is registered, <code>null</code> is returned. - * + * * @param name The name of the component manager to return or * <code>null</code> to return an array of all component managers. - * + * * @return An array containing one or more component managers according * to the <code>name</code> parameter or <code>null</code> if no * component manager with the given name is currently registered. @@ -443,7 +443,7 @@ * Schedules the given <code>task</code> for asynchrounous execution or * synchronously runs the task if the thread is not running. If this instance * is [EMAIL PROTECTED] #isActive() not active}, the task is not executed. - * + * * @param task The component task to execute */ void schedule( Runnable task ) @@ -482,7 +482,7 @@ * Method to actually emit the log message. If the LogService is available, * the message will be logged through the LogService. Otherwise the message * is logged to stdout (or stderr in case of LOG_ERROR level messages), - * + * * @param level The log level to log the message at * @param message The message to log * @param ex An optional <code>Throwable</code> whose stack trace is written, Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/XmlHandler.java URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/XmlHandler.java?rev=580966&r1=580965&r2=580966&view=diff ============================================================================== --- felix/trunk/scr/src/main/java/org/apache/felix/scr/XmlHandler.java (original) +++ felix/trunk/scr/src/main/java/org/apache/felix/scr/XmlHandler.java Mon Oct 1 07:08:33 2007 @@ -19,12 +19,18 @@ package org.apache.felix.scr; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Properties; import org.apache.felix.scr.parser.KXml2SAXHandler; import org.apache.felix.scr.parser.ParseException; +import org.osgi.framework.Bundle; /** @@ -36,6 +42,9 @@ public static final String NAMESPACE_URI = "http://www.osgi.org/xmlns/scr/v1.0.0"; + // the bundle containing the XML resource being parsed + private Bundle m_bundle; + // A reference to the current component private ComponentMetadata m_currentComponent; @@ -55,6 +64,14 @@ protected String overrideNamespace; + // creates an instance with the bundle owning the component descriptor + // file parsed by this instance + XmlHandler( Bundle bundle ) + { + m_bundle = bundle; + } + + /** * Method called when a tag opens * @@ -124,7 +141,7 @@ // Set the implementation class name (mandatory) m_currentComponent.setImplementationClassName( attrib.getProperty( "class" ) ); } - // 112.4.5 Properties and Property Elements + // 112.4.5 [...] Property Elements else if ( localName.equals( "property" ) ) { PropertyMetadata prop = new PropertyMetadata(); @@ -149,11 +166,11 @@ // hold the metadata pending m_pendingProperty = prop; } - // TODO: treat the case where a properties file name is provided (p. 292) } + // 112.4.5 Properties [...] Elements else if ( localName.equals( "properties" ) ) { - // TODO: implement the properties tag + readPropertiesEntry( attrib.getProperty( "entry" ) ); } // 112.4.6 Service Element else if ( localName.equals( "service" ) ) @@ -292,5 +309,68 @@ public void setColumnNumber( int columnNumber ) { // Not used + } + + + /** + * Reads the name property file from the bundle owning this descriptor. All + * properties read from the properties file are added to the current + * component's property meta data list. + * + * @param entryName The name of the bundle entry containing the propertes + * to be added. This must not be <code>null</code>. + * + * @throws ParseException If the entry name is <code>null</code> or no + * entry with the given name exists in the bundle or an error occurrs + * reading the properties file. + */ + private void readPropertiesEntry( String entryName ) throws ParseException + { + if ( entryName == null ) + { + throw new ParseException( "Missing entry attribute of properties element", null ); + } + + URL entryURL = m_bundle.getEntry( entryName ); + if ( entryURL == null ) + { + throw new ParseException( "Missing bundle entry " + entryName, null ); + } + + Properties props = new Properties(); + InputStream entryStream = null; + try + { + entryStream = entryURL.openStream(); + props.load( entryStream ); + } + catch ( IOException ioe ) + { + throw new ParseException( "Failed to read properties entry " + entryName, ioe ); + } + finally + { + if ( entryStream != null ) + { + try + { + entryStream.close(); + } + catch ( IOException ignore ) + { + // don't care + } + } + } + + // create PropertyMetadata for the properties from the file + for ( Iterator pi = props.entrySet().iterator(); pi.hasNext(); ) + { + Map.Entry pEntry = ( Map.Entry ) pi.next(); + PropertyMetadata prop = new PropertyMetadata(); + prop.setName( String.valueOf( pEntry.getKey() ) ); + prop.setValue( String.valueOf( pEntry.getValue() ) ); + m_currentComponent.addProperty( prop ); + } } }