001: /*
002: * Copyright (c) 2002-2003 by OpenSymphony
003: * All rights reserved.
004: */
005: package com.opensymphony.workflow.loader;
006:
007: import com.opensymphony.workflow.FactoryException;
008:
009: import java.io.*;
010:
011: import java.net.MalformedURLException;
012: import java.net.URL;
013:
014: import java.util.HashMap;
015: import java.util.Map;
016:
017: /**
018: * @author Hani Suleiman
019: * Date: May 10, 2002
020: * Time: 11:59:47 AM
021: */
022: public class URLWorkflowFactory extends AbstractWorkflowFactory
023: implements Serializable {
024: //~ Instance fields ////////////////////////////////////////////////////////
025:
026: private transient Map cache = new HashMap();
027:
028: //~ Methods ////////////////////////////////////////////////////////////////
029:
030: public void setLayout(String workflowName, Object layout) {
031: }
032:
033: public Object getLayout(String workflowName) {
034: return null;
035: }
036:
037: public boolean isModifiable(String name) {
038: return false;
039: }
040:
041: public String getName() {
042: return "";
043: }
044:
045: public WorkflowDescriptor getWorkflow(String name, boolean validate)
046: throws FactoryException {
047: boolean useCache = getProperties()
048: .getProperty("cache", "false").equals("true");
049:
050: if (useCache) {
051: WorkflowDescriptor descriptor = (WorkflowDescriptor) cache
052: .get(name);
053:
054: if (descriptor != null) {
055: return descriptor;
056: }
057: }
058:
059: try {
060: URL url = new URL(name);
061: WorkflowDescriptor descriptor = WorkflowLoader.load(url,
062: validate);
063:
064: if (useCache) {
065: cache.put(name, descriptor);
066: }
067:
068: return descriptor;
069: } catch (Exception e) {
070: throw new FactoryException("Unable to find workflow "
071: + name, e);
072: }
073: }
074:
075: public String[] getWorkflowNames() throws FactoryException {
076: throw new FactoryException(
077: "URLWorkflowFactory does not contain a list of workflow names");
078: }
079:
080: public void createWorkflow(String name) {
081: }
082:
083: public boolean removeWorkflow(String name) throws FactoryException {
084: throw new FactoryException("remove workflow not supported");
085: }
086:
087: public void renameWorkflow(String oldName, String newName) {
088: }
089:
090: public void save() {
091: }
092:
093: public boolean saveWorkflow(String name,
094: WorkflowDescriptor descriptor, boolean replace)
095: throws FactoryException {
096: WorkflowDescriptor c = (WorkflowDescriptor) cache.get(name);
097: URL url;
098:
099: try {
100: url = new URL(name);
101: } catch (MalformedURLException ex) {
102: throw new FactoryException("workflow '" + name
103: + "' is an invalid url:" + ex);
104: }
105:
106: boolean useCache = getProperties()
107: .getProperty("cache", "false").equals("true");
108:
109: if (useCache && (c != null) && !replace) {
110: return false;
111: }
112:
113: if (new File(url.getFile()).exists() && !replace) {
114: return false;
115: }
116:
117: Writer out;
118:
119: try {
120: out = new OutputStreamWriter(new FileOutputStream(url
121: .getFile()
122: + ".new"), "utf-8");
123: } catch (FileNotFoundException ex) {
124: throw new FactoryException(
125: "Could not create new file to save workflow "
126: + url.getFile());
127: } catch (UnsupportedEncodingException ex) {
128: throw new FactoryException(
129: "utf-8 encoding not supported, contact your JVM vendor!");
130: }
131:
132: //write it out to a new file, to ensure we don't end up with a messed up file if we're interrupted halfway for some reason
133: PrintWriter writer = new PrintWriter(new BufferedWriter(out));
134: writer.println(WorkflowDescriptor.XML_HEADER);
135: writer.println(WorkflowDescriptor.DOCTYPE_DECL);
136: descriptor.writeXML(writer, 0);
137: writer.flush();
138: writer.close();
139:
140: //now lets rename
141: File original = new File(url.getFile());
142: File backup = new File(url.getFile() + ".bak");
143: File updated = new File(url.getFile() + ".new");
144: boolean isOK = original.renameTo(backup);
145:
146: if (!isOK) {
147: throw new FactoryException(
148: "Unable to backup original workflow file "
149: + original + " to " + backup
150: + ", aborting save");
151: }
152:
153: isOK = updated.renameTo(original);
154:
155: if (!isOK) {
156: throw new FactoryException(
157: "Unable to rename new workflow file " + updated
158: + " to " + original + ", aborting save");
159: }
160:
161: backup.delete();
162:
163: if (useCache) {
164: cache.put(name, descriptor);
165: }
166:
167: return true;
168: }
169: }
|