/* * 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.diagram; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.Map.Entry; import org.apache.batik.dom.svg.SVGDOMImplementation; import org.apache.tuscany.sca.impl.artifacts.Component; import org.apache.tuscany.sca.impl.artifacts.Composite; import org.apache.tuscany.sca.impl.artifacts.DashedWire; import org.apache.tuscany.sca.impl.artifacts.Layer; import org.apache.tuscany.sca.impl.artifacts.Link; import org.apache.tuscany.sca.impl.artifacts.NormalWire; import org.apache.tuscany.sca.impl.artifacts.Property; import org.apache.tuscany.sca.impl.artifacts.Reference; import org.apache.tuscany.sca.impl.artifacts.Service; import org.apache.tuscany.sca.impl.artifacts.Text; import org.apache.tuscany.sca.impl.artifacts.Wire; import org.apache.tuscany.sca.impl.layout.ComponentEntity; import org.apache.tuscany.sca.impl.layout.CompositeEntity; import org.apache.tuscany.sca.impl.layout.Entity; import org.w3c.dom.DOMImplementation; import org.w3c.dom.Document; import org.w3c.dom.Element; public class DiagramGenerator { private CompositeEntity comp; private Document doc; private String svgNS ; private Element svgRoot; private ArrayList refs= new ArrayList(); private ArrayList sers= new ArrayList(); private int lastUsedChangingFactor = 0; enum changingFactor{a(20), b(25), c(30), d(35), e(40), f(15); private final int val; private changingFactor(int x){ val = x; } public int getVal(){ return val; } }; enum color {black}//, violet, red, green}; private int previousWireColor = 0; /** * Constructor to generate a SVG diagram for a given CompositeEntity * Object. */ public DiagramGenerator(CompositeEntity comp) { this.comp = comp; } /** * Draws the diagram. */ public Document buildSVGDocument(){ DOMImplementation impl = SVGDOMImplementation.getDOMImplementation(); svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI; doc = impl.createDocument(svgNS, "svg", null); // Get the root element (the 'svg' element). svgRoot = doc.getDocumentElement(); addLayer(); addComposite(); for(ComponentEntity ent: comp.getComponentList()){ addComponent(ent); addComponentService(ent); addComponentReference(ent); addComponentProperties(ent); } addCompositeService(); addCompositeReference(); addCompositeProperties(); addComponentConnections(); addReferencePromotion(); addServicePromotion(); addInclusions(); return doc; } private void addLayer() { Layer outerLayer = new Layer(); Element layerElt = outerLayer.addElement(doc, svgNS, 0, 0, comp.getHeight()+200, comp.getWidth()+400); svgRoot.appendChild(layerElt); } private void addReferencePromotion() { for(Iterator it= comp.getPromoteAReference().entrySet().iterator(); it.hasNext();){ Entry entry = (Entry) it.next(); String compositeRef = (String)entry.getKey(); String componentRef = (String)entry.getValue(); Reference r1 = getRef(compositeRef); Reference r2 = getRef(componentRef); if(r1 != null && r2 != null){ addWire(r2, r1); } } } private void addServicePromotion() { for(Iterator it= comp.getPromoteAService().entrySet().iterator(); it.hasNext();){ Entry entry = (Entry) it.next(); String compositeSer = (String)entry.getKey(); String componentSer = (String)entry.getValue(); Service s1 = getSer(compositeSer); Service s2 = getSer(componentSer); if(s1 != null && s2 != null){ addWire(s1, s2); } } } private void addInclusions() { Layer inclusionLayer = new Layer(); int constant = 5; int x0 = comp.getX()+constant; int y0 = comp.getY()+comp.getHeight()-(Component.DEFAULT_HEIGHT/2+constant); int height = Component.DEFAULT_HEIGHT/2; int width = comp.getWidth()-constant*2; Element layerElt = inclusionLayer.addElement(doc, svgNS, x0, y0, height, width , "#E5E5C0"); Element text = Text.addTextElement(doc, svgNS, x0+constant, y0+constant*2, "Included Composites"); svgRoot.appendChild(layerElt); svgRoot.appendChild(text); text = Text.addTextElement(doc, svgNS, x0+constant, y0+constant*7, ""); for(String includedComposite : comp.getIncludedComposites()){ Link link = new Link(); Element aLink = link.addElement(doc, svgNS, includedComposite+comp.getFileNameSuffix(), includedComposite); text.appendChild(aLink); } svgRoot.appendChild(text); } /** * Connects references to services. */ private void addComponentConnections() { for(Entity ent: comp.getComponentList()){ //if(ent instanceof ComponentEntity){ for(Iterator it= ((ComponentEntity)ent).getReferenceToServiceMap().entrySet().iterator(); it.hasNext();){ Entry entry = (Entry) it.next(); String ref = (String)entry.getKey(); String ser = (String)entry.getValue(); Reference r = getRef(ref); Service s = getSer(ser); if(r != null && s != null){ addWire(r,s); } } //} } } /** * This is to remove overlapping of wire elements */ private String getColor() { previousWireColor =previousWireColor % color.values().length; return color.values()[previousWireColor++].toString(); } /** * This is to remove overlapping of wire elements */ private int getChangingFactor() { lastUsedChangingFactor = lastUsedChangingFactor % changingFactor.values().length; return changingFactor.values()[lastUsedChangingFactor++].getVal(); } private void addWire(Reference r, Service s) { Wire edge = new NormalWire(); Element wire = edge.addElement(doc, svgNS, r, s, getChangingFactor(), getColor()); svgRoot.appendChild(wire); } private void addWire(Service s1, Service s2) { DashedWire edge = new DashedWire(); Element wire = edge.addElement(doc, svgNS, s1, s2, getChangingFactor(), getColor()); svgRoot.appendChild(wire); } private void addWire(Reference r1, Reference r2) { DashedWire edge = new DashedWire(); Element wire = edge.addElement(doc, svgNS, r1, r2, getChangingFactor(), getColor()); svgRoot.appendChild(wire); } private Service getSer(String ser) { for(Service s: sers){ if(s.getContainerName().equals(ser) || s.getName().equals(ser)){ return s; } } return null; } private Reference getRef(String ref) { for(Reference r: refs){ if(r.getContainerName().equals(ref) || r.getName().equals(ref)){ return r; } } return null; } private void addComponentProperties(ComponentEntity ent) { int propLen = ent.getPropLength(); int x= ent.getX() + Property.SPACING_FOR_COMPONENT; int y= ent.getY()-propLen/2; for(String prop: ent.getProperties()){ Property pro = new Property(); Element property = pro.addElement(doc, svgNS, x, y, propLen); Element text = Text.addTextElement(doc, svgNS, x, y, prop); svgRoot.appendChild(property); svgRoot.appendChild(text); x += (propLen + Property.SPACING_FOR_COMPONENT); pro.setName(prop); pro.setContainerName(ent.getName()); } } private void addComponentReference(ComponentEntity ent) { int refHeight = ent.getRefHeight(); int x=(ent.getX()+ent.getWidth())-(refHeight*2/3); int y=ent.getY() + Reference.SPACING_FOR_COMPONENT; for(String ref: setRefOrder(ent)){ Reference refer= new Reference(); Element polygon = refer.addElement(doc, svgNS, x, y, refHeight); Element text = Text.addTextElement(doc, svgNS, x, y+refHeight/2, ref); svgRoot.appendChild(polygon); svgRoot.appendChild(text); y += (refHeight + Reference.SPACING_FOR_COMPONENT); refer.setName(ref); refer.setContainerName(ent.getName()); refs.add(refer); } } /** * This method is used to organize the Component References, * in a manner where they are stay approximately in-line with the * connecting Service. This would enhance the clearness of the diagram. */ private String[] setRefOrder(ComponentEntity e){ ArrayList refs = e.getReferences(); ArrayList sers = new ArrayList(); String[] orderedRefs = new String[refs.size()]; //sers = new ArrayList(e.getReferenceToServiceMap().values()); sers = buildReferenceToMappingServiceList(refs, e); for(String eName: e.getAdjacentEntities()){ for(Entity ent: comp.getComponentList()){ if(ent.getName().equals(eName)){ for(String s : sers){ for(String s1: ent.getServices()){ //System.err.println("XXXXX "+ s1 +" ::: "+s); if(s1.equals(s) || s.equals(ent.getName())){ //System.err.println("|||||||| "+ sers.size()+ " ||| " + refs.size()+"|| "+orderedRefs.length); if(orderedRefs[ent.getLevel()] == null){ //System.err.println("XXXXX "+ sers.get(1)+ " ::::::: "+refs.get(1)); // System.err.println("XXXXX "+ sers.get(2)+ " ::::::: "+refs.get(2)); // System.err.println("XXXXX "+ sers.get(3)+ " ::::::: "+refs.get(3)); System.err.println("XXXXX "+ refs.get(sers.indexOf(s))+" ::: "+ent.getLevel()+" ::: "+ent.getName()); orderedRefs[ent.getLevel()] = refs.get(sers.indexOf(s)); break; } else{ for(int i=ent.getLevel();i buildReferenceToMappingServiceList(ArrayList refs, ComponentEntity e) { ArrayList sers = new ArrayList(); for(int i=0;i