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
75 public class DefaultFlowDefinitionManager implements FlowDefinitionManager {
76
77 private static Logger log = LoggerFactory.getLogger(DefaultFlowDefinitionManager.class);
78
79 private boolean saveWorkflowDefinitionInWorkItem = true;
80
81 private String flowDefinitionURLPattern;
82
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) is.close();} catch(Exception e) {
108 }
109
110 }
111 }
112
113 public String readDefinition(String workflowName) throws FlowDefinitionException {
114 Content node;
115 try {
116 node = getDefinitionNode(workflowName);
117 }
118 catch (RepositoryException e) {
119 throw new FlowDefinitionException("can't read workflow definition [" + workflowName + "]", e);
120 }
121 if (node == null){
122 throw new FlowDefinitionException("can't read workflow definition [" + workflowName + "]") ;
123 }
124 return node.getNodeData("value").getString();
125 }
126
127
128
129
130
131 public Content getDefinitionNode(String name) throws RepositoryException {
132 if (name == null) {
133 return null;
134 }
135 return ContentUtil.getContent(ContentRepository.CONFIG, WorkflowConstants.ROOT_PATH_FOR_FLOW + "/"+ name);
136 }
137
138 public void saveDefinition(String definition) throws FlowDefinitionException {
139 saveDefinition(extractWorkflowName(definition), definition);
140 }
141
142 protected void saveDefinition(String workflowName, String definition) throws FlowDefinitionException {
143 if (definition == null) {
144 return;
145 }
146
147 try {
148 HierarchyManager hm = MgnlContext.getSystemContext().getHierarchyManager(ContentRepository.CONFIG);
149 Content root = hm.getContent(WorkflowConstants.ROOT_PATH_FOR_FLOW);
150
151
152
153
154 final Content wfNode = ContentUtil.getOrCreateContent(root, workflowName, ItemType.CONTENTNODE);
155 NodeDataUtil.getOrCreateAndSet(wfNode, WorkflowConstants.FLOW_VALUE, definition);
156
157 root.save();
158 log.info("New flow added: " + workflowName);
159 }
160 catch (Exception e) {
161 throw new FlowDefinitionException("can't add flow", e);
162 }
163 }
164
165 protected String extractWorkflowName(String definition) throws FlowDefinitionException {
166 try {
167
168 final org.jdom.input.SAXBuilder builder = new org.jdom.input.SAXBuilder();
169 Document doc = builder.build(new StringReader(definition));
170 Element process_definition = doc.getRootElement();
171 return process_definition.getAttribute("name").getValue();
172 }
173 catch(Exception e){
174 throw new FlowDefinitionException("can't extract name out of the definition", e);
175 }
176 }
177
178 public List getDefinitionNames(){
179 ArrayList list = new ArrayList();
180
181 HierarchyManager hm = MgnlContext.getSystemContext().getHierarchyManager(ContentRepository.CONFIG);
182 Content root;
183 try {
184 root = hm.getContent(WorkflowConstants.ROOT_PATH_FOR_FLOW);
185 }
186 catch (RepositoryException e) {
187 log.error("can't read flow definitions", e);
188 return Collections.EMPTY_LIST;
189 }
190
191 Collection c = ContentUtil.getAllChildren(root);
192
193 Iterator it = c.iterator();
194 while (it.hasNext()) {
195 String name = ((Content) (it.next())).getName();
196 if (name != null) {
197 list.add(name);
198 }
199 }
200
201 return list;
202 }
203
204 public String getFlowDefinitionURLPattern() {
205 if (StringUtils.isEmpty(flowDefinitionURLPattern) || flowDefinitionURLPattern.equals("auto")) {
206 WebContextImpl impl = (WebContextImpl) MgnlContext.getInstance();
207 HttpServletRequest request = impl.getRequest();
208
209 StringBuffer baseurl = new StringBuffer();
210 baseurl.append("http");
211 if(request.isSecure()){
212 baseurl.append("s");
213 }
214 baseurl.append("://");
215 baseurl.append(request.getServerName());
216 baseurl.append(":");
217 baseurl.append(request.getServerPort());
218 baseurl.append(impl.getContextPath());
219 baseurl.append("/.magnolia/pages/flows.html");
220 baseurl.append("?command=showFlow&flowName=");
221 baseurl.append("{0}");
222 flowDefinitionURLPattern = baseurl.toString();
223 }
224
225 return this.flowDefinitionURLPattern;
226 }
227
228
229 public void setFlowDefinitionURLPattern(String flowDefinitionURLPattern) {
230 this.flowDefinitionURLPattern = flowDefinitionURLPattern;
231 }
232
233 }