org/objectweb/proactive/core/component/adl/vnexportation/ExportedVirtualNodesList.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.adl.vnexportation;
00032 
00033 import java.util.ArrayList;
00034 import java.util.Hashtable;
00035 import java.util.Iterator;
00036 import java.util.List;
00037 import java.util.Map;
00038 
00039 import org.apache.log4j.Logger;
00040 import org.objectweb.fractal.adl.ADLException;
00041 import org.objectweb.proactive.core.ProActiveRuntimeException;
00042 import org.objectweb.proactive.core.component.adl.nodes.VirtualNode;
00043 import org.objectweb.proactive.core.util.log.Loggers;
00044 import org.objectweb.proactive.core.util.log.ProActiveLogger;
00045 
00046 
00058 public class ExportedVirtualNodesList {
00059     public static final String COMPOSING_VIRTUAL_NODES_REGEX = "[^.;]+[.][^.;]+[;]?";
00060     private Logger logger = ProActiveLogger.getLogger(Loggers.COMPONENTS_ADL);
00061     private static ExportedVirtualNodesList instance = null;
00062     static Map linkedVirtualNodes;
00063     public static final String EMPTY_COMPOSING_VIRTUAL_NODES = "composing_virtual_nodes";
00064 
00065     private ExportedVirtualNodesList() {
00066         linkedVirtualNodes = new Hashtable();
00067     }
00068 
00073     public static ExportedVirtualNodesList instance() {
00074         if (instance == null) {
00075             instance = new ExportedVirtualNodesList();
00076         }
00077         return instance;
00078     }
00079 
00080     public Map getList() {
00081         return linkedVirtualNodes;
00082     }
00083 
00092     public void compose(String exportedVNComponent, String exportedVN,
00093         String baseVNComponent, String baseVN, boolean composingVNIsMultiple)
00094         throws ADLException {
00095         LinkedVirtualNode composerNode = getNode(exportedVNComponent,
00096                 exportedVN, true);
00097         LinkedVirtualNode composingNode = getNode(baseVNComponent, baseVN, true);
00098 
00099         //        if (exportedVNComponent.equals(baseVNComponent)) {
00100         //            composingNode.setSelfExported();
00101         //        }
00102         composingNode.setMultiple(composingVNIsMultiple);
00103         checkComposition(composerNode, composingNode);
00104         if (composingNode != composerNode) {
00105             boolean added = composerNode.addComposingVirtualNode(composingNode);
00106             if (added) {
00107                 if (logger.isDebugEnabled()) {
00108                     logger.debug("COMPOSED " + exportedVNComponent + "." +
00109                         exportedVN + " from " + baseVNComponent + "." + baseVN);
00110                 }
00111             }
00112         }
00113     }
00114 
00115     private void checkComposition(LinkedVirtualNode composerNode,
00116         LinkedVirtualNode composingNode) throws ADLException {
00117         if (composerNode.isMultiple()) {
00118             if (!composingNode.isMultiple()) {
00119                 throw new ADLException("cannot compose " +
00120                     composingNode.getDefiningComponentName() + '.' +
00121                     composingNode.getVirtualNodeName() +
00122                     " which is SINGLE, whith composer virtual node " +
00123                     composerNode.getDefiningComponentName() + '.' +
00124                     composerNode.getVirtualNodeName() +
00125                     " because it is already composed from a virtual node of cardinality MULTIPLE",
00126                     null);
00127             }
00128         } else {
00129             if (!composerNode.getComposingVirtualNodes().isEmpty() &&
00130                     composingNode.isMultiple()) {
00131                 throw new ADLException("cannot mix a MULTIPLE virtual node (" +
00132                     composingNode.getDefiningComponentName() + '.' +
00133                     composingNode.getVirtualNodeName() +
00134                     " with SINGLE virtual nodes in composer node " +
00135                     composerNode.getDefiningComponentName() + '.' +
00136                     composerNode.getVirtualNodeName(), null);
00137             }
00138         }
00139     }
00140 
00148     public void compose(String componentName, ExportedVirtualNode exportedVN,
00149         ComposingVirtualNode composingVN, boolean composingVNIsMultiple)
00150         throws ADLException {
00151         compose(componentName, exportedVN.getName(),
00152             composingVN.getComponent(),
00153             "this".equals(composingVN.getName()) ? componentName
00154                                                  : composingVN.getName(),
00155             composingVNIsMultiple);
00156     }
00157 
00158     public boolean addLeafVirtualNode(String componentName,
00159         String virtualNodeName, String cardinality) {
00160         LinkedVirtualNode oldLeaf = getLeafVirtualNode(componentName);
00161         if (oldLeaf != null) {
00162             // ensure only 1 leaf per component
00163             logger.info("removing old leaf virtual node : " +
00164                 oldLeaf.toString());
00165             ((List) linkedVirtualNodes.get(componentName)).remove(oldLeaf);
00166             oldLeaf = null;
00167         }
00168         if (cardinality.equals(VirtualNode.MULTIPLE)) {
00169             // remove *
00170             virtualNodeName = virtualNodeName.substring(0,
00171                     virtualNodeName.length() - 1);
00172         }
00173         LinkedVirtualNode lvn = getNode(componentName, virtualNodeName, false);
00174 
00175         if (lvn != null) {
00176             if (lvn.getComposingVirtualNodes().size() != 0) {
00177                 logger.error("Cannot add leaf virtual node " + virtualNodeName +
00178                     " as it already exists and composes vn");
00179                 return false;
00180             } else {
00181                 lvn.setIsLeaf();
00182             }
00183         }
00184         lvn = getNode(componentName, virtualNodeName, true);
00185         lvn.setIsLeaf();
00186         lvn.setMultiple(VirtualNode.MULTIPLE.equals(cardinality));
00187         return true;
00188     }
00189 
00190     public LinkedVirtualNode getLeafVirtualNode(String componentName) {
00191         LinkedVirtualNode lvn = null;
00192         if (linkedVirtualNodes.containsKey(componentName)) {
00193             List exportedVNs = (List) linkedVirtualNodes.get(componentName);
00194             Iterator it = exportedVNs.iterator();
00195             while (it.hasNext()) {
00196                 lvn = (LinkedVirtualNode) it.next();
00197                 if (lvn.isLeaf()) {
00198                     // there is only 1 leaf per component
00199                     return lvn;
00200                 }
00201             }
00202         }
00203         return null;
00204     }
00205 
00214     public LinkedVirtualNode getNode(String componentName,
00215         String virtualNodeName, boolean createIfNotFound) {
00216         LinkedVirtualNode lvn = null;
00217         if (linkedVirtualNodes.containsKey(componentName)) {
00218             List exportedVNs = (List) linkedVirtualNodes.get(componentName);
00219             Iterator it = exportedVNs.iterator();
00220             while (it.hasNext()) {
00221                 lvn = (LinkedVirtualNode) it.next();
00222                 if (lvn.getVirtualNodeName().equals(virtualNodeName)) {
00223                     return lvn;
00224                 }
00225                 if (lvn.getExportedVirtualNodeNameAfterComposition().equals(virtualNodeName)) {
00226                     return lvn;
00227                 }
00228             }
00229             if (createIfNotFound) {
00230                 // vn not listed
00231                 lvn = new LinkedVirtualNode(componentName, virtualNodeName);
00232                 exportedVNs.add(lvn);
00233                 return lvn;
00234             }
00235         } else {
00236             if (createIfNotFound) {
00237                 // component not listed
00238                 List list = new ArrayList();
00239                 list.add(lvn = new LinkedVirtualNode(componentName,
00240                             virtualNodeName));
00241                 linkedVirtualNodes.put(componentName, list);
00242                 return lvn;
00243             }
00244         }
00245 
00246         return null;
00247     }
00248 
00254     public List getExportedVirtualNodes(String componentName) {
00255         List list = new ArrayList();
00256         if (linkedVirtualNodes.containsKey(componentName)) {
00257             List linked_vns = (List) linkedVirtualNodes.get(componentName);
00258             Iterator it = linked_vns.iterator();
00259             while (it.hasNext()) {
00260                 LinkedVirtualNode linked_vn = (LinkedVirtualNode) it.next();
00261                 if (linked_vn.isExported()) {
00262                     list.add(linked_vn);
00263                 }
00264             }
00265         }
00266         return list;
00267     }
00268 
00269     public String getExportedVirtualNodesBeforeCompositionAsString(
00270         String componentName) {
00271         List evn = getExportedVirtualNodes(componentName);
00272         Iterator it = evn.iterator();
00273         StringBuffer buffer = new StringBuffer();
00274         LinkedVirtualNode lvn;
00275         while (it.hasNext()) {
00276             lvn = (LinkedVirtualNode) it.next();
00277             buffer.append(lvn.getExportedVirtualNodeNameBeforeComposition() +
00278                 (lvn.isMultiple() ? "*" : ""));
00279             if (it.hasNext()) {
00280                 buffer.append(";");
00281             }
00282         }
00283         return buffer.toString();
00284     }
00285 
00291     public String getExportedVirtualNodesAfterCompositionAsString(
00292         String componentName) {
00293         List evn = getExportedVirtualNodes(componentName);
00294         Iterator it = evn.iterator();
00295         StringBuffer buffer = new StringBuffer();
00296         LinkedVirtualNode lvn;
00297         while (it.hasNext()) {
00298             lvn = (LinkedVirtualNode) it.next();
00299             buffer.append(lvn.getExportedVirtualNodeNameAfterComposition() +
00300                 (lvn.isMultiple() ? "*" : ""));
00301             if (it.hasNext()) {
00302                 buffer.append(";");
00303             }
00304         }
00305         return buffer.toString();
00306     }
00307 
00316     public void addExportedVirtualNode(String componentName,
00317         String virtualNode, String composingVirtualNodes) {
00318         if (!composingVirtualNodes.equals(EMPTY_COMPOSING_VIRTUAL_NODES) &&
00319                 !(composingVirtualNodes.replaceAll(
00320                     COMPOSING_VIRTUAL_NODES_REGEX, "").length() == 0)) {
00321             throw new IllegalArgumentException(
00322                 "exported virtual nodes can only be made of one or several regular expressions like : [^.;]+[.][^.;]+[;]?\n" +
00323                 "and this exported virtual node is : " + componentName + "." +
00324                 virtualNode + "-->" + composingVirtualNodes);
00325         }
00326         LinkedVirtualNode exported_vn = getNode(componentName, virtualNode, true);
00327         if (virtualNode.equals(LinkedVirtualNode.EMPTY_VIRTUAL_NODE_NAME) ||
00328                 composingVirtualNodes.equals(EMPTY_COMPOSING_VIRTUAL_NODES)) {
00329             exported_vn.addComposingVirtualNode(getNode(
00330                     LinkedVirtualNode.EMPTY_COMPONENT_NAME,
00331                     LinkedVirtualNode.EMPTY_VIRTUAL_NODE_NAME, true));
00332             return;
00333         }
00334 
00335         //String[] split = composingVirtualNodes.split(COMPOSING_VIRTUAL_NODES_REGEX);
00336         String[] split = composingVirtualNodes.split(";");
00337         for (int i = 0; i < split.length; i++) {
00338             String vn = null;
00339             if (split[i].indexOf(".") == -1) {
00340                 // incorrect syntax
00341                 vn = "";
00342             } else {
00343                 String component = split[i].substring(0, split[i].indexOf("."));
00344                 vn = split[i].substring(split[i].indexOf(".") + 1,
00345                         ((split[i].indexOf(";") == -1) ? split[i].length()
00346                                                        : (split[i].length() -
00347                         1)));
00348 
00349                 // compose composing vn into composer vn
00350                 exported_vn.addComposingVirtualNode(getNode(component, vn, true));
00351             }
00352         }
00353     }
00354 
00360     public void removeExportedVirtualNode(String componentName,
00361         String virtualNodeName) {
00362         if (linkedVirtualNodes.containsKey(componentName)) {
00363             List exportedVNs = (List) linkedVirtualNodes.get(componentName);
00364             Iterator it = exportedVNs.iterator();
00365 
00366             //List to_remove = new ArrayList();
00367             LinkedVirtualNode to_remove = null;
00368             while (it.hasNext()) {
00369                 LinkedVirtualNode lvn = (LinkedVirtualNode) it.next();
00370                 if (lvn.getVirtualNodeName().equals(virtualNodeName) ||
00371                         lvn.getExportedVirtualNodeNameAfterComposition().equals(virtualNodeName)) {
00372                     // as the current list should not be modified while iterated, keep a list
00373                     // of elements to remove
00374                     to_remove = lvn;
00375                 }
00376             }
00377             if (to_remove == null) {
00378                 logger.error("trying to remove virtual node " + componentName +
00379                     "." + virtualNodeName + ", but could not find it");
00380                 return;
00381             }
00382 
00383             // remove from composer
00384             if (to_remove.getComposer() != null) {
00385                 to_remove.getComposer().getComposingVirtualNodes().remove(to_remove);
00386             }
00387             exportedVNs.remove(to_remove);
00388             //            it = to_remove.iterator();
00389             //            while (it.hasNext()) {
00390             //                LinkedVirtualNode lvn = (LinkedVirtualNode) it.next();
00391             //                exportedVNs.remove(lvn);
00392             //                lvn = null;
00393             //                System.out.println();
00394             //            }
00395         }
00396     }
00397 
00404     public List getComposingVirtualNodes(String componentName,
00405         String virtualNodeName) {
00406         LinkedVirtualNode lvn;
00407         if (linkedVirtualNodes.containsKey(componentName)) {
00408             List exportedVNs = (List) linkedVirtualNodes.get(componentName);
00409             Iterator it = exportedVNs.iterator();
00410             while (it.hasNext()) {
00411                 lvn = (LinkedVirtualNode) it.next();
00412                 if (lvn.getVirtualNodeName().equals(virtualNodeName)) {
00413                     return lvn.getComposingVirtualNodes();
00414                 }
00415                 if (lvn.getExportedVirtualNodeNameAfterComposition().equals(virtualNodeName)) {
00416                     return lvn.getComposingVirtualNodes();
00417                 }
00418             }
00419         }
00420         return null;
00421     }
00422 
00430     public void setComposingVirtualNodes(String componentName,
00431         String virtualNodeName, String composingVirtualNodes) {
00432         checkComposingVirtualNodesSyntax(composingVirtualNodes);
00433         LinkedVirtualNode exported_vn = getNode(componentName, virtualNodeName,
00434                 false);
00435         if (exported_vn == null) {
00436             throw new ProActiveRuntimeException("exported virtual node " +
00437                 componentName + '.' + virtualNodeName + " not found");
00438         }
00439 
00440         // 1. clean up existing composing virtual nodes
00441         List old_composing_vns = exported_vn.getComposingVirtualNodes();
00442         Iterator it = old_composing_vns.iterator();
00443         while (it.hasNext()) {
00444             ((LinkedVirtualNode) it.next()).setComposer(null);
00445         }
00446         exported_vn.getComposingVirtualNodes().clear();
00447 
00448         // 2. add new composing virtual nodes
00449         String[] split = composingVirtualNodes.split(";");
00450         for (int i = 0; i < split.length; i++) {
00451             String component = split[i].substring(0, split[i].indexOf("."));
00452             String vn = split[i].substring(split[i].indexOf(".") + 1,
00453                     ((split[i].indexOf(";") == -1) ? split[i].length()
00454                                                    : (split[i].length() - 1)));
00455 
00456             // compose composing vn into composer vn
00457             exported_vn.addComposingVirtualNode(getNode(component, vn, true));
00458         }
00459     }
00460 
00465     public static void checkComposingVirtualNodesSyntax(
00466         String composingVirtualNodes) {
00467         if (!(composingVirtualNodes.replaceAll(
00468                     ExportedVirtualNodesList.COMPOSING_VIRTUAL_NODES_REGEX, "")
00469                                        .length() == 0)) {
00470             throw new IllegalArgumentException(
00471                 "composing virtual nodes can only be made of one or several regular expressions like : [^.;]+[.][^.;]+[;]?");
00472         }
00473     }
00474 
00479     public List getInconsistentExportedVirtualNodes() {
00480         List wrong_exported_vns = new ArrayList();
00481 
00482         // 1. get iterator on lists of virtual nodes for each component
00483         Iterator iterator_on_lists_of_lvns = linkedVirtualNodes.values()
00484                                                                .iterator();
00485 
00486         // 2. loop : for each list (i.e. for each component), get lvns
00487         List lvns;
00488         LinkedVirtualNode lvn;
00489         while (iterator_on_lists_of_lvns.hasNext()) {
00490             lvns = (List) iterator_on_lists_of_lvns.next();
00491             Iterator iterator_on_lvns = lvns.iterator();
00492 
00493             // 3. loop : for each lvn of the list, check consistency
00494             while (iterator_on_lvns.hasNext()) {
00495                 lvn = (LinkedVirtualNode) iterator_on_lvns.next();
00496                 if (lvn.getComposingVirtualNodes().isEmpty() &&
00497                         !lvn.isSelfExported()) {
00498                     wrong_exported_vns.add(lvn);
00499                 }
00500             }
00501         }
00502         return wrong_exported_vns;
00503     }
00504 
00509     public void empty() {
00510         linkedVirtualNodes.clear();
00511     }
00512 
00513     public String toString() {
00514         StringBuffer buffer = new StringBuffer();
00515         Iterator it1 = linkedVirtualNodes.keySet().iterator();
00516         while (it1.hasNext()) {
00517             String component_name = (String) it1.next();
00518             buffer.append(component_name + " : ");
00519             List list = (List) linkedVirtualNodes.get(component_name);
00520             Iterator it2 = list.iterator();
00521             while (it2.hasNext()) {
00522                 LinkedVirtualNode lvn = (LinkedVirtualNode) it2.next();
00523                 buffer.append(lvn.toString());
00524             }
00525             buffer.append("\n");
00526         }
00527         return buffer.toString();
00528     }
00529 }

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