View Javadoc
1   package org.argeo.activities.ui;
2   
3   import java.util.ArrayList;
4   import java.util.List;
5   
6   import javax.jcr.Node;
7   import javax.jcr.NodeIterator;
8   import javax.jcr.RepositoryException;
9   import javax.jcr.Session;
10  
11  import org.argeo.activities.ActivitiesException;
12  import org.argeo.activities.ActivitiesNames;
13  import org.argeo.activities.ActivitiesService;
14  import org.argeo.activities.ActivitiesTypes;
15  import org.argeo.activities.ActivityValueCatalogs;
16  import org.argeo.cms.ui.eclipse.forms.AbstractFormPart;
17  import org.argeo.cms.ui.eclipse.forms.FormToolkit;
18  import org.argeo.connect.ConnectNames;
19  import org.argeo.connect.SystemAppService;
20  import org.argeo.connect.UserAdminService;
21  import org.argeo.connect.resources.ResourcesService;
22  import org.argeo.connect.ui.ConnectEditor;
23  import org.argeo.connect.ui.ConnectUiUtils;
24  import org.argeo.connect.ui.SystemWorkbenchService;
25  import org.argeo.connect.ui.util.LazyCTabControl;
26  import org.argeo.connect.util.ConnectJcrUtils;
27  import org.argeo.connect.util.XPathUtils;
28  import org.argeo.eclipse.ui.EclipseUiUtils;
29  import org.argeo.jcr.JcrUtils;
30  import org.eclipse.jface.viewers.DoubleClickEvent;
31  import org.eclipse.jface.viewers.IDoubleClickListener;
32  import org.eclipse.jface.viewers.IStructuredSelection;
33  import org.eclipse.jface.window.Window;
34  import org.eclipse.jface.wizard.WizardDialog;
35  import org.eclipse.swt.SWT;
36  import org.eclipse.swt.events.SelectionAdapter;
37  import org.eclipse.swt.events.SelectionEvent;
38  import org.eclipse.swt.events.TraverseEvent;
39  import org.eclipse.swt.events.TraverseListener;
40  import org.eclipse.swt.layout.GridData;
41  import org.eclipse.swt.layout.GridLayout;
42  import org.eclipse.swt.widgets.Button;
43  import org.eclipse.swt.widgets.Combo;
44  import org.eclipse.swt.widgets.Composite;
45  import org.eclipse.swt.widgets.Link;
46  import org.eclipse.swt.widgets.Shell;
47  import org.eclipse.swt.widgets.Text;
48  
49  public class ActivityChildrenList extends LazyCTabControl {
50  	private static final long serialVersionUID = 5906357274592489553L;
51  
52  	// private final static Log log = LogFactory.getLog(ActivityList.class);
53  
54  //	public final static String CTAB_ID = ActivitiesUiPlugin.PLUGIN_ID + ".ctab.activityList";
55  
56  	// Context
57  	private final UserAdminService userAdminService;
58  	private final ResourcesService resourcesService;
59  	private final ActivitiesService activitiesService;
60  	private final SystemAppService systemAppService;
61  	private final SystemWorkbenchService systemWorkbenchService;
62  	private final Node activity;
63  	private final ConnectEditor editor;
64  	private final FormToolkit toolkit;
65  
66  	// UI Objects
67  	private MyFormPart myFormPart;
68  	private MyActivityTableCmp activityTable;
69  
70  	@Override
71  	public void refreshPartControl() {
72  		myFormPart.refresh();
73  		ActivityChildrenList.this.layout(true, true);
74  	}
75  
76  	public ActivityChildrenList(Composite parent, int style, ConnectEditor editor,
77  			UserAdminService userAdminService, ResourcesService resourcesService, ActivitiesService activitiesService,
78  			SystemAppService systemAppService, SystemWorkbenchService systemWorkbenchService, Node entity) {
79  		super(parent, style);
80  		this.userAdminService = userAdminService;
81  		this.resourcesService = resourcesService;
82  		this.activitiesService = activitiesService;
83  		this.systemWorkbenchService = systemWorkbenchService;
84  		this.systemAppService = systemAppService;
85  		this.activity = entity;
86  		this.editor = editor;
87  		this.toolkit = editor.getFormToolkit();
88  	}
89  
90  	@Override
91  	public void createPartControl(Composite parent) {
92  		parent.setLayout(EclipseUiUtils.noSpaceGridLayout());
93  		Composite addCmp = null;
94  
95  		// TODO use finer rules to enable new activity addition
96  		if (ConnectJcrUtils.canEdit(activity)) {
97  			addCmp = toolkit.createComposite(parent);
98  			addCmp.setLayoutData(EclipseUiUtils.fillWidth());
99  		}
100 
101 		activityTable = new MyActivityTableCmp(parent, SWT.MULTI, activity);
102 		activityTable.setLayoutData(EclipseUiUtils.fillAll());
103 		activityTable.getTableViewer()
104 				.addDoubleClickListener(new ActivityTableDCL(systemWorkbenchService.getOpenEntityEditorCmdId()));
105 
106 		if (addCmp != null)
107 			addNewActivityPanel(addCmp, activity, activityTable);
108 
109 		myFormPart = new MyFormPart();
110 		myFormPart.initialize(editor.getManagedForm());
111 		editor.getManagedForm().addPart(myFormPart);
112 	}
113 
114 	private class MyFormPart extends AbstractFormPart {
115 
116 		@Override
117 		public void refresh() {
118 			activityTable.refresh();
119 			super.refresh();
120 		}
121 	}
122 
123 	private void addNewActivityPanel(final Composite addActivityBar, final Node entity,
124 			final MyActivityTableCmp activityTable) {
125 		// The Add Activity bar
126 		addActivityBar.setLayoutData(EclipseUiUtils.fillWidth());
127 		addActivityBar.setLayout(new GridLayout(7, false));
128 
129 		// Activity type
130 		final Combo typeCmb = new Combo(addActivityBar, SWT.NONE | SWT.READ_ONLY);
131 		GridData gd = new GridData(SWT.LEFT, SWT.CENTER, false, false);
132 		gd.widthHint = 100;
133 		typeCmb.setLayoutData(gd);
134 		typeCmb.setItems(ActivityValueCatalogs.getActivityTypeLabels());
135 		typeCmb.select(0);
136 
137 		toolkit.adapt(typeCmb, true, true);
138 
139 		// Title
140 		final Text titleTxt = ConnectUiUtils.createGDText(toolkit, addActivityBar, "Title",
141 				"Enter a short title for the activity to create", 150, 1);
142 
143 		// Description
144 		final Text descTxt = ConnectUiUtils.createGDText(toolkit, addActivityBar, "Description",
145 				"Enter a description for the activity to create", 300, 1);
146 
147 		Button validBtn = toolkit.createButton(addActivityBar, "Add activity", SWT.PUSH);
148 
149 		toolkit.createLabel(addActivityBar, " OR ", SWT.NONE);
150 
151 		final Link addTaskLk = new Link(addActivityBar, SWT.NONE);
152 		addTaskLk.setText("<a>Add a task</a>");
153 
154 		// Selection and traverse listeners
155 		validBtn.addSelectionListener(new SelectionAdapter() {
156 			private static final long serialVersionUID = 1L;
157 
158 			@Override
159 			public void widgetSelected(SelectionEvent e) {
160 				createActivity(entity, typeCmb, titleTxt, descTxt, activityTable);
161 			}
162 		});
163 
164 		TraverseListener travList = new TraverseListener() {
165 			private static final long serialVersionUID = 1L;
166 
167 			@Override
168 			public void keyTraversed(TraverseEvent e) {
169 				if (e.keyCode == SWT.CR) {
170 					e.doit = false;
171 					createActivity(entity, typeCmb, titleTxt, descTxt, activityTable);
172 				}
173 			}
174 		};
175 
176 		titleTxt.addTraverseListener(travList);
177 		descTxt.addTraverseListener(travList);
178 
179 		addTaskLk.addSelectionListener(new SelectionAdapter() {
180 			private static final long serialVersionUID = 1L;
181 
182 			@Override
183 			public void widgetSelected(SelectionEvent e) {
184 				if (createChildTask(addTaskLk.getShell()))
185 					activityTable.refresh();
186 			}
187 		});
188 	}
189 
190 	// LOCAL UI HELPERS
191 
192 	private class ActivityTableDCL implements IDoubleClickListener {
193 
194 		private String openEditorCmdId;
195 
196 		public ActivityTableDCL(String openEditorCmdId) {
197 			this.openEditorCmdId = openEditorCmdId;
198 		}
199 
200 		public void doubleClick(DoubleClickEvent event) {
201 			if (event.getSelection() == null || event.getSelection().isEmpty())
202 				return;
203 			Object obj = ((IStructuredSelection) event.getSelection()).getFirstElement();
204 			// try {
205 			Node currNode;
206 			if (obj instanceof Node)
207 				currNode = (Node) obj;
208 			else
209 				return;
210 			// String jcrId = currNode.getIdentifier();
211 			// CommandUtils.callCommand(openEditorCmdId, ConnectEditor.PARAM_JCR_ID, jcrId);
212 			systemWorkbenchService.openEntityEditor(currNode);
213 			// } catch (RepositoryException re) {
214 			// throw new ActivitiesException("Unable to open editor for node", re);
215 			// }
216 		}
217 	}
218 
219 	private class MyActivityTableCmp extends ActivityTable {
220 		private static final long serialVersionUID = 1L;
221 
222 		public MyActivityTableCmp(Composite parent, int style, Node entity) {
223 			super(parent, style, userAdminService, resourcesService, activitiesService, systemWorkbenchService, entity);
224 		}
225 
226 		protected void refreshFilteredList() {
227 			try {
228 				StringBuilder builder = new StringBuilder();
229 				builder.append("//element(*, ");
230 				builder.append(ActivitiesTypes.ACTIVITIES_ACTIVITY);
231 				builder.append(")");
232 				// get child activities
233 				builder.append("[");
234 				builder.append(XPathUtils.getPropertyEquals(ActivitiesNames.ACTIVITIES_PARENT_UID,
235 						ConnectJcrUtils.get(activity, ConnectNames.CONNECT_UID)));
236 				builder.append("]");
237 				NodeIterator nit = XPathUtils.createQuery(activity.getSession(), builder.toString()).execute()
238 						.getNodes();
239 
240 				List<Node> nodes = new ArrayList<Node>();
241 				while (nit.hasNext())
242 					nodes.add(nit.nextNode());
243 				getTableViewer().setInput(nodes.toArray());
244 			} catch (RepositoryException e) {
245 				throw new ActivitiesException("Unable to list child activities  under " + activity, e);
246 			}
247 		}
248 	}
249 
250 	private void createActivity(Node entity, Combo typeLbCmb, Text titleTxt, Text descTxt, ActivityTable table) {
251 		String typeLbl = typeLbCmb.getText();
252 		String title = titleTxt.getText();
253 		String desc = descTxt.getText();
254 		String type = ActivityValueCatalogs.getKeyByValue(ActivityValueCatalogs.MAPS_ACTIVITY_TYPES, typeLbl);
255 		if (createActivity(type, title, desc)) {
256 			table.refresh();
257 			typeLbCmb.select(0);
258 			titleTxt.setText("");
259 			descTxt.setText("");
260 			typeLbCmb.setFocus();
261 		}
262 	}
263 
264 	private boolean createChildTask(Shell shell) {
265 		Session tmpSession = null;
266 		Session targetSession = null;
267 		try {
268 			tmpSession = activity.getSession().getRepository().login();
269 			Node tmpTask = activitiesService.createDraftEntity(tmpSession, ActivitiesTypes.ACTIVITIES_TASK);
270 			tmpTask.setProperty(ActivitiesNames.ACTIVITIES_PARENT_UID,
271 					activity.getProperty(ConnectNames.CONNECT_UID).getString());
272 			NewSimpleTaskWizard wizard = new NewSimpleTaskWizard(userAdminService, activitiesService, tmpTask);
273 			WizardDialog dialog = new WizardDialog(shell, wizard);
274 			if (dialog.open() == Window.OK) {
275 				targetSession = activity.getSession().getRepository().login();
276 				Node targetParent = targetSession
277 						.getNode("/" + systemAppService.getBaseRelPath(ActivitiesTypes.ACTIVITIES_TASK));
278 				Node childTask = systemAppService.publishEntity(targetParent, ActivitiesTypes.ACTIVITIES_TASK, tmpTask);
279 				childTask = systemAppService.saveEntity(childTask, false);
280 				activity.getSession().refresh(true);
281 				return true;
282 			}
283 		} catch (RepositoryException e) {
284 			throw new ActivitiesException("Unable to create child task on " + activity, e);
285 		} finally {
286 			JcrUtils.logoutQuietly(tmpSession);
287 			JcrUtils.logoutQuietly(targetSession);
288 		}
289 		return false;
290 	}
291 
292 	private boolean createActivity(String type, String title, String desc) {
293 		Session tmpSession = null;
294 		Session targetSession = null;
295 		try {
296 			tmpSession = activity.getSession().getRepository().login();
297 			Node tmpChild = activitiesService.createDraftEntity(tmpSession, type);
298 			tmpChild.setProperty(ActivitiesNames.ACTIVITIES_PARENT_UID,
299 					activity.getProperty(ConnectNames.CONNECT_UID).getString());
300 			activitiesService.configureActivity(tmpChild, type, title, desc, null);
301 			targetSession = activity.getSession().getRepository().login();
302 			Node targetParent = targetSession
303 					.getNode("/" + systemAppService.getBaseRelPath(ActivitiesTypes.ACTIVITIES_ACTIVITY));
304 			Node childActivity = systemAppService.publishEntity(targetParent, type, tmpChild);
305 			childActivity = systemAppService.saveEntity(childActivity, false);
306 			activity.getSession().refresh(true);
307 			return true;
308 		} catch (RepositoryException e) {
309 			throw new ActivitiesException("Unable to create child activity under " + activity, e);
310 		} finally {
311 			JcrUtils.logoutQuietly(tmpSession);
312 			JcrUtils.logoutQuietly(targetSession);
313 		}
314 	}
315 }