FELIX-639 add some logging for unexpected elements in the XML file and
add some very simple Logger interface helping with the logging in the
component metadata parsing and setup.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@741708 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/BundleComponentActivator.java b/scr/src/main/java/org/apache/felix/scr/impl/BundleComponentActivator.java
index fa24dfd..ee62499 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/BundleComponentActivator.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/BundleComponentActivator.java
@@ -42,7 +42,7 @@
* a single bundle. It will read information from the metadata.xml file
* descriptors and create the corresponding managers.
*/
-class BundleComponentActivator
+class BundleComponentActivator implements Logger
{
// global component registration
private ComponentRegistry m_componentRegistry;
@@ -146,7 +146,7 @@
stream = descriptorURL.openStream();
BufferedReader in = new BufferedReader( new InputStreamReader( stream ) );
- XmlHandler handler = new XmlHandler( m_context.getBundle() );
+ XmlHandler handler = new XmlHandler( m_context.getBundle(), this );
KXml2SAXParser parser;
parser = new KXml2SAXParser( in );
@@ -489,7 +489,7 @@
* @param ex An optional <code>Throwable</code> whose stack trace is written,
* or <code>null</code> to not log a stack trace.
*/
- void log( int level, String message, ComponentMetadata metadata, Throwable ex )
+ public void log( int level, String message, ComponentMetadata metadata, Throwable ex )
{
if ( m_logLevel >= level )
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/ComponentMetadata.java b/scr/src/main/java/org/apache/felix/scr/impl/ComponentMetadata.java
index ecc798e..ee27ab5 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/ComponentMetadata.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/ComponentMetadata.java
@@ -69,7 +69,6 @@
// Flag that is set once the component is verified (its properties cannot be changed)
private boolean m_validated = false;
-
/////////////////////////////////////////// SETTERS //////////////////////////////////////
/**
@@ -317,16 +316,7 @@
/**
* Method used to verify if the semantics of this metadata are correct
*/
- void validate()
- {
- validate( null );
- }
-
-
- /**
- * Method used to verify if the semantics of this metadata are correct
- */
- void validate( BundleComponentActivator bundleComponentActivator )
+ void validate( Logger logger )
{
// nothing to do if already validated
if ( m_validated )
@@ -373,11 +363,8 @@
// flag duplicates
if ( !refs.add( refMeta.getName() ) )
{
- if ( bundleComponentActivator != null )
- {
- bundleComponentActivator.log( LogService.LOG_WARNING, "Detected duplicate reference name: \""
- + refMeta.getName() + "\"", this, null );
- }
+ logger.log( LogService.LOG_WARNING, "Detected duplicate reference name: \"" + refMeta.getName() + "\"",
+ this, null );
}
}
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/XmlHandler.java b/scr/src/main/java/org/apache/felix/scr/impl/XmlHandler.java
index 1f05b43..b144734 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/XmlHandler.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/XmlHandler.java
@@ -27,6 +27,7 @@
import org.apache.felix.scr.impl.parser.KXml2SAXHandler;
import org.apache.felix.scr.impl.parser.ParseException;
import org.osgi.framework.Bundle;
+import org.osgi.service.log.LogService;
/**
@@ -39,7 +40,10 @@
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;
+ private final Bundle m_bundle;
+
+ // logger for any messages
+ private final Logger m_logger;
// A reference to the current component
private ComponentMetadata m_currentComponent;
@@ -65,9 +69,10 @@
// creates an instance with the bundle owning the component descriptor
// file parsed by this instance
- XmlHandler( Bundle bundle )
+ XmlHandler( Bundle bundle, Logger logger )
{
m_bundle = bundle;
+ m_logger = logger;
}
@@ -226,6 +231,13 @@
m_currentComponent.addDependency( ref );
}
+
+ // unexpected element
+ else
+ {
+ m_logger.log( LogService.LOG_INFO, "Ignoring unsupported element " + localName + " (bundle "
+ + m_bundle.getLocation() + ")", null, null );
+ }
}
catch ( Exception ex )
{
@@ -233,6 +245,13 @@
throw new ParseException( "Exception during parsing", ex );
}
}
+
+ // unexpected namespace
+ else
+ {
+ m_logger.log( LogService.LOG_INFO, "Ignoring unsupported element {" + uri + "}" + localName + " (bundle "
+ + m_bundle.getLocation() + ")", null, null );
+ }
}
diff --git a/scr/src/test/java/org/apache/felix/scr/impl/ComponentMetadataTest.java b/scr/src/test/java/org/apache/felix/scr/impl/ComponentMetadataTest.java
index 10dd3a2..2e79705 100644
--- a/scr/src/test/java/org/apache/felix/scr/impl/ComponentMetadataTest.java
+++ b/scr/src/test/java/org/apache/felix/scr/impl/ComponentMetadataTest.java
@@ -27,6 +27,9 @@
public class ComponentMetadataTest extends TestCase
{
+ private TestLogger logger = new TestLogger();
+
+
// test various combinations of component metadata with respect to
// -- immediate: true, false, unset
// -- factory: set, unset
@@ -37,24 +40,24 @@
{
// immediate is default true if no service element is defined
final ComponentMetadata cm0 = createComponentMetadata( null, null );
- cm0.validate();
+ cm0.validate( logger );
assertTrue( "Component without service must be immediate", cm0.isImmediate() );
// immediate is explicit true
final ComponentMetadata cm1 = createComponentMetadata( Boolean.TRUE, null );
- cm1.validate();
+ cm1.validate( logger );
assertTrue( "Component must be immediate", cm1.isImmediate() );
// immediate is explicit true
final ComponentMetadata cm2 = createComponentMetadata( Boolean.TRUE, null );
cm2.setService( createServiceMetadata( null ) );
- cm2.validate();
+ cm2.validate( logger );
assertTrue( "Component must be immediate", cm2.isImmediate() );
// immediate is explicit true
final ComponentMetadata cm3 = createComponentMetadata( Boolean.TRUE, null );
cm3.setService( createServiceMetadata( Boolean.FALSE ) );
- cm3.validate();
+ cm3.validate( logger );
assertTrue( "Component must be immediate", cm3.isImmediate() );
// validation failure of immediate with service factory
@@ -62,7 +65,7 @@
cm4.setService( createServiceMetadata( Boolean.TRUE ) );
try
{
- cm4.validate();
+ cm4.validate( logger );
fail( "Expect validation failure for immediate service factory" );
}
catch ( ComponentException ce )
@@ -77,44 +80,44 @@
// immediate is default false if service element is defined
final ComponentMetadata cm0 = createComponentMetadata( null, null );
cm0.setService( createServiceMetadata( null ) );
- cm0.validate();
+ cm0.validate( logger );
assertFalse( "Component with service must be delayed", cm0.isImmediate() );
// immediate is default false if service element is defined
final ComponentMetadata cm1 = createComponentMetadata( null, null );
cm1.setService( createServiceMetadata( Boolean.TRUE ) );
- cm1.validate();
+ cm1.validate( logger );
assertFalse( "Component with service must be delayed", cm1.isImmediate() );
// immediate is default false if service element is defined
final ComponentMetadata cm2 = createComponentMetadata( null, null );
cm2.setService( createServiceMetadata( Boolean.FALSE ) );
- cm2.validate();
+ cm2.validate( logger );
assertFalse( "Component with service must be delayed", cm2.isImmediate() );
// immediate is false if service element is defined
final ComponentMetadata cm3 = createComponentMetadata( Boolean.FALSE, null );
cm3.setService( createServiceMetadata( null ) );
- cm3.validate();
+ cm3.validate( logger );
assertFalse( "Component with service must be delayed", cm3.isImmediate() );
// immediate is false if service element is defined
final ComponentMetadata cm4 = createComponentMetadata( Boolean.FALSE, null );
cm4.setService( createServiceMetadata( Boolean.TRUE ) );
- cm4.validate();
+ cm4.validate( logger );
assertFalse( "Component with service must be delayed", cm4.isImmediate() );
// immediate is false if service element is defined
final ComponentMetadata cm5 = createComponentMetadata( Boolean.FALSE, null );
cm5.setService( createServiceMetadata( Boolean.FALSE ) );
- cm5.validate();
+ cm5.validate( logger );
assertFalse( "Component with service must be delayed", cm5.isImmediate() );
// explicit delayed fails when there is no service
final ComponentMetadata cm6 = createComponentMetadata( Boolean.FALSE, null );
try
{
- cm6.validate();
+ cm6.validate( logger );
fail( "Expect validation failure for delayed component without service" );
}
catch ( ComponentException ce )
@@ -128,19 +131,19 @@
{
// immediate is default false if factory is defined
final ComponentMetadata cm0 = createComponentMetadata( null, "factory" );
- cm0.validate();
+ cm0.validate( logger );
assertFalse( "Component with factory must be delayed", cm0.isImmediate() );
// immediate is false if factory is defined
final ComponentMetadata cm1 = createComponentMetadata( Boolean.FALSE, "factory" );
- cm1.validate();
+ cm1.validate( logger );
assertFalse( "Component with factory must be delayed", cm1.isImmediate() );
// immediate is default false if factory is defined
final ComponentMetadata cm2 = createComponentMetadata( Boolean.TRUE, "factory" );
try
{
- cm2.validate();
+ cm2.validate( logger );
fail( "Expect validation failure for immediate factory component" );
}
catch ( ComponentException ce )
@@ -151,13 +154,13 @@
// immediate is default false if factory is defined
final ComponentMetadata cm10 = createComponentMetadata( null, "factory" );
cm10.setService( createServiceMetadata( null ) );
- cm10.validate();
+ cm10.validate( logger );
assertFalse( "Component with factory must be delayed", cm10.isImmediate() );
// immediate is false if factory is defined
final ComponentMetadata cm11 = createComponentMetadata( Boolean.FALSE, "factory" );
cm11.setService( createServiceMetadata( null ) );
- cm11.validate();
+ cm11.validate( logger );
assertFalse( "Component with factory must be delayed", cm11.isImmediate() );
// immediate is default false if factory is defined
@@ -165,7 +168,7 @@
cm12.setService( createServiceMetadata( null ) );
try
{
- cm12.validate();
+ cm12.validate( logger );
fail( "Expect validation failure for immediate factory component" );
}
catch ( ComponentException ce )
@@ -176,13 +179,13 @@
// immediate is default false if factory is defined
final ComponentMetadata cm20 = createComponentMetadata( null, "factory" );
cm20.setService( createServiceMetadata( Boolean.FALSE ) );
- cm20.validate();
+ cm20.validate( logger );
assertFalse( "Component with factory must be delayed", cm20.isImmediate() );
// immediate is false if factory is defined
final ComponentMetadata cm21 = createComponentMetadata( Boolean.FALSE, "factory" );
cm21.setService( createServiceMetadata( Boolean.FALSE ) );
- cm21.validate();
+ cm21.validate( logger );
assertFalse( "Component with factory must be delayed", cm21.isImmediate() );
// immediate is default false if factory is defined
@@ -190,7 +193,7 @@
cm22.setService( createServiceMetadata( Boolean.FALSE ) );
try
{
- cm22.validate();
+ cm22.validate( logger );
fail( "Expect validation failure for immediate factory component" );
}
catch ( ComponentException ce )
@@ -203,7 +206,7 @@
cm30.setService( createServiceMetadata( Boolean.TRUE ) );
try
{
- cm30.validate();
+ cm30.validate( logger );
fail( "Expect validation failure for factory component with service factory" );
}
catch ( ComponentException ce )
@@ -216,7 +219,7 @@
cm31.setService( createServiceMetadata( Boolean.TRUE ) );
try
{
- cm31.validate();
+ cm31.validate( logger );
fail( "Expect validation failure for factory component with service factory" );
}
catch ( ComponentException ce )
@@ -229,7 +232,7 @@
cm32.setService( createServiceMetadata( Boolean.TRUE ) );
try
{
- cm32.validate();
+ cm32.validate( logger );
fail( "Expect validation failure for immediate factory component with service factory" );
}
catch ( ComponentException ce )
@@ -240,6 +243,24 @@
}
+ public void testReference()
+ {
+ // two references, should validate
+ final ComponentMetadata cm1 = createComponentMetadata( Boolean.TRUE, null );
+ cm1.addDependency( createReferenceMetadata( "name1" ) );
+ cm1.addDependency( createReferenceMetadata( "name2" ) );
+ cm1.validate( logger );
+
+ // two references, must warn
+ final ComponentMetadata cm2 = createComponentMetadata( Boolean.TRUE, null );
+ cm2.addDependency( createReferenceMetadata( "name1" ) );
+ cm2.addDependency( createReferenceMetadata( "name1" ) );
+ cm2.validate( logger );
+ assertTrue( "Expected warning for duplicate reference name", logger.lastMessage != null
+ && logger.lastMessage.indexOf( "Detected duplicate reference name" ) >= 0 );
+ }
+
+
private ComponentMetadata createComponentMetadata( Boolean immediate, String factory )
{
ComponentMetadata meta = new ComponentMetadata();
@@ -267,4 +288,24 @@
}
return meta;
}
+
+
+ private ReferenceMetadata createReferenceMetadata( String name )
+ {
+ ReferenceMetadata meta = new ReferenceMetadata();
+ meta.setName( name );
+ meta.setInterface( "place.holder" );
+ return meta;
+ }
+
+ private static class TestLogger implements Logger
+ {
+ String lastMessage;
+
+
+ public void log( int level, String message, ComponentMetadata metadata, Throwable ex )
+ {
+ lastMessage = message;
+ }
+ }
}