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.dist.editors;
17  
18  import java.util.List;
19  
20  import javax.jcr.Node;
21  import javax.jcr.NodeIterator;
22  import javax.jcr.RepositoryException;
23  
24  import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
25  import org.argeo.jcr.JcrUtils;
26  import org.argeo.slc.SlcException;
27  import org.argeo.slc.SlcNames;
28  import org.argeo.slc.SlcTypes;
29  import org.argeo.slc.client.ui.dist.DistConstants;
30  import org.argeo.slc.client.ui.dist.DistImages;
31  import org.eclipse.jface.viewers.ColumnLabelProvider;
32  import org.eclipse.jface.viewers.IStructuredContentProvider;
33  import org.eclipse.jface.viewers.ITreeContentProvider;
34  import org.eclipse.jface.viewers.TableViewer;
35  import org.eclipse.jface.viewers.TableViewerColumn;
36  import org.eclipse.jface.viewers.TreeViewer;
37  import org.eclipse.jface.viewers.TreeViewerColumn;
38  import org.eclipse.jface.viewers.Viewer;
39  import org.eclipse.swt.SWT;
40  import org.eclipse.swt.graphics.Image;
41  import org.eclipse.swt.layout.GridData;
42  import org.eclipse.swt.layout.GridLayout;
43  import org.eclipse.swt.widgets.Composite;
44  import org.eclipse.swt.widgets.Table;
45  import org.eclipse.swt.widgets.Tree;
46  import org.eclipse.ui.forms.IManagedForm;
47  import org.eclipse.ui.forms.editor.FormEditor;
48  import org.eclipse.ui.forms.editor.FormPage;
49  import org.eclipse.ui.forms.widgets.FormToolkit;
50  import org.eclipse.ui.forms.widgets.ScrolledForm;
51  import org.eclipse.ui.forms.widgets.Section;
52  
53  /**
54   * Present main information of a given OSGI bundle
55   */
56  public class BundleDependencyPage extends FormPage implements SlcNames {
57  	// private final static Log log =
58  	// LogFactory.getLog(ArtifactDetailsPage.class);
59  
60  	// Main business Objects
61  	private Node currBundle;
62  
63  	// This page widgets
64  	private FormToolkit toolkit;
65  
66  	public BundleDependencyPage(FormEditor editor, String title,
67  			Node currentNode) {
68  		super(editor, "id", title);
69  		this.currBundle = currentNode;
70  	}
71  
72  	protected void createFormContent(IManagedForm managedForm) {
73  		ScrolledForm form = managedForm.getForm();
74  		toolkit = managedForm.getToolkit();
75  		try {
76  			if (currBundle.hasProperty(DistConstants.SLC_BUNDLE_NAME))
77  				form.setText(currBundle.getProperty(
78  						DistConstants.SLC_BUNDLE_NAME).getString());
79  			Composite body = form.getBody();
80  			GridLayout layout = new GridLayout(1, false);
81  			layout.horizontalSpacing = layout.marginWidth = 0;
82  			layout.verticalSpacing = layout.marginHeight = 0;
83  			body.setLayout(layout);
84  
85  			Composite part = toolkit.createComposite(body);
86  			createExportPackageSection(part);
87  			GridData gd = new GridData(SWT.FILL, SWT.TOP, true, false);
88  			gd.heightHint = 180;
89  			part.setLayoutData(gd);
90  
91  			part = toolkit.createComposite(body);
92  			createImportPackageSection(part);
93  			gd = new GridData(SWT.FILL, SWT.FILL, true, true);
94  			// gd.heightHint = 200;
95  			part.setLayoutData(gd);
96  
97  			part = toolkit.createComposite(body);
98  			createReqBundleSection(part);
99  			gd = new GridData(SWT.FILL, SWT.FILL, true, true);
100 			part.setLayoutData(gd);
101 
102 			managedForm.reflow(true);
103 
104 		} catch (RepositoryException e) {
105 			throw new SlcException("unexpected error "
106 					+ "while creating bundle details page");
107 		}
108 	}
109 
110 	// Workaround to add an artificial level to the export package browser
111 	private class LevelElem {
112 		private String label;
113 		private Object parent;
114 
115 		public LevelElem(String label, Object parent) {
116 			this.label = label;
117 			this.parent = parent;
118 		}
119 
120 		public String toString() {
121 			return label;
122 		}
123 
124 		public Object getParent() {
125 			return parent;
126 		}
127 	}
128 
129 	/** Export Package Section */
130 	private void createExportPackageSection(Composite parent)
131 			throws RepositoryException {
132 		parent.setLayout(new GridLayout());
133 
134 		// Define the TableViewer
135 
136 		Section section = addSection(parent, "Export packages");
137 		section.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
138 
139 		TreeViewer viewer = new TreeViewer(section, SWT.H_SCROLL | SWT.V_SCROLL
140 				| SWT.BORDER);
141 		final Tree tree = viewer.getTree();
142 		tree.setHeaderVisible(false);
143 		tree.setLinesVisible(true);
144 		tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
145 
146 		TreeViewerColumn col = new TreeViewerColumn(viewer, SWT.FILL);
147 		col.getColumn().setWidth(400);
148 
149 		col.setLabelProvider(new ColumnLabelProvider() {
150 			private static final long serialVersionUID = 1376400790495130862L;
151 
152 			@Override
153 			public String getText(Object element) {
154 				if (element instanceof Node)
155 					return JcrUtils.get((Node) element, SlcNames.SLC_NAME);
156 				else
157 					return element.toString();
158 			}
159 
160 			@Override
161 			public Image getImage(Object element) {
162 				if (element instanceof Node) {
163 					try {
164 						Node node = (Node) element;
165 						if (node.isNodeType(SlcTypes.SLC_EXPORTED_PACKAGE))
166 							return DistImages.IMG_PACKAGE;
167 					} catch (RepositoryException e) {
168 						throw new SlcException("Error retriving "
169 								+ "image for the labelProvider", e);
170 					}
171 				}
172 				return null;
173 			}
174 		});
175 
176 		viewer.setContentProvider(new ITreeContentProvider() {
177 			private static final long serialVersionUID = 1898086304761992568L;
178 
179 			public void dispose() {
180 			}
181 
182 			public void inputChanged(Viewer viewer, Object oldInput,
183 					Object newInput) {
184 			}
185 
186 			public Object[] getElements(Object inputElement) {
187 				try {
188 					List<Node> nodes = JcrUtils.nodeIteratorToList(listNodes(
189 							currBundle, SlcTypes.SLC_EXPORTED_PACKAGE,
190 							SlcNames.SLC_NAME));
191 					return nodes.toArray();
192 				} catch (RepositoryException e) {
193 					throw new SlcException("Cannot list children Nodes", e);
194 				}
195 			}
196 
197 			public Object[] getChildren(Object parentElement) {
198 				// Only 2 levels for the time being
199 				try {
200 					if (parentElement instanceof LevelElem) {
201 						Node node = (Node) ((LevelElem) parentElement)
202 								.getParent();
203 						List<Node> nodes = JcrUtils
204 								.nodeIteratorToList(listNodes(node,
205 										SlcTypes.SLC_JAVA_PACKAGE,
206 										SlcNames.SLC_NAME));
207 						return nodes.toArray();
208 					} else if (parentElement instanceof Node) {
209 						Node pNode = (Node) parentElement;
210 						if (pNode.isNodeType(SlcTypes.SLC_EXPORTED_PACKAGE)) {
211 							if (listNodes(pNode, SlcTypes.SLC_JAVA_PACKAGE,
212 									SlcNames.SLC_NAME).getSize() > 0) {
213 								Object[] result = { new LevelElem("uses", pNode) };
214 								return result;
215 							}
216 						}
217 					}
218 					return null;
219 				} catch (RepositoryException e) {
220 					throw new SlcException("Cannot list children Nodes", e);
221 				}
222 			}
223 
224 			public Object getParent(Object element) {
225 				// useless
226 				return null;
227 			}
228 
229 			public boolean hasChildren(Object element) {
230 				try {
231 					if (element instanceof LevelElem)
232 						return true;
233 					else {
234 						Node pNode = (Node) element;
235 						if (pNode.isNodeType(SlcTypes.SLC_EXPORTED_PACKAGE)) {
236 							return listNodes(pNode, SlcTypes.SLC_JAVA_PACKAGE,
237 									SlcNames.SLC_NAME).getSize() > 0;
238 						}
239 					}
240 					return false;
241 				} catch (RepositoryException e) {
242 					throw new SlcException("Cannot check children Nodes", e);
243 				}
244 			}
245 		});
246 
247 		section.setClient(tree);
248 		viewer.setInput("Initialize");
249 		// work around a display problem : the tree table has only a few lines
250 		// when the tree is not expended
251 		// viewer.expandToLevel(2);
252 	}
253 
254 	/** Import Package Section */
255 	private void createImportPackageSection(Composite parent)
256 			throws RepositoryException {
257 		parent.setLayout(new GridLayout());
258 
259 		// Define the TableViewer
260 		// toolkit.createLabel(parent, "Import packages", SWT.NONE).setFont(
261 		// EclipseUiUtils.getBoldFont(parent));
262 
263 		Section section = addSection(parent, "Import packages");
264 		section.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
265 		TableViewer viewer = new TableViewer(section, SWT.H_SCROLL
266 				| SWT.V_SCROLL | SWT.BORDER);
267 
268 		final Table table = viewer.getTable();
269 		table.setHeaderVisible(true);
270 		table.setLinesVisible(true);
271 		table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
272 
273 		// Name
274 		TableViewerColumn col = new TableViewerColumn(viewer, SWT.NONE);
275 		col.getColumn().setWidth(350);
276 		col.getColumn().setText("Name");
277 		col.setLabelProvider(new ColumnLabelProvider() {
278 			private static final long serialVersionUID = -7836022945221936898L;
279 
280 			@Override
281 			public String getText(Object element) {
282 				return JcrUtils.get((Node) element, SLC_NAME);
283 			}
284 
285 			public Image getImage(Object element) {
286 				return DistImages.IMG_PACKAGE;
287 			}
288 
289 		});
290 
291 		// Version
292 		col = new TableViewerColumn(viewer, SWT.NONE);
293 		col.getColumn().setWidth(100);
294 		col.getColumn().setText("Version");
295 		col.setLabelProvider(new ColumnLabelProvider() {
296 			private static final long serialVersionUID = -8277731617775091641L;
297 
298 			@Override
299 			public String getText(Object element) {
300 				return JcrUtils.get((Node) element, SLC_VERSION);
301 			}
302 		});
303 
304 		// Optional
305 		col = new TableViewerColumn(viewer, SWT.NONE);
306 		col.getColumn().setWidth(100);
307 		col.getColumn().setText("Optional");
308 		col.setLabelProvider(new ColumnLabelProvider() {
309 			private static final long serialVersionUID = -2388533169594840688L;
310 
311 			@Override
312 			public String getText(Object element) {
313 				return JcrUtils.get((Node) element, SLC_OPTIONAL);
314 			}
315 		});
316 
317 		viewer.setContentProvider(new TableContentProvider(
318 				SlcTypes.SLC_IMPORTED_PACKAGE, SLC_NAME));
319 		section.setClient(table);
320 		viewer.setInput("Initialize");
321 	}
322 
323 	/** Required Bundle Section */
324 	private void createReqBundleSection(Composite parent)
325 			throws RepositoryException {
326 		parent.setLayout(new GridLayout());
327 
328 		// Define the TableViewer
329 		Section section = addSection(parent, "Required bundles");
330 		section.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
331 
332 		// toolkit.createLabel(parent, "Required bundles", SWT.NONE).setFont(
333 		// EclipseUiUtils.getBoldFont(parent));
334 		TableViewer viewer = new TableViewer(section, SWT.H_SCROLL
335 				| SWT.V_SCROLL | SWT.BORDER);
336 
337 		final Table table = viewer.getTable();
338 		table.setHeaderVisible(true);
339 		table.setLinesVisible(true);
340 		table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
341 
342 		// Name
343 		TableViewerColumn col = new TableViewerColumn(viewer, SWT.NONE);
344 		col.getColumn().setWidth(300);
345 		col.getColumn().setText("Name");
346 		col.setLabelProvider(new ColumnLabelProvider() {
347 			private static final long serialVersionUID = 4423640365819800247L;
348 
349 			@Override
350 			public String getText(Object element) {
351 				return JcrUtils.get((Node) element, SLC_SYMBOLIC_NAME);
352 			}
353 
354 			@Override
355 			public Image getImage(Object element) {
356 				return DistImages.IMG_BUNDLE;
357 			}
358 		});
359 
360 		// Version
361 		col = new TableViewerColumn(viewer, SWT.NONE);
362 		col.getColumn().setWidth(140);
363 		col.getColumn().setText("Version");
364 		col.setLabelProvider(new ColumnLabelProvider() {
365 			private static final long serialVersionUID = 1898477425996646270L;
366 
367 			@Override
368 			public String getText(Object element) {
369 				return JcrUtils.get((Node) element, SLC_BUNDLE_VERSION);
370 			}
371 		});
372 
373 		// Optional
374 		col = new TableViewerColumn(viewer, SWT.NONE);
375 		col.getColumn().setWidth(100);
376 		col.getColumn().setText("Optional");
377 		col.setLabelProvider(new ColumnLabelProvider() {
378 			private static final long serialVersionUID = -7029999152302445581L;
379 
380 			@Override
381 			public String getText(Object element) {
382 				return JcrUtils.get((Node) element, SLC_OPTIONAL);
383 			}
384 		});
385 
386 		viewer.setContentProvider(new TableContentProvider(
387 				SlcTypes.SLC_REQUIRED_BUNDLE, SLC_SYMBOLIC_NAME));
388 		section.setClient(table);
389 		viewer.setInput("Initialize");
390 	}
391 
392 	/**
393 	 * Build repository request
394 	 * 
395 	 * FIXME Workaround for remote repository, the path to bundleartifact (for
396 	 * instance
397 	 * .../org/argeo/slc/org.argeo.slc.client.ui.dist/1.1.12/org.argeo.slc
398 	 * .client.ui.dist-1.1.12/ ) is not valid for method factory.childNode(); it
399 	 * fails parsing the "1.1.12" part, trying to cast it as a BigDecimal
400 	 * 
401 	 * */
402 	private NodeIterator listNodes(Node parent, String nodeType, String orderBy)
403 			throws RepositoryException {
404 		// QueryManager queryManager = currBundle.getSession().getWorkspace()
405 		// .getQueryManager();
406 		// QueryObjectModelFactory factory = queryManager.getQOMFactory();
407 		//
408 		// final String nodeSelector = "nodes";
409 		// Selector source = factory.selector(nodeType, nodeSelector);
410 		//
411 		// Constraint childOf = factory.childNode(nodeSelector,
412 		// parent.getPath());
413 		//
414 		// Ordering order =
415 		// factory.ascending(factory.propertyValue(nodeSelector,
416 		// orderBy));
417 		// Ordering[] orderings = { order };
418 		//
419 		// QueryObjectModel query = factory.createQuery(source, childOf,
420 		// orderings, null);
421 		//
422 		// QueryResult result = query.execute();
423 
424 		String pattern = null;
425 		if (SlcTypes.SLC_EXPORTED_PACKAGE.equals(nodeType))
426 			pattern = "slc:Export-Package*";
427 		else if (SlcTypes.SLC_JAVA_PACKAGE.equals(nodeType))
428 			pattern = "slc:uses*";
429 		else if (SlcTypes.SLC_IMPORTED_PACKAGE.equals(nodeType))
430 			pattern = "slc:Import-Package*";
431 		else if (SlcTypes.SLC_REQUIRED_BUNDLE.equals(nodeType))
432 			pattern = "slc:Require-Bundle*";
433 
434 		return parent.getNodes(pattern);
435 	}
436 
437 	private class TableContentProvider implements IStructuredContentProvider {
438 		private static final long serialVersionUID = 4133284637336320455L;
439 		private String nodeType;
440 		private String orderBy;
441 
442 		TableContentProvider(String nodeType, String orderBy) {
443 			this.nodeType = nodeType;
444 			this.orderBy = orderBy;
445 		}
446 
447 		public void dispose() {
448 		}
449 
450 		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
451 		}
452 
453 		public Object[] getElements(Object arg0) {
454 			try {
455 				List<Node> nodes = JcrUtils.nodeIteratorToList(listNodes(
456 						currBundle, nodeType, orderBy));
457 				return nodes.toArray();
458 			} catch (RepositoryException e) {
459 				ErrorFeedback.show("Cannot list children Nodes", e);
460 				return null;
461 			}
462 		}
463 	}
464 
465 	/* HELPERS */
466 	private Section addSection(Composite parent, String title) {
467 		Section section = toolkit.createSection(parent, Section.TITLE_BAR);
468 		section.setText(title);
469 		section.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
470 		return section;
471 	}
472 
473 }