]> git.argeo.org Git - gpl/argeo-slc.git/blob - plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/BundleDetailsPage.java
work on fetch and normalization.
[gpl/argeo-slc.git] / plugins / org.argeo.slc.client.ui.dist / src / main / java / org / argeo / slc / client / ui / dist / editors / BundleDetailsPage.java
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.net.URL;
19 import java.util.List;
20
21 import javax.jcr.Node;
22 import javax.jcr.NodeIterator;
23 import javax.jcr.RepositoryException;
24
25 import org.argeo.ArgeoException;
26 import org.argeo.eclipse.ui.ErrorFeedback;
27 import org.argeo.jcr.JcrUtils;
28 import org.argeo.slc.SlcException;
29 import org.argeo.slc.client.ui.dist.DistConstants;
30 import org.argeo.slc.client.ui.dist.DistImages;
31 import org.argeo.slc.client.ui.dist.utils.AbstractHyperlinkListener;
32 import org.argeo.slc.jcr.SlcNames;
33 import org.argeo.slc.jcr.SlcTypes;
34 import org.argeo.slc.repo.RepoConstants;
35 import org.argeo.slc.repo.RepoUtils;
36 import org.eclipse.jface.viewers.ColumnLabelProvider;
37 import org.eclipse.jface.viewers.IStructuredContentProvider;
38 import org.eclipse.jface.viewers.ITreeContentProvider;
39 import org.eclipse.jface.viewers.TableLayout;
40 import org.eclipse.jface.viewers.TableViewer;
41 import org.eclipse.jface.viewers.TableViewerColumn;
42 import org.eclipse.jface.viewers.TreeViewer;
43 import org.eclipse.jface.viewers.TreeViewerColumn;
44 import org.eclipse.jface.viewers.Viewer;
45 import org.eclipse.swt.SWT;
46 import org.eclipse.swt.graphics.Image;
47 import org.eclipse.swt.layout.GridData;
48 import org.eclipse.swt.layout.GridLayout;
49 import org.eclipse.swt.widgets.Button;
50 import org.eclipse.swt.widgets.Composite;
51 import org.eclipse.swt.widgets.Table;
52 import org.eclipse.swt.widgets.Text;
53 import org.eclipse.swt.widgets.Tree;
54 import org.eclipse.ui.PlatformUI;
55 import org.eclipse.ui.browser.IWebBrowser;
56 import org.eclipse.ui.browser.IWorkbenchBrowserSupport;
57 import org.eclipse.ui.forms.IManagedForm;
58 import org.eclipse.ui.forms.editor.FormEditor;
59 import org.eclipse.ui.forms.editor.FormPage;
60 import org.eclipse.ui.forms.events.HyperlinkEvent;
61 import org.eclipse.ui.forms.widgets.FormToolkit;
62 import org.eclipse.ui.forms.widgets.Hyperlink;
63 import org.eclipse.ui.forms.widgets.ScrolledForm;
64 import org.eclipse.ui.forms.widgets.Section;
65
66 /**
67 * Presents main information of a given OSGI bundle
68 */
69
70 public class BundleDetailsPage extends FormPage implements SlcNames, SlcTypes {
71 // private final static Log log =
72 // LogFactory.getLog(ArtifactDetailsPage.class);
73
74 // Main business Objects
75 private Node currBundle;
76
77 // This page widgets
78 private Text mavenSnippet;
79 private FormToolkit toolkit;
80
81 public BundleDetailsPage(FormEditor editor, String title, Node currentNode) {
82 super(editor, "id", title);
83 this.currBundle = currentNode;
84 }
85
86 protected void createFormContent(IManagedForm managedForm) {
87 ScrolledForm form = managedForm.getForm();
88 toolkit = managedForm.getToolkit();
89 try {
90 form.setText(currBundle.hasProperty(DistConstants.SLC_BUNDLE_NAME) ? currBundle
91 .getProperty(DistConstants.SLC_BUNDLE_NAME).getString()
92 : "");
93 Composite body = form.getBody();
94 GridLayout layout = new GridLayout(1, false);
95 layout.marginWidth = 5;
96 layout.verticalSpacing = 15;
97
98 body.setLayout(layout);
99 createdetailsPart(body);
100
101 createExportPackageSection(body);
102 createImportPackageSection(body);
103 createReqBundleSection(body);
104 createMavenSnippet(body);
105
106 } catch (RepositoryException e) {
107 throw new SlcException("unexpected error "
108 + "while creating bundle details page");
109 }
110 }
111
112 /** Add useful info for the current bundle */
113 private void createdetailsPart(Composite parent) throws RepositoryException {
114 Composite details = toolkit.createComposite(parent);
115 GridLayout layout = new GridLayout(2, false);
116 layout.horizontalSpacing = 20;
117 details.setLayout(layout);
118
119 createField(details, "Symbolic name", SlcNames.SLC_SYMBOLIC_NAME);
120 createField(details, "Version", SlcNames.SLC_BUNDLE_VERSION);
121 createField(details, "Group Id", SlcNames.SLC_GROUP_ID);
122 createHyperlink(details, "Licence", DistConstants.SLC_BUNDLE_LICENCE);
123 createField(details, "Vendor", DistConstants.SLC_BUNDLE_VENDOR);
124 addSourceAvailableLabel(details);
125
126 }
127
128 // helper to check if sources are available
129 private void addSourceAvailableLabel(Composite parent) {
130 Button srcChk = toolkit.createButton(parent, "Sources available",
131 SWT.CHECK);
132 srcChk.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 2, 1));
133
134 try {
135 String srcPath = RepoUtils.relatedPdeSourcePath(
136 RepoConstants.DEFAULT_ARTIFACTS_BASE_PATH, currBundle);
137 srcChk.setSelection(currBundle.getSession().nodeExists(srcPath));
138 } catch (RepositoryException e) {
139 throw new SlcException("Unable to check sources", e);
140 }
141 srcChk.setEnabled(false);
142 }
143
144 // Workaround to add an artificial level to the export package browser
145 private class LevelElem {
146 private String label;
147 private Object parent;
148
149 public LevelElem(String label, Object parent) {
150 this.label = label;
151 this.parent = parent;
152 }
153
154 public String toString() {
155 return label;
156 }
157
158 public Object getParent() {
159 return parent;
160 }
161 }
162
163 /** Export Package Section */
164 private void createExportPackageSection(Composite parent)
165 throws RepositoryException {
166
167 // Define the TableViewer
168 Section headerSection = addSection(parent, "Export packages");
169 // TreeViewer viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL
170 // | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER);
171 TreeViewer viewer = new TreeViewer(headerSection, SWT.MULTI
172 | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER);
173
174 final Tree tree = viewer.getTree();
175 tree.setHeaderVisible(false);
176 tree.setLinesVisible(true);
177 GridData gd = new GridData(SWT.LEFT, SWT.TOP, true, true);
178 gd.heightHint = 300;
179 tree.setLayoutData(gd);
180
181 TreeViewerColumn col = new TreeViewerColumn(viewer, SWT.FILL);
182 col.getColumn().setWidth(400);
183
184 col.setLabelProvider(new ColumnLabelProvider() {
185 @Override
186 public String getText(Object element) {
187 if (element instanceof Node)
188 return JcrUtils.get((Node) element, SlcNames.SLC_NAME);
189 else
190 return element.toString();
191 }
192
193 @Override
194 public Image getImage(Object element) {
195 if (element instanceof Node) {
196 try {
197 Node node = (Node) element;
198 if (node.isNodeType(SlcTypes.SLC_EXPORTED_PACKAGE))
199 return DistImages.IMG_PACKAGE;
200 } catch (RepositoryException e) {
201 throw new SlcException("Error retriving "
202 + "image for the labelProvider", e);
203 }
204 }
205 return null;
206 }
207 });
208
209 viewer.setContentProvider(new ITreeContentProvider() {
210
211 public void dispose() {
212 }
213
214 public void inputChanged(Viewer viewer, Object oldInput,
215 Object newInput) {
216 }
217
218 public Object[] getElements(Object inputElement) {
219 try {
220 List<Node> nodes = JcrUtils.nodeIteratorToList(listNodes(
221 currBundle, SlcTypes.SLC_EXPORTED_PACKAGE,
222 SlcNames.SLC_NAME));
223 return nodes.toArray();
224 } catch (RepositoryException e) {
225 throw new SlcException("Cannot list children Nodes", e);
226 }
227 }
228
229 public Object[] getChildren(Object parentElement) {
230 // Only 2 levels for the time being
231 try {
232 if (parentElement instanceof LevelElem) {
233 Node node = (Node) ((LevelElem) parentElement)
234 .getParent();
235 List<Node> nodes = JcrUtils
236 .nodeIteratorToList(listNodes(node,
237 SlcTypes.SLC_JAVA_PACKAGE,
238 SlcNames.SLC_NAME));
239 return nodes.toArray();
240 } else if (parentElement instanceof Node) {
241 Node pNode = (Node) parentElement;
242 if (pNode.isNodeType(SlcTypes.SLC_EXPORTED_PACKAGE)) {
243 if (listNodes(pNode, SlcTypes.SLC_JAVA_PACKAGE,
244 SlcNames.SLC_NAME).getSize() > 0) {
245 Object[] result = { new LevelElem("uses", pNode) };
246 return result;
247 }
248 }
249 }
250 return null;
251 } catch (RepositoryException e) {
252 throw new SlcException("Cannot list children Nodes", e);
253 }
254 }
255
256 public Object getParent(Object element) {
257 // useless
258 return null;
259 }
260
261 public boolean hasChildren(Object element) {
262 try {
263 if (element instanceof LevelElem)
264 return true;
265 else {
266 Node pNode = (Node) element;
267 if (pNode.isNodeType(SlcTypes.SLC_EXPORTED_PACKAGE)) {
268 return listNodes(pNode, SlcTypes.SLC_JAVA_PACKAGE,
269 SlcNames.SLC_NAME).getSize() > 0;
270 }
271 }
272 return false;
273 } catch (RepositoryException e) {
274 throw new SlcException("Cannot check children Nodes", e);
275 }
276 }
277 });
278
279 headerSection.setClient(tree);
280 viewer.setInput("Initialize");
281 // work around a display problem : the tree table has only a few lines
282 // when the tree is not expended
283 viewer.expandToLevel(3);
284 }
285
286 /** Import Package Section */
287 private void createImportPackageSection(Composite parent)
288 throws RepositoryException {
289
290 // Define the TableViewer
291 Section headerSection = addSection(parent, "Import packages");
292 TableViewer viewer = new TableViewer(headerSection, SWT.MULTI
293 | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER);
294
295 // Name
296 TableViewerColumn col = new TableViewerColumn(viewer, SWT.NONE);
297 col.getColumn().setWidth(350);
298 col.getColumn().setText("Name");
299 col.setLabelProvider(new ColumnLabelProvider() {
300 @Override
301 public String getText(Object element) {
302 return JcrUtils.get((Node) element, SLC_NAME);
303 }
304
305 public Image getImage(Object element) {
306 return DistImages.IMG_PACKAGE;
307 }
308
309 });
310
311 // Version
312 col = new TableViewerColumn(viewer, SWT.NONE);
313 col.getColumn().setWidth(100);
314 col.getColumn().setText("Version");
315 col.setLabelProvider(new ColumnLabelProvider() {
316 @Override
317 public String getText(Object element) {
318 return JcrUtils.get((Node) element, SLC_VERSION);
319 }
320 });
321
322 // Optional
323 col = new TableViewerColumn(viewer, SWT.NONE);
324 col.getColumn().setWidth(100);
325 col.getColumn().setText("Optional");
326 col.setLabelProvider(new ColumnLabelProvider() {
327 @Override
328 public String getText(Object element) {
329 return JcrUtils.get((Node) element, SLC_OPTIONAL);
330 }
331 });
332
333 final Table table = viewer.getTable();
334 table.setHeaderVisible(true);
335 table.setLinesVisible(true);
336 GridData gd = new GridData(SWT.LEFT, SWT.TOP, true, true);
337 gd.heightHint = 300;
338 table.setLayoutData(gd);
339
340 viewer.setContentProvider(new TableContentProvider(
341 SLC_IMPORTED_PACKAGE, SLC_NAME));
342 headerSection.setClient(viewer.getTable());
343
344 viewer.setInput("Initialize");
345 }
346
347 /** Required Bundle Section */
348 private void createReqBundleSection(Composite parent)
349 throws RepositoryException {
350
351 // Define the TableViewer
352 Section headerSection = addSection(parent, "Required bundles");
353 TableViewer viewer = new TableViewer(headerSection, SWT.MULTI
354 | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER);
355
356 // Name
357 TableViewerColumn col = new TableViewerColumn(viewer, SWT.NONE);
358 col.getColumn().setWidth(300);
359 col.getColumn().setText("Name");
360 col.setLabelProvider(new ColumnLabelProvider() {
361 @Override
362 public String getText(Object element) {
363 return JcrUtils.get((Node) element, SLC_SYMBOLIC_NAME);
364 }
365
366 @Override
367 public Image getImage(Object element) {
368 return DistImages.IMG_BUNDLE;
369 }
370 });
371
372 // Version
373 col = new TableViewerColumn(viewer, SWT.NONE);
374 col.getColumn().setWidth(140);
375 col.getColumn().setText("Version");
376 col.setLabelProvider(new ColumnLabelProvider() {
377 @Override
378 public String getText(Object element) {
379 return JcrUtils.get((Node) element, SLC_BUNDLE_VERSION);
380 }
381 });
382
383 // Version
384 col = new TableViewerColumn(viewer, SWT.NONE);
385 col.getColumn().setWidth(100);
386 col.getColumn().setText("Optional");
387 col.setLabelProvider(new ColumnLabelProvider() {
388 @Override
389 public String getText(Object element) {
390 return JcrUtils.get((Node) element, SLC_OPTIONAL);
391 }
392 });
393
394 final Table table = viewer.getTable();
395 table.setHeaderVisible(true);
396 table.setLinesVisible(true);
397
398 viewer.setContentProvider(new TableContentProvider(SLC_REQUIRED_BUNDLE,
399 SLC_SYMBOLIC_NAME));
400 headerSection.setClient(viewer.getTable());
401
402 viewer.setInput("Initialize");
403 }
404
405 /**
406 * Build repository request
407 *
408 * FIXME Workaround for remote repository, the path to bundleartifact (for
409 * instance
410 * .../org/argeo/slc/org.argeo.slc.client.ui.dist/1.1.12/org.argeo.slc
411 * .client.ui.dist-1.1.12/ ) is not valid for method factory.childNode(); it
412 * fails parsing the "1.1.12" part, trying to cast it as a BigDecimal
413 *
414 * */
415 private NodeIterator listNodes(Node parent, String nodeType, String orderBy)
416 throws RepositoryException {
417 // QueryManager queryManager = currBundle.getSession().getWorkspace()
418 // .getQueryManager();
419 // QueryObjectModelFactory factory = queryManager.getQOMFactory();
420 //
421 // final String nodeSelector = "nodes";
422 // Selector source = factory.selector(nodeType, nodeSelector);
423 //
424 // Constraint childOf = factory.childNode(nodeSelector,
425 // parent.getPath());
426 //
427 // Ordering order =
428 // factory.ascending(factory.propertyValue(nodeSelector,
429 // orderBy));
430 // Ordering[] orderings = { order };
431 //
432 // QueryObjectModel query = factory.createQuery(source, childOf,
433 // orderings, null);
434 //
435 // QueryResult result = query.execute();
436
437 String pattern = null;
438 if (SlcTypes.SLC_EXPORTED_PACKAGE.equals(nodeType))
439 pattern = "slc:Export-Package*";
440 else if (SlcTypes.SLC_JAVA_PACKAGE.equals(nodeType))
441 pattern = "slc:uses*";
442 else if (SlcTypes.SLC_IMPORTED_PACKAGE.equals(nodeType))
443 pattern = "slc:Import-Package*";
444 else if (SlcTypes.SLC_REQUIRED_BUNDLE.equals(nodeType))
445 pattern = "slc:Require-Bundle*";
446
447 return parent.getNodes(pattern);
448 }
449
450 private class TableContentProvider implements IStructuredContentProvider {
451 private String nodeType;
452 private String orderBy;
453
454 TableContentProvider(String nodeType, String orderBy) {
455 this.nodeType = nodeType;
456 this.orderBy = orderBy;
457 }
458
459 public void dispose() {
460 }
461
462 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
463 }
464
465 public Object[] getElements(Object arg0) {
466 try {
467 List<Node> nodes = JcrUtils.nodeIteratorToList(listNodes(
468 currBundle, nodeType, orderBy));
469 return nodes.toArray();
470 } catch (RepositoryException e) {
471 ErrorFeedback.show("Cannot list children Nodes", e);
472 return null;
473 }
474 }
475 }
476
477 /* HELPERS */
478 private void createField(Composite parent, String label, String jcrPropName)
479 throws RepositoryException {
480 toolkit.createLabel(parent, label, SWT.NONE);
481 Text txt = toolkit.createText(parent, "", SWT.SINGLE);
482 txt.setText(currBundle.hasProperty(jcrPropName) ? currBundle
483 .getProperty(jcrPropName).getString() : "");
484 txt.setEditable(false);
485 GridData gd = new GridData(SWT.FILL, SWT.TOP, true, false);
486 txt.setLayoutData(gd);
487 }
488
489 private Section addSection(Composite parent, String title) {
490 Section section = toolkit.createSection(parent, Section.TWISTIE);
491 section.setText(title);
492 section.setExpanded(false);
493 GridData gd = new GridData(SWT.FILL, SWT.FILL, false, false);
494 section.setLayoutData(gd);
495 Composite body = new Composite(section, SWT.FILL);
496 section.setClient(body);
497 // Layout
498 body.setLayout(new TableLayout());
499 return section;
500 }
501
502 private void createHyperlink(Composite parent, String label,
503 String jcrPropName) throws RepositoryException {
504 toolkit.createLabel(parent, label, SWT.NONE);
505 if (currBundle.hasProperty(jcrPropName)) {
506 final Hyperlink link = toolkit.createHyperlink(parent, currBundle
507 .getProperty(jcrPropName).getString(), SWT.NONE);
508 link.addHyperlinkListener(new AbstractHyperlinkListener() {
509 @Override
510 public void linkActivated(HyperlinkEvent e) {
511 try {
512 IWorkbenchBrowserSupport browserSupport = PlatformUI
513 .getWorkbench().getBrowserSupport();
514 IWebBrowser browser = browserSupport
515 .createBrowser(
516 IWorkbenchBrowserSupport.LOCATION_BAR
517 | IWorkbenchBrowserSupport.NAVIGATION_BAR,
518 "SLC Distribution browser",
519 "SLC Distribution browser",
520 "A tool tip");
521 browser.openURL(new URL(link.getText()));
522 } catch (Exception ex) {
523 throw new SlcException("error opening browser", ex); //$NON-NLS-1$
524 }
525 }
526 });
527 } else
528 toolkit.createLabel(parent, "", SWT.NONE);
529 }
530
531 /** Creates a text area with corresponding maven snippet */
532 private void createMavenSnippet(Composite parent) {
533 mavenSnippet = new Text(parent, SWT.MULTI | SWT.WRAP | SWT.BORDER);
534 GridData gd = new GridData(GridData.FILL_HORIZONTAL);
535 gd.grabExcessHorizontalSpace = true;
536 gd.heightHint = 100;
537 mavenSnippet.setLayoutData(gd);
538 mavenSnippet.setText(generateXmlSnippet());
539 }
540
541 // Helpers
542 private String generateXmlSnippet() {
543 try {
544 StringBuffer sb = new StringBuffer();
545 sb.append("<dependency>\n");
546 sb.append("\t<groupId>");
547 sb.append(currBundle.getProperty(SLC_GROUP_ID).getString());
548 sb.append("</groupId>\n");
549 sb.append("\t<artifactId>");
550 sb.append(currBundle.getProperty(SLC_ARTIFACT_ID).getString());
551 sb.append("</artifactId>\n");
552 sb.append("\t<version>");
553 sb.append(currBundle.getProperty(SLC_ARTIFACT_VERSION).getString());
554 sb.append("</version>\n");
555 sb.append("</dependency>");
556 return sb.toString();
557 } catch (RepositoryException re) {
558 throw new ArgeoException(
559 "unexpected error while generating maven snippet");
560 }
561 }
562 }