
org.objectweb.fractal.julia.control.content.BindingContentMixin Maven / Gradle / Ivy
The newest version!
/***
* Julia: France Telecom's implementation of the Fractal API
* Copyright (C) 2001-2011 France Telecom R&D
*
* 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: Eric Bruneton
*/
package org.objectweb.fractal.julia.control.content;
import org.objectweb.fractal.api.Component;
import org.objectweb.fractal.api.Interface;
import org.objectweb.fractal.api.NoSuchInterfaceException;
import org.objectweb.fractal.api.control.BindingController;
import org.objectweb.fractal.api.control.ContentController;
import org.objectweb.fractal.api.control.IllegalBindingException;
import org.objectweb.fractal.api.control.IllegalContentException;
import org.objectweb.fractal.api.control.IllegalLifeCycleException;
import org.objectweb.fractal.api.control.SuperController;
import org.objectweb.fractal.api.type.InterfaceType;
import org.objectweb.fractal.julia.control.binding.ChainedIllegalBindingException;
import org.objectweb.fractal.julia.control.binding.Util;
import java.util.List;
/**
* Provides binding related checks to a {@link ContentController}.
*
*
* Requirements
*
* - the types of the sub components of this component must be instances of
* {@link org.objectweb.fractal.api.type.ComponentType}.
* - the sub components of this component must support interface
* introspection, i.e. their interfaces must implement {@link Interface}.
* - TODO requirements pour parents, pour composants clients et servers des sous composants
*
*/
public abstract class BindingContentMixin implements ContentController {
// -------------------------------------------------------------------------
// Private constructor
// -------------------------------------------------------------------------
private BindingContentMixin () {
}
// -------------------------------------------------------------------------
// Fields and methods added and overriden by the mixin class
// -------------------------------------------------------------------------
/**
* Checks that this operation will not create non local bindings, and then
* calls the overriden method.
*
* @param subComponent the component to be removed from this component.
* @throws IllegalContentException if the given component cannot be removed
* from this component.
* @throws IllegalLifeCycleException if this component has a {@link
* org.objectweb.fractal.api.control.LifeCycleController} interface, but it is not in an appropriate state
* to perform this operation.
*/
public void removeFcSubComponent (final Component subComponent)
throws IllegalContentException, IllegalLifeCycleException
{
try {
checkFcRemoveSubComponent(subComponent);
} catch (IllegalBindingException e) {
throw new ChainedIllegalContentException(
e,
_this_weaveableC,
subComponent,
"Would create non local bindings");
}
_super_removeFcSubComponent(subComponent);
}
/**
* Checks that the removal of the given sub component will not create non
* local bindings.
*
* @param subComponent a sub component that will be removed from this
* component.
* @throws IllegalBindingException if the removal of the given sub component
* would create non local bindings.
*/
public void checkFcRemoveSubComponent (final Component subComponent)
throws IllegalBindingException
{
Component parent;
try {
parent = (Component)_this_weaveableC.getFcInterface("component");
if (parent == null) {
return;
}
} catch (NoSuchInterfaceException e) {
return;
}
BindingController bc;
try {
bc = (BindingController)subComponent.getFcInterface("binding-controller");
} catch (NoSuchInterfaceException e) {
bc = null;
}
Object[] itfs = subComponent.getFcInterfaces();
for (int i = 0; i < itfs.length; ++i) {
Interface itf;
InterfaceType itfType;
try {
itf = (Interface)itfs[i];
itfType = (InterfaceType)itf.getFcItfType();
} catch (ClassCastException e) {
continue;
}
if (itfType.isFcClientItf()) {
if (bc != null) {
Interface sItf;
try {
sItf = (Interface)bc.lookupFc(itf.getFcItfName());
} catch (NoSuchInterfaceException e) {
continue;
} catch (ClassCastException e) {
continue;
}
if (sItf != null) {
checkFcLocalBinding(itf, parent, sItf, null);
}
}
} else {
Object[] potentialClients;
try {
potentialClients = Util.getFcPotentialClientsOf(itf).toArray();
} catch (Exception e) {
continue;
}
for (int j = 0; j < potentialClients.length; ++j) {
Component c = (Component)potentialClients[j];
List clientItfs;
try {
clientItfs = Util.getFcClientItfsBoundTo(c, itf);
} catch (Exception e) {
continue;
}
if (clientItfs.size() > 0) {
checkFcLocalBinding((Interface)clientItfs.get(0), null, itf, parent);
}
}
}
}
}
/**
* Checks that a given binding is a local binding.
*
* @param cItf a client interface.
* @param cId the parent from which the client component has been removed, or
* null if the client component has not been removed from a
* parent component.
* @param sItf the server interface to which the client interface is bound.
* @param sId the parent from which the server component has been removed, or
* null if the server component has not been removed from a
* parent component.
* @throws IllegalBindingException if the given binding is not a local
* binding.
*/
private void checkFcLocalBinding (
final Interface cItf,
final Component cId,
final Interface sItf,
final Component sId) throws IllegalBindingException
{
Component client = cItf.getFcItfOwner();
Component server = sItf.getFcItfOwner();
if (client.equals(server)) {
return;
}
SuperController cSc = null;
SuperController sSc = null;
try {
cSc = (SuperController)client.getFcInterface("super-controller");
} catch (NoSuchInterfaceException ignored) {
}
try {
sSc = (SuperController)server.getFcInterface("super-controller");
} catch (NoSuchInterfaceException ignored) {
}
if (cItf.isFcInternalItf()) {
// check client component is a parent of server component
if (cSc != null) {
Component[] sP = sSc.getFcSuperComponents();
for (int i = 0; i < sP.length; ++i) {
Component p = sP[i];
if (sId == null || !p.equals(sId)) {
if (p.equals(client)) {
return;
}
}
}
} else {
return;
}
} else {
if (sItf.isFcInternalItf()) {
// check server component is a parent of client component
if (cSc != null) {
Component[] cP = cSc.getFcSuperComponents();
for (int i = 0; i < cP.length; ++i) {
Component p = cP[i];
if (cId == null || !p.equals(cId)) {
if (p.equals(server)) {
return;
}
}
}
} else {
return;
}
} else {
// check client and server components have a common parent
if (cSc != null && sSc != null) {
Component[] cP = cSc.getFcSuperComponents();
Component[] sP = sSc.getFcSuperComponents();
for (int i = 0; i < cP.length; ++i) {
Component p = cP[i];
if (cId == null || !p.equals(cId)) {
for (int j = 0; j < sP.length; ++j) {
Component q = sP[j];
if (sId == null || !q.equals(sId)) {
if (p.equals(q)) {
return;
}
}
}
}
}
} else {
return;
}
}
}
throw new ChainedIllegalBindingException(
null,
_this_weaveableC,
sId,
cItf.getFcItfName(),
sItf.getFcItfName(),
"Not a local binding");
}
// -------------------------------------------------------------------------
// Fields and methods required by the mixin class in the base class
// -------------------------------------------------------------------------
/**
* The weaveableOptC field required by this mixin. This field is
* supposed to reference the {@link Component} interface of the component to
* which this controller object belongs.
*/
public Component _this_weaveableC;
/**
* The {@link ContentController#removeFcSubComponent removeFcSubComponent}
* method overriden by this mixin.
*
* @param subComponent the component to be removed from this component.
* @throws IllegalContentException if the given component cannot be removed
* from this component.
* @throws IllegalLifeCycleException if this component has a {@link
* org.objectweb.fractal.api.control.LifeCycleController} interface, but it is not in an appropriate state
* to perform this operation.
*/
public abstract void _super_removeFcSubComponent (Component subComponent)
throws IllegalContentException, IllegalLifeCycleException;
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy