![JAR search and dependency download from the Maven repository](/logo.png)
org.objectweb.fractal.koch.factory.MPrimitiveImpl Maven / Gradle / Ivy
The newest version!
/***
* Julia
* Copyright (C) 2005-2006 INRIA, France Telecom, 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: [email protected]
*
* Author: Lionel Seinturier
*/
package org.objectweb.fractal.koch.factory;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.objectweb.fractal.api.Component;
import org.objectweb.fractal.api.NoSuchInterfaceException;
import org.objectweb.fractal.api.Type;
import org.objectweb.fractal.api.control.BindingController;
import org.objectweb.fractal.api.control.IllegalBindingException;
import org.objectweb.fractal.api.control.IllegalLifeCycleException;
import org.objectweb.fractal.api.control.LifeCycleController;
import org.objectweb.fractal.api.control.NameController;
import org.objectweb.fractal.api.type.ComponentType;
import org.objectweb.fractal.api.type.InterfaceType;
import org.objectweb.fractal.julia.ComponentInterface;
import org.objectweb.fractal.julia.control.binding.ChainedIllegalBindingException;
import org.objectweb.fractal.julia.control.content.SuperControllerNotifier;
import org.objectweb.fractal.julia.control.lifecycle.ChainedIllegalLifeCycleException;
import org.objectweb.fractal.julia.control.lifecycle.LifeCycleCoordinator;
import org.objectweb.fractal.koch.control.binding.BindingControllerDef;
import org.objectweb.fractal.koch.control.component.ComponentControllerDef;
/**
* Implementation of the control membrane for mPrimitive components.
* mPrimitive components are primitive control components.
*
* @author Lionel Seinturier
* @since 2.5
*/
public class MPrimitiveImpl
implements
Component, BindingController, NameController, SuperControllerNotifier,
LifeCycleCoordinator {
protected Type type;
protected Object content;
public MPrimitiveImpl( Type type, Object content ) {
this.type = type;
this.content = content;
setFcIsBCNotifiable();
if(isBCNotifiable) {
notifyBindFcComponent();
}
}
// -----------------------------------------------------------------
// Implementation of the Component interface
// -----------------------------------------------------------------
public Type getFcType() {
return type;
}
public Object getFcInterface(String interfaceName)
throws NoSuchInterfaceException {
if( fcInterfaces.containsKey(interfaceName) ) {
Object itf = fcInterfaces.get(interfaceName);
return itf;
}
if( interfaceName.equals("/content") ) {
return content;
}
// Collection interfaces
ComponentType ct = (ComponentType) type;
InterfaceType[] its = ct.getFcInterfaceTypes();
for (int i = 0; i < its.length; i++) {
String itname = its[i].getFcItfName();
if( its[i].isFcCollectionItf() && interfaceName.startsWith(itname) ) {
String colitname = "/collection/" + itname;
ComponentInterface citf = (ComponentInterface) fcInterfaces.get(colitname);
ComponentInterface clone = (ComponentInterface) citf.clone();
clone.setFcItfName(interfaceName);
fcInterfaces.put(interfaceName, clone);
return clone;
}
}
throw new NoSuchInterfaceException(interfaceName);
}
public Object[] getFcInterfaces() {
return fcInterfaces.values().toArray();
}
private Map fcInterfaces = new HashMap();
// -----------------------------------------------------------------
// Implementation of the BindingController interface
// -----------------------------------------------------------------
public String[] listFc() {
if(isBCNotifiable) {
notifyListFc();
}
Set names = new HashSet();
for (Iterator iter = fcInterfaces.entrySet().iterator(); iter.hasNext();) {
Map.Entry entry = (Map.Entry) iter.next();
ComponentInterface itf = (ComponentInterface) entry.getValue();
Object target = itf.getFcItfImpl();
if( target != null && (target instanceof ComponentInterface) ) {
String itfName = (String) entry.getKey();
names.add(itfName);
}
}
return (String[]) names.toArray( new String[names.size()] );
}
public Object lookupFc(String arg0) throws NoSuchInterfaceException {
if(isBCNotifiable) {
String s = arg0.startsWith("//") ? arg0.substring(2) : arg0;
notifyLookupFc(s);
}
// Singleton client interfaces
if( fcInterfaces.containsKey(arg0) ) {
Object o = fcInterfaces.get(arg0);
ComponentInterface itf = (ComponentInterface) o;
InterfaceType it = (InterfaceType) itf.getFcItfType();
if( it.isFcClientItf() ) {
return itf.getFcItfImpl();
}
}
// Collection client interfaces
if( fcInterfaces.containsKey("/collection/"+arg0) ) {
List bound = new ArrayList();
for (Iterator iter = fcInterfaces.keySet().iterator(); iter.hasNext();) {
String itfName = (String) iter.next();
if( itfName.startsWith(arg0) ) {
Object o = lookupFc(itfName);
bound.add(o);
}
}
return bound;
}
throw new NoSuchInterfaceException(arg0);
}
public void bindFc(String arg0, Object arg1)
throws NoSuchInterfaceException, IllegalBindingException, IllegalLifeCycleException {
if(isBCNotifiable) {
String s = arg0.startsWith("//") ? arg0.substring(2) : arg0;
notifyBindFc(s,arg1);
}
/*
* Let the client interface delegate the call to the target.
* Register the binding.
*/
Object o = getFcInterface(arg0);
ComponentInterface itf = (ComponentInterface) o;
itf.setFcItfImpl(arg1);
}
public void unbindFc(String arg0)
throws NoSuchInterfaceException, IllegalBindingException, IllegalLifeCycleException {
if(isBCNotifiable) {
String s = arg0.startsWith("//") ? arg0.substring(2) : arg0;
notifyUnBindFc(s);
}
Object o = getFcInterface(arg0);
ComponentInterface itf = (ComponentInterface) o;
itf.setFcItfImpl(null);
}
// -----------------------------------------------------------------
// Implementation of the NameController interface
// -----------------------------------------------------------------
private String fcName;
public String getFcName() {
return fcName;
}
public void setFcName(String arg0) {
fcName = arg0;
}
// -----------------------------------------------------------------
// Implementation of the SuperControllerNotifier interface
// -----------------------------------------------------------------
protected List fcSupers = new ArrayList(1);
public Component[] getFcSuperComponents() {
return (Component[]) fcSupers.toArray(new Component[fcSupers.size()]);
}
public void addedToFc( Component c ) {
fcSupers.add(c);
}
public void removedFromFc( Component c ) {
fcSupers.remove(c);
}
// -----------------------------------------------------------------
// Implementation specific
// -----------------------------------------------------------------
public void setFcInterfaces( Map fcInterfaces ) {
this.fcInterfaces = fcInterfaces;
weaveableC = (Component) fcInterfaces.get(ComponentControllerDef.NAME);
}
protected void setFcIsBCNotifiable() {
if( !(type instanceof ComponentType) ) {
return;
}
ComponentType ct = (ComponentType) type;
try {
ct.getFcInterfaceType("//"+BindingControllerDef.NAME);
/*
* The content of this control-component exports a
* //binding-controller interface.
* We can not perform notifications in this case.
*/
return;
}
catch (NoSuchInterfaceException e) {}
isBCNotifiable = (content instanceof BindingController);
}
/**
* Field set to true when the content of this control-component must be
* notified when a binding controller operation is emitted.
*/
protected boolean isBCNotifiable = false;
/**
* Inject the reference of the current control membrane in the content of
* the associated control component.
*
* @since 2.5.2.4
*/
protected void notifyBindFcComponent() {
try {
((BindingController)content).bindFc("component",this);
}
catch (Exception e) {
final String msg = e.getClass()+": "+e.getMessage();
throw new RuntimeException(msg);
}
}
/**
* Notify the listFc operation to the control component associated with the
* current control membrane.
*
* @since 2.5.2.4
*/
protected void notifyListFc() {
((BindingController)content).listFc();
}
/**
* Notify the lookupFc operation to the control component associated with
* the current control membrane.
*
* @since 2.5.2.4
*/
protected void notifyLookupFc( String s ) throws NoSuchInterfaceException {
((BindingController)content).lookupFc(s);
}
/**
* Inject the specified reference in the content of the associated control
* component.
*
* @param s the name of the reference
* @param arg1 the reference
* @since 2.5.2.4
*/
protected void notifyBindFc( String s, Object arg1 )
throws
NoSuchInterfaceException, IllegalBindingException,
IllegalLifeCycleException {
((BindingController)content).bindFc(s,arg1);
}
/**
* Inject the null
value for the specified reference name in
* the content of the associated control component.
*
* @param s the name of the reference
* @since 2.5.2.4
*/
protected void notifyUnBindFc( String s )
throws
NoSuchInterfaceException, IllegalBindingException,
IllegalLifeCycleException {
((BindingController)content).unbindFc(s);
}
// -----------------------------------------------------------------
// Implementation of the LifeCycleCoordinator interface
// -----------------------------------------------------------------
/**
* The {@link Component} interface of the component to which this controller
* object belongs.
* @see org.objectweb.fractal.julia.UseComponentMixin#weaveableC
*/
private Component weaveableC;
/**
* Calls the overriden method and then calls the {@link #setFcContentState
* setFcContentState} method.
*
* @return true if the execution state has changed, or false
* if it had already the {@link #STARTED STARTED} value.
* @throws IllegalLifeCycleException if a problem occurs.
* @see org.objectweb.fractal.julia.control.lifecycle.ContainerLifeCycleMixin#setFcStarted()
*/
public boolean setFcStarted() throws IllegalLifeCycleException {
synchronized(this) {
if (setFcStarted$0()) {
// setFcContentState(true);
return true;
}
return false;
}
}
/**
* The components that are currently active.
* @see org.objectweb.fractal.julia.control.lifecycle.BasicLifeCycleCoordinatorMixin#fcActive
*/
private List fcActive;
/**
* Checks the mandatory client interfaces of the component (and of all its sub
* components) and then calls the overriden method.
*
* @throws IllegalLifeCycleException if a problem occurs.
* @see org.objectweb.fractal.julia.control.lifecycle.TypeLifeCycleMixin#startFc()
*/
public void startFc() throws IllegalLifeCycleException {
Component thisComponent;
try {
thisComponent = ((Component)(weaveableC.getFcInterface("component")));
} catch (NoSuchInterfaceException e) {
throw new ChainedIllegalLifeCycleException(e , weaveableC , "Cannot start the component");
}
List allSubComponents = org.objectweb.fractal.julia.control.content.Util.getAllSubComponents(thisComponent);
for (int i = 0 ; i < (allSubComponents.size()) ; ++i) {
Component subComponent = ((Component)(allSubComponents.get(i)));
try {
checkFcMandatoryInterfaces(subComponent);
} catch (IllegalBindingException e) {
throw new ChainedIllegalLifeCycleException(e , weaveableC , "Cannot start the component");
}
}
startFc$0();
}
/**
* The life cycle state of this component. Zero means stopped, one means
* stopping and two means started.
* @see org.objectweb.fractal.julia.control.lifecycle.BasicLifeCycleControllerMixin#fcState
*/
public int fcState;
/**
* Sets the lifecycle state of this component and of all its direct and
* indirect sub components that have a {@link LifeCycleCoordinator} interface.
*
* @param started true to set the lifecycle state of the components
* to {@link #STARTED STARTED}, or false to set this state to
* {@link #STOPPED STOPPED}.
* @throws IllegalLifeCycleException if a problem occurs.
* @see org.objectweb.fractal.julia.control.lifecycle.BasicLifeCycleCoordinatorMixin#setFcState(boolean)
*/
public void setFcState(final boolean started) throws IllegalLifeCycleException {
Component thisComponent;
try {
thisComponent = ((Component)(weaveableC.getFcInterface("component")));
} catch (NoSuchInterfaceException e) {
throw new ChainedIllegalLifeCycleException(e , weaveableC , "Cannot set the lifecycle state");
}
List allSubComponents = org.objectweb.fractal.julia.control.content.Util.getAllSubComponents(thisComponent);
for (int i = 0 ; i < (allSubComponents.size()) ; ++i) {
Component c = ((Component)(allSubComponents.get(i)));
LifeCycleCoordinator lc;
try {
lc = ((LifeCycleCoordinator)(c.getFcInterface("lifecycle-controller")));
} catch (Exception e) {
try {
lc = ((LifeCycleCoordinator)(c.getFcInterface("/lifecycle-coordinator")));
} catch (NoSuchInterfaceException f) {
continue;
}
}
if (started) {
lc.setFcStarted();
} else {
lc.setFcStopped();
}
}
}
/**
* The number of currently executing method calls in this component.
* @see org.objectweb.fractal.julia.control.lifecycle.BasicLifeCycleControllerMixin#fcInvocationCounter
*/
public int fcInvocationCounter;
/**
* Calls the overriden method and then calls the {@link #setFcContentState
* setFcContentState} method.
*
* @return true if the execution state has changed, or false
* if it had already the {@link #STOPPED STOPPED} value.
* @throws IllegalLifeCycleException if a problem occurs.
* @see org.objectweb.fractal.julia.control.lifecycle.ContainerLifeCycleMixin#setFcStopped()
*/
public boolean setFcStopped() throws IllegalLifeCycleException {
synchronized(this) {
if (setFcStopped$0()) {
// setFcContentState(false);
return true;
}
return false;
}
}
/**
* The coordinator used to stop this component with other components
* simultaneously.
* @see org.objectweb.fractal.julia.control.lifecycle.BasicLifeCycleControllerMixin#fcCoordinator
*/
private LifeCycleCoordinator fcCoordinator;
/*
* Do not notify the content.
* Problematic in the case of the lifecycle control component.
*/
///**
// * Calls the {@link LifeCycleController#startFc startFc} or {@link
// * LifeCycleController#stopFc stopFc} method on the encapsulated component.
// * This method does nothing if there is no encapsulated component, or if it
// * does not implement the {@link LifeCycleController} interface.
// *
// * @param started true to call the {@link LifeCycleController#startFc
// * startFc}, or false to call the {@link
// * LifeCycleController#stopFc stopFc} method.
// * @throws IllegalLifeCycleException if a problem occurs.
// * @see org.objectweb.fractal.julia.control.lifecycle.ContainerLifeCycleMixin#setFcContentState(boolean)
// */
//public void setFcContentState(final boolean started) throws IllegalLifeCycleException {
// Object content;
// try {
// content = weaveableOptC.getFcInterface("/content");
// } catch (NullPointerException e) {
// return ;
// } catch (NoSuchInterfaceException e) {
// return ;
// }
// if (content == (this)) {
// if ((this) instanceof ContentLifeCycleController) {
// if (started) {
// ((ContentLifeCycleController)(this)).startFcContent();
// } else {
// ((ContentLifeCycleController)(this)).stopFcContent();
// }
// }
// } else if (content instanceof LifeCycleController) {
// if (started) {
// ((LifeCycleController)(content)).startFc();
// } else {
// ((LifeCycleController)(content)).stopFc();
// }
// }
//}
/**
* Checks that all the mandatory client interface of the given component are
* bound.
*
* @param c a component.
* @throws IllegalBindingException if a mandatory client interface of the
* given component is not bound.
* @see org.objectweb.fractal.julia.control.lifecycle.TypeLifeCycleMixin#checkFcMandatoryInterfaces(org.objectweb.fractal.api.Component)
*/
public void checkFcMandatoryInterfaces(final Component c) throws IllegalBindingException {
BindingController bc;
try {
bc = ((BindingController)(c.getFcInterface("binding-controller")));
} catch (NoSuchInterfaceException e) {
return ;
}
ComponentType compType = ((ComponentType)(c.getFcType()));
String[] names = bc.listFc();
for (int i = 0 ; i < (names.length) ; ++i) {
InterfaceType itfType;
try {
itfType = compType.getFcInterfaceType(names[i]);
} catch (NoSuchInterfaceException e) {
continue;
}
if ((itfType.isFcClientItf()) && (!(itfType.isFcOptionalItf()))) {
Object sItf;
try {
sItf = bc.lookupFc(names[i]);
} catch (NoSuchInterfaceException e) {
continue;
}
if (sItf == null) {
throw new ChainedIllegalBindingException(null , c , null , names[i] , null , "Mandatory client interface unbound");
}
}
}
}
/**
* @see org.objectweb.fractal.julia.control.lifecycle.BasicLifeCycleCoordinatorMixin#fcActivated(org.objectweb.fractal.julia.control.lifecycle.LifeCycleCoordinator)
*/
public boolean fcActivated(final LifeCycleCoordinator component) {
synchronized(fcActive) {
if ((fcActive.size()) > 0) {
if (!(fcActive.contains(component))) {
fcActive.add(component);
}
return true;
}
return false;
}
}
/**
* @see org.objectweb.fractal.julia.control.lifecycle.BasicLifeCycleControllerMixin#getFcState()
*/
public String getFcState() {
return (fcState) == 0 ? LifeCycleController.STOPPED : LifeCycleController.STARTED;
}
/**
* @see org.objectweb.fractal.julia.control.lifecycle.BasicLifeCycleControllerMixin#startFc()
*/
private void startFc$0() throws IllegalLifeCycleException {
if ((fcState) != 2) {
setFcState(true);
}
}
/**
* @see org.objectweb.fractal.julia.control.lifecycle.BasicLifeCycleCoordinatorMixin#fcInactivated(org.objectweb.fractal.julia.control.lifecycle.LifeCycleCoordinator)
*/
public void fcInactivated(final LifeCycleCoordinator component) {
synchronized(fcActive) {
fcActive.remove(component);
fcActive.notifyAll();
}
}
/**
* @see org.objectweb.fractal.julia.control.lifecycle.BasicLifeCycleControllerMixin#stopFc()
*/
public void stopFc() throws IllegalLifeCycleException {
if ((fcState) == 2) {
stopFc(new LifeCycleCoordinator[]{ getFcCoordinator() });
setFcState(false);
}
}
/**
* @see org.objectweb.fractal.julia.control.lifecycle.BasicLifeCycleControllerMixin#setFcStarted()
*/
private boolean setFcStarted$0() {
synchronized(this) {
if ((fcState) == 2) {
return false;
}
fcState = 2;
notifyAll();
return true;
}
}
/**
* Stops the given components simultaneously. This method sets the state of
* the components to "STOPPING", waits until all the components
* are simultaneoulsy inactive (their state is known thanks to the {@link
* #fcActivated fcActivated} and {@link #fcInactivated fcInactivated} callback
* methods), and then sets the state of the components to {@link #STOPPED
* STOPPED}.
*
* @param components the {@link LifeCycleCoordinator} interface of the
* components to be stopped.
* @throws IllegalLifeCycleException if a problem occurs.
* @see org.objectweb.fractal.julia.control.lifecycle.BasicLifeCycleCoordinatorMixin#stopFc(org.objectweb.fractal.julia.control.lifecycle.LifeCycleCoordinator[])
*/
public void stopFc(final LifeCycleCoordinator[] components) throws IllegalLifeCycleException {
fcActive = new ArrayList();
for (int i = 0 ; i < (components.length) ; ++i) {
if (components[i].getFcState().equals(LifeCycleController.STARTED)) {
fcActive.add(components[i]);
}
}
LifeCycleCoordinator c;
try {
c = ((LifeCycleCoordinator)(weaveableC.getFcInterface("lifecycle-controller")));
} catch (Exception e) {
try {
c = ((LifeCycleCoordinator)(weaveableC.getFcInterface("/lifecycle-coordinator")));
} catch (NoSuchInterfaceException f) {
throw new ChainedIllegalLifeCycleException(f , weaveableC , "Cannot stop components");
}
}
for (int i = 0 ; i < (components.length) ; ++i) {
if (components[i].getFcState().equals(LifeCycleController.STARTED)) {
components[i].setFcStopping(c);
}
}
synchronized(fcActive) {
while ((fcActive.size()) > 0) {
try {
fcActive.wait();
} catch (InterruptedException e) {
}
}
}
for (int i = 0 ; i < (components.length) ; ++i) {
if (components[i].getFcState().equals(LifeCycleController.STARTED)) {
components[i].setFcStopped();
}
}
fcActive = null;
}
/**
* @see org.objectweb.fractal.julia.control.lifecycle.BasicLifeCycleControllerMixin#setFcStopping(org.objectweb.fractal.julia.control.lifecycle.LifeCycleCoordinator)
*/
public void setFcStopping(final LifeCycleCoordinator coordinator) {
synchronized(this) {
fcState = 1;
fcCoordinator = coordinator;
if ((fcInvocationCounter) == 0) {
fcCoordinator.fcInactivated(getFcCoordinator());
}
}
}
/**
* @see org.objectweb.fractal.julia.control.lifecycle.BasicLifeCycleControllerMixin#setFcStopped()
*/
private boolean setFcStopped$0() {
synchronized(this) {
if ((fcState) == 0) {
return false;
}
fcState = 0;
fcCoordinator = null;
return true;
}
}
/**
* Increments the number of currently executing method calls in this
* component. If the component is started this method just increments this
* counter. If the component is stopped, it waits until the component is
* restarted, and then increments the counter. Finally, if the component is
* stopping, there are two cases. If the counter is not null, it is just
* incremented. If it is null, this method asks the coordinator if the method
* call can be executed, or if it should be delayed until the component is
* restarted. The method then blocks or not, depending on the coordinator's
* response, before incrementing the counter.
* @see org.objectweb.fractal.julia.control.lifecycle.BasicLifeCycleControllerMixin#incrementFcInvocationCounter()
*/
public void incrementFcInvocationCounter() {
boolean ok;
do {
if ((fcState) == 0) {
ok = false;
} else if ((fcState) == 1) {
if ((fcInvocationCounter) == 0) {
ok = fcCoordinator.fcActivated(getFcCoordinator());
} else {
ok = true;
}
} else {
ok = true;
}
if (!ok) {
try {
wait();
} catch (final InterruptedException e) {
}
}
} while (!ok );
++(fcInvocationCounter);
}
/**
* Decrements the number of currently executing method calls in this
* component. If the component is stopping, and if the counter of currently
* executing method calls becomes null after being decremented, this method
* notifies the coordinator that the component has become inactive.
* @see org.objectweb.fractal.julia.control.lifecycle.BasicLifeCycleControllerMixin#decrementFcInvocationCounter()
*/
public void decrementFcInvocationCounter() {
--(fcInvocationCounter);
if ((fcInvocationCounter) == 0) {
fcCoordinator.fcInactivated(getFcCoordinator());
}
}
/**
* Returns the {@link LifeCycleCoordinator} interface of this component.
*
* @return the {@link LifeCycleCoordinator} interface of the component to
* which this controller object belongs.
* @see org.objectweb.fractal.julia.control.lifecycle.BasicLifeCycleControllerMixin#getFcCoordinator()
*/
public LifeCycleCoordinator getFcCoordinator() {
try {
return ((LifeCycleCoordinator)(weaveableC.getFcInterface("lifecycle-controller")));
} catch (Exception e) {
try {
return ((LifeCycleCoordinator)(weaveableC.getFcInterface("/lifecycle-coordinator")));
} catch (NoSuchInterfaceException f) {
throw new Error("Internal error");
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy