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.core.Content;
37 import info.magnolia.cms.core.ItemType;
38 import info.magnolia.cms.core.HierarchyManager;
39 import info.magnolia.cms.util.ContentUtil;
40 import info.magnolia.cms.util.NodeDataUtil;
41 import info.magnolia.context.MgnlContext;
42 import info.magnolia.context.WebContextImpl;
43 import info.magnolia.module.workflow.WorkflowConstants;
44 import info.magnolia.repository.RepositoryConstants;
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 @Override
83 public void configure(LaunchItem launchItem, String workflowName) throws FlowDefinitionException {
84 if(saveWorkflowDefinitionInWorkItem){
85 launchItem.setWorkflowDefinitionUrl(WorkflowConstants.ATTRIBUTE_WORKFLOW_DEFINITION_URL);
86 String flowDef = readDefinition(workflowName);
87 launchItem.getAttributes().puts(WorkflowConstants.ATTRIBUTE_DEFINITION, flowDef);
88 }
89 else{
90 InputStream is = null;
91 String surl = getFlowDefinitionURLPattern();
92 surl = MessageFormat.format(surl, new String[]{workflowName});
93 try {
94 URL url = new URL(surl);
95 URLConnection connection = url.openConnection();
96 connection.connect();
97 is = connection.getInputStream();
98 launchItem.setWorkflowDefinitionUrl(surl);
99 }
100 catch (MalformedURLException e) {
101 throw new FlowDefinitionException("can't use workflow name [" + workflowName + "] because the url[" + surl + "] is not an url", e);
102 }
103 catch (IOException e) {
104 throw new FlowDefinitionException("can't use workflow name [" + workflowName + "] because the url[" + surl + "] is not accessible", e);
105 }
106 finally {
107 try {if(is!=null) {
108 is.close();
109 }} catch(Exception e) {
110 }
111
112 }
113 }
114
115 @Override
116 public String readDefinition(String workflowName) throws FlowDefinitionException {
117 Content node;
118 try {
119 node = getDefinitionNode(workflowName);
120 }
121 catch (RepositoryException e) {
122 throw new FlowDefinitionException("can't read workflow definition [" + workflowName + "]", e);
123 }
124 if (node == null){
125 throw new FlowDefinitionException("can't read workflow definition [" + workflowName + "]") ;
126 }
127 return node.getNodeData("value").getString();
128 }
129
130
131
132
133
134 public Content getDefinitionNode(String name) throws RepositoryException {
135 if (name == null) {
136 return null;
137 }
138 return ContentUtil.getContent(RepositoryConstants.CONFIG, WorkflowConstants.ROOT_PATH_FOR_FLOW + "/"+ name);
139 }
140
141 @Override
142 public void saveDefinition(String definition) throws FlowDefinitionException {
143 saveDefinition(extractWorkflowName(definition), definition);
144 }
145
146 protected void saveDefinition(String workflowName, String definition) throws FlowDefinitionException {
147 if (definition == null) {
148 return;
149 }
150
151 try {
152 HierarchyManager hm = MgnlContext.getSystemContext().getHierarchyManager(RepositoryConstants.CONFIG);
153 Content root = hm.getContent(WorkflowConstants.ROOT_PATH_FOR_FLOW);
154
155
156
157
158 final Content wfNode = ContentUtil.getOrCreateContent(root, workflowName, ItemType.CONTENTNODE);
159 NodeDataUtil.getOrCreateAndSet(wfNode, WorkflowConstants.FLOW_VALUE, definition);
160
161 root.save();
162 log.info("New flow added: " + workflowName);
163 }
164 catch (Exception e) {
165 throw new FlowDefinitionException("can't add flow", e);
166 }
167 }
168
169 protected String extractWorkflowName(String definition) throws FlowDefinitionException {
170 try {
171
172 final org.jdom.input.SAXBuilder builder = new org.jdom.input.SAXBuilder();
173 Document doc = builder.build(new StringReader(definition));
174 Element process_definition = doc.getRootElement();
175 return process_definition.getAttribute("name").getValue();
176 }
177 catch(Exception e){
178 throw new FlowDefinitionException("can't extract name out of the definition", e);
179 }
180 }
181
182 @Override
183 public List getDefinitionNames(){
184 ArrayList list = new ArrayList();
185
186 HierarchyManager hm = MgnlContext.getSystemContext().getHierarchyManager(RepositoryConstants.CONFIG);
187 Content root;
188 try {
189 root = hm.getContent(WorkflowConstants.ROOT_PATH_FOR_FLOW);
190 }
191 catch (RepositoryException e) {
192 log.error("can't read flow definitions", e);
193 return Collections.EMPTY_LIST;
194 }
195
196 Collection c = ContentUtil.getAllChildren(root);
197
198 Iterator it = c.iterator();
199 while (it.hasNext()) {
200 String name = ((Content) (it.next())).getName();
201 if (name != null) {
202 list.add(name);
203 }
204 }
205
206 return list;
207 }
208
209 public String getFlowDefinitionURLPattern() {
210 if (StringUtils.isEmpty(flowDefinitionURLPattern) || flowDefinitionURLPattern.equals("auto")) {
211 WebContextImpl impl = (WebContextImpl) MgnlContext.getInstance();
212 HttpServletRequest request = impl.getRequest();
213
214 StringBuffer baseurl = new StringBuffer();
215 baseurl.append("http");
216 if(request.isSecure()){
217 baseurl.append("s");
218 }
219 baseurl.append("://");
220 baseurl.append(request.getServerName());
221 baseurl.append(":");
222 baseurl.append(request.getServerPort());
223 baseurl.append(impl.getContextPath());
224 baseurl.append("/.magnolia/pages/flows.html");
225 baseurl.append("?command=showFlow&flowName=");
226 baseurl.append("{0}");
227 flowDefinitionURLPattern = baseurl.toString();
228 }
229
230 return this.flowDefinitionURLPattern;
231 }
232
233
234 public void setFlowDefinitionURLPattern(String flowDefinitionURLPattern) {
235 this.flowDefinitionURLPattern = flowDefinitionURLPattern;
236 }
237
238 }