1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.module.workflow.flows;
35
36 import info.magnolia.cms.beans.config.ContentRepository;
37 import info.magnolia.cms.core.Content;
38 import info.magnolia.cms.core.ItemType;
39 import info.magnolia.cms.core.HierarchyManager;
40 import info.magnolia.cms.util.ContentUtil;
41 import info.magnolia.cms.util.NodeDataUtil;
42 import info.magnolia.context.MgnlContext;
43 import info.magnolia.context.WebContextImpl;
44 import info.magnolia.module.workflow.WorkflowConstants;
45
46 import java.io.IOException;
47 import java.io.InputStream;
48 import java.io.StringReader;
49 import java.net.MalformedURLException;
50 import java.net.URL;
51 import java.net.URLConnection;
52 import java.text.MessageFormat;
53 import java.util.ArrayList;
54 import java.util.Collection;
55 import java.util.Collections;
56 import java.util.Iterator;
57 import java.util.List;
58
59 import javax.jcr.RepositoryException;
60 import javax.servlet.http.HttpServletRequest;
61
62 import openwfe.org.engine.workitem.LaunchItem;
63
64 import org.apache.commons.lang.StringUtils;
65 import org.jdom.Document;
66 import org.jdom.Element;
67 import org.slf4j.Logger;
68 import org.slf4j.LoggerFactory;
69
70
71
72
73
74 public class DefaultFlowDefinitionManager implements FlowDefinitionManager {
75
76 private static Logger log = LoggerFactory.getLogger(DefaultFlowDefinitionManager.class);
77
78 private boolean saveWorkflowDefinitionInWorkItem = true;
79
80 private String flowDefinitionURLPattern;
81
82 public void configure(LaunchItem launchItem, String workflowName) throws FlowDefinitionException {
83 if(saveWorkflowDefinitionInWorkItem){
84 launchItem.setWorkflowDefinitionUrl(WorkflowConstants.ATTRIBUTE_WORKFLOW_DEFINITION_URL);
85 String flowDef = readDefinition(workflowName);
86 launchItem.getAttributes().puts(WorkflowConstants.ATTRIBUTE_DEFINITION, flowDef);
87 }
88 else{
89 InputStream is = null;
90 String surl = getFlowDefinitionURLPattern();
91 surl = MessageFormat.format(surl, new String[]{workflowName});
92 try {
93 URL url = new URL(surl);
94 URLConnection connection = url.openConnection();
95 connection.connect();
96 is = connection.getInputStream();
97 launchItem.setWorkflowDefinitionUrl(surl);
98 }
99 catch (MalformedURLException e) {
100 throw new FlowDefinitionException("can't use workflow name [" + workflowName + "] because the url[" + surl + "] is not an url", e);
101 }
102 catch (IOException e) {
103 throw new FlowDefinitionException("can't use workflow name [" + workflowName + "] because the url[" + surl + "] is not accessible", e);
104 }
105 finally {
106 try {if(is!=null) is.close();} catch(Exception e) {
107 }
108
109 }
110 }
111
112 public String readDefinition(String workflowName) throws FlowDefinitionException {
113 Content node;
114 try {
115 node = getDefinitionNode(workflowName);
116 }
117 catch (RepositoryException e) {
118 throw new FlowDefinitionException("can't read workflow definition [" + workflowName + "]", e);
119 }
120 if (node == null){
121 throw new FlowDefinitionException("can't read workflow definition [" + workflowName + "]") ;
122 }
123 return node.getNodeData("value").getString();
124 }
125
126
127
128
129
130 public Content getDefinitionNode(String name) throws RepositoryException {
131 if (name == null) {
132 return null;
133 }
134 return ContentUtil.getContent(ContentRepository.CONFIG, WorkflowConstants.ROOT_PATH_FOR_FLOW + "/"+ name);
135 }
136
137 public void saveDefinition(String definition) throws FlowDefinitionException {
138 saveDefinition(extractWorkflowName(definition), definition);
139 }
140
141 protected void saveDefinition(String workflowName, String definition) throws FlowDefinitionException {
142 if (definition == null) {
143 return;
144 }
145
146 try {
147 HierarchyManager hm = MgnlContext.getSystemContext().getHierarchyManager(ContentRepository.CONFIG);
148 Content root = hm.getContent(WorkflowConstants.ROOT_PATH_FOR_FLOW);
149
150
151
152
153 final Content wfNode = ContentUtil.getOrCreateContent(root, workflowName, ItemType.CONTENTNODE);
154 NodeDataUtil.getOrCreateAndSet(wfNode, WorkflowConstants.FLOW_VALUE, definition);
155
156 root.save();
157 log.info("New flow added: " + workflowName);
158 }
159 catch (Exception e) {
160 throw new FlowDefinitionException("can't add flow", e);
161 }
162 }
163
164 protected String extractWorkflowName(String definition) throws FlowDefinitionException {
165 try {
166
167 final org.jdom.input.SAXBuilder builder = new org.jdom.input.SAXBuilder();
168 Document doc = builder.build(new StringReader(definition));
169 Element process_definition = doc.getRootElement();
170 return process_definition.getAttribute("name").getValue();
171 }
172 catch(Exception e){
173 throw new FlowDefinitionException("can't extract name out of the definition", e);
174 }
175 }
176
177 public List getDefinitionNames(){
178 ArrayList list = new ArrayList();
179
180 HierarchyManager hm = MgnlContext.getSystemContext().getHierarchyManager(ContentRepository.CONFIG);
181 Content root;
182 try {
183 root = hm.getContent(WorkflowConstants.ROOT_PATH_FOR_FLOW);
184 }
185 catch (RepositoryException e) {
186 log.error("can't read flow definitions", e);
187 return Collections.EMPTY_LIST;
188 }
189
190 Collection c = ContentUtil.getAllChildren(root);
191
192 Iterator it = c.iterator();
193 while (it.hasNext()) {
194 String name = ((Content) (it.next())).getName();
195 if (name != null) {
196 list.add(name);
197 }
198 }
199
200 return list;
201 }
202
203 public String getFlowDefinitionURLPattern() {
204 if (StringUtils.isEmpty(flowDefinitionURLPattern) || flowDefinitionURLPattern.equals("auto")) {
205 WebContextImpl impl = (WebContextImpl) MgnlContext.getInstance();
206 HttpServletRequest request = impl.getRequest();
207
208 StringBuffer baseurl = new StringBuffer();
209 baseurl.append("http");
210 if(request.isSecure()){
211 baseurl.append("s");
212 }
213 baseurl.append("://");
214 baseurl.append(request.getServerName());
215 baseurl.append(":");
216 baseurl.append(request.getServerPort());
217 baseurl.append(impl.getContextPath());
218 baseurl.append("/.magnolia/pages/flows.html");
219 baseurl.append("?command=showFlow&flowName=");
220 baseurl.append("{0}");
221 flowDefinitionURLPattern = baseurl.toString();
222 }
223
224 return this.flowDefinitionURLPattern;
225 }
226
227
228 public void setFlowDefinitionURLPattern(String flowDefinitionURLPattern) {
229 this.flowDefinitionURLPattern = flowDefinitionURLPattern;
230 }
231
232 }