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.URL;
012: import java.net.URLConnection;
013: import java.net.URLEncoder;
014:
015: import java.util.HashMap;
016: import java.util.Iterator;
017: import java.util.Map;
018:
019: /**
020: * @author Hani Suleiman
021: * Date: Dec 17, 2004
022: * Time: 12:00:36 AM
023: */
024: public class HTTPWorkflowFactory extends AbstractWorkflowFactory {
025: //~ Instance fields ////////////////////////////////////////////////////////
026:
027: protected Map workflows;
028: protected boolean reload;
029:
030: //~ Methods ////////////////////////////////////////////////////////////////
031:
032: public void setLayout(String workflowName, Object layout) {
033: }
034:
035: public Object getLayout(String workflowName) {
036: return null;
037: }
038:
039: public boolean isModifiable(String name) {
040: return true;
041: }
042:
043: public String getName() {
044: return null;
045: }
046:
047: public WorkflowDescriptor getWorkflow(String name, boolean validate)
048: throws FactoryException {
049: HTTPWorkflowConfig c = (HTTPWorkflowConfig) workflows.get(name);
050:
051: if (c == null) {
052: throw new FactoryException("Unknown workflow name \""
053: + name + '\"');
054: }
055:
056: if (c.descriptor != null) {
057: loadWorkflow(c);
058: }
059:
060: c.descriptor.setName(name);
061:
062: return c.descriptor;
063: }
064:
065: public String[] getWorkflowNames() throws FactoryException {
066: int i = 0;
067: String[] res = new String[workflows.keySet().size()];
068: Iterator it = workflows.keySet().iterator();
069:
070: while (it.hasNext()) {
071: res[i++] = (String) it.next();
072: }
073:
074: return res;
075: }
076:
077: public void createWorkflow(String name) {
078: }
079:
080: public void initDone() throws FactoryException {
081: }
082:
083: public boolean removeWorkflow(String name) throws FactoryException {
084: throw new FactoryException("remove workflow not supported");
085: }
086:
087: /* (non-Javadoc)
088: * @see com.opensymphony.workflow.loader.AbstractWorkflowFactory#renameWorkflow(java.lang.String, java.lang.String)
089: */
090: public void renameWorkflow(String oldName, String newName) {
091: }
092:
093: /* (non-Javadoc)
094: * @see com.opensymphony.workflow.loader.AbstractWorkflowFactory#save()
095: */
096: public void save() {
097: }
098:
099: /* (non-Javadoc)
100: * @see com.opensymphony.workflow.loader.AbstractWorkflowFactory#saveWorkflow(java.lang.String, com.opensymphony.workflow.loader.WorkflowDescriptor, boolean)
101: */
102: public boolean saveWorkflow(String name,
103: WorkflowDescriptor descriptor, boolean replace)
104: throws FactoryException {
105: HTTPWorkflowConfig c = (HTTPWorkflowConfig) workflows.get(name);
106:
107: if ((c != null) && !replace) {
108: return false;
109: }
110:
111: if (c == null) {
112: throw new UnsupportedOperationException(
113: "Saving of new workflow is not currently supported");
114: }
115:
116: Writer out;
117:
118: // [KAP] comment this line to disable all the validation while saving a workflow
119: //descriptor.validate();
120: try {
121: out = new OutputStreamWriter(null, "utf-8");
122: } catch (UnsupportedEncodingException ex) {
123: throw new FactoryException(
124: "utf-8 encoding not supported, contact your JVM vendor!");
125: }
126:
127: writeXML(descriptor, out);
128:
129: //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
130: //now lets rename
131: return true;
132: }
133:
134: protected static String get(String urlValue, Map data)
135: throws IOException {
136: BufferedReader input;
137:
138: StringBuffer value = new StringBuffer(urlValue);
139:
140: if (data.size() > 0) {
141: if (value.indexOf("?") == -1) {
142: value.append("?");
143: } else {
144: value.append("&");
145: }
146: }
147:
148: Iterator i = data.entrySet().iterator();
149:
150: while (i.hasNext()) {
151: Map.Entry entry = (Map.Entry) i.next();
152: value.append(entry.getKey()).append('=');
153: value.append(URLEncoder.encode((String) entry.getValue(),
154: "utf-8"));
155:
156: if (i.hasNext()) {
157: value.append("&");
158: }
159: }
160:
161: URL url = new URL(urlValue);
162: URLConnection connection = url.openConnection();
163: connection.setDoOutput(true);
164: connection.setUseCaches(false);
165:
166: input = new BufferedReader(new InputStreamReader(connection
167: .getInputStream()));
168:
169: StringBuffer output = new StringBuffer();
170: String line;
171:
172: while (null != (line = input.readLine())) {
173: output.append(line).append('\n');
174: }
175:
176: input.close();
177:
178: return output.toString();
179: }
180:
181: protected static String post(String urlValue, Map data)
182: throws IOException {
183: BufferedReader input;
184:
185: URL url = new URL(urlValue);
186: URLConnection connection = url.openConnection();
187: connection.setDoInput(true);
188: connection.setDoOutput(true);
189: connection.setUseCaches(false);
190: connection.setRequestProperty("Content-Type",
191: "application/x-www-form-urlencoded");
192:
193: DataOutputStream out = new DataOutputStream(connection
194: .getOutputStream());
195:
196: StringBuffer content = new StringBuffer();
197: Iterator i = data.entrySet().iterator();
198:
199: while (i.hasNext()) {
200: Map.Entry entry = (Map.Entry) i.next();
201: content.append(entry.getKey()).append('=');
202: content.append(URLEncoder.encode((String) entry.getValue(),
203: "utf-8"));
204:
205: if (i.hasNext()) {
206: content.append("&");
207: }
208: }
209:
210: out.writeBytes(content.toString());
211: out.flush();
212: out.close();
213:
214: input = new BufferedReader(new InputStreamReader(connection
215: .getInputStream()));
216:
217: StringBuffer output = new StringBuffer();
218: String line;
219:
220: while (null != (line = input.readLine())) {
221: output.append(line).append('\n');
222: }
223:
224: input.close();
225:
226: return output.toString();
227: }
228:
229: protected String readLayoutBuffer(final String url,
230: final String docId) throws Exception {
231: Map map = new HashMap();
232: map.put("docId", docId);
233: map.put("command", "layout");
234:
235: return get(url, map);
236: }
237:
238: protected String readWorkflowBuffer(final String url,
239: final String docId) throws Exception {
240: Map map = new HashMap();
241: map.put("docId", docId);
242: map.put("command", "workflow");
243:
244: return get(url, map);
245: }
246:
247: protected String writeWorkflowDescriptor(final String url,
248: final String docId, final String name,
249: final String workflowXML) throws Exception {
250: String ret = null;
251:
252: Map map = new HashMap();
253: map.put("docId", docId);
254: map.put("data", workflowXML);
255: map.put("command", "workflow");
256:
257: return post(url, map);
258: }
259:
260: protected String writeWorkflowLayout(final String url,
261: final String docId, final String name,
262: final String layoutXML) throws Exception {
263: Map map = new HashMap();
264: map.put("docId", docId);
265: map.put("data", layoutXML);
266: map.put("command", "layout");
267:
268: return post(url, map);
269: }
270:
271: protected void writeXML(WorkflowDescriptor descriptor, Writer out) {
272: PrintWriter writer = new PrintWriter(new BufferedWriter(out));
273: writer.println(WorkflowDescriptor.XML_HEADER);
274: writer.println(WorkflowDescriptor.DOCTYPE_DECL);
275: descriptor.writeXML(writer, 0);
276: writer.flush();
277: writer.close();
278: }
279:
280: private void loadWorkflow(HTTPWorkflowConfig c)
281: throws FactoryException {
282: /*
283: try
284: {
285: c.descriptor = WorkflowLoader.load(c.url);
286: }
287: catch (Exception e)
288: {
289: throw new FactoryException("Error in workflow descriptor: " + c.url, e);
290: }
291: */
292: }
293:
294: //~ Inner Classes //////////////////////////////////////////////////////////
295:
296: static class HTTPWorkflowConfig {
297: String docId;
298: String name;
299: String service_addr;
300: WorkflowDescriptor descriptor;
301:
302: //long lastModified;
303: public HTTPWorkflowConfig(String service_addr, String name,
304: String docId) {
305: this.service_addr = service_addr;
306: this.name = name;
307: this.docId = docId;
308: }
309: }
310: }
|