001: /*
002: * The contents of this file are subject to the
003: * Mozilla Public License Version 1.1 (the "License");
004: * you may not use this file except in compliance with the License.
005: * You may obtain a copy of the License at http://www.mozilla.org/MPL/
006: *
007: * Software distributed under the License is distributed on an "AS IS"
008: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
009: * See the License for the specific language governing rights and
010: * limitations under the License.
011: *
012: * The Initial Developer of the Original Code is Simulacra Media Ltd.
013: * Portions created by Simulacra Media Ltd are Copyright (C) Simulacra Media Ltd, 2004.
014: *
015: * All Rights Reserved.
016: *
017: * Contributor(s):
018: */
019: package org.openharmonise.workfloweditor;
020:
021: import java.awt.geom.*;
022: import java.awt.geom.Point2D.Float;
023: import java.io.*;
024: import java.util.*;
025:
026: import javax.xml.parsers.*;
027:
028: import org.jaxen.dom.*;
029: import org.openharmonise.commons.xml.*;
030: import org.openharmonise.vfs.context.*;
031: import org.w3c.dom.*;
032:
033: /**
034: * Manages the local storage of workflow diagram layouts.
035: *
036: * @author Matthew Large
037: * @version $Revision: 1.1 $
038: *
039: */
040: public class WorkflowLayoutStore implements ContextListener {
041:
042: /**
043: * Instance, following the singleton pattern.
044: */
045: private static WorkflowLayoutStore m_instance = null;
046:
047: /**
048: * Map of workflow path to map of workflow stage instance to 2D point.
049: */
050: private HashMap m_workflows = new HashMap();
051:
052: /**
053: *
054: */
055: private WorkflowLayoutStore() {
056: super ();
057: ContextHandler.getInstance().addListener(
058: ContextType.CONTEXT_SHUTDOWN, this );
059: this .load();
060: }
061:
062: /**
063: * Returns the workflow layout store instance following the singleton
064: * pattern.
065: *
066: * @return Current instance
067: */
068: public static WorkflowLayoutStore getInstance() {
069: if (m_instance == null) {
070: m_instance = new WorkflowLayoutStore();
071: }
072: return m_instance;
073: }
074:
075: /**
076: * Sets the layout position of a specific workflow stage instance as
077: * part of a specific workflow.
078: *
079: * @param sWorkflowPath Full path to workflow
080: * @param sStagePath Full path to workflow stage instance
081: * @param point 2D point
082: */
083: public void setStageLayout(String sWorkflowPath, String sStagePath,
084: Point2D.Float point) {
085: HashMap stageMap = (HashMap) this .m_workflows
086: .get(sWorkflowPath);
087: if (stageMap == null) {
088: stageMap = new HashMap();
089: this .m_workflows.put(sWorkflowPath, stageMap);
090: }
091: stageMap.put(sStagePath, point);
092: }
093:
094: private void moveGraphsToTopLeft() {
095: Iterator itor = this .m_workflows.values().iterator();
096: while (itor.hasNext()) {
097: float minX = (float) 10000000000.0;
098: float minY = (float) 10000000000.0;
099:
100: HashMap stageMap = (HashMap) itor.next();
101: Iterator itor2 = stageMap.keySet().iterator();
102: while (itor2.hasNext()) {
103: String sStagePath = (String) itor2.next();
104: Point2D.Float point = (Float) stageMap.get(sStagePath);
105: if (point.x < minX) {
106: minX = point.x;
107: }
108: if (point.y < minY) {
109: minY = point.y;
110: }
111: }
112:
113: float diffX = 0;
114: float diffY = 0;
115:
116: if (minX > 20) {
117: diffX = minX - 20;
118: }
119: if (minY > 20) {
120: diffY = minY - 20;
121: }
122:
123: if (diffX > 0 || diffY > 0) {
124: itor2 = stageMap.keySet().iterator();
125: while (itor2.hasNext()) {
126: String sStagePath = (String) itor2.next();
127: Point2D.Float point = (Float) stageMap
128: .get(sStagePath);
129: point.x = point.x - diffX;
130: point.y = point.y - diffY;
131: }
132: }
133: }
134: }
135:
136: /**
137: * Returns the layout position for a given workflow stage instance as
138: * part of a specific workflow.
139: *
140: * @param sWorkflowPath Full path to workflow
141: * @param sStagePath Full path to workflow stage instance
142: * @return 2D point
143: */
144: public Point2D.Float getStageLayout(String sWorkflowPath,
145: String sStagePath) {
146: Point2D.Float point = null;
147:
148: HashMap stageMap = (HashMap) this .m_workflows
149: .get(sWorkflowPath);
150: if (stageMap != null) {
151: point = (Float) stageMap.get(sStagePath);
152: }
153:
154: return point;
155: }
156:
157: /**
158: * Loads the workflow layout information from a local XML file.
159: *
160: */
161: private void load() {
162: File fXML = new File("C:\\ContentManager\\layouts.xml");
163: if (fXML.exists()) {
164: try {
165: Document xml = DocumentBuilderFactory.newInstance()
166: .newDocumentBuilder().parse(
167: new org.xml.sax.InputSource(
168: new FileReader(fXML)));
169:
170: DOMXPath xpWorkflows = new DOMXPath("child::workflow");
171: List workflows = xpWorkflows.selectNodes(xml
172: .getDocumentElement());
173: Iterator itor = workflows.iterator();
174: while (itor.hasNext()) {
175: Element elWorkflow = (Element) itor.next();
176: DOMXPath xpStages = new DOMXPath(
177: "child::workflowstage");
178: DOMXPath xpPath = new DOMXPath("child::path/.");
179: String sWorkflowPath = xpPath
180: .stringValueOf(elWorkflow);
181: List stages = xpStages.selectNodes(elWorkflow);
182: Iterator itor2 = stages.iterator();
183: while (itor2.hasNext()) {
184: Element elStage = (Element) itor2.next();
185: float x = java.lang.Float.parseFloat(elStage
186: .getAttribute("x"));
187: float y = java.lang.Float.parseFloat(elStage
188: .getAttribute("y"));
189: String sStagePath = xpPath
190: .stringValueOf(elStage);
191: Point2D.Float point = new Point2D.Float(x, y);
192: this .setStageLayout(sWorkflowPath, sStagePath,
193: point);
194: }
195: }
196:
197: this .moveGraphsToTopLeft();
198:
199: } catch (Exception e) {
200: e.printStackTrace();
201: }
202: }
203: }
204:
205: /**
206: * Saves the workflow layout information to a local XML file.
207: *
208: */
209: private void save() {
210: try {
211: Document xml = DocumentBuilderFactory.newInstance()
212: .newDocumentBuilder().newDocument();
213:
214: Element elRoot = xml.createElement("layouts");
215:
216: Iterator itor = this .m_workflows.keySet().iterator();
217: while (itor.hasNext()) {
218: String sWorkflowPath = (String) itor.next();
219:
220: Element elWorkflow = xml.createElement("workflow");
221: elRoot.appendChild(elWorkflow);
222:
223: Element elPath = xml.createElement("path");
224: Text txt = xml.createTextNode(sWorkflowPath);
225: elPath.appendChild(txt);
226: elWorkflow.appendChild(elPath);
227: elRoot.appendChild(elWorkflow);
228:
229: HashMap stageMap = (HashMap) this .m_workflows
230: .get(sWorkflowPath);
231: Iterator itor2 = stageMap.keySet().iterator();
232: while (itor2.hasNext()) {
233: String sStagePath = (String) itor2.next();
234: Point2D.Float point = (Float) stageMap
235: .get(sStagePath);
236: float x = point.x;
237: float y = point.y;
238:
239: Element elStage = xml
240: .createElement("workflowstage");
241: elWorkflow.appendChild(elStage);
242: elStage.setAttribute("x", new java.lang.Float(x)
243: .toString());
244: elStage.setAttribute("y", new java.lang.Float(y)
245: .toString());
246:
247: elPath = xml.createElement("path");
248: txt = xml.createTextNode(sStagePath);
249: elPath.appendChild(txt);
250: elStage.appendChild(elPath);
251:
252: }
253: }
254:
255: File fXML = new File("C:\\ContentManager\\layouts.xml");
256: XMLPrettyPrint printer = new XMLPrettyPrint();
257: printer.printNodeToFile(elRoot, fXML);
258:
259: } catch (ParserConfigurationException e) {
260: e.printStackTrace();
261: } catch (FactoryConfigurationError e) {
262: e.printStackTrace();
263: }
264: }
265:
266: /* (non-Javadoc)
267: * @see com.simulacramedia.contentmanager.context.ContextListener#contextMessage(com.simulacramedia.contentmanager.context.ContextEvent)
268: */
269: public void contextMessage(ContextEvent ce) {
270: if (ce.CONTEXT_TYPE == ContextType.CONTEXT_SHUTDOWN) {
271: this.save();
272: }
273: }
274:
275: }
|