View Javadoc
1   /*
2    * Copyright (C) 2007-2012 Argeo GmbH
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *         http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.argeo.slc.client.ui.editors;
17  
18  import java.util.HashMap;
19  import java.util.Map;
20  import java.util.UUID;
21  
22  import javax.jcr.Node;
23  import javax.jcr.NodeIterator;
24  import javax.jcr.Property;
25  import javax.jcr.Repository;
26  import javax.jcr.RepositoryException;
27  import javax.jcr.Session;
28  
29  import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
30  import org.argeo.jcr.JcrUtils;
31  import org.argeo.slc.SlcException;
32  import org.argeo.slc.SlcNames;
33  import org.argeo.slc.SlcTypes;
34  import org.argeo.slc.client.ui.ClientUiPlugin;
35  import org.argeo.slc.client.ui.controllers.ProcessController;
36  import org.argeo.slc.execution.ExecutionModulesManager;
37  import org.argeo.slc.execution.ExecutionProcess;
38  import org.argeo.slc.jcr.SlcJcrUtils;
39  import org.eclipse.core.runtime.IProgressMonitor;
40  import org.eclipse.rap.rwt.service.ServerPushSession;
41  import org.eclipse.ui.IEditorInput;
42  import org.eclipse.ui.IEditorSite;
43  import org.eclipse.ui.IWorkbenchPage;
44  import org.eclipse.ui.PartInitException;
45  import org.eclipse.ui.PlatformUI;
46  import org.eclipse.ui.forms.editor.FormEditor;
47  
48  /** Editor for an execution process. */
49  public class ProcessEditor extends FormEditor implements SlcTypes, SlcNames {
50  	private static final long serialVersionUID = 509589737739132467L;
51  
52  	public final static String ID = ClientUiPlugin.ID + ".processEditor";
53  
54  	private Repository repository;
55  	private Session session;
56  	private Node processNode;
57  	private ProcessController processController;
58  	private ServerPushSession pushSession;
59  
60  	private ProcessBuilderPage builderPage;
61  
62  	private ExecutionModulesManager modulesManager;
63  
64  	@Override
65  	public void init(IEditorSite site, IEditorInput input)
66  			throws PartInitException {
67  		super.init(site, input);
68  		pushSession = new ServerPushSession();
69  		pushSession.start();
70  		try {
71  			session = repository.login();
72  		} catch (RepositoryException e1) {
73  			throw new SlcException("Cannot log in to repository");
74  		}
75  
76  		ProcessEditorInput pei = (ProcessEditorInput) input;
77  		String processPath = pei.getProcessPath();
78  		try {
79  			if (processPath != null) {
80  				if (!session.itemExists(processPath))
81  					throw new SlcException("Process " + processPath
82  							+ " does not exist");
83  				processNode = session.getNode(processPath);
84  			} else {// new
85  				processNode = newProcessNode(pei);
86  			}
87  			setPartName(processNode.getName());
88  		} catch (RepositoryException e) {
89  			throw new SlcException("Cannot initialize editor for " + pei, e);
90  		}
91  
92  	}
93  
94  	protected Node newProcessNode(ProcessEditorInput pei)
95  			throws RepositoryException {
96  		String uuid = UUID.randomUUID().toString();
97  		String processPath = SlcJcrUtils.createExecutionProcessPath(session,
98  				uuid);
99  		Node processNode = JcrUtils.mkdirs(session, processPath, SLC_PROCESS);
100 		processNode.setProperty(SLC_UUID, uuid);
101 		processNode.setProperty(SLC_STATUS, ExecutionProcess.NEW);
102 		Node processFlow = processNode.addNode(SLC_FLOW);
103 		processFlow.addMixin(SLC_REALIZED_FLOW);
104 		return processNode;
105 	}
106 
107 	@Override
108 	public boolean isDirty() {
109 		if (getProcessStatus().equals(ExecutionProcess.NEW))
110 			return true;
111 		return super.isDirty();
112 	}
113 
114 	protected String getProcessStatus() {
115 		try {
116 			return processNode.getProperty(SLC_STATUS).getString();
117 		} catch (RepositoryException e) {
118 			throw new SlcException("Cannot retrieve status for " + processNode,
119 					e);
120 		}
121 	}
122 
123 	@Override
124 	public void dispose() {
125 		JcrUtils.logoutQuietly(session);
126 		if (pushSession != null)
127 			pushSession.stop();
128 		super.dispose();
129 	}
130 
131 	/** Actually runs the process. */
132 	void process() {
133 		// the modifications have to be saved before execution
134 		try {
135 			processNode.setProperty(SLC_STATUS, ExecutionProcess.SCHEDULED);
136 		} catch (RepositoryException e) {
137 			throw new SlcException("Cannot update status of " + processNode, e);
138 		}
139 
140 		// save
141 		doSave(null);
142 
143 		try {
144 			// make sure modules are started for all nodes
145 			for (NodeIterator nit = processNode.getNode(SLC_FLOW).getNodes(); nit
146 					.hasNext();) {
147 				Node flowNode = nit.nextNode();
148 				try {
149 					String flowDefPath = flowNode.getNode(SLC_ADDRESS)
150 							.getProperty(Property.JCR_PATH).getString();
151 					Node executionModuleNode = flowNode.getSession().getNode(
152 							SlcJcrUtils.modulePath(flowDefPath));
153 					if (!executionModuleNode.getProperty(SLC_STARTED)
154 							.getBoolean())
155 						ClientUiPlugin.startStopExecutionModule(modulesManager,
156 								executionModuleNode);
157 				} catch (Exception e) {
158 					ErrorFeedback.show(
159 							"Cannot start execution module related to "
160 									+ flowNode, e);
161 				}
162 			}
163 
164 			// Actually process
165 			ExecutionProcess process = processController.process(processNode);
166 			Map<String, String> properties = new HashMap<String, String>();
167 			properties.put(ExecutionModulesManager.SLC_PROCESS_ID,
168 					process.getUuid());
169 			// modulesManager.registerProcessNotifier(this, properties);
170 		} catch (Exception e) {
171 			ErrorFeedback.show("Execution of " + processNode + " failed", e);
172 		}
173 	}
174 
175 	void kill() {
176 		processController.kill(processNode);
177 	}
178 
179 	/** Opens a new editor with a copy of this process */
180 	void relaunch() {
181 		try {
182 			Node duplicatedNode = duplicateProcess();
183 			IWorkbenchPage activePage = PlatformUI.getWorkbench()
184 					.getActiveWorkbenchWindow().getActivePage();
185 			activePage.openEditor(
186 					new ProcessEditorInput(duplicatedNode.getPath()),
187 					ProcessEditor.ID);
188 			close(false);
189 		} catch (Exception e1) {
190 			throw new SlcException("Cannot relaunch " + processNode, e1);
191 		}
192 	}
193 
194 	/** Duplicates the process */
195 	protected Node duplicateProcess() {
196 		try {
197 			Session session = processNode.getSession();
198 			String uuid = UUID.randomUUID().toString();
199 			String destPath = SlcJcrUtils.createExecutionProcessPath(session,
200 					uuid);
201 			Node newNode = JcrUtils.mkdirs(session, destPath,
202 					SlcTypes.SLC_PROCESS);
203 
204 			Node rootRealizedFlowNode = newNode.addNode(SLC_FLOW);
205 			// copy node
206 			JcrUtils.copy(processNode.getNode(SLC_FLOW), rootRealizedFlowNode);
207 
208 			newNode.setProperty(SLC_UUID, uuid);
209 			newNode.setProperty(SLC_STATUS, ExecutionProcess.INITIALIZED);
210 
211 			// reset realized flow status
212 			// we just manage one level for the time being
213 			NodeIterator nit = rootRealizedFlowNode.getNodes(SLC_FLOW);
214 			while (nit.hasNext()) {
215 				nit.nextNode().setProperty(SLC_STATUS,
216 						ExecutionProcess.INITIALIZED);
217 			}
218 
219 			session.save();
220 			return newNode;
221 		} catch (RepositoryException e) {
222 			throw new SlcException("Cannot duplicate process", e);
223 		}
224 	}
225 
226 	@Override
227 	protected void addPages() {
228 		try {
229 			builderPage = new ProcessBuilderPage(this, processNode);
230 			addPage(builderPage);
231 			firePropertyChange(PROP_DIRTY);
232 		} catch (PartInitException e) {
233 			throw new SlcException("Cannot add pages", e);
234 		}
235 
236 	}
237 
238 	@Override
239 	public void doSave(IProgressMonitor monitor) {
240 		try {
241 			String status = processNode.getProperty(SLC_STATUS).getString();
242 			if (status.equals(ExecutionProcess.NEW))
243 				processNode.setProperty(SLC_STATUS,
244 						ExecutionProcess.INITIALIZED);
245 			session.save();
246 			builderPage.commit(true);
247 			editorDirtyStateChanged();
248 		} catch (RepositoryException e) {
249 			throw new SlcException("Cannot save " + processNode, e);
250 			// } finally {
251 			// JcrUtils.discardQuietly(session);
252 		}
253 	}
254 
255 	public void setEditorTitle(String title) {
256 		setPartName(title);
257 	}
258 
259 	@Override
260 	public void doSaveAs() {
261 	}
262 
263 	@Override
264 	public boolean isSaveAsAllowed() {
265 		return false;
266 	}
267 
268 	public void setRepository(Repository repository) {
269 		this.repository = repository;
270 	}
271 
272 	public void setProcessController(ProcessController processController) {
273 		this.processController = processController;
274 	}
275 
276 	public void setModulesManager(ExecutionModulesManager modulesManager) {
277 		this.modulesManager = modulesManager;
278 	}
279 }