diff options
author | antelder <antelder@13f79535-47bb-0310-9956-ffa450edef68> | 2012-04-12 09:14:28 +0000 |
---|---|---|
committer | antelder <antelder@13f79535-47bb-0310-9956-ffa450edef68> | 2012-04-12 09:14:28 +0000 |
commit | bad1f71da1978610806427e2e2a2f96a2fb5b88e (patch) | |
tree | 334e5c38ba5cc33fd853e37c640728ec020862fb /sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org | |
parent | 57c2c65b9d869afc1be14926da2ece51ab52231b (diff) |
Tag 2.0 RC1
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1325166 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org')
24 files changed, 4088 insertions, 0 deletions
diff --git a/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/Artifact.java b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/Artifact.java new file mode 100644 index 0000000000..4751cff023 --- /dev/null +++ b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/Artifact.java @@ -0,0 +1,156 @@ +/* + * 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.diagram.artifacts; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +public abstract class Artifact { + + private String name; + private String containerName; + private int height; + private int width; + private int xCoordinate; + private int yCoordinate; + private Document doc; + private String svgNs; + private static final String ROUND_CORNER = "20"; + + /** + * Abstract method + * @param document DOM document + * @param svgNs namespace URI + * @param x x-coordinate + * @param y y-coordinate + * @param height height of the shape + * @param width width of the shape + * @return DOM Element + */ + public abstract Element addElement(Document document, String svgNs, int x, int y, int height, int width); + + // public abstract Element addElement(Document document, String svgNs, + // int x, int y); + + public int getHeight() { + return height; + } + + public void setHeight(int height) { + this.height = height; + } + + public int getWidth() { + return width; + } + + public void setWidth(int width) { + this.width = width; + } + + public int getxCoordinate() { + return xCoordinate; + } + + public void setxCoordinate(int xCoordinate) { + this.xCoordinate = xCoordinate; + } + + public int getyCoordinate() { + return yCoordinate; + } + + public void setyCoordinate(int yCoordinate) { + this.yCoordinate = yCoordinate; + } + + public Document getDoc() { + return doc; + } + + public void setDoc(Document doc) { + this.doc = doc; + } + + public String getSvgNs() { + return svgNs; + } + + public void setSvgNs(String svgNs) { + this.svgNs = svgNs; + } + + public static String getRoundCorner() { + return ROUND_CORNER; + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setContainerName(String containerName) { + this.containerName = containerName; + } + + public String getContainerName() { + return containerName; + } + + /** + * Parse the component/service|reference/binding names + * @param compoundName + * @return An array of names + */ + public static String[] parseNames(String compoundName) { + String[] names = new String[] {"", "", ""}; + if (compoundName != null) { + String[] parts = compoundName.split("/"); + for (int i = 0; i < parts.length; i++) { + names[i] = parts[i]; + } + } + return names; + } + + public static boolean matches(String compoundName, String... parts) { + String names[] = parseNames(compoundName); + if (parts.length > names.length) { + return false; + } + for (int i = 0; i < parts.length; i++) { + if (parts[i].length() > 0 && names[i].length() > 0 && !names[i].equals(parts[i])) { + return false; + } + } + return true; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("Artifact [containerName=").append(containerName).append(", name=").append(name).append("]"); + return builder.toString(); + } + +} diff --git a/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/ComponentArtifact.java b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/ComponentArtifact.java new file mode 100755 index 0000000000..6a9480d4ea --- /dev/null +++ b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/ComponentArtifact.java @@ -0,0 +1,60 @@ +/* + * 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.diagram.artifacts; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +public class ComponentArtifact extends Artifact { + + /** + * Create an element with specified height and width + */ + public Element addElement(Document document, String svgNs, int x, int y, int height, int width) { + + this.setHeight(height); + this.setWidth(width); + this.setxCoordinate(x); + this.setyCoordinate(y); + + Element rectangle = document.createElementNS(svgNs, "rect"); + rectangle.setAttributeNS(null, "x", String.valueOf(x)); + rectangle.setAttributeNS(null, "y", String.valueOf(y)); + rectangle.setAttributeNS(null, "rx", getRoundCorner()); + rectangle.setAttributeNS(null, "ry", getRoundCorner()); + rectangle.setAttributeNS(null, "width", String.valueOf(width)); + rectangle.setAttributeNS(null, "height", String.valueOf(height)); +// rectangle.setAttributeNS(null, "fill", "#3D59AB"); +// rectangle.setAttributeNS(null, "stroke", "#104E8B"); +// rectangle.setAttributeNS(null, "fill-opacity", "0.75"); + rectangle.setAttributeNS(null, "class", "component"); + return rectangle; + } + + /** + * Create an element with default height and width + */ + public Element addElement(Document document, String svgNs, int x, int y) { + + return addElement(document, svgNs, x, y, Constant.COMPONENT_DEFAULT_HEIGHT, Constant.COMPONENT_DEFAULT_WIDTH); + + } + +} diff --git a/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/CompositeArtifact.java b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/CompositeArtifact.java new file mode 100755 index 0000000000..4f67dfbb3b --- /dev/null +++ b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/CompositeArtifact.java @@ -0,0 +1,58 @@ +/* + * 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.diagram.artifacts; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +/** + * Structure of a "Composite" element in SCA, as a SVG element + * + */ +public class CompositeArtifact extends Artifact { + + public Element addElement(Document document, String svgNs, int x, int y, int height, int width) { + + this.setHeight(height); + this.setWidth(width); + this.setxCoordinate(x); + this.setyCoordinate(y); + + Element rectangle = document.createElementNS(svgNs, "rect"); + rectangle.setAttributeNS(null, "x", String.valueOf(x)); + rectangle.setAttributeNS(null, "y", String.valueOf(y)); + rectangle.setAttributeNS(null, "rx", getRoundCorner()); + rectangle.setAttributeNS(null, "ry", getRoundCorner()); + rectangle.setAttributeNS(null, "width", String.valueOf(width)); + rectangle.setAttributeNS(null, "height", String.valueOf(height)); + // rectangle.setAttributeNS(null, "fill", "#E5E5E5"); + // rectangle.setAttributeNS(null, "stroke", "#919191"); + // rectangle.setAttributeNS(null, "alignment-baseline", "middle"); + rectangle.setAttributeNS(null, "class", "composite"); + + return rectangle; + } + + // //OBSOLETE + // public Element addElement(Document document, String svgNs, int x, int y) { + // return null; + // } + +} diff --git a/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/Constant.java b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/Constant.java new file mode 100755 index 0000000000..c27d82dd6d --- /dev/null +++ b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/Constant.java @@ -0,0 +1,46 @@ +/* + * 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.diagram.artifacts; + +public final class Constant { + + public static final int COMPONENT_DEFAULT_WIDTH = 200; + public static final int COMPONENT_DEFAULT_HEIGHT = 130; + public static final int COMPONENT_TEXT_SPACING = 20; + + public static final int DEFAULT_MAXIMUM_HEIGHT_FOR_COMPONENT_OF_PROPERTY = 20; + public static final int DEFAULT_MAXIMUM_HEIGHT_FOR_COMPOSITE_OF_PROPERTY = 40; + public static final int SPACING_FOR_COMPONENT_OF_PROPERTY = 20; + public static final int SPACING_FOR_COMPOSITE_OF_PROPERTY = 40; + + public static final int DEFAULT_MAXIMUM_HEIGHT_FOR_COMPONENT_OF_REFERENCE = 30; + public static final int DEFAULT_MAXIMUM_HEIGHT_FOR_COMPOSITE_OF_REFERENCE = 60; + public static final int SPACING_FOR_COMPONENT_OF_REFERENCE = 10; + public static final int SPACING_FOR_COMPOSITE_OF_REFERENCE = 30; + + public static final int DEFAULT_MAXIMUM_HEIGHT_FOR_COMPONENT_OF_SERVICE = 30; + public static final int DEFAULT_MAXIMUM_HEIGHT_FOR_COMPOSITE_OF_SERVICE = 60; + public static final int SPACING_FOR_COMPONENT_OF_SERVICE = 10; + public static final int SPACING_FOR_COMPOSITE_OF_SERVICE = 30; + + public static final int SPACING_FOR_TEXT = 2; + + public static final int MAX_LEVELS = 8; + +} diff --git a/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/DashedWire.java b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/DashedWire.java new file mode 100755 index 0000000000..229b14e083 --- /dev/null +++ b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/DashedWire.java @@ -0,0 +1,83 @@ +/* + * 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.diagram.artifacts; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +public class DashedWire extends WireArtifact { + + @Override + public Element addElement(Document document, String svgNs, Object a, Object b, int changingFactor, String color) { + + Element polyline = document.createElementNS(svgNs, "polyline"); + int x1 = 0, x2 = 0, y1 = 0, y2 = 0; + + if (a instanceof ServiceArtifact && b instanceof ServiceArtifact) { + + ServiceArtifact aService1 = (ServiceArtifact)a; + ServiceArtifact aService2 = (ServiceArtifact)b; + + x1 = aService1.getxCoordinate() + aService1.getHeight() * 3 / 2; + y1 = aService1.getyCoordinate() + aService1.getHeight() / 2; + + x2 = aService2.getxCoordinate() + aService2.getHeight() / 2; + y2 = aService2.getyCoordinate() + aService2.getHeight() / 2; + + } + + else if (a instanceof ReferenceArtifact && b instanceof ReferenceArtifact) { + + ReferenceArtifact aReference1 = (ReferenceArtifact)a; + ReferenceArtifact aReference2 = (ReferenceArtifact)b; + + x1 = aReference1.getxCoordinate() + aReference1.getHeight() * 3 / 2; + y1 = aReference1.getyCoordinate() + aReference1.getHeight() / 2; + + x2 = aReference2.getxCoordinate() + aReference2.getHeight() / 2; + y2 = aReference2.getyCoordinate() + aReference2.getHeight() / 2; + + } + + polyline = setWireAttributes(x1, y1, x2, y2, polyline, changingFactor, color); + +// polyline.setAttributeNS(null, "stroke-dasharray", "3 3"); + polyline.setAttributeNS(null, "class", "wire dashedWire"); + + + return polyline; + } + + /** + * <script type="text/ecmascript"><![CDATA[ + <SCRIPT LANGUAGE="JavaScript"> + + var test = document.open("store_diagram.svg"); + + </SCRIPT> + ]]></script> + + <!--rect x="0" y="0" alignment-baseline="central" fill="#E5E5D0" width="1400" rx="20" ry="20" height="560" stroke="#919191"/><rect x="200" y="100" alignment-baseline="central" fill="#E5E5E5" width="1000" rx="20" ry="20" height="360" stroke="#919191"/><text x="700" font-size="20" dominant-baseline="mathematical" y="120" text-anchor="middle"> + + <a xlink:href="store_diagram.svg" xlink:show="new">MyValueComposite2</a></text--> + + */ + +} diff --git a/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/ImplementationArtifact.java b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/ImplementationArtifact.java new file mode 100644 index 0000000000..21bcadf872 --- /dev/null +++ b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/ImplementationArtifact.java @@ -0,0 +1,62 @@ +/* + * 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.diagram.artifacts; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +public class ImplementationArtifact extends Artifact { + + /** + * Create an element with specified height and width + */ + public Element addElement(Document document, String svgNs, int x, int y, int height, int width) { + + this.setHeight(height); + this.setWidth(width); + this.setxCoordinate(x); + this.setyCoordinate(y); + + Element rectangle = document.createElementNS(svgNs, "rect"); + rectangle.setAttributeNS(null, "x", x + ""); + rectangle.setAttributeNS(null, "y", y + ""); +// rectangle.setAttributeNS(null, "rx", getRoundCorner()); +// rectangle.setAttributeNS(null, "ry", getRoundCorner()); + rectangle.setAttributeNS(null, "width", width + ""); + rectangle.setAttributeNS(null, "height", height + ""); + rectangle.setAttributeNS(null, "fill", "purple"); + rectangle.setAttributeNS(null, "stroke", "black"); + rectangle.setAttributeNS(null, "stroke-width", "1"); + rectangle.setAttributeNS(null, "fill-opacity", "0.1"); + + rectangle.setAttributeNS(null, "class", "implementation"); + return rectangle; + } + + /** + * Create an element with default height and width + */ + public Element addElement(Document document, String svgNs, int x, int y) { + + return addElement(document, svgNs, x, y, Constant.COMPONENT_DEFAULT_HEIGHT/2, Constant.COMPONENT_DEFAULT_WIDTH/2); + + } + +} diff --git a/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/Layer.java b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/Layer.java new file mode 100755 index 0000000000..858226f801 --- /dev/null +++ b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/Layer.java @@ -0,0 +1,61 @@ +/* + * 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.diagram.artifacts; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +/** + * Structure of a "Outermost layer" : not a SCA artifact + * + */ +public class Layer extends Artifact { + + public Element addElement(Document document, String svgNs, int x, int y, int height, int width) { + + this.setHeight(height); + this.setWidth(width); + this.setxCoordinate(x); + this.setyCoordinate(y); + + Element rectangle = document.createElementNS(svgNs, "rect"); + rectangle.setAttributeNS(null, "x", x + ""); + rectangle.setAttributeNS(null, "y", y + ""); + rectangle.setAttributeNS(null, "rx", getRoundCorner()); + rectangle.setAttributeNS(null, "ry", getRoundCorner()); + rectangle.setAttributeNS(null, "width", width + ""); + rectangle.setAttributeNS(null, "height", height + ""); +// rectangle.setAttributeNS(null, "fill", "#E5E5D0"); +// rectangle.setAttributeNS(null, "stroke", "#919191"); +// rectangle.setAttributeNS(null, "alignment-baseline", "middle"); + rectangle.setAttributeNS(null, "class", "layer"); + + return rectangle; + } + + public Element addElement(Document document, String svgNs, int x, int y, int height, int width, String fillColor) { + + Element rect = addElement(document, svgNs, x, y, height, width); + rect.setAttributeNS(null, "fill", fillColor); + + return rect; + } + +} diff --git a/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/Link.java b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/Link.java new file mode 100755 index 0000000000..3e1e368681 --- /dev/null +++ b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/Link.java @@ -0,0 +1,41 @@ +/* + * 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.diagram.artifacts; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +/** + * An "a" element to link two SVG diagrams: not a SCA artifact + * + */ +public class Link { + + public Element addElement(Document document, String svgNs, String fileName, String compName) { + + Element link = document.createElementNS(svgNs, "a"); + link.setAttributeNS(null, "xlink:href", fileName); + link.setAttributeNS(null, "xlink:show", "new"); + link.setTextContent(" [" + compName + "] "); + + return link; + } + +} diff --git a/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/NormalWire.java b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/NormalWire.java new file mode 100755 index 0000000000..c3abe8d2e2 --- /dev/null +++ b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/NormalWire.java @@ -0,0 +1,46 @@ +/* + * 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.diagram.artifacts; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +public class NormalWire extends WireArtifact { + + @Override + public Element addElement(Document document, String svgNs, Object a, Object b, int changingFactor, String color) { + + ReferenceArtifact aReference = (ReferenceArtifact)a; + ServiceArtifact aService = (ServiceArtifact)b; + + Element polyline = document.createElementNS(svgNs, "polyline"); + int x1 = aReference.getxCoordinate() + aReference.getHeight() * 3 / 2; + int y1 = aReference.getyCoordinate() + aReference.getHeight() / 2; + + int x2 = aService.getxCoordinate() + aService.getHeight() / 2; + int y2 = aService.getyCoordinate() + aService.getHeight() / 2; + + polyline = setWireAttributes(x1, y1, x2, y2, polyline, changingFactor, color); + polyline.setAttributeNS(null, "class", "wire normalWire"); + + return polyline; + } + +} diff --git a/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/PropertyArtifact.java b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/PropertyArtifact.java new file mode 100755 index 0000000000..8622c7ad04 --- /dev/null +++ b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/PropertyArtifact.java @@ -0,0 +1,60 @@ +/* + * 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.diagram.artifacts; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +public class PropertyArtifact extends Artifact { + + /** + * Property is a square. + * ___ + * | | + * |___| + * + */ + public Element addElement(Document document, String svgNs, int x, int y, int height, int width) { + + this.setHeight(height); + this.setWidth(width); + this.setxCoordinate(x); + this.setyCoordinate(y); + + Element rectangle = document.createElementNS(svgNs, "rect"); + rectangle.setAttributeNS(null, "x", x + ""); + rectangle.setAttributeNS(null, "y", y + ""); + rectangle.setAttributeNS(null, "width", height + ""); + rectangle.setAttributeNS(null, "height", height + ""); + rectangle.setAttributeNS(null, "fill", "#EEEE00"); + rectangle.setAttributeNS(null, "stroke", "#EEC900"); + //rectangle.setAttributeNS(null, "fill-opacity", "0.75"); + + rectangle.setAttributeNS(null, "class", "property"); + + return rectangle; + } + + public Element addElement(Document document, String svgNs, int x, int y, int height) { + + return addElement(document, svgNs, x, y, height, height); + } + +} diff --git a/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/ReferenceArtifact.java b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/ReferenceArtifact.java new file mode 100755 index 0000000000..dc561f8e49 --- /dev/null +++ b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/ReferenceArtifact.java @@ -0,0 +1,88 @@ +/* + * 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.diagram.artifacts; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +public class ReferenceArtifact extends Artifact { + + /** + * In a Reference the (x,y) coordinates refers to the top corner edge of the polygon + * (x,y)______ + * \ \ + * \ \ + * / / + * /____ / + */ + public Element addElement(Document document, String svgNs, int x, int y, int height, int width) { + + this.setHeight(height); + this.setWidth(width); + this.setxCoordinate(x); + this.setyCoordinate(y); + + int halfOfHeight = height / 2; + + Element polygon = document.createElementNS(svgNs, "polygon"); + polygon.setAttributeNS(null, "points", "" + x + + "," + + y + + " " + + "" + + (x + 2 * halfOfHeight) + + "," + + (y) + + " " + + "" + + (x + 3 * halfOfHeight) + + "," + + (y + halfOfHeight) + + " " + + "" + + (x + 2 * halfOfHeight) + + "," + + (y + 2 * halfOfHeight) + + " " + + "" + + (x) + + "," + + (y + 2 * halfOfHeight) + + " " + + "" + + (x + halfOfHeight) + + "," + + (y + halfOfHeight) + + " "); + + polygon.setAttributeNS(null, "fill", "#BF3EFF"); + polygon.setAttributeNS(null, "stroke", "#68228B"); + polygon.setAttributeNS(null, "class", "reference"); + + + return polygon; + } + + public Element addElement(Document document, String svgNs, int x, int y, int height) { + + return this.addElement(document, svgNs, x, y, height, height * 3 / 2); + } + +} diff --git a/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/ServiceArtifact.java b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/ServiceArtifact.java new file mode 100755 index 0000000000..4f305b4ba5 --- /dev/null +++ b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/ServiceArtifact.java @@ -0,0 +1,95 @@ +/* + * 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.diagram.artifacts; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +public class ServiceArtifact extends Artifact { + + /** + * In a Service the (x,y) coordinates refers to the top corner edge of the polygon + * (x,y)______ + * \ \ + * \ \ + * / / + * /____ / + */ + public Element addElement(Document document, String svgNs, int x, int y, int height, int width) { + + this.setHeight(height); + this.setWidth(width); + this.setxCoordinate(x); + this.setyCoordinate(y); + + int halfOfHeight = height / 2; + + Element polygon = document.createElementNS(svgNs, "polygon"); + polygon.setAttributeNS(null, "points", "" + x + + "," + + y + + " " + + "" + + (x + 2 * halfOfHeight) + + "," + + (y) + + " " + + "" + + (x + 3 * halfOfHeight) + + "," + + (y + halfOfHeight) + + " " + + "" + + (x + 2 * halfOfHeight) + + "," + + (y + 2 * halfOfHeight) + + " " + + "" + + (x) + + "," + + (y + 2 * halfOfHeight) + + " " + + "" + + (x + halfOfHeight) + + "," + + (y + halfOfHeight) + + " "); + + polygon.setAttributeNS(null, "fill", "#00CD66"); + polygon.setAttributeNS(null, "stroke", "#008B45"); + polygon.setAttributeNS(null, "class", "service"); + return polygon; + } + + /** + * Width is 3/2 times of the height + * @param document + * @param svgNs + * @param x + * @param y + * @param height + * @return + */ + public Element addElement(Document document, String svgNs, int x, int y, int height) { + + return this.addElement(document, svgNs, x, y, height, height * 3 / 2); + } + +} diff --git a/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/Style.java b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/Style.java new file mode 100644 index 0000000000..14e4e7e909 --- /dev/null +++ b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/Style.java @@ -0,0 +1,118 @@ +/* + * 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.diagram.artifacts; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.StringWriter; + +import org.w3c.dom.CDATASection; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +/** + * CSS style element + */ +public class Style { + private static final String DEFAULT_CSS = "rect.composite {" + " fill: #E5E5E5;" + + " stroke: #919191;" + + " alignment-baseline: middle;" + + " }\n" + + " rect.component {" + + " fill: #3D59AB;" + + " stroke: #104E8B;" + + " fill-opacity: 0.75;" + + " }\n" + + " rect.property {" + + " fill: #EEEE00;" + + " stroke: #EEC900;" + + " }\n" + + " polygon.reference {" + + " fill: #BF3EFF;" + + " stroke: #68228B;" + + " }\n" + + " polygon.service {" + + " fill: #00CD66;" + + " stroke: #008B45;" + + " }\n" + + " polyline.wire {" + + " stroke-width: 2;" + + " fill: none;" + + " }\n" + + " polyline.normalWire {" + + " }\n" + + " polyline.dashedWire {" + + " stroke-dasharray: 3,3;" + + " }\n" + + " rect.layer {" + + " fill: #E5E5D0;" + + " stroke: #919191;" + + " alignment-baseline: middle;" + + " }\n"; + + private static volatile String css; + + public Element addElement(Document document, String svgNs, String styleSheet) { + + Element style = document.createElementNS(svgNs, "style"); + style.setAttributeNS(null, "type", "text/css"); + + if (styleSheet == null) { + try { + if (css == null) { + css = readCSS(); + } + } catch (IOException e) { + // Ignore + css = DEFAULT_CSS; + } + styleSheet = css; + } + + CDATASection cdata = document.createCDATASection(styleSheet); + style.appendChild(cdata); + + return style; + } + + private static String readCSS() throws IOException { + InputStream is = Style.class.getResourceAsStream("composite-diagram.css"); + InputStreamReader reader = new InputStreamReader(is, "UTF-8"); + + StringWriter sw = new StringWriter(); + char[] buf = new char[4096]; + while (true) { + int size = reader.read(buf); + if (size < 0) { + break; + } else { + sw.write(buf, 0, size); + } + } + reader.close(); + String template = sw.toString(); + // return template.replaceFirst("/\\*(?:.|[\\n\\r])*?\\*/", ""); // Unfortunately it causes StackOverFlow in Apache Jenkins build + int i1 = template.indexOf("/*"); + int i2 = template.indexOf("*/", i1); + String result = template.substring(0, i1) + template.substring(i2 + 2, template.length()); + return result; + } +} diff --git a/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/Text.java b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/Text.java new file mode 100644 index 0000000000..580209d289 --- /dev/null +++ b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/Text.java @@ -0,0 +1,38 @@ +/* + * 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.diagram.artifacts; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +public class Text { + + public static Element addTextElement(Document document, String svgNs, int x, int y, String content) { + Element text = document.createElementNS(svgNs, "text"); + text.setAttributeNS(null, "x", x + ""); + text.setAttributeNS(null, "y", y + ""); + //text.setAttributeNS(null, "text-anchor", "middle"); + text.setAttributeNS(null, "dominant-baseline", "mathematical"); + text.setAttributeNS(null, "font-size", "15"); + text.setTextContent(content); + text.setAttributeNS(null, "class", "name"); + return text; + } +} diff --git a/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/WireArtifact.java b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/WireArtifact.java new file mode 100755 index 0000000000..80466621b6 --- /dev/null +++ b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/artifacts/WireArtifact.java @@ -0,0 +1,88 @@ +/* + * 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.diagram.artifacts; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +public abstract class WireArtifact { + + public abstract Element addElement(Document document, + String svgNs, + Object a, + Object b, + int changingFactor, + String color); + + public Element setWireAttributes(int x1, int y1, int x2, int y2, Element polyline, int changingFactor, String color) { + + if (y1 == y2 && x2 > x1) { + polyline.setAttributeNS(null, "points", x1 + "," + y1 + " " + x2 + "," + y2); + } else if (y1 == y2 && x1 > x2) { + polyline.setAttributeNS(null, "points", x1 + "," + + y1 + + " " + + (x1 + changingFactor) + + "," + + y1 + + " " + + (x1 + changingFactor) + + "," + + (y1 - (changingFactor * 2)) + + " " + + (x2 - changingFactor) + + "," + + (y1 - (changingFactor * 2)) + + " " + + (x2 - changingFactor) + + "," + + (y1) + + " " + + (x2) + + "," + + (y1)); + + } else { + polyline.setAttributeNS(null, "points", x1 + "," + + y1 + + " " + + (x1 + changingFactor) + + "," + + y1 + + " " + + (x1 + changingFactor) + + "," + + y2 + + " " + + x2 + + "," + + y2); + } + + polyline.setAttributeNS(null, "stroke", color); + polyline.setAttributeNS(null, "stroke-width", "2"); + polyline.setAttributeNS(null, "fill", "none"); + + polyline.setAttributeNS(null, "class", "wire"); + + return polyline; + } + +} diff --git a/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/generator/DiagramGenerator.java b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/generator/DiagramGenerator.java new file mode 100755 index 0000000000..ccedac5451 --- /dev/null +++ b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/generator/DiagramGenerator.java @@ -0,0 +1,667 @@ +/* + * 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.diagram.generator; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Map.Entry; + +import org.apache.batik.dom.svg.SVGDOMImplementation; +import org.apache.tuscany.sca.diagram.artifacts.Artifact; +import org.apache.tuscany.sca.diagram.artifacts.ComponentArtifact; +import org.apache.tuscany.sca.diagram.artifacts.CompositeArtifact; +import org.apache.tuscany.sca.diagram.artifacts.Constant; +import org.apache.tuscany.sca.diagram.artifacts.DashedWire; +import org.apache.tuscany.sca.diagram.artifacts.ImplementationArtifact; +import org.apache.tuscany.sca.diagram.artifacts.Layer; +import org.apache.tuscany.sca.diagram.artifacts.Link; +import org.apache.tuscany.sca.diagram.artifacts.NormalWire; +import org.apache.tuscany.sca.diagram.artifacts.PropertyArtifact; +import org.apache.tuscany.sca.diagram.artifacts.ReferenceArtifact; +import org.apache.tuscany.sca.diagram.artifacts.ServiceArtifact; +import org.apache.tuscany.sca.diagram.artifacts.Style; +import org.apache.tuscany.sca.diagram.artifacts.Text; +import org.apache.tuscany.sca.diagram.artifacts.WireArtifact; +import org.apache.tuscany.sca.diagram.layout.ComponentEntity; +import org.apache.tuscany.sca.diagram.layout.CompositeEntity; +import org.apache.tuscany.sca.diagram.layout.Entity; +import org.w3c.dom.DOMImplementation; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +public class DiagramGenerator { + + private static final String XLINK_NS = "http://www.w3.org/1999/xlink"; + private CompositeEntity comp; + private Document doc; + private String svgNS; + private Element svgRoot; + private ArrayList<ReferenceArtifact> refs = new ArrayList<ReferenceArtifact>(); + private ArrayList<ServiceArtifact> sers = new ArrayList<ServiceArtifact>(); + private int diagramHeight, diagramWidth; + + private boolean isHtml; + private final String baseURL; + + private int lastUsedChangingFactor = 0; + + enum ChangingFactor { + a(20), b(40), c(60), d(80), e(100), f(120), g(140), h(160); + + 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, boolean isHtml, String baseURL) { + + this.comp = comp; + this.isHtml = isHtml; + this.baseURL = baseURL; + + } + + /** + * 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(); + + svgRoot.setAttribute("xmlns:xlink", XLINK_NS); + + setDiagramHeight(comp.getHeight() + 200); + setDiagramWidth(comp.getWidth() + 400); + + svgRoot.setAttributeNS(null, "viewBox", "0 0 " + getDiagramWidth() + " " + getDiagramHeight()); + + svgRoot.appendChild(new Style().addElement(doc, svgNS, null)); + + addLayer(); + addComposite(); + + for (ComponentEntity ent : comp.getComponentList()) { + + addComponent(ent); + addComponentProperties(ent); + addComponentService(ent); + addComponentReference(ent); + } + + addCompositeProperties(); + addCompositeService(); + addCompositeReference(); + + addComponentConnections(); + addReferencePromotion(); + addServicePromotion(); + + addInclusions(); + + return doc; + } + + private void addLayer() { + + Layer outerLayer = new Layer(); + Element layerElt = outerLayer.addElement(doc, svgNS, 0, 0, getDiagramHeight(), getDiagramWidth()); + svgRoot.appendChild(layerElt); + } + + private void addReferencePromotion() { + + for (Iterator<Entry<String, ArrayList<String>>> it = comp.getPromoteAReference().entrySet().iterator(); it + .hasNext();) { + Entry<String, ArrayList<String>> entry = it.next(); + String compositeRef = entry.getKey(); + ArrayList<String> componentRef = entry.getValue(); + + ReferenceArtifact r1 = getRef(comp.getName() + "/" + compositeRef); + + for (String ref : componentRef) { + + ReferenceArtifact r2 = getRef(ref); + + if (r1 != null && r2 != null) { + addWire(r2, r1); + } + } + + } + } + + private void addServicePromotion() { + + for (Iterator<Entry<String, String>> it = comp.getPromoteAService().entrySet().iterator(); it.hasNext();) { + Entry<String, String> entry = it.next(); + String compositeSer = entry.getKey(); + String componentSer = entry.getValue(); + + ServiceArtifact s1 = getSer(comp.getName() + "/" + compositeSer); + ServiceArtifact s2 = getSer(componentSer); + + if (s1 != null && s2 != null) { + addWire(s1, s2); + } + } + } + + private void addInclusions() { + + if (!comp.getIncludedComposites().isEmpty()) { + + Layer inclusionLayer = new Layer(); + int constant = 10; + int x0 = comp.getX() + constant; + int y0 = comp.getY() + comp.getHeight() - (80 + constant); + int height = 80; + int width = comp.getWidth() - constant * 2; + + Element layerElt = inclusionLayer.addElement(doc, svgNS, x0, y0, height, width); + + 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, ""); + + String ext; + + if (isHtml) { + ext = ".html"; + } else { + ext = ".svg"; + } + + for (String includedComposite : comp.getIncludedComposites()) { + + Link link = new Link(); + Element aLink = + link.addElement(doc, svgNS, includedComposite + comp.getFileNameSuffix() + ext, 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<Entry<String, String>> it = + ((ComponentEntity)ent).getReferenceToServiceMap().entrySet().iterator(); it.hasNext();) { + Entry<String, String> entry = it.next(); + String ref = entry.getKey(); + String ser = entry.getValue(); + + ReferenceArtifact r = getRef(ent.getName() + "/" + ref); + ServiceArtifact 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(ReferenceArtifact r, ServiceArtifact s) { + + WireArtifact edge = new NormalWire(); + Element wire = edge.addElement(doc, svgNS, r, s, getChangingFactor(), getColor()); + svgRoot.appendChild(wire); + } + + private void addWire(ServiceArtifact s1, ServiceArtifact s2) { + + DashedWire edge = new DashedWire(); + Element wire = edge.addElement(doc, svgNS, s1, s2, getChangingFactor(), getColor()); + svgRoot.appendChild(wire); + } + + private void addWire(ReferenceArtifact r1, ReferenceArtifact r2) { + + DashedWire edge = new DashedWire(); + Element wire = edge.addElement(doc, svgNS, r1, r2, getChangingFactor(), getColor()); + svgRoot.appendChild(wire); + } + + private ServiceArtifact getSer(String ser) { + + for (ServiceArtifact s : sers) { + if (Artifact.matches(ser, s.getContainerName(), s.getName())) { + return s; + } + } + return null; + } + + private ReferenceArtifact getRef(String ref) { + + for (ReferenceArtifact r : refs) { + + if (Artifact.matches(ref, r.getContainerName(), r.getName())) { + return r; + } + } + return null; + } + + private void addComponentProperties(ComponentEntity ent) { + int propLen = ent.getPropWidth(); + int x = ent.getX() + Constant.SPACING_FOR_COMPONENT_OF_PROPERTY; + int y = ent.getY() - propLen / 2; + + for (String prop : ent.getProperties()) { + PropertyArtifact pro = new PropertyArtifact(); + Element property = pro.addElement(doc, svgNS, x, y, propLen); + Element text = Text.addTextElement(doc, svgNS, x, y - Constant.SPACING_FOR_TEXT, prop); + + Element child = property; + if (baseURL != null) { + String url = baseURL + "/components/" + ent.getName() + "/properties/" + prop; + child = createLink(property, url); + } + + svgRoot.appendChild(child); + svgRoot.appendChild(text); + + x += (propLen + Constant.SPACING_FOR_COMPONENT_OF_PROPERTY); + + 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() + Constant.SPACING_FOR_COMPONENT_OF_REFERENCE; + + for (String ref : setRefOrder(ent)) { + ReferenceArtifact refer = new ReferenceArtifact(); + Element polygon = refer.addElement(doc, svgNS, x, y, refHeight); + + Element child = polygon; + if (baseURL != null) { + String url = baseURL + "/components/" + ent.getName() + "/services/" + ref; + child = createLink(polygon, url); + } + + Element text = Text.addTextElement(doc, svgNS, x, y - Constant.SPACING_FOR_TEXT, ref); + svgRoot.appendChild(child); + svgRoot.appendChild(text); + + y += (refHeight + Constant.SPACING_FOR_COMPONENT_OF_REFERENCE); + + 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<String> refs = e.getReferences(); + ArrayList<String> sers = new ArrayList<String>(); + String[] orderedRefs = new String[refs.size()]; + + //sers = new ArrayList<String>(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()) { + if (s1.equals(s) || s.equals(ent.getName())) { + if (orderedRefs[ent.getLevel()] == null) { + orderedRefs[ent.getLevel()] = refs.get(sers.indexOf(s)); + break; + } else { + for (int i = ent.getLevel(); i < orderedRefs.length; i++) { + if (orderedRefs[i] == null) { + + orderedRefs[i] = refs.get(sers.indexOf(s)); + break; + } + } + } + } + } + } + } + } + } + + //adding references which are not connected to any service + for (String ref : refs) { + for (int i = 0; i < orderedRefs.length; i++) { + if (ref.equals(orderedRefs[i])) { + break; + } else if (orderedRefs[i] == null) { + orderedRefs[i] = ref; + break; + } + } + } + + return orderedRefs; + } + + private ArrayList<String> buildReferenceToMappingServiceList(ArrayList<String> refs, ComponentEntity e) { + + ArrayList<String> sers = new ArrayList<String>(); + + for (int i = 0; i < refs.size(); i++) { + sers.add(i, ""); + } + + for (Iterator<Entry<String, String>> it = e.getReferenceToServiceMap().entrySet().iterator(); it.hasNext();) { + + Entry<String, String> entry = it.next(); + String ref = entry.getKey(); + String ser = entry.getValue(); + //System.out.println("---------"+ref); + int idx = refs.indexOf(ref); + //System.out.println("---------"+sers.get(idx)); + sers.remove(idx); + sers.add(idx, ser); + //System.out.println(refs.get(idx)+"---"+sers.get(idx)); + + } + + return sers; + } + + private void addComponentService(ComponentEntity ent) { + int serHeight = ent.getSerHeight(); + int x = ent.getX() - (serHeight * 2 / 3); + int y = ent.getY() + Constant.SPACING_FOR_COMPONENT_OF_SERVICE; + + //System.out.println("''''''"+ent.getName() +" '''''' "+ ent.getServices().size()); + for (String ser : ent.getServices()) { + + ServiceArtifact serve = new ServiceArtifact(); + Element polygon = serve.addElement(doc, svgNS, x, y, serHeight); + Element text; + if (!ser.endsWith("Impl")) + text = Text.addTextElement(doc, svgNS, x, y - Constant.SPACING_FOR_TEXT, ser); + else + text = Text.addTextElement(doc, svgNS, x, y - Constant.SPACING_FOR_TEXT, ""); + + Element child = polygon; + if (baseURL != null) { + String url = baseURL + "/components/" + ent.getName() + "/services/" + ser; + child = createLink(polygon, url); + } + + svgRoot.appendChild(child); + svgRoot.appendChild(text); + + y += (serHeight + Constant.SPACING_FOR_COMPONENT_OF_SERVICE); + + serve.setName(ser); + serve.setContainerName(ent.getName()); + sers.add(serve); + } + } + + private void addCompositeService() { + + int serHeight = comp.getSerHeight(); + int x = comp.getX() - (serHeight * 2 / 3); + int y = + comp.getY() + getStartingPoint(comp.getHeight(), serHeight, Constant.SPACING_FOR_COMPOSITE_OF_SERVICE, comp + .getServices().size()); + + //int y= comp.getY() + Constant.SPACING_FOR_COMPOSITE_OF_SERVICE; + + //System.err.println(serHeight); + //System.out.println("''''''"+((CompositeEntity)comp).getName() +" '''''' "+ comp.getServices().size()); + for (String ser : comp.getServices()) { + + ServiceArtifact serve = new ServiceArtifact(); + Element polygon = serve.addElement(doc, svgNS, x, y, serHeight); + Element text; + if (!ser.endsWith("Impl")) + text = Text.addTextElement(doc, svgNS, x, y - Constant.SPACING_FOR_TEXT, ser); + else + text = Text.addTextElement(doc, svgNS, x, y - Constant.SPACING_FOR_TEXT, ""); + + svgRoot.appendChild(polygon); + svgRoot.appendChild(text); + + y += (serHeight + Constant.SPACING_FOR_COMPOSITE_OF_SERVICE); + + serve.setName(ser); + serve.setContainerName(comp.getName()); + sers.add(serve); + } + } + + private void addCompositeReference() { + + int refHeight = comp.getRefHeight(); + + int x = (comp.getX() + comp.getWidth()) - (refHeight * 2 / 3); + int y = + comp.getY() + getStartingPoint(comp.getHeight(), + refHeight, + Constant.SPACING_FOR_COMPOSITE_OF_REFERENCE, + comp.getReferences().size()); + + for (String ref : comp.getReferences()) { + ReferenceArtifact refer = new ReferenceArtifact(); + Element polygon = refer.addElement(doc, svgNS, x, y, refHeight); + Element text = Text.addTextElement(doc, svgNS, x, y - Constant.SPACING_FOR_TEXT, ref); + svgRoot.appendChild(polygon); + svgRoot.appendChild(text); + + y += (refHeight + Constant.SPACING_FOR_COMPOSITE_OF_REFERENCE); + + refer.setName(ref); + refer.setContainerName(comp.getName()); + refs.add(refer); + + } + + } + + //Algorithm to position in center + private int getStartingPoint(int compDim, int artifactDim, int gap, int artifactQty) { + + int x = (compDim - artifactQty * artifactDim - (artifactQty - 1) * gap) / 2; + return x; + } + + private void addCompositeProperties() { + int propLen = comp.getPropWidth(); + + int x = + comp.getX() + getStartingPoint(comp.getWidth(), propLen, Constant.SPACING_FOR_COMPOSITE_OF_PROPERTY, comp + .getProperties().size()); + //int x= comp.getX() + Constant.SPACING_FOR_COMPOSITE_OF_PROPERTY; + int y = comp.getY() - propLen / 2; + + for (String prop : comp.getProperties()) { + PropertyArtifact pro = new PropertyArtifact(); + Element property = pro.addElement(doc, svgNS, x, y, propLen); + Element text = Text.addTextElement(doc, svgNS, x, y - Constant.SPACING_FOR_TEXT, prop); + + svgRoot.appendChild(property); + svgRoot.appendChild(text); + + x += (propLen + Constant.SPACING_FOR_COMPOSITE_OF_PROPERTY); + + pro.setName(prop); + pro.setContainerName(comp.getName()); + } + } + + private void addComponent(Entity ent) { + + ComponentArtifact comp = new ComponentArtifact(); + //System.err.println(ent.getX()); + Element com = comp.addElement(doc, svgNS, ent.getX(), ent.getY(), ent.getHeight(), ent.getWidth()); + + Element component = com; + if (baseURL != null) { + String url = baseURL + "/components/" + ent.getName(); + component = createLink(com, url); + } + + Element text = + Text.addTextElement(doc, + svgNS, + ent.getX(), + ent.getY() + (ent.getHeight() + Constant.COMPONENT_TEXT_SPACING), + ent.getName()); + + svgRoot.appendChild(component); + svgRoot.appendChild(text); + + comp.setName(ent.getName()); + + if (ent.getImplementation() == null) { + return; + } + // Add the implementation + ImplementationArtifact impl = new ImplementationArtifact(); + impl.setName(ent.getImplementation()); + impl.setContainerName(ent.getName()); + Element implElement = + impl.addElement(doc, + svgNS, + ent.getX() + ent.getWidth() / 4, + ent.getY() + ent.getHeight() / 4, + ent.getHeight() / 2, + ent.getWidth() / 2); + + Element text2 = + Text.addTextElement(doc, + svgNS, + ent.getX() + ent.getWidth() / 4, + ent.getY() + (ent.getHeight() / 4 + Constant.COMPONENT_TEXT_SPACING), + ent.getImplementation()); + text2.setAttributeNS(null, "font-size", "10"); + if (baseURL != null) { + String url = baseURL + "/components/" + ent.getName() + "/implementation"; + implElement = createLink(implElement, url); + } + svgRoot.appendChild(implElement); + svgRoot.appendChild(text2); + + } + + private Element createLink(Element com, String url) { + Element link = doc.createElementNS(svgNS, "a"); + link.setAttributeNS(XLINK_NS, "xlink:href", url); + link.appendChild(com); + return link; + } + + private void addComposite() { + + CompositeArtifact composite = new CompositeArtifact(); + + Element composi = composite.addElement(doc, svgNS, comp.getX(), comp.getY(), comp.getHeight(), comp.getWidth()); + Element text = Text.addTextElement(doc, svgNS, comp.getX() + 20, comp.getY() + 20, comp.getName()); + + svgRoot.appendChild(composi); + svgRoot.appendChild(text); + + composite.setName(comp.getName()); + + } + + public void setDiagramHeight(int diagramHeight) { + this.diagramHeight = diagramHeight; + } + + public int getDiagramHeight() { + return diagramHeight; + } + + public void setDiagramWidth(int diagramWidth) { + this.diagramWidth = diagramWidth; + } + + public int getDiagramWidth() { + return diagramWidth; + } + +} diff --git a/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/html/HTMLWrapper.java b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/html/HTMLWrapper.java new file mode 100755 index 0000000000..cf399bf23c --- /dev/null +++ b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/html/HTMLWrapper.java @@ -0,0 +1,90 @@ +/* + * 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.diagram.html; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; + +public class HTMLWrapper { + + private File htmlFilePath; + private String compositeName; + private String svg; + + /** + * + * @param svg + * @param compositeName + * @param htmlFilePath + */ + public HTMLWrapper(String svg, String compositeName, File htmlFilePath) { + + this.svg = svg; + this.compositeName = compositeName; + this.htmlFilePath = htmlFilePath; + } + + public String buildHTML() throws Exception { + String content = + "" + "<html>\n" + + "<head>\n" + + "<h1 align='center'>Apache Tuscany - Composite Diagram Generator</h1>\n" + + "<h2 align='center'>" + + compositeName + + "</h2>\n" + + "</br>\n" + + + // "<script type=\"text/javascript\" src=\""+CANVG_LIB_DIR+RGB_FILE+"\"></script>\n" + + // "<script type=\"text/javascript\" src=\""+CANVG_LIB_DIR+CANVG_FILE+"\"></script>\n" + + // "<script type=\"text/javascript\">\n" + + // "window.onload = function() {\n" + + // "//load '../path/to/your.svg' in the canvas with id = 'canvas'\n" + + // "canvg('canvas', '"+svgFileName+"')\n" + + // "//load a svg snippet in the canvas with id = 'drawingArea'\n" + + // "canvg(document.getElementById('drawingArea'), '<svg>...</svg>')\n" + + // "canvg('canvas', '"+svgFileName+"', {})\n" + + // "}\n" + + // "</script>\n" + + "</head>\n" + + "<body>\n" + + svg + + "\n" + + + // "<canvas id=\"canvas\" width=\""+compositeWidth+"px\" height=\""+compositeHeight+"px\">\n" + + // "</canvas>\n" + + "</body>\n" + + "</html>"; + + fileWriter(content); + + return content; + + } + + private void fileWriter(String content) throws Exception { + + FileWriter fileWriter = new FileWriter(htmlFilePath); + BufferedWriter bufferedWriter = new BufferedWriter(fileWriter); + bufferedWriter.append(content); + bufferedWriter.close(); + + } +} diff --git a/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/layout/ComponentEntity.java b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/layout/ComponentEntity.java new file mode 100755 index 0000000000..50da28ec67 --- /dev/null +++ b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/layout/ComponentEntity.java @@ -0,0 +1,223 @@ +/* + * 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.diagram.layout; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.tuscany.sca.diagram.artifacts.Constant; + +/** + * Represents an unit (a component including its references, services, properties + * and adjacent units) in the diagram. + * + */ +public class ComponentEntity extends Entity { + + private Map<String, String> referenceToServiceMap = new HashMap<String, String>(); + + public ComponentEntity() { + setStartPosition(200); + setHeight(Constant.COMPONENT_DEFAULT_HEIGHT); + setWidth(Constant.COMPONENT_DEFAULT_WIDTH); + + setRefHeight(Constant.DEFAULT_MAXIMUM_HEIGHT_FOR_COMPONENT_OF_REFERENCE); + setSerHeight(Constant.DEFAULT_MAXIMUM_HEIGHT_FOR_COMPONENT_OF_SERVICE); + setPropWidth(Constant.DEFAULT_MAXIMUM_HEIGHT_FOR_COMPONENT_OF_PROPERTY); + } + + public void build() { + // Find the services height + int size1 = services.size(); + int total1 = size1 * serHeight + (size1 + 1) * Constant.SPACING_FOR_COMPONENT_OF_SERVICE; + + // Find the references height + int size2 = references.size(); + int total2 = size2 * refHeight + (size2 + 1) * Constant.SPACING_FOR_COMPONENT_OF_REFERENCE; + + int total = Math.max(total1, total2); + height = Math.max(total, height); + + // Find the properties width + int size3 = properties.size(); + int total3 = size3 * propWidth + (size3 + 1) * Constant.SPACING_FOR_COMPONENT_OF_PROPERTY; + + width = Math.max(width, total3); + + } + + /** + * Put a value to referenceToServiceMap + * @param ref + * @param ser + * @return successfully added or not + */ + //assumption there can not be two services for the same reference + public boolean addToRefToSerMap(String ref, String ser) { + //ref = ref.toLowerCase(); + //ser = ser.toLowerCase(); + + if (referenceToServiceMap.containsKey(ref)) + return false; + + referenceToServiceMap.put(ref, ser); + return true; + } + + /** + * Retrieve a service name for a given reference + * @param ref + * @return service name + */ + public String getSerOfRef(String ref) { + //ref = ref.toLowerCase(); + + if (!referenceToServiceMap.containsKey(ref)) + return null; + + return referenceToServiceMap.get(ref); + } + + public Map<String, String> getReferenceToServiceMap() { + return referenceToServiceMap; + } + + public void setReferenceToServiceMap(HashMap<String, String> referenceToServiceMap) { + this.referenceToServiceMap = referenceToServiceMap; + } + + // public int getNoOfRefs(){ + // return references.size(); + // } + // + // public int getNoOfSers(){ + // return services.size(); + // } + // + // public int getNoOfProps(){ + // return properties.size(); + // } + // + // public int getNoOfAdjacentUnits(){ + // return adjacentEntities.size(); + // } + // + // /** + // * Put a value to referenceToServiceMap + // * @param ref + // * @param ser + // * @return successfully added or not + // */ + // //assumption there can not be two services for the same reference + // public boolean addToRefToSerMap(String ref, String ser){ + // //ref = ref.toLowerCase(); + // //ser = ser.toLowerCase(); + // + // if (referenceToServiceMap.containsKey(ref)) + // return false; + // + // referenceToServiceMap.put(ref, ser); + // return true; + // } + // + // /** + // * Retrieve a service name for a given reference + // * @param ref + // * @return service name + // */ + // public String getSerOfRef(String ref){ + // //ref = ref.toLowerCase(); + // + // if (!referenceToServiceMap.containsKey(ref)) + // return null; + // + // return referenceToServiceMap.get(ref); + // } + // + // public void addAService(String serName){ + // //serName = serName.toLowerCase(); + // services.add(serName); + // + // } + // + // public void addAReference(String refName){ + // //refName = refName.toLowerCase(); + // references.add(refName); + // + // } + // + // public void addAProperty(String propName){ + // //propName = propName.toLowerCase(); + // properties.add(propName); + // + // } + // + // public void addAnAdjacentEntity(String x){ + //// System.out.println("eee "+x); + // adjacentEntities.add(x); + // + // } + // + // public void addAnConnectedEntity(String x){ + //// System.out.println("eee "+x); + // adjacentEntities.add(x); + // + // } + // + // public HashMap<String, String> getReferenceToServiceMap() { + // return referenceToServiceMap; + // } + // public void setReferenceToServiceMap( + // HashMap<String, String> referenceToServiceMap) { + // this.referenceToServiceMap = referenceToServiceMap; + // } + // public ArrayList<String> getProperties() { + // return properties; + // } + // public void setProperties(ArrayList<String> properties) { + // this.properties = properties; + // } + // public HashSet<String> getAdjacentEntities() { + // return adjacentEntities; + // } + // public void setAdjacentEntities(HashSet<String> adjacentEntities) { + // this.adjacentEntities = adjacentEntities; + // } + // public void setServices(ArrayList<String> services) { + // this.services = services; + // } + // + // public ArrayList<String> getServices() { + // return services; + // } + // + // public ArrayList<String> getReferences() { + // return references; + // } + + // public void setConnectedEntities(HashSet<String> connectedEntities) { + // this.connectedEntities = connectedEntities; + // } + // + // public HashSet<String> getConnectedEntities() { + // return connectedEntities; + // } + +} diff --git a/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/layout/CompositeEntity.java b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/layout/CompositeEntity.java new file mode 100755 index 0000000000..1520b0ae83 --- /dev/null +++ b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/layout/CompositeEntity.java @@ -0,0 +1,182 @@ +/* + * 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.diagram.layout; + +import java.util.ArrayList; +import java.util.HashMap; + +import org.apache.tuscany.sca.diagram.artifacts.Constant; + +/** + * Represents an unit (a component including its references, services, properties + * and adjacent units) in the diagram. + * + */ +public class CompositeEntity extends Entity { + + // private String componentName; + // private int X, Y, level=-1, lane=-1, refHeight, serHeight, propLength; + // private final int height= Component.DEFAULT_HEIGHT, width= Component.DEFAULT_WIDTH; + // public static final int defaultNoOfSers= Component.DEFAULT_HEIGHT / (Service.MAXIMUM_HEIGHT+Service.SPACING); + // public static final int defaultNoOfRefs= Component.DEFAULT_HEIGHT / (Reference.MAXIMUM_HEIGHT+Reference.SPACING); //same value for defaultNoOfSers + // public static final int defaultNoOfProps= Component.DEFAULT_WIDTH / (Property.MAXIMUM_HEIGHT+Property.SPACING); + + private final String fileNameSuffix = "_diagram"; + private int maxInternalLevel = -1; + private int maxInternalLane = -1; + private ComponentEntity[] componentList; + private int[][] connections; + private HashMap<String, String> promoteAService = new HashMap<String, String>(); + private HashMap<String, ArrayList<String>> promoteAReference = new HashMap<String, ArrayList<String>>(); + private ArrayList<String> includedComposites = new ArrayList<String>(); + + //private HashSet<String> connectedEntities = new HashSet<String>(); + + public CompositeEntity(String name) { + setStartPosition(200); + setLevel(0); + setLane(0); + + setX(getStartPosition()); + setY(getStartPosition() / 2); + + setName(name); + + setRefHeight(Constant.DEFAULT_MAXIMUM_HEIGHT_FOR_COMPOSITE_OF_REFERENCE); + setSerHeight(Constant.DEFAULT_MAXIMUM_HEIGHT_FOR_COMPOSITE_OF_SERVICE); + setPropWidth(Constant.DEFAULT_MAXIMUM_HEIGHT_FOR_COMPOSITE_OF_PROPERTY); + } + + public void build() { + int h = height; + int w = width; + + // Find the services height + int size1 = services.size(); + int total1 = size1 * serHeight + (size1 + 1) * Constant.SPACING_FOR_COMPOSITE_OF_SERVICE; + + // Find the references height + int size2 = references.size(); + int total2 = size2 * refHeight + (size2 + 1) * Constant.SPACING_FOR_COMPOSITE_OF_REFERENCE; + + int total = Math.max(total1, total2); + + if (!includedComposites.isEmpty()) { + height = Math.max(total, h) + 80 + getY(); + } else { + height = Math.max(total, h) + getY(); + } + + // Find the properties width + int size3 = properties.size(); + int total3 = size3 * propWidth + (size3 + 1) * Constant.SPACING_FOR_COMPOSITE_OF_PROPERTY; + + width = Math.max(w, total3) + getX(); + } + + public int getMaxInternalLevel() { + return maxInternalLevel; + } + + public int getMaxInternalLane() { + return maxInternalLane; + } + + public boolean addToPromoteAService(String compositeSer, String componentSer) { + //ref = ref.toLowerCase(); + //ser = ser.toLowerCase(); + + if (promoteAService.containsKey(compositeSer)) + return false; + + promoteAService.put(compositeSer, componentSer); + return true; + } + + public void setPromoteAService(HashMap<String, String> promoteAService) { + this.promoteAService = promoteAService; + } + + public HashMap<String, String> getPromoteAService() { + return promoteAService; + } + + public boolean addToPromoteAReference(String compositeRef, String componentRef) { + ArrayList<String> list; + + if (promoteAReference.containsKey(compositeRef)) { + list = promoteAReference.get(compositeRef); + } else { + list = new ArrayList<String>(); + } + + list.add(componentRef); + promoteAReference.put(compositeRef, list); + return true; + } + + public boolean addToIncludedComposites(String composite) { + + includedComposites.add(composite); + + return true; + } + + public void setPromoteAReference(HashMap<String, ArrayList<String>> promoteAReference) { + this.promoteAReference = promoteAReference; + } + + public HashMap<String, ArrayList<String>> getPromoteAReference() { + return promoteAReference; + } + + public ComponentEntity[] getComponentList() { + return componentList; + } + + public void setComponentList(ComponentEntity[] componentList) { + this.componentList = componentList; + } + + public void setConnections(int[][] connections) { + this.connections = connections; + } + + public int[][] getConnections() { + return connections; + } + + public ArrayList<String> getIncludedComposites() { + return includedComposites; + } + + public String getFileNameSuffix() { + return fileNameSuffix; + } + + public void setMaxInternalLevel(int maxInternalLevel) { + this.maxInternalLevel = maxInternalLevel; + } + + public void setMaxInternalLane(int maxInternalLane) { + this.maxInternalLane = maxInternalLane; + } + +} diff --git a/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/layout/Entity.java b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/layout/Entity.java new file mode 100755 index 0000000000..cd9f1b8133 --- /dev/null +++ b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/layout/Entity.java @@ -0,0 +1,265 @@ +/* + * 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.diagram.layout; + +import java.util.ArrayList; +import java.util.HashSet; + +public abstract class Entity { + protected int id = -1; //a unique integer id (0..n) + protected String name; // a unique name + protected int spaceFactor = 2; //which determines the free space surrounded by this + protected int x; // x coordinate + protected int y; // y coordinate + protected int level = -1; // corresponding row which this entity is placed + protected int lane = -1; // corresponding column which this entity is placed + protected boolean positionSet = false; + protected int height; // height of the entity + protected int width; // width of the entity + protected int refHeight; // height of a reference element + protected int serHeight; // height of a service element + protected int propWidth; // length of a property element + + protected int startPosition = 0; + protected Entity parent = null; + + protected ArrayList<String> references = new ArrayList<String>(); + + protected ArrayList<String> services = new ArrayList<String>(); + + protected ArrayList<String> properties = new ArrayList<String>(); + + protected HashSet<String> adjacentEntities = new HashSet<String>(); + + protected String implementation; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getX() { + return x; + } + + public void setX(int x) { + this.x = x; + } + + public int getY() { + return y; + } + + public void setY(int y) { + this.y = y; + } + + public int getLevel() { + return level; + } + + public void setLevel(int level) { + this.level = level; + } + + public int getLane() { + return lane; + } + + public void setLane(int lane) { + this.lane = lane; + } + + public int getHeight() { + return height; + } + + public void setHeight(int height) { + this.height = height; + } + + public int getWidth() { + return width; + } + + public void setWidth(int width) { + this.width = width; + } + + public int getRefHeight() { + return refHeight; + } + + public void setRefHeight(int refHeight) { + this.refHeight = refHeight; + } + + public int getSerHeight() { + return serHeight; + } + + public void setSerHeight(int serHeight) { + this.serHeight = serHeight; + } + + public int getPropWidth() { + return propWidth; + } + + public void setPropWidth(int propLength) { + this.propWidth = propLength; + } + + public int getNoOfRefs() { + return references.size(); + } + + public int getNoOfSers() { + return services.size(); + } + + public int getNoOfProps() { + return properties.size(); + } + + public int getNoOfAdjacentUnits() { + return adjacentEntities.size(); + } + + public void addAService(String serName) { + //serName = serName.toLowerCase(); + services.add(serName); + + } + + public void addAReference(String refName) { + //refName = refName.toLowerCase(); + references.add(refName); + + } + + public void addAProperty(String propName) { + //propName = propName.toLowerCase(); + properties.add(propName); + + } + + public void addAnAdjacentEntity(String x) { + // System.out.println("eee "+x); + adjacentEntities.add(x); + + } + + public void addAnConnectedEntity(String x) { + // System.out.println("eee "+x); + adjacentEntities.add(x); + + } + + public ArrayList<String> getProperties() { + return properties; + } + + public void setProperties(ArrayList<String> properties) { + this.properties = properties; + } + + public HashSet<String> getAdjacentEntities() { + return adjacentEntities; + } + + public void setAdjacentEntities(HashSet<String> adjacentEntities) { + this.adjacentEntities = adjacentEntities; + } + + public void setServices(ArrayList<String> services) { + this.services = services; + } + + public ArrayList<String> getServices() { + return services; + } + + public ArrayList<String> getReferences() { + return references; + } + + public void setId(int id) { + this.id = id; + } + + public int getId() { + return id; + } + + public void setPositionSet(boolean isPositionSet) { + this.positionSet = isPositionSet; + } + + public boolean isPositionSet() { + return positionSet; + } + + public int getSpaceFactor() { + return spaceFactor; + } + + public void setSpaceFactor(int spaceFactor) { + this.spaceFactor = spaceFactor; + } + + public void setStartPosition(int startPosition) { + this.startPosition = startPosition; + } + + public int getStartPosition() { + return startPosition; + } + + public void setParent(Entity parent) { + this.parent = parent; + } + + public Entity getParent() { + return parent; + } + + public String getImplementation() { + return implementation; + } + + public void setImplementation(String implementation) { + this.implementation = implementation; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("Entity [id=").append(id).append(", name=").append(name).append("]"); + return builder.toString(); + } + + /** + * Adjust the items and coordinates + */ + public abstract void build(); +} diff --git a/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/layout/EntityBuilder.java b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/layout/EntityBuilder.java new file mode 100755 index 0000000000..485ced717d --- /dev/null +++ b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/layout/EntityBuilder.java @@ -0,0 +1,562 @@ +/* + * 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.diagram.layout; + +import org.apache.tuscany.sca.diagram.artifacts.Constant; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +public class EntityBuilder { + + private Document dom; + + private int totalWidth = 0; + private int totalHeight = 0; + + private CompositeEntity composite = null; + + /** + * Constructor which initiates the DOM document + * @param aDom DOM document + */ + public EntityBuilder(Document aDom) { + dom = aDom; + } + + public CompositeEntity buildCompositeEntity() { + + //get the root element + Element docEle = dom.getDocumentElement(); + + String compositeName; + compositeName = docEle.getAttribute("name"); + //System.out.println("compositeName "+compositeName); + + ComponentEntity[] comps = buildComponentEntities(docEle); + + composite = new CompositeEntity(compositeName); + + setParent(comps); + + //System.out.println("ComponentEntity "+comps[0].getLevel()); + int[][] conns = buildConnectionMatrix(comps); + + composite.setComponentList(comps); + composite.setConnections(conns); + + LayoutBuilder buildLayout = new LayoutBuilder(comps, conns, Constant.MAX_LEVELS); + buildLayout.placeEntities(); + composite.setHeight(buildLayout.getTotalHeight()); + composite.setWidth(buildLayout.getTotalWidth()); + composite.setMaxInternalLane(buildLayout.getTotalLane()); + composite.setMaxInternalLevel(buildLayout.getTotalLevel()); + + //System.out.println("conns "+conns[0][0]); + + buildCompositeService(docEle); + buildCompositeReference(docEle); + buildCompositeProperty(docEle); + + addInclusions(docEle); + + composite.build(); + + return composite; + } + + // private void assignCoordinates() { + // + // for(Entity ent: elts){ + // ent.setX(ent.getParent().getX() + ent.getStartPosition()); + // ent.setY(ent.getParent().getY() + ent.getStartPosition()/2); + // } + // } + + private void setParent(ComponentEntity[] comps) { + + for (ComponentEntity comp : comps) { + comp.setParent(composite); + } + } + + private void buildCompositeService(Element docEle) { + + NodeList nl = docEle.getElementsByTagName("service"); + //System.err.println("^^^^^^^^^ "+nl.getLength()); + if (nl != null && nl.getLength() > 0) { + + for (int i = 0; i < nl.getLength(); i++) { + + Element elt = (Element)nl.item(i); + + if (elt.getParentNode().getNodeName().equals("composite")) { + String compositeSer = elt.getAttribute("name"); + composite.addAService(compositeSer); + + String target = elt.getAttribute("promote"); + + String service, serviceComp; + String[] arr1 = extractComp(target); + serviceComp = arr1[0]; + service = arr1[1]; + + if (service == null) { + composite.addToPromoteAService(compositeSer, serviceComp); + } else { + composite.addToPromoteAService(compositeSer, serviceComp + "/" + service); + } + } + + } + } + } + + private void buildCompositeReference(Element docEle) { + + NodeList nl = docEle.getElementsByTagName("reference"); + //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); + + if (elt.getParentNode().getNodeName().equals("composite")) { + String compositeRef = elt.getAttribute("name"); + composite.addAReference(compositeRef); + + String targetStr = elt.getAttribute("promote"); + + String[] targets = targetStr.split(" "); + + for (String target : targets) { + + String reference, referenceComp; + String[] arr1 = extractComp(target); + referenceComp = arr1[0]; + reference = arr1[1]; + + if (reference == null) { + composite.addToPromoteAReference(compositeRef, referenceComp); + } else { + composite.addToPromoteAReference(compositeRef, referenceComp + "/" + reference); + } + } + + } + } + } + } + + private void buildCompositeProperty(Element docEle) { + + NodeList nl = docEle.getElementsByTagName("property"); + //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); + + if (elt.getParentNode().getNodeName().equals("composite")) { + String compositeProp = elt.getAttribute("name"); + composite.addAProperty(compositeProp); + } + } + } + } + + private void addInclusions(Element docEle) { + + NodeList nl = docEle.getElementsByTagName("include"); + //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); + + if (elt.getParentNode().getNodeName().equals("composite")) { + String compToBeIncluded = elt.getAttribute("name"); + composite.addToIncludedComposites(compToBeIncluded); + } + } + } + } + + private int[][] buildConnectionMatrix(ComponentEntity[] comps) { + + int[][] connections = new int[comps.length][comps.length]; + connections = initConnections(connections); + + for (Entity ent : comps) { + for (String name : ent.getAdjacentEntities()) { + ComponentEntity e2 = findEntity(comps, name); + if (ent != null && e2 != null) { + //System.out.println("^^^^^^^^^ "+e2.getName()); + connections[ent.getId()][e2.getId()] = 1; + } + } + + } + + return connections; + } + + private String[] extractComp(String str) { + + String[] arr = new String[2]; + + if (str.contains("/")) { + arr = str.split("/"); + } else { + arr[0] = str; + arr[1] = null; + } + return arr; + } + + private int[][] initConnections(int[][] connections) { + + for (int i = 0; i < connections.length; i++) { + for (int j = 0; j < connections.length; j++) { + connections[i][j] = 0; + } + } + return connections; + } + + public ComponentEntity[] buildComponentEntities(Element docEle) { + + ComponentEntity[] elts = null; + + // //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 ComponentEntity[nl.getLength()]; + + for (int i = 0; i < nl.getLength(); i++) { + elts[i] = new ComponentEntity(); + Element nVal = (Element)nl.item(i); + //System.out.println(nVal.hasAttribute("name")); + elts[i].setId(i); + elts[i].setName(nVal.getAttribute("name")); + + setImplementation(nVal, elts[i]); + setServices(nVal, elts[i]); + setReferences(nVal, elts[i]); + setProperties(nVal, elts[i]); + + elts[i].build(); + } + } + + buildWires(docEle, elts); + // //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; + // } + // + // ComponentEntity e = findEntity(referenceComp); + // System.out.println("^^^^^^^^^ "+e.getName()); + // if(e != null){ + // createConnection(e, reference, serviceComp, service); + // } + // } + // } + // + // positionEntities(elts); + // + // calculateProperties(elts); + // print(elts); + + return elts; + + } + + private void buildWires(Element docEle, ComponentEntity[] elts) { + + //sec. 5.4 in the spec + NodeList 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; + + String[] arr1 = extractComp(target); + serviceComp = arr1[0]; + service = arr1[1]; + + String[] arr2 = extractComp(source); + referenceComp = arr2[0]; + reference = arr2[1]; + + // //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; + // } + // + ComponentEntity e1 = findEntity(elts, referenceComp); + //ComponentEntity e2 = findEntity(comps, serviceComp); + + //System.out.println("^^^^^^^^^ "+e1.getName()); + if (e1 != null) { + //System.out.println("^^^^^^^^^ "+e1.getId()); + //connections[e1.getId()][e2.getId()] = 1; + createConnection(e1, reference, serviceComp, service); + } + } + } + + } + + private ComponentEntity findEntity(ComponentEntity[] elts, String componentName) { + + for (ComponentEntity e : elts) { + if (e.getName().equals(componentName)) { + return e; + } + } + return null; + } + + private void setReferences(Element nVal, ComponentEntity 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(ComponentEntity ent, String reference, String serviceComp, String service) { + + String referenceComp = ent.getName(); + + if (reference != null && service != null) { + + ent.addToRefToSerMap(reference, serviceComp + "/" + service); + ent.addAnAdjacentEntity(serviceComp); + } else if (reference == null && service != null) { + ent.addToRefToSerMap(referenceComp, serviceComp + "/" + service); + ent.addAnAdjacentEntity(serviceComp); + } else if (reference != null && service == null) { + ent.addToRefToSerMap(reference, serviceComp); + ent.addAnAdjacentEntity(serviceComp); + } else { + ent.addToRefToSerMap(referenceComp, serviceComp); + ent.addAnAdjacentEntity(serviceComp); + } + } + + @SuppressWarnings("unused") + private void print(ComponentEntity[] elts) { + + for (ComponentEntity ent : elts) { + System.out.println(ent.getName() + " : " + + ent.getLevel() + + " : " + + ent.getLane() + + " : " + + ent.getX() + + " : " + + ent.getY()); + } + } + + private void setServices(Element nVal, ComponentEntity 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")); + } + } else { + + 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 = extractServiceName(elt.getAttribute("class")); + ent.addAService(serName); + } + } + + } + + } + + private void setImplementation(Element nVal, ComponentEntity ent) { + NodeList nodes = nVal.getChildNodes(); + + for (int i = 0; i < nodes.getLength(); i++) { + if (nodes.item(i) instanceof Element) { + Element elt = (Element)nodes.item(i); + String name = elt.getNodeName(); + if (name != null && name.contains(":")) { + name = name.substring(name.indexOf(':') + 1).trim(); + } + if (name != null && name.startsWith("implementation.")) { + String type = name.substring("implementation.".length()); + if ("implementation.java".equals(name)) { + String cls = elt.getAttribute("class"); + ent.setImplementation(type + ":" + extractClassName(cls)); + } else { + ent.setImplementation(type); + } + break; + } + } + } + } + + private String extractClassName(String classAttr) { + if (classAttr == null) { + return ""; + } else { + int index = classAttr.lastIndexOf('.'); + return classAttr.substring(index + 1); + } + } + + /** + * + * This will extract the service name part from the class attribute of + * implementation.java element. + * eg: if class = "NirmalServiceImpl", returning service name would be "NirmalService" + */ + private String extractServiceName(String classAttr) { + if (classAttr != null) { + String[] x = classAttr.split("\\."); + String name = x[x.length - 1]; + if (name.endsWith("Impl")) { + return name.substring(0, name.length() - 4); + } else { + return name; + } + } + return ""; + } + + private void setProperties(Element nVal, ComponentEntity 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; + } + +} diff --git a/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/layout/LayoutBuilder.java b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/layout/LayoutBuilder.java new file mode 100755 index 0000000000..d67dee1629 --- /dev/null +++ b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/layout/LayoutBuilder.java @@ -0,0 +1,296 @@ +/* + * 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.diagram.layout; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import org.apache.tuscany.sca.diagram.artifacts.Constant; + +public class LayoutBuilder { + + private Entity[] elts; + private int[][] conns; + private int maxLevels = 8; + + private int totalLevel; + private int totalLane; + + private int totalHeight; + private int totalWidth; + + private int[][] graph; + + /** + * Constructor which takes set of entities and their connection matrix + * + * @param entities + * @param connections + * @param maxLevels + */ + public LayoutBuilder(Entity[] entities, int[][] connections, int maxLevels) { + elts = entities; + graph = connections; // Keep the original connections + + // Clone the connections + int len = connections.length; + conns = new int[len][]; + for (int i = 0; i < len; i++) { + conns[i] = new int[len]; + for (int j = 0; j < len; j++) { + conns[i][j] = connections[i][j]; + } + } + this.maxLevels = maxLevels; + } + + /** + * Layout Building Algorithm + * ~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * Here we position (i.e. assigning a level and a lane) all Entities + * 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 connected Entities of starting Entity. + * * If there are connected entities; + * *For each connected Entity; + * *We assign a corresponding level and a lane + * *Then recurse the procedure for connections of the assigned Entity + * + * + */ + public Entity[] placeEntities() { + + sortEntities(); + + // Build the grid for entities + Entity[][] grid = new Entity[totalLane + 1][totalLevel + 1]; + int[] height = new int[totalLevel + 1]; + int[] width = new int[totalLane + 1]; + + for (Entity e : elts) { + grid[e.getLane()][e.getLevel()] = e; + if (height[e.getLevel()] < e.getHeight() + Constant.COMPONENT_DEFAULT_HEIGHT) { + height[e.getLevel()] = e.getHeight() + Constant.COMPONENT_DEFAULT_HEIGHT; + } + if (width[e.getLane()] < e.getWidth() + Constant.COMPONENT_DEFAULT_WIDTH) { + width[e.getLane()] = e.getWidth() + Constant.COMPONENT_DEFAULT_WIDTH; + } + } + + for (int i = 1; i < totalLane + 1; i++) { + width[i] += width[i - 1]; + } + + for (int j = 1; j < totalLevel + 1; j++) { + height[j] += height[j - 1]; + } + + totalWidth = width[totalLane]; + totalHeight = height[totalLevel]; + + for (int i = 0; i < totalLane + 1; i++) { + for (int j = 0; j < totalLevel + 1; j++) { + Entity ent = grid[i][j]; + if (ent != null) { + int w = ent.getLane() == 0 ? 0 : width[i - 1]; + ent.setX(ent.getParent().getX() + ent.getStartPosition() + w); + int h = ent.getLevel() == 0 ? 0 : height[j - 1]; + ent.setY(ent.getParent().getY() + ent.getStartPosition() / 2 + h); + } + } + } + + return elts; + + } + + private Entity findEntity(int i) { + + for (Entity ent : elts) { + if (ent.getId() == i) { + return ent; + } + } + return null; + } + + private void setPosition(Entity ent, int level, int lane) { + if (totalLane < lane) { + totalLane = lane; + } + if (totalLevel < level) { + totalLevel = level; + } + ent.setLevel(level); + ent.setLane(lane); + ent.setPositionSet(true); + } + + /** + * http://en.wikipedia.org/wiki/Coffman%E2%80%93Graham_algorithm#The_algorithm + * @param sorted + * @param e1 + * @param e2 + * @return + */ + private int compareEntities(List<Integer> sorted, int e1, int e2) { + List<Integer> neighbors1 = findIncomingNeighbors(e1); + List<Integer> neighbors2 = findIncomingNeighbors(e2); + + if (neighbors1.isEmpty() && neighbors2.isEmpty()) { + return 0; + } else if (neighbors1.isEmpty()) { + return -1; + } else if (neighbors2.isEmpty()) { + return 1; + } + + int max = graph.length + 1; + int n1 = max; + int n2 = max; + for (int i = sorted.size() - 1; i >= 0; i--) { + if (neighbors1.contains(sorted.get(i))) { + n1 = i; + } + if (neighbors2.contains(sorted.get(i))) { + n2 = i; + } + if (n1 == n2) { + // Need to try the 2nd most recently added incoming neighbor + // Reset the indexes and continue + n1 = max; + n2 = max; + continue; + } + } + return n1 - n2; + } + + private List<Integer> findIncomingNeighbors(int e1) { + // Get all the inbound connections for a given entity + List<Integer> ins = new ArrayList<Integer>(); + for (int i = 0; i < graph.length; i++) { + if (graph[i][e1] == 1) { + ins.add(i); + } + } + return ins; + } + + /** + * Perform a topological sort on the graph so that we can place the entities into level/lane grids + * http://en.wikipedia.org/wiki/Coffman%E2%80%93Graham_algorithm#The_algorithm + */ + List<Integer> sortEntities() { + int lane = 0; + final List<Integer> sorted = new ArrayList<Integer>(); + while (true) { + List<Integer> ids = new ArrayList<Integer>(); + for (int i = 0; i < conns.length; i++) { + Entity ent = findEntity(i); + if (ent.isPositionSet()) { + continue; + } + boolean beingConnected = false; + for (int j = 0; j < conns.length; j++) { + if (conns[j][i] == 1) { + beingConnected = true; + break; + } + } + if (!beingConnected) { + ids.add(i); + } + } + + if (ids.isEmpty()) { + boolean end = true; + // There might be circular dependencies + for (Entity e : elts) { + if (!e.isPositionSet()) { + // Pick the first one + ids.add(e.getId()); + end = false; + break; + } + } + if (end) { + return sorted; + } + } + int level = 0; + Collections.sort(ids, new Comparator<Integer>() { + + @Override + public int compare(Integer e1, Integer e2) { + return compareEntities(sorted, e1, e2); + } + }); + for (int i : ids) { + sorted.add(i); + + if (maxLevels > 0 && level > 0 && (level % maxLevels == 0)) { + // Overflow to the next lane + level = 0; + lane++; + } + + setPosition(findEntity(i), level++, lane); + for (int j = 0; j < conns.length; j++) { + // Remove the connections from i + conns[i][j] = 0; + } + } + lane++; + } + } + + public int getTotalLevel() { + return totalLevel; + } + + public int getTotalLane() { + return totalLane; + } + + public int getTotalHeight() { + return totalHeight; + } + + public int getTotalWidth() { + return totalWidth; + } + +} diff --git a/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/layout/TuscanyCompositeEntityBuilder.java b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/layout/TuscanyCompositeEntityBuilder.java new file mode 100755 index 0000000000..ef8dd3b27e --- /dev/null +++ b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/layout/TuscanyCompositeEntityBuilder.java @@ -0,0 +1,378 @@ +/* + * 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.diagram.layout; + +import java.util.List; + +import javax.xml.namespace.QName; + +import org.apache.tuscany.sca.assembly.Component; +import org.apache.tuscany.sca.assembly.ComponentProperty; +import org.apache.tuscany.sca.assembly.ComponentReference; +import org.apache.tuscany.sca.assembly.ComponentService; +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.assembly.CompositeReference; +import org.apache.tuscany.sca.assembly.CompositeService; +import org.apache.tuscany.sca.assembly.Endpoint; +import org.apache.tuscany.sca.assembly.EndpointReference; +import org.apache.tuscany.sca.assembly.Implementation; +import org.apache.tuscany.sca.assembly.Property; +import org.apache.tuscany.sca.assembly.Reference; +import org.apache.tuscany.sca.assembly.Service; +import org.apache.tuscany.sca.assembly.Wire; +import org.apache.tuscany.sca.diagram.artifacts.Artifact; +import org.apache.tuscany.sca.diagram.artifacts.Constant; +import org.apache.tuscany.sca.implementation.java.JavaImplementation; + +public class TuscanyCompositeEntityBuilder { + + private Composite tuscanyComp; + + private int totalWidth = 0; + private int totalHeight = 0; + + CompositeEntity composite = null; + + /** + * Constructor which initiates the DOM document + * @param aDom DOM document + */ + public TuscanyCompositeEntityBuilder(Composite comp) { + tuscanyComp = comp; + } + + public CompositeEntity buildCompositeEntity() { + + String compositeName = tuscanyComp.getName().getLocalPart(); + // System.out.println("compositeName " + compositeName); + + ComponentEntity[] comps = buildComponentEntities(); + + buildTargets(comps); + buildWires(tuscanyComp.getWires(), comps); + + composite = new CompositeEntity(compositeName); + + setParent(comps); + + // System.out.println("ComponentEntity " + comps[0].getId()); + int[][] conns = buildConnectionMatrix(comps); + // System.out.println("ComponentEntity " + conns[0][0]); + + composite.setComponentList(comps); + composite.setConnections(conns); + + LayoutBuilder buildLayout = new LayoutBuilder(comps, conns, Constant.MAX_LEVELS); + buildLayout.placeEntities(); + composite.setHeight(buildLayout.getTotalHeight()); + composite.setWidth(buildLayout.getTotalWidth()); + composite.setMaxInternalLane(buildLayout.getTotalLane()); + composite.setMaxInternalLevel(buildLayout.getTotalLevel()); + + // System.out.println("conns " + conns[0][0]); + + buildCompositeService(); + buildCompositeReference(); + buildCompositeProperty(); + + addInclusions(); + + composite.build(); + + return composite; + } + + private void setParent(ComponentEntity[] comps) { + + for (ComponentEntity comp : comps) { + comp.setParent(composite); + } + } + + private void buildCompositeService() { + + List<Service> sers = tuscanyComp.getServices(); + + for (int i = 0; i < sers.size(); i++) { + Service compositeSer = sers.get(i); + composite.addAService(compositeSer.getName()); + String service = ((CompositeService)compositeSer).getPromotedService().getName(); + + composite.addToPromoteAService(compositeSer.getName(), service); + } + + } + + private void buildCompositeReference() { + + List<Reference> refs = tuscanyComp.getReferences(); + + for (int i = 0; i < refs.size(); i++) { + Reference compositeRef = refs.get(i); + composite.addAReference(compositeRef.getName()); + + List<ComponentReference> promotedRefs = ((CompositeReference)compositeRef).getPromotedReferences(); + + for (ComponentReference ref : promotedRefs) { + String reference = ref.getName(); + + composite.addToPromoteAReference(compositeRef.getName(), reference); + } + + } + + } + + private void buildCompositeProperty() { + + List<Property> props = tuscanyComp.getProperties(); + + for (int i = 0; i < props.size(); i++) { + Property compositeProp = props.get(i); + composite.addAProperty(compositeProp.getName()); + } + + } + + private void addInclusions() { + + List<Composite> includes = tuscanyComp.getIncludes(); + + for (int i = 0; i < includes.size(); i++) { + Composite anInclude = includes.get(i); + composite.addToIncludedComposites(anInclude.getName().getLocalPart()); + } + + } + + private int[][] buildConnectionMatrix(ComponentEntity[] comps) { + + int[][] connections = new int[comps.length][comps.length]; + connections = initConnections(connections); + + for (Entity ent : comps) { + for (String name : ent.getAdjacentEntities()) { + ComponentEntity e2 = findEntity(comps, name); + if (ent != null && e2 != null) { + //System.out.println("^^^^^^^^^ "+e2.getName()); + connections[ent.getId()][e2.getId()] = 1; + } + } + + } + + return connections; + } + + private String extractComp(ComponentEntity[] elts, String str, boolean isReference) { + String[] names = Artifact.parseNames(str); + if (isReference) { + for (ComponentEntity elt : elts) { + if (elt.getName().equals(names[0])) { + for (String ref : elt.getReferences()) { + if (ref.equals(names[1])) { + return elt.getName(); + } + } + } + } + } else { + for (ComponentEntity elt : elts) { + if (elt.getName().equals(names[0])) { + for (String ser : elt.getServices()) { + if (ser.equals(names[1])) { + return elt.getName(); + } + } + } + } + } + return ""; + + } + + private int[][] initConnections(int[][] connections) { + + for (int i = 0; i < connections.length; i++) { + for (int j = 0; j < connections.length; j++) { + connections[i][j] = 0; + } + } + return connections; + } + + public ComponentEntity[] buildComponentEntities() { + + ComponentEntity[] elts = null; + + List<Component> components = tuscanyComp.getComponents(); + + elts = new ComponentEntity[components.size()]; + + for (int i = 0; i < components.size(); i++) { + Component aComp = components.get(i); + + elts[i] = new ComponentEntity(); + elts[i].setId(i); + elts[i].setName(aComp.getName()); + + Implementation implementation = aComp.getImplementation(); + if (implementation != null) { + String impl = ""; + QName type = implementation.getType(); + if (JavaImplementation.TYPE.equals(type)) { + impl = "java:" + ((JavaImplementation)implementation).getJavaClass().getSimpleName(); + } else if (implementation instanceof Composite) { + impl = "composite:" + ((Composite)implementation).getName().getLocalPart(); + } else { + impl = type.getLocalPart(); + } + elts[i].setImplementation(impl); + } + + setServices(aComp.getServices(), elts[i]); + setReferences(aComp.getReferences(), elts[i]); + setProperties(aComp.getProperties(), elts[i]); + + elts[i].build(); + } + + return elts; + + } + + private void buildTargets(ComponentEntity[] components) { + + for (Component c : tuscanyComp.getComponents()) { + ComponentEntity sourceComponent = findEntity(components, c.getName()); + for (ComponentReference ref : c.getReferences()) { + for (EndpointReference epr : ref.getEndpointReferences()) { + Endpoint ep = epr.getTargetEndpoint(); + if (ep != null && ep.getComponent() != null && ep.getService() != null) { + createConnection(sourceComponent, ref.getName(), ep.getComponent().getName(), ep.getService() + .getName()); + } + } + } + } + } + + private void buildWires(List<Wire> wires, ComponentEntity[] elts) { + + for (int i = 0; i < wires.size(); i++) { + String service, serviceComp, reference, referenceComp; + Wire aWire = wires.get(i); + + reference = aWire.getSource().getName(); + service = aWire.getTarget().getName(); + + referenceComp = extractComp(elts, reference, true); + serviceComp = extractComp(elts, service, false); + + ComponentEntity e1 = findEntity(elts, referenceComp); + + //System.out.println("^^^^^^^^^ "+e1.getName()); + if (e1 != null) { + //System.out.println("^^^^^^^^^ "+e1.getId()); + //connections[e1.getId()][e2.getId()] = 1; + createConnection(e1, reference, serviceComp, service); + } + } + + } + + private ComponentEntity findEntity(ComponentEntity[] elts, String componentName) { + + for (ComponentEntity e : elts) { + if (e.getName().equals(componentName)) { + return e; + } + } + return null; + } + + private void setReferences(List<ComponentReference> refs, ComponentEntity ent) { + + for (int i = 0; i < refs.size(); i++) { + ent.addAReference(refs.get(i).getName()); + } + + } + + private void createConnection(ComponentEntity ent, String reference, String serviceComp, String service) { + + String referenceComp = ent.getName(); + + if (reference != null && service != null) { + + ent.addToRefToSerMap(reference, serviceComp + "/" + service); + ent.addAnAdjacentEntity(serviceComp); + } else if (reference == null && service != null) { + ent.addToRefToSerMap(referenceComp, serviceComp + "/" + service); + ent.addAnAdjacentEntity(serviceComp); + } else if (reference != null && service == null) { + ent.addToRefToSerMap(reference, serviceComp); + ent.addAnAdjacentEntity(serviceComp); + } else { + ent.addToRefToSerMap(referenceComp, serviceComp); + ent.addAnAdjacentEntity(serviceComp); + } + } + + @SuppressWarnings("unused") + private void print(ComponentEntity[] elts) { + + for (ComponentEntity ent : elts) { + System.out.println(ent.getName() + " : " + + ent.getLevel() + + " : " + + ent.getLane() + + " : " + + ent.getX() + + " : " + + ent.getY()); + } + } + + private void setServices(List<ComponentService> sers, ComponentEntity ent) { + + for (int i = 0; i < sers.size(); i++) { + ent.addAService(sers.get(i).getName()); + } + + } + + private void setProperties(List<ComponentProperty> props, ComponentEntity ent) { + + for (int i = 0; i < props.size(); i++) { + ent.addAProperty(props.get(i).getName()); + } + + } + + public int getTotalWidth() { + return totalWidth; + } + + public int getTotalHeight() { + return totalHeight; + } + +} diff --git a/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/main/Main.java b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/main/Main.java new file mode 100755 index 0000000000..033c1a6d00 --- /dev/null +++ b/sca-java-2.x/tags/2.0-RC1/modules/composite-diagram/src/main/java/org/apache/tuscany/sca/diagram/main/Main.java @@ -0,0 +1,325 @@ +/* + * 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.diagram.main; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.StringWriter; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.apache.batik.transcoder.Transcoder; +import org.apache.batik.transcoder.TranscoderException; +import org.apache.batik.transcoder.TranscoderInput; +import org.apache.batik.transcoder.TranscoderOutput; +import org.apache.batik.transcoder.image.JPEGTranscoder; +import org.apache.batik.transcoder.image.PNGTranscoder; +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.cli.Option; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; +import org.apache.commons.cli.PosixParser; +import org.apache.tuscany.sca.diagram.generator.DiagramGenerator; +import org.apache.tuscany.sca.diagram.html.HTMLWrapper; +import org.apache.tuscany.sca.diagram.layout.CompositeEntity; +import org.apache.tuscany.sca.diagram.layout.EntityBuilder; +import org.apache.tuscany.sca.diagram.layout.TuscanyCompositeEntityBuilder; +import org.apache.tuscany.sca.node.NodeFactory; +import org.apache.tuscany.sca.node.configuration.NodeConfiguration; +import org.apache.tuscany.sca.node.extensibility.NodeExtension; +import org.w3c.dom.Document; + +public class Main { + + static Options getCommandLineOptions() { + Options options = new Options(); + Option opt1 = new Option("s", "svg", false, "Generate SVG diagrams"); + options.addOption(opt1); + Option opt2 = new Option("h", "html", false, "Generate HTML documents"); + options.addOption(opt2); + + Option opt3 = new Option("j", "jpeg", false, "Generate JPEG diagrams"); + options.addOption(opt3); + + Option opt4 = new Option("o", "output", true, "Output directory"); + options.addOption(opt4); + + return options; + } + + /** + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + CommandLineParser parser = new PosixParser(); + Options options = getCommandLineOptions(); + CommandLine cli = null; + boolean help = false; + try { + cli = parser.parse(options, args); + if (cli.getArgList().size() == 0) { + help = true; + } + } catch (ParseException e) { + System.out.println(e); + help = true; + } + + // Print out the options and quit + if (help) { + HelpFormatter formatter = new HelpFormatter(); + formatter.printHelp("<-h> <-s> <-o outputDirectory> file1 file2 ...: ", options); + return; + } + + boolean isHtml = false; + boolean isSvg = false; + boolean isJpeg = false; + isSvg = cli.hasOption('s'); + isHtml = cli.hasOption('h'); + isJpeg = cli.hasOption('j'); + + if (!isSvg && !isHtml && !isJpeg) { + isSvg = true; + isHtml = true; + } + + String outFileDir; + + if (cli.hasOption('o')) { + outFileDir = cli.getOptionValue('o'); + } else { + outFileDir = "."; + } + File dir = new File(outFileDir); + String[] compositeFiles = cli.getArgs(); + generate(dir, null, isSvg, isHtml, false, compositeFiles); + } + + public static void generate(File dir, + String baseURL, + boolean isSvg, + boolean isHtml, + boolean isJpeg, + String... compositeFiles) throws Exception { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + for (String str : compositeFiles) { + + if (str != null) { + + DocumentBuilder db = dbf.newDocumentBuilder(); + Document doc = db.parse(str); + + EntityBuilder eb = new EntityBuilder(doc); + CompositeEntity comp = eb.buildCompositeEntity(); + + DiagramGenerator dg = new DiagramGenerator(comp, isHtml, baseURL); + Document svg = dg.buildSVGDocument(); + + if (isJpeg) { + String jpgFileName = comp.getName() + comp.getFileNameSuffix() + ".jpg"; + svgToJPEG(svg, new File(dir, jpgFileName)); + } + + String svgContent = extractSvg(svg); + + if (isSvg) { + writeSVG(dir, svgContent, comp); + } + + if (isHtml) { + writeHTML(dir, svgContent, comp); + } + + } + } + } + + private static void writeHTML(File dir, String svg, CompositeEntity comp) throws Exception { + + File htmlFile = new File(dir, comp.getName() + comp.getFileNameSuffix() + ".html"); + HTMLWrapper html = new HTMLWrapper(svg, comp.getName(), htmlFile); + html.buildHTML(); + + // System.err.println("--------------HTML Output for " + comp.getName() + "--------------\n"); + // System.out.println(content); + // System.err.println("--------------------------------------------------------------\n"); + + } + + private static File writeSVG(File dir, String svg, CompositeEntity comp) throws Exception { + + String svgFileName = comp.getName() + comp.getFileNameSuffix() + ".svg"; + File svgFile = new File(dir, svgFileName); + FileWriter fw = new FileWriter(svgFile); + fw.write(svg); + fw.close(); + return svgFile; + } + + private static String extractSvg(Document svg) throws Exception { + // Print the DOM node + + StringWriter sw = new StringWriter(); + StreamResult result = new StreamResult(sw); + + transform(svg, result); + String svgString = sw.toString(); + + return svgString; + } + + private static void transform(Document svg, StreamResult result) throws Exception { + // Set up the output transformer + TransformerFactory transfac = TransformerFactory.newInstance(); + + Transformer trans = transfac.newTransformer(); + trans.setOutputProperty(OutputKeys.INDENT, "yes"); + trans.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); + + DOMSource source = new DOMSource(svg); + trans.transform(source, result); + } + + public static void svgToJPEG(File svg, File jpeg) throws IOException, TranscoderException { + // Create the transcoder input. + TranscoderInput input = new TranscoderInput(svg.toURI().toString()); + // Create the transcoder output. + OutputStream ostream = new FileOutputStream(jpeg); + TranscoderOutput output = new TranscoderOutput(ostream); + + // Create a JPEG transcoder + Transcoder t = new JPEGTranscoder(); + + // Set the transcoding hints. + t.addTranscodingHint(JPEGTranscoder.KEY_QUALITY, new Float(1.0)); + + // Save the image. + t.transcode(input, output); + + // Flush and close the stream. + ostream.flush(); + ostream.close(); + } + + public static void svgToJPEG(Document svg, File jpeg) throws IOException, TranscoderException { + // Create the transcoder input. + TranscoderInput input = new TranscoderInput(svg); + // Create the transcoder output. + OutputStream ostream = new FileOutputStream(jpeg); + TranscoderOutput output = new TranscoderOutput(ostream); + + // Create a JPEG transcoder + Transcoder t = new JPEGTranscoder(); + + // Set the transcoding hints. + t.addTranscodingHint(JPEGTranscoder.KEY_QUALITY, new Float(1.0)); + + // Save the image. + t.transcode(input, output); + + // Flush and close the stream. + ostream.flush(); + ostream.close(); + } + + public static void svgToJPEG(InputStream svg, OutputStream jpeg) throws IOException, TranscoderException { + // Create the transcoder input. + TranscoderInput input = new TranscoderInput(svg); + + TranscoderOutput output = new TranscoderOutput(jpeg); + + // Create a JPEG transcoder + Transcoder t = new JPEGTranscoder(); + + // Set the transcoding hints. + t.addTranscodingHint(JPEGTranscoder.KEY_QUALITY, new Float(1.0)); + + // Save the image. + t.transcode(input, output); + + // Flush and close the stream. + svg.close(); + jpeg.flush(); + jpeg.close(); + } + + public static void svgToPNG(InputStream svg, OutputStream png) throws IOException, TranscoderException { + // Create the transcoder input. + TranscoderInput input = new TranscoderInput(svg); + + TranscoderOutput output = new TranscoderOutput(png); + + // Create a JPEG transcoder + Transcoder t = new PNGTranscoder(); + + // Save the image. + t.transcode(input, output); + + // Flush and close the stream. + svg.close(); + png.flush(); + png.close(); + } + + /** + * Generate the SVG diagram from + * @param configuration + * @param classLoader + * @return The XML string for the SVG + * @throws Exception + */ + public static String generateDiagram(NodeConfiguration configuration, ClassLoader classLoader, String baseURL) + throws Exception { + ClassLoader currentTCCL = null; + if (classLoader != null) { + currentTCCL = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(classLoader); + } + + try { + NodeFactory factory = NodeFactory.getInstance(); + NodeExtension node = factory.loadNode(configuration); + TuscanyCompositeEntityBuilder builder = new TuscanyCompositeEntityBuilder(node.getDomainComposite()); + CompositeEntity compositeEntity = builder.buildCompositeEntity(); + DiagramGenerator generator = new DiagramGenerator(compositeEntity, false, baseURL); + Document doc = generator.buildSVGDocument(); + return extractSvg(doc); + } finally { + if (currentTCCL != null) { + Thread.currentThread().setContextClassLoader(currentTCCL); + } + } + } + +} |