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.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
00100
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
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
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
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
00231 lvn = new LinkedVirtualNode(componentName, virtualNodeName);
00232 exportedVNs.add(lvn);
00233 return lvn;
00234 }
00235 } else {
00236 if (createIfNotFound) {
00237
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
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
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
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
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
00373
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
00384 if (to_remove.getComposer() != null) {
00385 to_remove.getComposer().getComposingVirtualNodes().remove(to_remove);
00386 }
00387 exportedVNs.remove(to_remove);
00388
00389
00390
00391
00392
00393
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
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
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
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
00483 Iterator iterator_on_lists_of_lvns = linkedVirtualNodes.values()
00484 .iterator();
00485
00486
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
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 }