Commit 72b11002 authored by Lionel Seinturier's avatar Lionel Seinturier
Browse files

Bug fix for unwired optional component references: inject the null value.

Associated tests.
parent 4e32fcf3
Tinfi 1.2
---------
* bug fix for unwired optional component references: inject the null value
Tinfi 1.1.2
-----------
* new ContentClassMetaData API to enable the dynamic declaration of injection
......
......@@ -23,8 +23,6 @@ runtime/oo-dyn/
Having a generic initializer should bypass this difficulty.
runtime-oo/
* inject null for unbound client (optional) interfaces (not the reference of a
ServiceReference instance)
* support dependency re-injection on references (see p54 of
http://docs.oasis-open.org/opencsa/sca-j/sca-javacaa-1.1-spec-cd03.pdf)
* support polymorphic setter methods in POJOs (see p12 of "SCA Service Component
......
......@@ -283,12 +283,12 @@ public abstract class AbstractScopeManager implements ScopeManager {
// Collection references
List<?> l = (List<?>) sr;
for (Object o : l) {
checkMandatoryReferenceHasBeenSet(o,name);
checkMandatoryReferenceHasBeenSet(o,ip,name);
}
}
else {
// Singleton references
checkMandatoryReferenceHasBeenSet(sr,name);
checkMandatoryReferenceHasBeenSet(sr,ip,name);
}
}
else {
......@@ -440,23 +440,17 @@ public abstract class AbstractScopeManager implements ScopeManager {
* @param name the name of the service reference
* @throws ContentInstantiationException if the reference has not been set
*/
private void checkMandatoryReferenceHasBeenSet( Object sr, String name )
private void checkMandatoryReferenceHasBeenSet(
Object sr, InjectionPoint<Reference> ip, String name )
throws ContentInstantiationException {
ServiceReference<?> sref = (ServiceReference<?>) sr;
ComponentInterface ci = (ComponentInterface) sref.getService();
Interceptor intercept = (Interceptor) ci.getFcItfImpl(); // Skip the interceptor
Object impl = intercept.getFcItfDelegate();
if( impl == null ) {
InjectionPoint<Reference> ip = ccmd.refs.get(name);
Reference ref = ip.getAnnotation();
if (ref.required()) {
String msg =
"Mandatory reference " + name + " in component " +
nc.getFcName() + " should have been set";
throw new ContentInstantiationException(msg);
}
}
Reference ref = ip.getAnnotation();
if ( ref.required() && sr==null ) {
String msg =
"Mandatory reference " + name + " in component " +
nc.getFcName() + " should have been set";
throw new ContentInstantiationException(msg);
}
}
/**
......@@ -481,19 +475,31 @@ public abstract class AbstractScopeManager implements ScopeManager {
return srs;
}
else {
Object clientItf = comp.getFcInterface(name);
Object sr = getServiceReference(clientItf);
Object itf = comp.getFcInterface(name);
Object sr = getServiceReference(itf);
return sr;
}
}
/**
* Return a {@link ServiceReference} corresponding to the specified client
* interface.
* interface or <code>null</code> if the client interface is not bound.
*/
private Object getServiceReference( Object clientItf ) {
ServiceReference<?> sr =
((TinfiComponentOutInterface<?>) clientItf).getServiceReference();
ComponentInterface itf = (ComponentInterface) clientItf;
Interceptor outInterceptor = (Interceptor) itf.getFcItfImpl();
Object delegate = outInterceptor.getFcItfDelegate();
if( delegate == null ) {
/*
* Unbound client interface. At this point this means that this is
* an optional interface. Mandatory unbound interfaces are detected
* when starting the component.
*/
return null;
}
TinfiComponentOutInterface<?> tcoi =
(TinfiComponentOutInterface<?>) clientItf;
ServiceReference<?> sr = tcoi.getServiceReference();
return sr;
}
......
......@@ -102,7 +102,8 @@
<adl>org.ow2.frascati.tinfi.PropertyComposite</adl>
<adl>org.ow2.frascati.tinfi.ReconfigurableComponentContext</adl>
<adl>org.ow2.frascati.tinfi.ReferenceMultiple</adl>
<adl>org.ow2.frascati.tinfi.ReferenceNotSet</adl>
<adl>org.ow2.frascati.tinfi.ReferenceMandatoryNotSet</adl>
<adl>org.ow2.frascati.tinfi.ReferenceOptionalNotSet</adl>
<adl>org.ow2.frascati.tinfi.SCAContentController</adl>
<adl>org.ow2.frascati.tinfi.SCAContentControllerDummy</adl>
<adl>org.ow2.frascati.tinfi.ScopeComposite</adl>
......@@ -199,7 +200,8 @@
<adl>org.ow2.frascati.tinfi.PropertyComposite</adl>
<adl>org.ow2.frascati.tinfi.ReconfigurableComponentContext</adl>
<adl>org.ow2.frascati.tinfi.ReferenceMultiple</adl>
<adl>org.ow2.frascati.tinfi.ReferenceNotSet</adl>
<adl>org.ow2.frascati.tinfi.ReferenceMandatoryNotSet</adl>
<adl>org.ow2.frascati.tinfi.ReferenceOptionalNotSet</adl>
<adl>org.ow2.frascati.tinfi.SCAContentController</adl>
<adl>org.ow2.frascati.tinfi.SCAContentControllerDummy</adl>
<adl>org.ow2.frascati.tinfi.ScopeComposite</adl>
......
......@@ -26,11 +26,11 @@ package org.ow2.frascati.tinfi;
import org.osoa.sca.annotations.Reference;
/**
* Component implementation used for testing references.
* Component implementation used for testing mandatory references.
*
* @author Lionel Seinturier <Lionel.Seinturier@univ-lille1.fr>
*/
public class ReferenceNotSetImpl implements Runnable {
public class ReferenceMandatoryNotSetImpl implements Runnable {
@Reference(required=true)
public Runnable s;
......
/***
* OW2 FraSCAti Tinfi
* Copyright (C) 2009 INRIA, USTL
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Contact: frascati@ow2.org
*
* Author: Lionel Seinturier
*/
package org.ow2.frascati.tinfi;
import java.util.List;
import org.osoa.sca.annotations.Reference;
/**
* Component implementation used for testing optional references.
*
* @author Lionel Seinturier <Lionel.Seinturier@univ-lille1.fr>
* @since 1.2
*/
public class ReferenceOptionalNotSetImpl implements ReferenceOptionalNotSetItf {
@Reference(required=false)
public Runnable opt;
@Reference(required=false)
public List<Runnable> opts;
public Runnable opt() {
return opt;
}
public List<Runnable> opts() {
return opts;
}
}
/***
* OW2 FraSCAti Tinfi
* Copyright (C) 2009 INRIA, USTL
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Contact: frascati@ow2.org
*
* Author: Lionel Seinturier
*/
package org.ow2.frascati.tinfi;
import java.util.List;
/**
* Component interface used for testing optional references.
*
* @author Lionel Seinturier <Lionel.Seinturier@univ-lille1.fr>
* @since 1.2
*/
public interface ReferenceOptionalNotSetItf {
public Runnable opt();
public List<Runnable> opts();
}
......@@ -13,5 +13,6 @@
</component>
<binding client="this.r" server="client.r" />
<binding client="client.s" server="client.r" />
</definition>
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE definition PUBLIC "-//objectweb.org//DTD Fractal ADL 2.0//EN" "classpath://org/objectweb/fractal/adl/xml/standard.dtd">
<definition name="org.ow2.frascati.tinfi.ReferenceNotSet" >
<definition name="org.ow2.frascati.tinfi.ReferenceMandatoryNotSet" >
<interface name="r" role="server" signature="java.lang.Runnable" />
<component name="server">
<interface name="r" role="server" signature="java.lang.Runnable" />
<interface name="s" contingency="optional" role="client" signature="java.lang.Runnable" />
<content class="org.ow2.frascati.tinfi.ReferenceNotSetImpl"/>
<content class="org.ow2.frascati.tinfi.ReferenceMandatoryNotSetImpl"/>
<controller desc="scaPrimitive" />
</component>
......
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE definition PUBLIC "-//objectweb.org//DTD Fractal ADL 2.0//EN" "classpath://org/objectweb/fractal/adl/xml/standard.dtd">
<definition name="org.ow2.frascati.tinfi.ReferenceOptionalNotSet" >
<interface name="r" role="server" signature="org.ow2.frascati.tinfi.ReferenceOptionalNotSetItf" />
<component name="server">
<interface name="r" role="server" signature="org.ow2.frascati.tinfi.ReferenceOptionalNotSetItf" />
<interface name="opt" contingency="optional" role="client" signature="java.lang.Runnable" />
<interface name="opts" contingency="optional" cardinality="collection" role="client" signature="java.lang.Runnable" />
<content class="org.ow2.frascati.tinfi.ReferenceOptionalNotSetImpl"/>
<controller desc="scaPrimitive" />
</component>
<binding client="this.r" server="server.r" />
</definition>
......@@ -23,6 +23,8 @@
package org.ow2.frascati.tinfi;
import java.util.List;
import org.junit.Assert;
import org.junit.Test;
import org.objectweb.fractal.api.NoSuchInterfaceException;
......@@ -43,7 +45,7 @@ public class ReferenceTestCase {
IllegalLifeCycleException, NoSuchInterfaceException,
java.lang.InstantiationException {
String adl = getClass().getPackage().getName()+".ReferenceNotSet";
String adl = getClass().getPackage().getName()+".ReferenceMandatoryNotSet";
String service = "r";
Runnable itf = TinfiDomain.getService(adl,Runnable.class,service);
......@@ -54,6 +56,28 @@ public class ReferenceTestCase {
catch(TinfiRuntimeException re) {}
}
@Test
public void testOptional()
throws
ClassNotFoundException, InstantiationException, IllegalAccessException,
IllegalLifeCycleException, NoSuchInterfaceException,
java.lang.InstantiationException {
String adl = getClass().getPackage().getName()+".ReferenceOptionalNotSet";
String service = "r";
ReferenceOptionalNotSetItf itf =
TinfiDomain.getService(
adl, ReferenceOptionalNotSetItf.class, service );
Runnable opt = itf.opt();
Assert.assertNull("Unbound optional reference should be null",opt);
List<Runnable> opts = itf.opts();
Assert.assertNotNull("Unbound optional multiple reference should not be null",opts);
int size = opts.size();
Assert.assertEquals("Unbound optional multiple reference should be an empty array",0,size);
}
@Test
public void testMultiple()
throws
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment