/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.tuscany.sca.impl.layout; import java.util.ArrayList; import java.util.HashMap; import org.apache.tuscany.sca.impl.artifacts.Component; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; public class EntityBuilder { private Document dom; private final int initPoint = 200;//initial point private final int spaceX = Component.DEFAULT_WIDTH*2; private final int spaceY = Component.DEFAULT_HEIGHT*2; private ArrayList levelCount = new ArrayList();//keeps track of levels used in lanes //components connected to each other are tracked using following map private HashMap> connectedEntities = new HashMap>(); private int totalWidth=0; private int totalHeight=0; private Entity startEnt = null; private String compositeName; Entity[] elts = null; /** * Constructor which initiates the DOM document * @param aDom DOM document */ public EntityBuilder(Document aDom){ dom = aDom; } /** * Layout Building Algorithm * ~~~~~~~~~~~~~~~~~~~~~~~~~ * * An Entity object represents a component element of a composite XML. * Here we position (i.e. assigning a level and a lane) all such components * in a unique cell of a grid. * * lane0 lane1 lane2 lane3 .... * _______________________________ * level0 | | | | | * |_______|_______|_______|_______| * level1 | | | | | * |_______|_______|_______|_______| * level2 | | | | | * * 1) Determining the Entity at level0, lane0 (starting entity) * -First Entity in the list of Entities which has one or more adjacent Entities * -If there is only one Entity it will eventually chosen * * 2) Get adjacent Entities of starting Entity. * * If there are adjacent entities; * *For each adjacent Entity; * * * @return */ public Entity[] buildEntities(){ //get the root element Element docEle = dom.getDocumentElement(); compositeName = docEle.getAttribute("name"); System.out.println("compositeName "+compositeName); //get a nodelist of elements NodeList nl = docEle.getElementsByTagName("component"); if(nl != null && nl.getLength() > 0 ) { elts = new Entity[nl.getLength()]; for(int i = 0 ; i < nl.getLength();i++) { elts[i] = new Entity(); Element nVal = (Element)nl.item(i); //System.out.println(nVal.hasAttribute("name")); elts[i].setComponentName(nVal.getAttribute("name")); setServices(nVal, elts[i]); setReferences(nVal, elts[i]); setProperties(nVal, elts[i]); elts[i].referenceHeight(); elts[i].serviceHeight(); elts[i].propertyLength(); } } //sec. 5.4 in the spec nl = docEle.getElementsByTagName("wire"); System.out.println("^^^^^^^^^ "+nl.getLength()); if(nl != null && nl.getLength() > 0 ) { for(int i = 0 ; i < nl.getLength();i++) { Element elt = (Element)nl.item(i); String source = elt.getAttribute("source"); String target = elt.getAttribute("target"); String service, serviceComp, reference, referenceComp; System.out.println("^^^^^^^^^ "+source+" ::: "+target); if(target.contains("/")){ String[] arr = target.split("/"); serviceComp = arr[0]; service = arr[1]; } else{ serviceComp = target; service = null; } if(source.contains("/")){ String[] arr = source.split("/"); referenceComp = arr[0]; reference = arr[1]; } else{ referenceComp = source; reference = null; } Entity e = findEntity(referenceComp); System.out.println("^^^^^^^^^ "+e.getComponentName()); if(e != null){ createConnection(e, reference, serviceComp, service); } } } positionEntities(elts); calculateProperties(elts); print(elts); return elts; } private Entity findEntity(String componentName) { for(Entity e: elts){ if(e.getComponentName().equals(componentName)){ return e; } } return null; } private void setReferences(Element nVal, Entity ent) { NodeList nl = nVal.getElementsByTagName("reference"); if(nl != null && nl.getLength() > 0 ) { for(int i = 0 ; i < nl.getLength();i++) { Element elt = (Element)nl.item(i); String target = elt.getAttribute("target"); String ref = elt.getAttribute("name"); if(target.contains("/")){ String[] arr = target.split("/"); createConnection(ent, ref, arr[0], arr[1]); // ent.addToRefToSerMap(ref, arr[1]); // ent.addAnAdjacentEntity(arr[0]); // addToConnectedEntities(ent.getComponentName(), arr[0]); // addToConnectedEntities(arr[0], ent.getComponentName()); } else if(!target.equals("")){ createConnection(ent, ref, target, null); // ent.addToRefToSerMap(ref, target); // ent.addAnAdjacentEntity(target); // addToConnectedEntities(ent.getComponentName(), target); // addToConnectedEntities(target, ent.getComponentName()); } ent.addAReference(ref); } } } private void createConnection(Entity ent, String reference, String serviceComp, String service) { String referenceComp = ent.getComponentName(); if(reference != null && service != null){ ent.addToRefToSerMap(reference, service); ent.addAnAdjacentEntity(serviceComp); addToConnectedEntities(referenceComp, serviceComp); addToConnectedEntities(serviceComp, referenceComp); } else if(reference == null && service != null){ ent.addToRefToSerMap(referenceComp, service); ent.addAnAdjacentEntity(serviceComp); addToConnectedEntities(referenceComp, serviceComp); addToConnectedEntities(serviceComp, referenceComp); } else if(reference != null && service == null){ ent.addToRefToSerMap(reference, serviceComp); ent.addAnAdjacentEntity(serviceComp); addToConnectedEntities(referenceComp, serviceComp); addToConnectedEntities(serviceComp, referenceComp); } else{ ent.addToRefToSerMap(referenceComp, serviceComp); ent.addAnAdjacentEntity(serviceComp); addToConnectedEntities(referenceComp, serviceComp); addToConnectedEntities(serviceComp, referenceComp); } } private void calculateProperties(Entity[] elts) { int level=0, lane=0; for(Entity ent: elts){ level = max(level, ent.getLevel()); lane = max(lane, ent.getLane()); } totalHeight += spaceY*(level+1) + initPoint; totalWidth += spaceX*(lane+1) + initPoint; System.err.println(totalHeight + " :: "+totalWidth); } private int max(int a, int b){ if(a>=b) return a; return b; } private void print(Entity[] elts) { for(Entity ent: elts){ System.out.println(ent.getComponentName()+" : "+ent.getLevel()+" : " +ent.getLane()+" : "+ent.getX()+" : "+ent.getY()); } } private void positionEntities(Entity[] ents){ for(Entity ent: ents){ if(ent.getAdjacentEntities().size() != 0 || ents.length==1){ setPosition(ent, initPoint, initPoint, 0, 0); levelCount.add(0, 1); startEnt = ent; System.err.println(ent.getComponentName()); break; } } if(startEnt != null) assignPositions(ents, startEnt); } private void assignPositions(Entity[] ents, Entity ent){ int i=0; if(ent.getAdjacentEntities().size()>0){ System.out.println(ent.getComponentName()); for(String name: ent.getAdjacentEntities()){ //System.out.println("eee "+name); for(Entity aEnt: ents){ i++; if(name.equalsIgnoreCase(aEnt.getComponentName())){ int lane = ent.getLane()+1; if(levelCount.size()<= lane){ levelCount.add(lane, 1); setPosition(aEnt, ent.getX()+spaceX, ent.getY(), 0, lane); } else{ int level = levelCount.get(lane); levelCount.add(lane, level+1); setPosition(aEnt, ent.getX()+spaceX, ent.getY()+spaceY*level, level, lane); } if(i conns = connectedEntities.get(ent.getComponentName()); System.err.println(conns.size()); if(conns.size()>0){ for(String conn: conns){ System.err.println("conn "+conn +" : "+ent.getComponentName()); for(Entity e: ents){ if(e.getLane() == -1 && e.getComponentName().equals(conn)){ int lane = ent.getLane()-1; System.err.println(lane); int level = levelCount.get(lane); levelCount.add(lane, level+1); setPosition(e, ent.getX()-spaceX, ent.getY()+spaceY*level, level, lane); break; } } } } } } private void setPosition(Entity ent, int x, int y, int level, int lane){ ent.setX(x); ent.setY(y); ent.setLevel(level); ent.setLane(lane); } private String[] splitValues(String str){ return str.split("/"); } private void addToConnectedEntities(String ent1, String ent2) { System.err.println(ent1+" : "+ent2); ArrayList list; if(connectedEntities.containsKey(ent1)){ list = connectedEntities.get(ent1); } else{ list =new ArrayList(); } list.add(ent2); connectedEntities.put(ent1, list); } private void setServices(Element nVal, Entity ent) { NodeList nl = nVal.getElementsByTagName("service"); if(nl != null && nl.getLength() > 0 ) { for(int i = 0 ; i < nl.getLength();i++) { Element elt = (Element)nl.item(i); ent.addAService(elt.getAttribute("name")); } } NodeList nl1 = nVal.getElementsByTagName("implementation.java"); if(nl1 != null && nl1.getLength() > 0 ) { for(int i = 0 ; i < nl1.getLength();i++) { Element elt = (Element)nl1.item(i); System.out.println(elt.getAttribute("class")); String serName = elt.getAttribute("class").split("\\.")[1]; ent.addAService(serName); } } } private void setProperties(Element nVal, Entity ent) { NodeList nl = nVal.getElementsByTagName("property"); if(nl != null && nl.getLength() > 0 ) { for(int i = 0 ; i < nl.getLength();i++) { Element elt = (Element)nl.item(i); ent.addAProperty(elt.getAttribute("name")); } } } public void setCompositeName(String compositeName) { this.compositeName = compositeName; } public String getCompositeName() { return compositeName; } public int getTotalWidth() { return totalWidth; } public int getTotalHeight() { return totalHeight; } }