00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030  
00031 package org.objectweb.proactive.core.component.controller;
00032 
00033 import java.io.Serializable;
00034 import java.util.ArrayList;
00035 import java.util.Hashtable;
00036 import java.util.Iterator;
00037 import java.util.List;
00038 import java.util.Map;
00039 import java.util.concurrent.ExecutorService;
00040 import java.util.concurrent.Executors;
00041 
00042 import org.apache.log4j.Logger;
00043 import org.objectweb.fractal.api.Component;
00044 import org.objectweb.fractal.api.NoSuchInterfaceException;
00045 import org.objectweb.fractal.api.control.ContentController;
00046 import org.objectweb.fractal.api.control.IllegalContentException;
00047 import org.objectweb.fractal.api.control.IllegalLifeCycleException;
00048 import org.objectweb.fractal.api.factory.InstantiationException;
00049 import org.objectweb.fractal.api.type.TypeFactory;
00050 import org.objectweb.fractal.util.Fractal;
00051 import org.objectweb.proactive.core.ProActiveRuntimeException;
00052 import org.objectweb.proactive.core.component.Constants;
00053 import org.objectweb.proactive.core.component.exceptions.ContentControllerExceptionListException;
00054 import org.objectweb.proactive.core.component.identity.ProActiveComponent;
00055 import org.objectweb.proactive.core.component.type.ProActiveTypeFactoryImpl;
00056 import org.objectweb.proactive.core.group.Group;
00057 import org.objectweb.proactive.core.group.ProActiveGroup;
00058 import org.objectweb.proactive.core.util.log.Loggers;
00059 import org.objectweb.proactive.core.util.log.ProActiveLogger;
00060 
00061 
00068 public class ProActiveContentControllerImpl extends AbstractProActiveController
00069     implements ProActiveContentController, Serializable {
00070     private static Logger logger = ProActiveLogger.getLogger(Loggers.COMPONENTS);
00071     List<Component> fcSubComponents;
00072     Map<Component, IllegalContentException> contentExceptions = new Hashtable<Component, IllegalContentException>();
00073     Map<Component, IllegalLifeCycleException> lifeCycleExceptions = new Hashtable<Component, IllegalLifeCycleException>();
00074 
00078     public ProActiveContentControllerImpl(Component owner) {
00079         super(owner);
00080         fcSubComponents = new ArrayList<Component>();
00081     }
00082     
00083         protected void setControllerItfType() {
00084             try {
00085                 setItfType(ProActiveTypeFactoryImpl.instance().createFcItfType(Constants.CONTENT_CONTROLLER,
00086                         ProActiveContentController.class.getName(), TypeFactory.SERVER,
00087                         TypeFactory.MANDATORY, TypeFactory.SINGLE));
00088             } catch (InstantiationException e) {
00089                 throw new ProActiveRuntimeException("cannot create controller " +
00090                     this.getClass().getName());
00091             }
00092         }
00093 
00094 
00095 
00096         
00097 
00098 
00099 
00100 
00101     public Object[] getFcInternalInterfaces() {
00102         logger.error(
00103             "Internal interfaces are only accessible from the stub, i.e. from outside of this component");
00104         return null;
00105     }
00106 
00107     
00108 
00109 
00110 
00111 
00112     public Object getFcInternalInterface(String interfaceName)
00113         throws NoSuchInterfaceException {
00114         return ((ProActiveComponent) getFcItfOwner()).getRepresentativeOnThis()
00115                 .getFcInterface(interfaceName);
00116     }
00117 
00118     
00119 
00120 
00121     public Component[] getFcSubComponents() {
00122         return fcSubComponents.toArray(new Component[fcSubComponents.size()]);
00123     }
00124 
00125     public boolean isSubComponent(Component component) {
00126         if (ProActiveGroup.isGroup(component)) {
00127             Group<Component> group = ProActiveGroup.getGroup(component);
00128             for (Iterator<Component> it = group.iterator(); it.hasNext();) {
00129                 if (!fcSubComponents.contains(it.next())) {
00130                     return false;
00131                 }
00132             }
00133         } else if (!fcSubComponents.contains(component)) {
00134             return false;
00135         }
00136 
00137         return true;
00138     }
00139 
00140     
00141 
00142 
00143 
00144 
00145     public void addFcSubComponent(Component subComponent)
00146         throws IllegalLifeCycleException, IllegalContentException {
00147         checkLifeCycleIsStopped();
00148             
00149             
00150             
00151             
00152             try {
00153                 
00154                 if (ProActiveGroup.isGroup(subComponent)) {
00155                         try {
00156                                                 addFcSubComponent(ProActiveGroup.getGroup(subComponent));
00157                                         } catch (ContentControllerExceptionListException e) {
00158                                                 e.printStackTrace();
00159                                                 throw new IllegalContentException("problem adding a list of component to a composite : " + e.getMessage());
00160                                         }
00161                         return;
00162                 }
00163                 if (Fractal.getSuperController(subComponent)
00164                                .getFcSuperComponents().length != 0) {
00165                     throw new IllegalContentException(
00166                         "This implementation of the Fractal model does not currently allow sharing : " +
00167                         Fractal.getNameController(subComponent).getFcName() +
00168                         " has no super controller");
00169                 }
00170             } catch (NoSuchInterfaceException e) {
00171                 logger.error(
00172                     "could not check that the subcomponent is not shared, continuing ignoring this verification ... " +
00173                     e);
00174             }
00175 
00176         ProActiveComponent this_component = ((ProActiveComponent) getFcItfOwner());
00177         Component ref_on_this_component = this_component.getRepresentativeOnThis();
00178 
00179         
00180         if (ref_on_this_component.equals(subComponent)) {
00181             try {
00182                 throw new IllegalArgumentException("cannot add " +
00183                     Fractal.getNameController(getFcItfOwner()).getFcName() +
00184                     " component into itself ");
00185             } catch (NoSuchInterfaceException e) {
00186                 logger.error(e.getMessage());
00187             }
00188         }
00189 
00190         
00191         if (getAllSubComponents(this_component).contains(ref_on_this_component)) {
00192             String name;
00193             try {
00194                 name = Fractal.getNameController(subComponent).getFcName();
00195             } catch (NoSuchInterfaceException nsie) {
00196                 throw new ProActiveRuntimeException("cannot access the component parameters controller",
00197                     nsie);
00198             }
00199             throw new IllegalArgumentException("already a sub component : " +
00200                 name);
00201         }
00202 
00203         fcSubComponents.add(subComponent);
00204         
00205         try {
00206             Object itf = subComponent.getFcInterface(Constants.SUPER_CONTROLLER);
00207 
00208             ((ProActiveSuperController) itf).addParent(ref_on_this_component);
00209         } catch (NoSuchInterfaceException e) {
00210             throw new IllegalContentException(
00211                 "Cannot add component : cannot find super-controller interface.");
00212         }
00213     }
00214 
00215     
00216 
00217 
00218     public void removeFcSubComponent(Component subComponent)
00219         throws IllegalLifeCycleException, IllegalContentException {
00220         checkLifeCycleIsStopped();
00221         try {
00222             if (((ProActiveBindingController) Fractal.getBindingController(
00223                         getFcItfOwner())).isBound().booleanValue()) {
00224                 throw new IllegalContentException(
00225                     "cannot remove a sub component that holds bindings on its external client interfaces");
00226             }
00227         } catch (NoSuchInterfaceException ignored) {
00228             
00229         }
00230         if (!fcSubComponents.remove(subComponent)) {
00231             throw new IllegalArgumentException("not a sub component : " +
00232                 subComponent);
00233         }
00234         try {
00235             ((ProActiveSuperController) Fractal.getSuperController(subComponent)).removeParent(subComponent);
00236         } catch (NoSuchInterfaceException e) {
00237             fcSubComponents.add(subComponent);
00238             throw new IllegalContentException(
00239                 "cannot remove component : cannot find super-controller interface");
00240         }
00241     }
00242 
00243     
00244 
00245 
00246 
00247 
00248     private List<Component> getAllSubComponents(final Component component) {
00249         List<Component> allSubComponents = new ArrayList<Component>();
00250         List<Component> stack = new ArrayList<Component>();
00251 
00252         
00253         Component[] subComponents = getFcSubComponents();
00254 
00255         for (int i = subComponents.length - 1; i >= 0; --i) {
00256             stack.add(subComponents[i]);
00257         }
00258         while (stack.size() > 0) {
00259             int index = stack.size() - 1;
00260             Component c = stack.get(index);
00261             stack.remove(index);
00262 
00263             if (!allSubComponents.contains(c)) {
00264                 try {
00265                     ContentController cc = (ContentController) c.getFcInterface(Constants.CONTENT_CONTROLLER);
00266                     subComponents = cc.getFcSubComponents();
00267                     for (int i = subComponents.length - 1; i >= 0; --i) {
00268                         stack.add(subComponents[i]);
00269                     }
00270                 } catch (NoSuchInterfaceException ignored) {
00271                     
00272                 }
00273                 allSubComponents.add(c);
00274             }
00275         }
00276         return allSubComponents;
00277     }
00278     
00279     
00280         public void addFcSubComponent(List<Component> subComponents) throws ContentControllerExceptionListException {
00281                 lifeCycleExceptions.clear();
00282                 contentExceptions.clear();
00283                 
00284                 ExecutorService threadPool = Executors.newCachedThreadPool();
00285                 ContentControllerExceptionListException e = new ContentControllerExceptionListException();
00286                 for (Iterator<Component> iter = subComponents.iterator(); iter.hasNext();) {
00287                         Component element = iter.next();
00288                         AddSubComponentTask task = new AddSubComponentTask(e, this, element);
00289                         threadPool.execute(task);
00290                 }
00291                 threadPool.shutdown();
00292                 if (!e.isEmpty()) {
00293                         throw e;
00294                 }
00295         }
00296         
00297         public void removeFcSubComponent(List<Component> subComponents) throws ContentControllerExceptionListException {
00298                 lifeCycleExceptions.clear();
00299                 contentExceptions.clear();
00300                 
00301                 ExecutorService threadPool = Executors.newCachedThreadPool();
00302                 ContentControllerExceptionListException e = new ContentControllerExceptionListException();
00303                 for (Iterator<Component> iter = subComponents.iterator(); iter.hasNext();) {
00304                         Component element = iter.next();
00305                         RemoveSubComponentTask task = new RemoveSubComponentTask(e, this, element);
00306                         threadPool.execute(task);
00307                 }
00308                 threadPool.shutdown();
00309                 if (!e.isEmpty()) {
00310                         throw e;
00311                 }
00312                 
00313         }
00314         
00315         
00316         private static class AddSubComponentTask implements Runnable {
00317                 
00318                 ContentControllerExceptionListException exceptions;
00319                 ProActiveContentControllerImpl controller;
00320                 Component component;
00321                 
00322                 
00323                 public AddSubComponentTask(ContentControllerExceptionListException exceptions, ProActiveContentControllerImpl controller, Component component) {
00324                         this.exceptions = exceptions;
00325                         this.controller = controller;
00326                         this.component = component;
00327                 }
00328                 
00329                 public void run() {
00330                         try {
00331                                 controller.addFcSubComponent(component);
00332                         } catch (IllegalContentException e) {
00333                                 e.printStackTrace();
00334                                 exceptions.addIllegalContentException(component, e);
00335                         } catch (IllegalLifeCycleException e) {
00336                                 e.printStackTrace();
00337                                 exceptions.addIllegalLifeCycleException(component, e);
00338                         }
00339                 }
00340                 
00341                 
00342         }
00343         
00344         
00345 private static class RemoveSubComponentTask implements Runnable {
00346                 
00347                 ContentControllerExceptionListException exceptions;
00348                 ProActiveContentControllerImpl controller;
00349                 Component component;
00350                 
00351                 public RemoveSubComponentTask(ContentControllerExceptionListException exceptions, ProActiveContentControllerImpl controller, Component component) {
00352                         this.exceptions = exceptions;
00353                         this.controller = controller;
00354                         this.component = component;
00355                 }
00356                 
00357                 public void run() {
00358                         try {
00359                                 controller.removeFcSubComponent(component);
00360                         } catch (IllegalContentException e) {
00361                                 e.printStackTrace();
00362                                 exceptions.addIllegalContentException(component, e);
00363                         } catch (IllegalLifeCycleException e) {
00364                                 e.printStackTrace();
00365                                 exceptions.addIllegalLifeCycleException(component, e);
00366                         }
00367                 }
00368                 
00369                 
00370         }
00371     
00372     
00373 }