001: package com.opensymphony.workflow.loader;
002:
003: import java.io.*;
004: import java.util.*;
005: import java.net.URL;
006: import java.net.MalformedURLException;
007:
008: import com.opensymphony.workflow.FactoryException;
009: import com.opensymphony.workflow.designer.Layout;
010: import com.opensymphony.workflow.designer.Prefs;
011: import com.opensymphony.workflow.designer.ResourceManager;
012: import com.opensymphony.workflow.designer.WorkflowGraph;
013:
014: /**
015: * @author Hani Suleiman (hani@formicary.net)
016: * Date: May 15, 2003
017: * Time: 7:56:36 PM
018: */
019: public class Workspace extends XMLWorkflowFactory {
020: private Map layouts = new HashMap();
021: private File workflowsXML;
022: private File configFile;
023:
024: public Workspace() {
025: workflows = new HashMap();
026: }
027:
028: public void initDone() throws FactoryException {
029: String name = getProperties().getProperty("resource", null);
030: if (name != null)
031: name = name.replace('\\', '/');
032: if (name != null && name.indexOf('/') == -1) {
033: //it's a relative path to resource, lets convert it
034: try {
035: configFile = new File(new URL(Prefs.INSTANCE.get(
036: Prefs.LAST_WORKSPACE, null)).getFile());
037: } catch (MalformedURLException e) {
038: throw new FactoryException(e);
039: }
040: try {
041: workflowsXML = new File(configFile.getParentFile(),
042: name);
043: getProperties().setProperty("resource",
044: workflowsXML.toURL().toString());
045: } catch (MalformedURLException e) {
046: e.printStackTrace();
047: }
048: }
049: super .initDone();
050: String dir = workflowsXML.getParent();
051: Iterator iter = workflows.values().iterator();
052: while (iter.hasNext()) {
053: WorkflowConfig config = (WorkflowConfig) iter.next();
054: if (config.location.indexOf('/') == -1
055: && config.location.indexOf('\\') == -1) {
056: try {
057: File file = new File(dir, config.location);
058: config.url = file.toURL();
059: if (file.exists())
060: config.lastModified = file.lastModified();
061: } catch (MalformedURLException e) {
062: e.printStackTrace();
063: }
064: }
065: }
066: //now read in all layouts
067: iter = workflows.entrySet().iterator();
068: while (iter.hasNext()) {
069: Map.Entry entry = (Map.Entry) iter.next();
070: String workflowName = entry.getKey().toString();
071: WorkflowConfig config = (WorkflowConfig) entry.getValue();
072: String layoutUrl = getLayoutURL(config, workflowName);
073: layouts.put(workflowName, layoutUrl);
074: }
075: }
076:
077: private String getLayoutURL(
078: XMLWorkflowFactory.WorkflowConfig config,
079: String workflowName) {
080: try {
081: if (config.url == null)
082: config.url = new File(workflowsXML.getParentFile(),
083: workflowName + ".xml").toURL();
084: } catch (MalformedURLException e) {
085: e.printStackTrace();
086: }
087: String layoutUrl = config.url.toString();
088: layoutUrl = layoutUrl.substring(0,
089: layoutUrl.lastIndexOf('/') + 1);
090: layoutUrl = layoutUrl + workflowName + ".lyt";
091: return layoutUrl;
092: }
093:
094: public String getName() {
095: return configFile != null ? configFile.getName().substring(0,
096: configFile.getName().lastIndexOf('.')) : "<new>";
097: }
098:
099: public boolean isNew() {
100: return workflowsXML == null;
101: }
102:
103: public void importDescriptor(String name, InputStream is) {
104: WorkflowConfig config = new WorkflowConfig(null, "file", name
105: + ".xml");
106: try {
107: File file = new File(workflowsXML.getParentFile(), name
108: + ".xml");
109: config.url = file.toURL();
110: config.lastModified = file.lastModified();
111: workflows.put(name, config);
112: } catch (MalformedURLException e) {
113: //can't really happen
114: e.printStackTrace();
115: }
116: }
117:
118: public Object getLayout(String workflowName) {
119: Object obj = layouts.get(workflowName);
120: if (obj == null)
121: return null;
122: if (obj instanceof Layout)
123: return (Layout) obj;
124: String url = obj.toString();
125: try {
126: InputStream is = new URL(url).openStream();
127: if (is != null) {
128: Layout layout = new Layout(is);
129: layout.setUrl(url);
130: layouts.put(workflowName, layout);
131: return layout;
132: }
133: } catch (FileNotFoundException ex) {
134: //that's ok, no saved layout
135: } catch (java.io.IOException e) {
136: e.printStackTrace();
137: }
138: return null;
139: }
140:
141: public void save() {
142: if (workflowsXML == null) {
143: return;
144: }
145: try {
146: if (!configFile.exists()) {
147: //this is a brand new workspace, so lets create the main config file
148: PrintWriter out = new PrintWriter(new BufferedWriter(
149: new FileWriter(configFile)));
150: out.println("<osworkflow>");
151: out
152: .println(" <persistence class=\"com.opensymphony.workflow.spi.memory.MemoryWorkflowStore\"/>");
153: out
154: .println(" <factory class=\"com.opensymphony.workflow.loader.Workspace\">");
155: out
156: .println(" <property key=\"resource\" value=\"workflows.xml\" />");
157: out.println(" </factory>");
158: out.println("</osworkflow>");
159: out.flush();
160: out.close();
161: }
162: PrintWriter out = new PrintWriter(new BufferedWriter(
163: new FileWriter(workflowsXML)));
164: out.println("<workflows>");
165: Iterator iter = workflows.entrySet().iterator();
166: while (iter.hasNext()) {
167: Map.Entry entry = (Map.Entry) iter.next();
168: WorkflowConfig config = (WorkflowConfig) entry
169: .getValue();
170: if (config.location == null)
171: config.location = entry.getKey() + ".xml";
172: out.println(" <workflow name=\"" + entry.getKey()
173: + "\" type=\"file\" location=\""
174: + config.location + "\" />");
175: }
176: out.println("</workflows>");
177: out.flush();
178: out.close();
179: } catch (IOException e) {
180: e.printStackTrace();
181: }
182: }
183:
184: public boolean removeWorkflow(String name) throws FactoryException {
185: WorkflowConfig removed = (WorkflowConfig) workflows
186: .remove(name);
187: if (removed == null)
188: return false;
189: save();
190: if (removed.url != null
191: && removed.url.getProtocol().equals("file")) {
192: return new File(removed.url.getFile()).delete();
193: }
194: return true;
195: }
196:
197: public WorkflowDescriptor getWorkflow(String name, boolean validate)
198: throws FactoryException {
199: WorkflowConfig config = (WorkflowConfig) workflows.get(name);
200: if (config == null)
201: return null;
202: if (config.url == null) {
203: return config.descriptor;
204: }
205: try {
206: return super .getWorkflow(name, validate);
207: } catch (FactoryException e) {
208: //something went wrong, so lets delete the workflow from our list
209: workflows.remove(name);
210: throw e;
211: }
212: }
213:
214: public boolean saveWorkflow(String name,
215: WorkflowDescriptor descriptor, WorkflowGraph graph,
216: boolean replace) throws FactoryException {
217: Object obj = layouts.get(name);
218: if (obj instanceof Layout) {
219: Layout layout = (Layout) obj;
220: try {
221: WorkflowConfig config = (WorkflowConfig) workflows
222: .get(name);
223: URL url = new URL(getLayoutURL(config, name));
224: File file = new File(url.getFile());
225: PrintWriter out = new PrintWriter(new BufferedWriter(
226: new FileWriter(file)));
227: layout.writeXML(out, 0, graph);
228: out.flush();
229: out.close();
230: if (config.location == null) {
231: config.location = name + ".xml";
232: config.url = new File(workflowsXML.getParentFile(),
233: config.location).toURL();
234: }
235: } catch (IOException e) {
236: e.printStackTrace();
237: return false;
238: }
239: }
240: if (descriptor != null) {
241: WorkflowConfig config = (WorkflowConfig) workflows
242: .get(name);
243: if (config.url != null) {
244: descriptor.getMetaAttributes().put("generator",
245: "OSWOrkflow Designer");
246: descriptor.getMetaAttributes().put("lastModified",
247: (new Date()).toString());
248: return super .saveWorkflow(name, descriptor, replace);
249: } else {
250: System.out
251: .println("WARN: *** saveWorkflow called with config.location="
252: + config.location + " url is null");
253: }
254: }
255: return false;
256: }
257:
258: public void setLayout(String workflowName, Object layout) {
259: layouts.put(workflowName, layout);
260: }
261:
262: public File getLocation() {
263: return workflowsXML;
264: }
265:
266: public void setLocation(File file) {
267: this .workflowsXML = new File(file.getParentFile(),
268: "workflows.xml");
269: this .configFile = file;
270: }
271:
272: public void createWorkflow(String name) {
273: WorkflowConfig config = new WorkflowConfig(null, "file", null);
274: config.descriptor = DescriptorFactory.getFactory()
275: .createWorkflowDescriptor();
276: config.descriptor.setName(name);
277: ActionDescriptor initialAction = DescriptorFactory.getFactory()
278: .createActionDescriptor();
279: initialAction.setName(ResourceManager
280: .getString("action.initial.start"));
281: config.descriptor.getInitialActions().add(initialAction);
282: config.descriptor.getMetaAttributes().put("created",
283: (new Date()).toString());
284: workflows.put(name, config);
285: }
286:
287: public void renameWorkflow(String oldName, String newName) {
288: //todo need to keep track of deleted workflows and delete their files on save
289: WorkflowConfig config = (WorkflowConfig) workflows.get(oldName);
290: config.location = newName + ".xml";
291: try {
292: config.url = new File(workflowsXML.getParentFile(),
293: config.location).toURL();
294: } catch (MalformedURLException e) {
295: //this can't ever happen
296: e.printStackTrace();
297: }
298: workflows.remove(oldName);
299: workflows.put(newName, config);
300: }
301: }
|