2 * Copyright (C) 2007-2012 Argeo GmbH
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org
.argeo
.slc
.client
.ui
.dist
.editors
;
19 import java
.util
.List
;
21 import javax
.jcr
.Node
;
22 import javax
.jcr
.NodeIterator
;
23 import javax
.jcr
.RepositoryException
;
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
.dialogs
.IMessageProvider
;
37 import org
.eclipse
.jface
.viewers
.ColumnLabelProvider
;
38 import org
.eclipse
.jface
.viewers
.IStructuredContentProvider
;
39 import org
.eclipse
.jface
.viewers
.ITreeContentProvider
;
40 import org
.eclipse
.jface
.viewers
.TableLayout
;
41 import org
.eclipse
.jface
.viewers
.TableViewer
;
42 import org
.eclipse
.jface
.viewers
.TableViewerColumn
;
43 import org
.eclipse
.jface
.viewers
.TreeViewer
;
44 import org
.eclipse
.jface
.viewers
.TreeViewerColumn
;
45 import org
.eclipse
.jface
.viewers
.Viewer
;
46 import org
.eclipse
.swt
.SWT
;
47 import org
.eclipse
.swt
.graphics
.Image
;
48 import org
.eclipse
.swt
.layout
.GridData
;
49 import org
.eclipse
.swt
.layout
.GridLayout
;
50 import org
.eclipse
.swt
.widgets
.Button
;
51 import org
.eclipse
.swt
.widgets
.Composite
;
52 import org
.eclipse
.swt
.widgets
.Table
;
53 import org
.eclipse
.swt
.widgets
.Text
;
54 import org
.eclipse
.swt
.widgets
.Tree
;
55 import org
.eclipse
.ui
.PlatformUI
;
56 import org
.eclipse
.ui
.browser
.IWebBrowser
;
57 import org
.eclipse
.ui
.browser
.IWorkbenchBrowserSupport
;
58 import org
.eclipse
.ui
.forms
.IManagedForm
;
59 import org
.eclipse
.ui
.forms
.editor
.FormEditor
;
60 import org
.eclipse
.ui
.forms
.editor
.FormPage
;
61 import org
.eclipse
.ui
.forms
.events
.HyperlinkEvent
;
62 import org
.eclipse
.ui
.forms
.widgets
.FormToolkit
;
63 import org
.eclipse
.ui
.forms
.widgets
.Hyperlink
;
64 import org
.eclipse
.ui
.forms
.widgets
.ScrolledForm
;
65 import org
.eclipse
.ui
.forms
.widgets
.Section
;
68 * Present main information of a given OSGI bundle
70 public class BundleDetailsPage
extends FormPage
implements SlcNames
, SlcTypes
{
71 // private final static Log log =
72 // LogFactory.getLog(ArtifactDetailsPage.class);
74 // Main business Objects
75 private Node currBundle
;
78 private Text mavenSnippet
;
79 private FormToolkit toolkit
;
81 public BundleDetailsPage(FormEditor editor
, String title
, Node currentNode
) {
82 super(editor
, "id", title
);
83 this.currBundle
= currentNode
;
86 protected void createFormContent(IManagedForm managedForm
) {
87 ScrolledForm form
= managedForm
.getForm();
88 toolkit
= managedForm
.getToolkit();
90 form
.setText(currBundle
.hasProperty(DistConstants
.SLC_BUNDLE_NAME
) ? currBundle
91 .getProperty(DistConstants
.SLC_BUNDLE_NAME
).getString()
93 form
.setMessage(" test", IMessageProvider
.NONE
);
94 Composite body
= form
.getBody();
95 GridLayout layout
= new GridLayout(1, false);
96 layout
.marginWidth
= 5;
97 layout
.verticalSpacing
= 15;
99 body
.setLayout(layout
);
100 createdetailsPart(body
);
102 createExportPackageSection(body
);
103 createImportPackageSection(body
);
104 createReqBundleSection(body
);
105 createMavenSnippet(body
);
107 } catch (RepositoryException e
) {
108 throw new SlcException("unexpected error "
109 + "while creating bundle details page");
113 /** Displays useful info for the current bundle */
114 private void createdetailsPart(Composite parent
) throws RepositoryException
{
115 Composite details
= toolkit
.createComposite(parent
);
116 GridLayout layout
= new GridLayout(2, false);
117 layout
.horizontalSpacing
= 20;
118 details
.setLayout(layout
);
120 createField(details
, "Symbolic name", SlcNames
.SLC_SYMBOLIC_NAME
);
121 createField(details
, "Version", SlcNames
.SLC_BUNDLE_VERSION
);
122 createField(details
, "Group Id", SlcNames
.SLC_GROUP_ID
);
123 createHyperlink(details
, "Licence", DistConstants
.SLC_BUNDLE_LICENCE
);
124 createField(details
, "Vendor", DistConstants
.SLC_BUNDLE_VENDOR
);
125 addSourceAvailableLabel(details
);
128 // helper to check if sources are available
129 private void addSourceAvailableLabel(Composite parent
) {
130 Button srcChk
= toolkit
.createButton(parent
, "Sources available",
132 srcChk
.setLayoutData(new GridData(SWT
.FILL
, SWT
.TOP
, true, false, 2, 1));
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
);
141 srcChk
.setEnabled(false);
144 // Workaround to add an artificial level to the export package browser
145 private class LevelElem
{
146 private String label
;
147 private Object parent
;
149 public LevelElem(String label
, Object parent
) {
151 this.parent
= parent
;
154 public String
toString() {
158 public Object
getParent() {
163 /** Export Package Section */
164 private void createExportPackageSection(Composite parent
)
165 throws RepositoryException
{
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
);
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);
179 tree
.setLayoutData(gd
);
181 TreeViewerColumn col
= new TreeViewerColumn(viewer
, SWT
.FILL
);
182 col
.getColumn().setWidth(400);
184 col
.setLabelProvider(new ColumnLabelProvider() {
186 public String
getText(Object element
) {
187 if (element
instanceof Node
)
188 return JcrUtils
.get((Node
) element
, SlcNames
.SLC_NAME
);
190 return element
.toString();
194 public Image
getImage(Object element
) {
195 if (element
instanceof Node
) {
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
);
209 viewer
.setContentProvider(new ITreeContentProvider() {
211 public void dispose() {
214 public void inputChanged(Viewer viewer
, Object oldInput
,
218 public Object
[] getElements(Object inputElement
) {
220 List
<Node
> nodes
= JcrUtils
.nodeIteratorToList(listNodes(
221 currBundle
, SlcTypes
.SLC_EXPORTED_PACKAGE
,
223 return nodes
.toArray();
224 } catch (RepositoryException e
) {
225 throw new SlcException("Cannot list children Nodes", e
);
229 public Object
[] getChildren(Object parentElement
) {
230 // Only 2 levels for the time being
232 if (parentElement
instanceof LevelElem
) {
233 Node node
= (Node
) ((LevelElem
) parentElement
)
235 List
<Node
> nodes
= JcrUtils
236 .nodeIteratorToList(listNodes(node
,
237 SlcTypes
.SLC_JAVA_PACKAGE
,
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
) };
251 } catch (RepositoryException e
) {
252 throw new SlcException("Cannot list children Nodes", e
);
256 public Object
getParent(Object element
) {
261 public boolean hasChildren(Object element
) {
263 if (element
instanceof LevelElem
)
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;
273 } catch (RepositoryException e
) {
274 throw new SlcException("Cannot check children Nodes", e
);
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);
286 /** Import Package Section */
287 private void createImportPackageSection(Composite parent
)
288 throws RepositoryException
{
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
);
296 TableViewerColumn col
= new TableViewerColumn(viewer
, SWT
.NONE
);
297 col
.getColumn().setWidth(350);
298 col
.getColumn().setText("Name");
299 col
.setLabelProvider(new ColumnLabelProvider() {
301 public String
getText(Object element
) {
302 return JcrUtils
.get((Node
) element
, SLC_NAME
);
305 public Image
getImage(Object element
) {
306 return DistImages
.IMG_PACKAGE
;
312 col
= new TableViewerColumn(viewer
, SWT
.NONE
);
313 col
.getColumn().setWidth(100);
314 col
.getColumn().setText("Version");
315 col
.setLabelProvider(new ColumnLabelProvider() {
317 public String
getText(Object element
) {
318 return JcrUtils
.get((Node
) element
, SLC_VERSION
);
323 col
= new TableViewerColumn(viewer
, SWT
.NONE
);
324 col
.getColumn().setWidth(100);
325 col
.getColumn().setText("Optional");
326 col
.setLabelProvider(new ColumnLabelProvider() {
328 public String
getText(Object element
) {
329 return JcrUtils
.get((Node
) element
, SLC_OPTIONAL
);
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);
338 table
.setLayoutData(gd
);
340 viewer
.setContentProvider(new TableContentProvider(
341 SLC_IMPORTED_PACKAGE
, SLC_NAME
));
342 headerSection
.setClient(viewer
.getTable());
344 viewer
.setInput("Initialize");
347 /** Required Bundle Section */
348 private void createReqBundleSection(Composite parent
)
349 throws RepositoryException
{
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
);
357 TableViewerColumn col
= new TableViewerColumn(viewer
, SWT
.NONE
);
358 col
.getColumn().setWidth(300);
359 col
.getColumn().setText("Name");
360 col
.setLabelProvider(new ColumnLabelProvider() {
362 public String
getText(Object element
) {
363 return JcrUtils
.get((Node
) element
, SLC_SYMBOLIC_NAME
);
367 public Image
getImage(Object element
) {
368 return DistImages
.IMG_BUNDLE
;
373 col
= new TableViewerColumn(viewer
, SWT
.NONE
);
374 col
.getColumn().setWidth(140);
375 col
.getColumn().setText("Version");
376 col
.setLabelProvider(new ColumnLabelProvider() {
378 public String
getText(Object element
) {
379 return JcrUtils
.get((Node
) element
, SLC_BUNDLE_VERSION
);
384 col
= new TableViewerColumn(viewer
, SWT
.NONE
);
385 col
.getColumn().setWidth(100);
386 col
.getColumn().setText("Optional");
387 col
.setLabelProvider(new ColumnLabelProvider() {
389 public String
getText(Object element
) {
390 return JcrUtils
.get((Node
) element
, SLC_OPTIONAL
);
394 final Table table
= viewer
.getTable();
395 table
.setHeaderVisible(true);
396 table
.setLinesVisible(true);
398 viewer
.setContentProvider(new TableContentProvider(SLC_REQUIRED_BUNDLE
,
400 headerSection
.setClient(viewer
.getTable());
402 viewer
.setInput("Initialize");
406 * Build repository request
408 * FIXME Workaround for remote repository, the path to bundleartifact (for
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
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();
421 // final String nodeSelector = "nodes";
422 // Selector source = factory.selector(nodeType, nodeSelector);
424 // Constraint childOf = factory.childNode(nodeSelector,
425 // parent.getPath());
428 // factory.ascending(factory.propertyValue(nodeSelector,
430 // Ordering[] orderings = { order };
432 // QueryObjectModel query = factory.createQuery(source, childOf,
435 // QueryResult result = query.execute();
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*";
447 return parent
.getNodes(pattern
);
450 private class TableContentProvider
implements IStructuredContentProvider
{
451 private String nodeType
;
452 private String orderBy
;
454 TableContentProvider(String nodeType
, String orderBy
) {
455 this.nodeType
= nodeType
;
456 this.orderBy
= orderBy
;
459 public void dispose() {
462 public void inputChanged(Viewer viewer
, Object oldInput
, Object newInput
) {
465 public Object
[] getElements(Object arg0
) {
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
);
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
);
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
);
498 body
.setLayout(new TableLayout());
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() {
510 public void linkActivated(HyperlinkEvent e
) {
512 IWorkbenchBrowserSupport browserSupport
= PlatformUI
513 .getWorkbench().getBrowserSupport();
514 IWebBrowser browser
= browserSupport
516 IWorkbenchBrowserSupport
.LOCATION_BAR
517 | IWorkbenchBrowserSupport
.NAVIGATION_BAR
,
518 "SLC Distribution browser",
519 "SLC Distribution browser",
521 browser
.openURL(new URL(link
.getText()));
522 } catch (Exception ex
) {
523 throw new SlcException("error opening browser", ex
); //$NON-NLS-1$
528 toolkit
.createLabel(parent
, "", SWT
.NONE
);
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;
537 mavenSnippet
.setLayoutData(gd
);
538 mavenSnippet
.setText(generateXmlSnippet());
542 private String
generateXmlSnippet() {
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");