Java tutorial
/* * JBoss, Home of Professional Open Source * Copyright 2005, JBoss Inc., and individual contributors as indicated * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jbpm.gd.common.editor; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.io.StringWriter; import java.io.Writer; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.part.FileEditorInput; import org.jbpm.gd.common.model.NamedElement; import org.jbpm.gd.common.model.SemanticElement; import org.jbpm.gd.common.notation.AbstractNodeContainer; import org.jbpm.gd.common.notation.BendPoint; import org.jbpm.gd.common.notation.Edge; import org.jbpm.gd.common.notation.Node; import org.jbpm.gd.common.notation.NodeContainer; import org.jbpm.gd.common.notation.NotationElement; import org.jbpm.gd.common.notation.NotationMapping; import org.jbpm.gd.common.notation.RootContainer; import org.jbpm.gd.jpdl.Logger; public abstract class AbstractContentProvider implements ContentProvider { protected abstract SemanticElement getEdgeSemanticElement(Node node, Element notationInfo, int index); protected abstract SemanticElement getNodeSemanticElement(NodeContainer node, Element notationInfo, int index); protected abstract void addNodes(NodeContainer nodeContainer, Element notationInfo); protected abstract void addEdges(Node node, Element notationInfo); protected abstract SemanticElement findDestination(Edge edge, Node source); protected String getRootNotationInfoElement() { return "<root-container/>"; } protected String createInitialNotationInfo() { StringBuffer buffer = new StringBuffer(); buffer.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); buffer.append("\n\n"); buffer.append(getRootNotationInfoElement()); return buffer.toString(); } public String getNotationInfoFileName(String semanticInfoFileName) { return ".gpd." + semanticInfoFileName; } public String getDiagramImageFileName(String semanticInfoFileName) { String result; int index = semanticInfoFileName.indexOf(".xml"); result = index > -1 ? semanticInfoFileName.substring(0, index) : semanticInfoFileName; return result + ".jpg"; } protected void processRootContainer(RootContainer rootContainer, Element notationInfo) { addDimension(rootContainer, notationInfo); addNodes(rootContainer, notationInfo); postProcess(rootContainer); } protected void addNodes(NodeContainer nodeContainer, SemanticElement[] semanticElements, Element notationInfo) { List notationInfoElements = notationInfo == null ? new ArrayList() : notationInfo.elements(); for (int i = 0; i < semanticElements.length; i++) { Element notationInfoElement = null; String nodeName = ((NamedElement) semanticElements[i]).getName(); for (int j = 0; j < notationInfoElements.size(); j++) { Element element = (Element) notationInfoElements.get(j); String elementName = element.attributeValue("name"); if ((elementName != null && elementName.equals(nodeName)) || (elementName == null && nodeName == null)) { notationInfoElement = element; } } // if (notationInfoElements.size() >= i + 1) { // notationInfoElement = (Element)notationInfoElements.get(i); // } addNode(nodeContainer, semanticElements[i], notationInfoElement); } } protected void addEdges(Node node, SemanticElement[] semanticElements, Element notationInfo) { List notationInfoElements = notationInfo == null ? new ArrayList() : notationInfo.elements(); for (int i = 0; i < semanticElements.length; i++) { Element notationInfoElement = null; if (notationInfoElements.size() >= i + 1) { notationInfoElement = (Element) notationInfoElements.get(i); } addEdge(node, semanticElements[i], notationInfoElement); } } protected void addNode(NodeContainer nodeContainer, SemanticElement semanticElement, Element notationInfoElement) { String notationElementId = NotationMapping.getNotationElementId(semanticElement.getElementId()); Node notationElement = (Node) nodeContainer.getFactory().create(notationElementId); notationElement.setSemanticElement(semanticElement); notationElement.register(); nodeContainer.addNode(notationElement); semanticElement.addPropertyChangeListener(notationElement); processNode(notationElement, notationInfoElement); if (notationElement instanceof NodeContainer) { addNodes((NodeContainer) notationElement, notationInfoElement); } } protected void addEdge(Node node, SemanticElement semanticElement, Element notationInfoElement) { NotationElement notationElement = node.getRegisteredNotationElementFor(semanticElement); if (notationElement == null) { String notationElementId = NotationMapping.getNotationElementId(semanticElement.getElementId()); notationElement = (NotationElement) node.getFactory().create(notationElementId); notationElement.setSemanticElement(semanticElement); notationElement.register(); node.addLeavingEdge((Edge) notationElement); semanticElement.addPropertyChangeListener(notationElement); } processEdge((Edge) notationElement, notationInfoElement); } protected void addDimension(RootContainer processDefinitionNotationElement, Element processDiagramInfo) { String width = processDiagramInfo.attributeValue("width"); String height = processDiagramInfo.attributeValue("height"); Dimension dimension = new Dimension(width == null ? 0 : Integer.valueOf(width).intValue(), height == null ? 0 : Integer.valueOf(height).intValue()); processDefinitionNotationElement.setDimension(dimension); } protected void processNode(Node node, Element notationInfoElement) { addConstraint(node, notationInfoElement); addEdges(node, notationInfoElement); } protected void processEdge(Edge edge, Element edgeInfo) { processLabel(edge, edgeInfo); addBendpoints(edge, edgeInfo); } protected void addBendpoints(Edge edge, Element edgeInfo) { if (edgeInfo != null) { List list = edgeInfo.elements("bendpoint"); for (int i = 0; i < list.size(); i++) { addBendpoint(edge, (Element) list.get(i), i); } } } protected BendPoint addBendpoint(Edge edge, Element bendpointInfo, int index) { BendPoint result = new BendPoint(); processBendpoint(result, bendpointInfo); edge.addBendPoint(result); return result; } protected void processBendpoint(BendPoint bendPoint, Element bendpointInfo) { int w1 = Integer.valueOf(bendpointInfo.attributeValue("w1")).intValue(); int h1 = Integer.valueOf(bendpointInfo.attributeValue("h1")).intValue(); int w2 = Integer.valueOf(bendpointInfo.attributeValue("w2")).intValue(); int h2 = Integer.valueOf(bendpointInfo.attributeValue("h2")).intValue(); Dimension d1 = new Dimension(w1, h1); Dimension d2 = new Dimension(w2, h2); bendPoint.setRelativeDimensions(d1, d2); } private void processLabel(Edge edge, Element edgeInfo) { Element label = null; if (edgeInfo != null) { label = edgeInfo.element("label"); } if (label != null) { Point offset = new Point(); offset.x = Integer.valueOf(label.attributeValue("x")).intValue(); offset.y = Integer.valueOf(label.attributeValue("y")).intValue(); edge.getLabel().setOffset(offset); } } private void addConstraint(Node node, Element nodeInfo) { Rectangle constraint = node.getConstraint().getCopy(); Dimension initialDimension = NotationMapping.getInitialDimension(node.getSemanticElement().getElementId()); if (initialDimension != null) { constraint.setSize(initialDimension); } if (nodeInfo != null) { constraint.x = Integer.valueOf(nodeInfo.attributeValue("x")).intValue(); constraint.y = Integer.valueOf(nodeInfo.attributeValue("y")).intValue(); constraint.width = Integer.valueOf(nodeInfo.attributeValue("width")).intValue(); constraint.height = Integer.valueOf(nodeInfo.attributeValue("height")).intValue(); } node.setConstraint(constraint); } protected void postProcess(NodeContainer nodeContainer) { List nodes = nodeContainer.getNodes(); for (int i = 0; i < nodes.size(); i++) { Node node = (Node) nodes.get(i); List edges = node.getLeavingEdges(); for (int j = 0; j < edges.size(); j++) { Edge edge = (Edge) edges.get(j); SemanticElement destination = findDestination(edge, node); Node target = (Node) edge.getFactory().getRegisteredNotationElementFor(destination); if (target != null && edge.getTarget() == null) { target.addArrivingEdge(edge); } } if (node instanceof NodeContainer) { postProcess((NodeContainer) node); } } } public boolean saveToInput(IEditorInput input, RootContainer rootContainer) { boolean result = true; try { IFile file = getNotationInfoFile(((IFileEditorInput) input).getFile()); InputStreamReader reader = new InputStreamReader(file.getContents()); Element notationInfo = new SAXReader().read(reader).getRootElement(); if (upToDateCheck(notationInfo)) { getNotationInfoFile(((IFileEditorInput) input).getFile()).setContents( new ByteArrayInputStream(toNotationInfoXml(rootContainer).getBytes()), true, true, null); } else { result = false; } } catch (Exception e) { e.printStackTrace(); } return result; } protected String toNotationInfoXml(RootContainer rootContainer) { StringWriter writer = new StringWriter(); write(rootContainer, writer); return writer.toString(); } protected void write(RootContainer rootContainer, Writer writer) { try { Document document = DocumentHelper.createDocument(); Element root = document.addElement("root-container"); write(rootContainer, root); XMLWriter xmlWriter = new XMLWriter(writer, OutputFormat.createPrettyPrint()); xmlWriter.write(document); } catch (IOException e) { e.printStackTrace(new PrintWriter(writer)); } } protected void write(RootContainer rootContainer, Element element) { addAttribute(element, "name", ((NamedElement) rootContainer.getSemanticElement()).getName()); addAttribute(element, "width", Integer.toString(rootContainer.getDimension().width)); addAttribute(element, "height", Integer.toString(rootContainer.getDimension().height)); Iterator iter = rootContainer.getNodes().iterator(); while (iter.hasNext()) { write((Node) iter.next(), element); } } protected void write(Node node, Element element) { Element newElement = null; if (node instanceof AbstractNodeContainer) { newElement = addElement(element, "node-container"); } else { newElement = addElement(element, "node"); } addAttribute(newElement, "name", ((NamedElement) node.getSemanticElement()).getName()); addAttribute(newElement, "x", String.valueOf(node.getConstraint().x)); addAttribute(newElement, "y", String.valueOf(node.getConstraint().y)); addAttribute(newElement, "width", String.valueOf(node.getConstraint().width)); addAttribute(newElement, "height", String.valueOf(node.getConstraint().height)); if (node instanceof AbstractNodeContainer) { Iterator nodes = ((AbstractNodeContainer) node).getNodes().iterator(); while (nodes.hasNext()) { write((Node) nodes.next(), newElement); } } Iterator edges = node.getLeavingEdges().iterator(); while (edges.hasNext()) { Edge edge = (Edge) edges.next(); write(edge, addElement(newElement, "edge")); } } protected void write(Edge edge, Element element) { Point offset = edge.getLabel().getOffset(); if (offset != null) { Element label = addElement(element, "label"); addAttribute(label, "x", String.valueOf(offset.x)); addAttribute(label, "y", String.valueOf(offset.y)); } Iterator bendpoints = edge.getBendPoints().iterator(); while (bendpoints.hasNext()) { write((BendPoint) bendpoints.next(), addElement(element, "bendpoint")); } } protected void write(BendPoint bendpoint, Element bendpointElement) { addAttribute(bendpointElement, "w1", String.valueOf(bendpoint.getFirstRelativeDimension().width)); addAttribute(bendpointElement, "h1", String.valueOf(bendpoint.getFirstRelativeDimension().height)); addAttribute(bendpointElement, "w2", String.valueOf(bendpoint.getSecondRelativeDimension().width)); addAttribute(bendpointElement, "h2", String.valueOf(bendpoint.getSecondRelativeDimension().height)); } protected Element addElement(Element element, String elementName) { Element newElement = element.addElement(elementName); return newElement; } protected void addAttribute(Element e, String attributeName, String value) { if (value != null) { e.addAttribute(attributeName, value); } } private void createNotationInfoFile(IFile notationInfoFile) { try { notationInfoFile.create(new ByteArrayInputStream(createInitialNotationInfo().toString().getBytes()), true, null); } catch (CoreException e) { Logger.logError(e); } } protected IFile getNotationInfoFile(IFile semanticInfoFile) { IProject project = semanticInfoFile.getProject(); IPath semanticInfoPath = semanticInfoFile.getProjectRelativePath(); IPath notationInfoPath = semanticInfoPath.removeLastSegments(1) .append(getNotationInfoFileName(semanticInfoFile.getName())); IFile notationInfoFile = project.getFile(notationInfoPath); if (!notationInfoFile.exists()) { createNotationInfoFile(notationInfoFile); } return notationInfoFile; } public void addNotationInfo(RootContainer rootContainer, IEditorInput input) { try { IFile file = getNotationInfoFile(((FileEditorInput) input).getFile()); if (file.exists()) { InputStreamReader reader = new InputStreamReader(file.getContents()); Element notationInfo = new SAXReader().read(reader).getRootElement(); boolean changed = convertCheck(notationInfo); processRootContainer(rootContainer, notationInfo); if (changed) { file.setContents(new ByteArrayInputStream(toNotationInfoXml(rootContainer).getBytes()), true, true, null); } } else { file.create(new ByteArrayInputStream(createInitialNotationInfo().toString().getBytes()), true, null); } } catch (DocumentException e) { e.printStackTrace(); throw new RuntimeException(e); } catch (CoreException e) { e.printStackTrace(); throw new RuntimeException(e); } } private boolean convertCheck(Element notationInfo) { boolean changed = false; if ("process-diagram".equals(notationInfo.getName()) || "pageflow-diagram".equals(notationInfo.getName())) { MessageDialog dialog = new MessageDialog(null, "Convert To 3.1.x Format", null, "A file created with an older GPD version was detected. " + "If you open this file it will be converted to the 3.1.x " + "format and overwritten.\n" + "Do you want to continue?", MessageDialog.QUESTION, new String[] { "Convert And Open", "Continue Without Converting" }, 0); if (dialog.open() == 0) { convertToRootContainer(notationInfo); changed = true; } } return changed; } private boolean upToDateCheck(Element notationInfo) { if ("process-diagram".equals(notationInfo.getName()) || "pageflow-diagram".equals(notationInfo.getName())) { MessageDialog dialog = new MessageDialog(null, "GPD 3.0.x Format Detected", null, "The file you are trying to save contains GPD 3.0.x information." + "Saving the file will result in an automatic conversion into the 3.1.x format." + "It will be impossible to open it with the old GPD.\n" + "Do you want to continue?", MessageDialog.QUESTION, new String[] { "Save And Convert", "Cancel" }, 0); return dialog.open() == 0; } return true; } private void convertToRootContainer(Element notationInfo) { notationInfo.setName("root-container"); convertChildrenToEdge(notationInfo); } private void convertChildrenToEdge(Element element) { List list = element.elements(); for (int i = 0; i < list.size(); i++) { convertToEdge((Element) list.get(i)); } } private void convertToEdge(Element element) { if ("transition".equals(element.getName())) { element.setName("edge"); } convertChildrenToEdge(element); } }