org/objectweb/proactive/core/component/controller/ProActiveContentControllerImpl.java

00001 /* 
00002  * ################################################################
00003  * 
00004  * ProActive: The Java(TM) library for Parallel, Distributed, 
00005  *            Concurrent computing with Security and Mobility
00006  * 
00007  * Copyright (C) 1997-2007 INRIA/University of Nice-Sophia Antipolis
00008  * Contact: proactive@objectweb.org
00009  * 
00010  * This library is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU Lesser General Public
00012  * License as published by the Free Software Foundation; either
00013  * version 2.1 of the License, or any later version.
00014  *  
00015  * This library is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  * Lesser General Public License for more details.
00019  * 
00020  * You should have received a copy of the GNU Lesser General Public
00021  * License along with this library; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
00023  * USA
00024  *  
00025  *  Initial developer(s):               The ProActive Team
00026  *                        http://www.inria.fr/oasis/ProActive/contacts.html
00027  *  Contributor(s): 
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      * @see org.objectweb.fractal.api.control.ContentController#getFcInternalInterfaces()
00098      *
00099      * in this implementation, the external interfaces are also internal interfaces
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      * @see org.objectweb.fractal.api.control.ContentController#getFcInternalInterface(String)
00109      *
00110      *  in this implementation, the external interfaces are also internal interfaces
00111      *         */
00112     public Object getFcInternalInterface(String interfaceName)
00113         throws NoSuchInterfaceException {
00114         return ((ProActiveComponent) getFcItfOwner()).getRepresentativeOnThis()
00115                 .getFcInterface(interfaceName);
00116     }
00117 
00118     /*
00119      * @see org.objectweb.fractal.api.control.ContentController#getFcSubComponents()
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      * @see org.objectweb.fractal.api.control.ContentController#addFcSubComponent(Component)
00142      *
00143      * if subComponent is a group, each element of the group is added as a subcomponent
00144      */
00145     public void addFcSubComponent(Component subComponent)
00146         throws IllegalLifeCycleException, IllegalContentException {
00147         checkLifeCycleIsStopped();
00148             // no sharing in the current implementation of Fractal
00149             // => only one parent for a given component
00150             // FIXME control requests are enqueued
00151             // pb is that the subComponent might not be stopped
00152             try {
00153                 // could not do this invocation on a group (non reifiable return type)
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         // check whether the subComponent is the component itself
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         // check whether already a sub component
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         // add a ref on the current component
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      * @see org.objectweb.fractal.api.control.ContentController#removeFcSubComponent(Component)
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             // no binding controller
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      * Returns all the direct and indirect sub components of the given component.
00245      * @param component a component.
00246      * @return all the direct and indirect sub components of the given component.
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         // first layer of sub components retreived directly (do not go through the representative)
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                     // c is not a composite component: nothing to do
00272                 }
00273                 allSubComponents.add(c);
00274             }
00275         }
00276         return allSubComponents;
00277     }
00278     
00279     // TODO factorize code
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 }

Generated on Mon Jan 22 15:16:06 2007 for ProActive by  doxygen 1.5.1