You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by fm...@apache.org on 2009/07/31 18:11:00 UTC
svn commit: r799652 - in /felix/trunk/scr/src:
main/java/org/apache/felix/scr/impl/BundleComponentActivator.java
test/java/org/apache/felix/scr/impl/BundleComponentActivatorTest.java
Author: fmeschbe
Date: Fri Jul 31 16:10:59 2009
New Revision: 799652
URL: http://svn.apache.org/viewvc?rev=799652&view=rev
Log:
FELIX-928 Apply patch by Alin Derhiciu (thanks) and factored the actual descriptor
reading into a separate method.
Added:
felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/BundleComponentActivatorTest.java (with props)
Modified:
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/BundleComponentActivator.java
Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/BundleComponentActivator.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/BundleComponentActivator.java?rev=799652&r1=799651&r2=799652&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/BundleComponentActivator.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/BundleComponentActivator.java Fri Jul 31 16:10:59 2009
@@ -25,6 +25,7 @@
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
+import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
@@ -35,6 +36,7 @@
import org.apache.felix.scr.impl.metadata.ComponentMetadata;
import org.apache.felix.scr.impl.metadata.XmlHandler;
import org.apache.felix.scr.impl.parser.KXml2SAXParser;
+import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.service.component.ComponentException;
import org.osgi.service.log.LogService;
@@ -127,8 +129,8 @@
{
String descriptorLocation = st.nextToken();
- URL descriptorURL = m_context.getBundle().getResource( descriptorLocation );
- if ( descriptorURL == null )
+ URL[] descriptorURLs = findDescriptors( m_context.getBundle(), descriptorLocation );
+ if ( descriptorURLs.length == 0 )
{
// 112.4.1 If an XML document specified by the header cannot be located in the bundle and its attached
// fragments, SCR must log an error message with the Log Service, if present, and continue.
@@ -137,80 +139,150 @@
continue;
}
- InputStream stream = null;
- try
+ // load from the descriptors
+ for ( int i = 0; i < descriptorURLs.length; i++ )
+ {
+ loadDescriptor( descriptorURLs[i] );
+ }
+ }
+ }
+
+
+ /**
+ * Finds component descriptors based on descriptor location.
+ *
+ * @param bundle bundle to search for descriptor files
+ * @param descriptorLocation descriptor location
+ * @return array of descriptors or empty array if none found
+ */
+ static URL[] findDescriptors( final Bundle bundle, final String descriptorLocation )
+ {
+ if ( bundle == null || descriptorLocation == null || descriptorLocation.trim().length() == 0 )
+ {
+ return new URL[0];
+ }
+
+ // for compatibility with previoues versions (<= 1.0.8) use getResource() for non wildcarded entries
+ if ( descriptorLocation.indexOf( "*" ) == -1 )
+ {
+ final URL descriptor = bundle.getResource( descriptorLocation );
+ if ( descriptor == null )
{
- stream = descriptorURL.openStream();
+ return new URL[0];
+ }
+ return new URL[]
+ { descriptor };
+ }
+
+ // split pattern and path
+ final int lios = descriptorLocation.lastIndexOf( "/" );
+ final String path;
+ final String filePattern;
+ if ( lios > 0 )
+ {
+ path = descriptorLocation.substring( 0, lios );
+ filePattern = descriptorLocation.substring( lios + 1 );
+ }
+ else
+ {
+ path = "/";
+ filePattern = descriptorLocation;
+ }
+
+ // find the entries
+ final Enumeration entries = bundle.findEntries( path, filePattern, false );
+ if ( entries == null || !entries.hasMoreElements() )
+ {
+ return new URL[0];
+ }
+
+ // create the result list
+ List urls = new ArrayList();
+ while ( entries.hasMoreElements() )
+ {
+ urls.add( entries.nextElement() );
+ }
+ return ( URL[] ) urls.toArray( new URL[urls.size()] );
+ }
+
+
+ private void loadDescriptor( final URL descriptorURL )
+ {
+ // simple path for log messages
+ final String descriptorLocation = descriptorURL.getPath();
+
+ InputStream stream = null;
+ try
+ {
+ stream = descriptorURL.openStream();
- BufferedReader in = new BufferedReader( new InputStreamReader( stream ) );
- XmlHandler handler = new XmlHandler( m_context.getBundle(), this );
- KXml2SAXParser parser;
+ BufferedReader in = new BufferedReader( new InputStreamReader( stream ) );
+ XmlHandler handler = new XmlHandler( m_context.getBundle(), this );
+ KXml2SAXParser parser;
- parser = new KXml2SAXParser( in );
+ parser = new KXml2SAXParser( in );
- parser.parseXML( handler );
+ parser.parseXML( handler );
- // 112.4.2 Component descriptors may contain a single, root component element
- // or one or more component elements embedded in a larger document
- Iterator i = handler.getComponentMetadataList().iterator();
- while ( i.hasNext() )
+ // 112.4.2 Component descriptors may contain a single, root component element
+ // or one or more component elements embedded in a larger document
+ Iterator i = handler.getComponentMetadataList().iterator();
+ while ( i.hasNext() )
+ {
+ ComponentMetadata metadata = ( ComponentMetadata ) i.next();
+ try
{
- ComponentMetadata metadata = ( ComponentMetadata ) i.next();
- try
- {
- // check and reserve the component name
- m_componentRegistry.checkComponentName( metadata.getName() );
+ // check and reserve the component name
+ m_componentRegistry.checkComponentName( metadata.getName() );
- // validate the component metadata
- metadata.validate( this );
+ // validate the component metadata
+ metadata.validate( this );
- // Request creation of the component manager
- ComponentHolder holder = m_componentRegistry.createComponentHolder( this, metadata );
+ // Request creation of the component manager
+ ComponentHolder holder = m_componentRegistry.createComponentHolder( this, metadata );
- // register the component after validation
- m_componentRegistry.registerComponent( metadata.getName(), holder );
- m_managers.add( holder );
-
- // enable the component
- if ( metadata.isEnabled() )
- {
- holder.enableComponents();
- }
- }
- catch ( Throwable t )
- {
- // There is a problem with this particular component, we'll log the error
- // and proceed to the next one
- log( LogService.LOG_ERROR, "Cannot register Component", metadata, t );
+ // register the component after validation
+ m_componentRegistry.registerComponent( metadata.getName(), holder );
+ m_managers.add( holder );
- // make sure the name is not reserved any more
- m_componentRegistry.unregisterComponent( metadata.getName() );
+ // enable the component
+ if ( metadata.isEnabled() )
+ {
+ holder.enableComponents();
}
}
- }
- catch ( IOException ex )
- {
- // 112.4.1 If an XML document specified by the header cannot be located in the bundle and its attached
- // fragments, SCR must log an error message with the Log Service, if present, and continue.
+ catch ( Throwable t )
+ {
+ // There is a problem with this particular component, we'll log the error
+ // and proceed to the next one
+ log( LogService.LOG_ERROR, "Cannot register Component", metadata, t );
- log( LogService.LOG_ERROR, "Problem reading descriptor entry '" + descriptorLocation + "'", null, ex );
- }
- catch ( Exception ex )
- {
- log( LogService.LOG_ERROR, "General problem with descriptor entry '" + descriptorLocation + "'", null,
- ex );
+ // make sure the name is not reserved any more
+ m_componentRegistry.unregisterComponent( metadata.getName() );
+ }
}
- finally
+ }
+ catch ( IOException ex )
+ {
+ // 112.4.1 If an XML document specified by the header cannot be located in the bundle and its attached
+ // fragments, SCR must log an error message with the Log Service, if present, and continue.
+
+ log( LogService.LOG_ERROR, "Problem reading descriptor entry '" + descriptorLocation + "'", null, ex );
+ }
+ catch ( Exception ex )
+ {
+ log( LogService.LOG_ERROR, "General problem with descriptor entry '" + descriptorLocation + "'", null, ex );
+ }
+ finally
+ {
+ if ( stream != null )
{
- if ( stream != null )
+ try
+ {
+ stream.close();
+ }
+ catch ( IOException ignore )
{
- try
- {
- stream.close();
- }
- catch ( IOException ignore )
- {
- }
}
}
}
Added: felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/BundleComponentActivatorTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/BundleComponentActivatorTest.java?rev=799652&view=auto
==============================================================================
--- felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/BundleComponentActivatorTest.java (added)
+++ felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/BundleComponentActivatorTest.java Fri Jul 31 16:10:59 2009
@@ -0,0 +1,183 @@
+/*
+ * 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.scr.impl;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import junit.framework.TestCase;
+
+import org.easymock.EasyMock;
+import org.osgi.framework.Bundle;
+
+public class BundleComponentActivatorTest extends TestCase
+{
+
+ /**
+ * Test that an empty array is returned for a null bundle.
+ */
+ public void test_findDescriptors_withNullBundle()
+ {
+ final URL[] urls = BundleComponentActivator.findDescriptors( null, "foo.xml" );
+ assertNotNull( "Descriptor array is not null", urls );
+ assertEquals( "Descriptor array length", 0, urls.length );
+ }
+
+ /**
+ * Test that an empty array is returned for a null location.
+ */
+ public void test_findDescriptors_withNullLocation()
+ {
+ final URL[] urls = BundleComponentActivator.findDescriptors( new MockBundle(), null );
+ assertNotNull( "Descriptor array is not null", urls );
+ assertEquals( "Descriptor array length", 0, urls.length );
+ }
+
+ /**
+ * Test that an empty array is returned for an empty location.
+ */
+ public void test_findDescriptors_withEmptyLocation()
+ {
+ final URL[] urls = BundleComponentActivator.findDescriptors( new MockBundle(), "" );
+ assertNotNull( "Descriptor array is not null", urls );
+ assertEquals( "Descriptor array length", 0, urls.length );
+ }
+
+ /**
+ * Test that an empty array is returned for a location containing only blanks.
+ */
+ public void test_findDescriptors_withBlankLocation()
+ {
+ final URL[] urls = BundleComponentActivator.findDescriptors( new MockBundle(), " " );
+ assertNotNull( "Descriptor array is not null", urls );
+ assertEquals( "Descriptor array length", 0, urls.length );
+ }
+
+ /**
+ * Test that when using a non wilcarded location, getResource() will be used (for legacy reasons) and the returned
+ * array is the one returned by bundle method call.
+ *
+ * @throws MalformedURLException unexpected
+ */
+ public void test_findDescriptors_withNonWildcardLocation()
+ throws MalformedURLException
+ {
+ URL descriptor = new URL( "file:foo.xml" );
+ final Bundle bundle = EasyMock.createNiceMock( Bundle.class );
+ EasyMock.expect( bundle.getResource( "/some/location/foo.xml" ) ).andReturn( descriptor );
+
+ EasyMock.replay( new Object[]{ bundle } );
+ final URL[] urls = BundleComponentActivator.findDescriptors( bundle, "/some/location/foo.xml" );
+ EasyMock.verify( new Object[]{ bundle } );
+
+ assertNotNull( "Descriptor array is not null", urls );
+ assertEquals( "Descriptor length", 1, urls.length );
+ assertEquals( "Descriptor", descriptor, urls[ 0 ] );
+ }
+
+ public void findDescriptors_withWildcardLocation( final String location,
+ final String path,
+ final String filePattern )
+ throws MalformedURLException
+ {
+ final URL[] urls = new URL[]
+ {
+ new URL( "file:foo1.xml" ),
+ new URL( "file:foo2.xml" )
+ };
+ final Enumeration de = new Vector( Arrays.asList( urls ) ).elements();
+ final Bundle bundle = EasyMock.createNiceMock( Bundle.class );
+ EasyMock.expect( bundle.findEntries( path, filePattern, false ) ).andReturn( de );
+
+ EasyMock.replay( new Object[]{ bundle } );
+ final URL[] actualUrls = BundleComponentActivator.findDescriptors( bundle, location );
+ EasyMock.verify( new Object[]{ bundle } );
+
+ assertNotNull( "Descriptor array is not null", actualUrls );
+ assertEquals( "Descriptor length", urls.length, actualUrls.length );
+ for( int i = 0; i < actualUrls.length; i++ )
+ {
+ assertEquals( "Descriptor", urls[ i ], actualUrls[ i ] );
+ }
+ }
+
+ /**
+ * Test that when using "*.xml", path will be root of bundle "/" and file pattern will be "*.xml".
+ *
+ * @throws MalformedURLException unexpected
+ */
+ public void test_findDescriptors_withWildcardLocation01()
+ throws MalformedURLException
+ {
+ findDescriptors_withWildcardLocation( "*.xml", "/", "*.xml" );
+ }
+
+ /**
+ * Test that when using "/foo/*.xml", path will be "/foo/" and file pattern will be "*.xml".
+ *
+ * @throws MalformedURLException unexpected
+ */
+ public void test_findDescriptors_withWildcardLocation02()
+ throws MalformedURLException
+ {
+ findDescriptors_withWildcardLocation( "/foo/*.xml", "/foo", "*.xml" );
+ }
+
+ /**
+ * Test that in case that no resources are found (bundle return null) an empty array is returned.
+ *
+ * @throws MalformedURLException unexpected
+ */
+ public void test_findDescriptors_withWildcardLocation_nullEnum()
+ throws MalformedURLException
+ {
+ final Bundle bundle = EasyMock.createNiceMock( Bundle.class );
+ EasyMock.expect( bundle.findEntries( "/", "*.xml", false ) ).andReturn( null );
+
+ EasyMock.replay( new Object[]{ bundle } );
+ final URL[] actualUrls = BundleComponentActivator.findDescriptors( bundle, "*.xml" );
+ EasyMock.verify( new Object[]{ bundle } );
+
+ assertNotNull( "Descriptor array is not null", actualUrls );
+ assertEquals( "Descriptor length", 0, actualUrls.length );
+ }
+
+ /**
+ * Test that in case that no resources are found (bundle return empty enum) an empty array is returned.
+ *
+ * @throws MalformedURLException unexpected
+ */
+ public void test_findDescriptors_withWildcardLocation_emptyEnum()
+ throws MalformedURLException
+ {
+ final Bundle bundle = EasyMock.createNiceMock( Bundle.class );
+ EasyMock.expect( bundle.findEntries( "/", "*.xml", false ) ).andReturn( new Vector().elements() );
+
+ EasyMock.replay( new Object[]{ bundle } );
+ final URL[] actualUrls = BundleComponentActivator.findDescriptors( bundle, "*.xml" );
+ EasyMock.verify( new Object[]{ bundle } );
+
+ assertNotNull( "Descriptor array is not null", actualUrls );
+ assertEquals( "Descriptor length", 0, actualUrls.length );
+ }
+
+}
\ No newline at end of file
Propchange: felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/BundleComponentActivatorTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/BundleComponentActivatorTest.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev Url