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
.eclipse
.jface
.viewers
.ColumnLabelProvider
;
35 import org
.eclipse
.jface
.viewers
.IStructuredContentProvider
;
36 import org
.eclipse
.jface
.viewers
.ITreeContentProvider
;
37 import org
.eclipse
.jface
.viewers
.TableLayout
;
38 import org
.eclipse
.jface
.viewers
.TableViewer
;
39 import org
.eclipse
.jface
.viewers
.TableViewerColumn
;
40 import org
.eclipse
.jface
.viewers
.TreeViewer
;
41 import org
.eclipse
.jface
.viewers
.TreeViewerColumn
;
42 import org
.eclipse
.jface
.viewers
.Viewer
;
43 import org
.eclipse
.swt
.SWT
;
44 import org
.eclipse
.swt
.graphics
.Image
;
45 import org
.eclipse
.swt
.layout
.GridData
;
46 import org
.eclipse
.swt
.layout
.GridLayout
;
47 import org
.eclipse
.swt
.widgets
.Composite
;
48 import org
.eclipse
.swt
.widgets
.Table
;
49 import org
.eclipse
.swt
.widgets
.Text
;
50 import org
.eclipse
.swt
.widgets
.Tree
;
51 import org
.eclipse
.ui
.PlatformUI
;
52 import org
.eclipse
.ui
.browser
.IWebBrowser
;
53 import org
.eclipse
.ui
.browser
.IWorkbenchBrowserSupport
;
54 import org
.eclipse
.ui
.forms
.IManagedForm
;
55 import org
.eclipse
.ui
.forms
.editor
.FormEditor
;
56 import org
.eclipse
.ui
.forms
.editor
.FormPage
;
57 import org
.eclipse
.ui
.forms
.events
.HyperlinkEvent
;
58 import org
.eclipse
.ui
.forms
.widgets
.FormToolkit
;
59 import org
.eclipse
.ui
.forms
.widgets
.Hyperlink
;
60 import org
.eclipse
.ui
.forms
.widgets
.ScrolledForm
;
61 import org
.eclipse
.ui
.forms
.widgets
.Section
;
64 * Presents main information of a given OSGI bundle
67 public class BundleDetailsPage
extends FormPage
implements SlcNames
, SlcTypes
{
68 // private final static Log log =
69 // LogFactory.getLog(ArtifactDetailsPage.class);
71 // Main business Objects
72 private Node currBundle
;
75 private Text mavenSnippet
;
76 private FormToolkit toolkit
;
78 public BundleDetailsPage(FormEditor editor
, String title
, Node currentNode
) {
79 super(editor
, "id", title
);
80 this.currBundle
= currentNode
;
83 protected void createFormContent(IManagedForm managedForm
) {
84 ScrolledForm form
= managedForm
.getForm();
85 toolkit
= managedForm
.getToolkit();
87 form
.setText(currBundle
.hasProperty(DistConstants
.SLC_BUNDLE_NAME
) ? currBundle
88 .getProperty(DistConstants
.SLC_BUNDLE_NAME
).getString()
90 Composite body
= form
.getBody();
91 GridLayout layout
= new GridLayout(1, false);
92 layout
.marginWidth
= 5;
93 layout
.verticalSpacing
= 15;
95 body
.setLayout(layout
);
96 createdetailsPart(body
);
98 createExportPackageSection(body
);
99 createImportPackageSection(body
);
100 createReqBundleSection(body
);
101 createMavenSnipet(body
);
103 } catch (RepositoryException e
) {
104 throw new SlcException("unexpected error "
105 + "while creating bundle details page");
109 /** Add useful info for the current bundle */
110 private void createdetailsPart(Composite parent
) throws RepositoryException
{
111 Composite details
= toolkit
.createComposite(parent
);
112 GridLayout layout
= new GridLayout(2, false);
113 layout
.horizontalSpacing
= 20;
114 details
.setLayout(layout
);
116 createField(details
, "Symbolic name", SlcNames
.SLC_SYMBOLIC_NAME
);
117 createField(details
, "Version", SlcNames
.SLC_BUNDLE_VERSION
);
118 createField(details
, "Group Id", SlcNames
.SLC_GROUP_ID
);
119 // Single sourcing issue: this does not works with rap
120 createHyperlink(details
, "Licence", DistConstants
.SLC_BUNDLE_LICENCE
);
121 // createField(details, "Licence", DistConstants.SLC_BUNDLE_LICENCE);
123 createField(details
, "Vendor", DistConstants
.SLC_BUNDLE_VENDOR
);
127 // Workaround to add an artificial level to the export package browser
128 private class LevelElem
{
129 private String label
;
130 private Object parent
;
132 public LevelElem(String label
, Object parent
) {
134 this.parent
= parent
;
137 public String
toString() {
141 public Object
getParent() {
146 /** Export Package Section */
147 private void createExportPackageSection(Composite parent
)
148 throws RepositoryException
{
150 // Define the TableViewer
151 Section headerSection
= addSection(parent
, "Export packages");
152 // TreeViewer viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL
153 // | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER);
154 TreeViewer viewer
= new TreeViewer(headerSection
, SWT
.MULTI
155 | SWT
.H_SCROLL
| SWT
.V_SCROLL
| SWT
.FULL_SELECTION
| SWT
.BORDER
);
157 final Tree tree
= viewer
.getTree();
158 tree
.setHeaderVisible(false);
159 tree
.setLinesVisible(true);
160 GridData gd
= new GridData(SWT
.LEFT
, SWT
.TOP
, true, true);
162 tree
.setLayoutData(gd
);
164 TreeViewerColumn col
= new TreeViewerColumn(viewer
, SWT
.FILL
);
165 col
.getColumn().setWidth(400);
167 col
.setLabelProvider(new ColumnLabelProvider() {
169 public String
getText(Object element
) {
170 if (element
instanceof Node
)
171 return JcrUtils
.get((Node
) element
, SlcNames
.SLC_NAME
);
173 return element
.toString();
177 public Image
getImage(Object element
) {
178 if (element
instanceof Node
) {
180 Node node
= (Node
) element
;
181 if (node
.isNodeType(SlcTypes
.SLC_EXPORTED_PACKAGE
))
182 return DistImages
.IMG_PACKAGE
;
183 } catch (RepositoryException e
) {
184 throw new SlcException("Error retriving "
185 + "image for the labelProvider", e
);
192 viewer
.setContentProvider(new ITreeContentProvider() {
194 public void dispose() {
197 public void inputChanged(Viewer viewer
, Object oldInput
,
201 public Object
[] getElements(Object inputElement
) {
203 List
<Node
> nodes
= JcrUtils
.nodeIteratorToList(listNodes(
204 currBundle
, SlcTypes
.SLC_EXPORTED_PACKAGE
,
206 return nodes
.toArray();
207 } catch (RepositoryException e
) {
208 throw new SlcException("Cannot list children Nodes", e
);
212 public Object
[] getChildren(Object parentElement
) {
213 // Only 2 levels for the time being
215 if (parentElement
instanceof LevelElem
) {
216 Node node
= (Node
) ((LevelElem
) parentElement
)
218 List
<Node
> nodes
= JcrUtils
219 .nodeIteratorToList(listNodes(node
,
220 SlcTypes
.SLC_JAVA_PACKAGE
,
222 return nodes
.toArray();
223 } else if (parentElement
instanceof Node
) {
224 Node pNode
= (Node
) parentElement
;
225 if (pNode
.isNodeType(SlcTypes
.SLC_EXPORTED_PACKAGE
)) {
226 if (listNodes(pNode
, SlcTypes
.SLC_JAVA_PACKAGE
,
227 SlcNames
.SLC_NAME
).getSize() > 0) {
228 Object
[] result
= { new LevelElem("uses", pNode
) };
234 } catch (RepositoryException e
) {
235 throw new SlcException("Cannot list children Nodes", e
);
239 public Object
getParent(Object element
) {
244 public boolean hasChildren(Object element
) {
246 if (element
instanceof LevelElem
)
249 Node pNode
= (Node
) element
;
250 if (pNode
.isNodeType(SlcTypes
.SLC_EXPORTED_PACKAGE
)) {
251 return listNodes(pNode
, SlcTypes
.SLC_JAVA_PACKAGE
,
252 SlcNames
.SLC_NAME
).getSize() > 0;
256 } catch (RepositoryException e
) {
257 throw new SlcException("Cannot check children Nodes", e
);
262 headerSection
.setClient(tree
);
263 viewer
.setInput("Initialize");
264 // work around a display problem : the tree table has only a few lines
265 // when the tree is not expended
266 viewer
.expandToLevel(3);
269 /** Import Package Section */
270 private void createImportPackageSection(Composite parent
)
271 throws RepositoryException
{
273 // Define the TableViewer
274 Section headerSection
= addSection(parent
, "Import packages");
275 TableViewer viewer
= new TableViewer(headerSection
, SWT
.MULTI
276 | SWT
.H_SCROLL
| SWT
.V_SCROLL
| SWT
.FULL_SELECTION
| SWT
.BORDER
);
279 TableViewerColumn col
= new TableViewerColumn(viewer
, SWT
.NONE
);
280 col
.getColumn().setWidth(350);
281 col
.getColumn().setText("Name");
282 col
.setLabelProvider(new ColumnLabelProvider() {
284 public String
getText(Object element
) {
285 return JcrUtils
.get((Node
) element
, SLC_NAME
);
288 public Image
getImage(Object element
) {
289 return DistImages
.IMG_PACKAGE
;
295 col
= new TableViewerColumn(viewer
, SWT
.NONE
);
296 col
.getColumn().setWidth(100);
297 col
.getColumn().setText("Version");
298 col
.setLabelProvider(new ColumnLabelProvider() {
300 public String
getText(Object element
) {
301 return JcrUtils
.get((Node
) element
, SLC_VERSION
);
306 col
= new TableViewerColumn(viewer
, SWT
.NONE
);
307 col
.getColumn().setWidth(100);
308 col
.getColumn().setText("Optional");
309 col
.setLabelProvider(new ColumnLabelProvider() {
311 public String
getText(Object element
) {
312 return JcrUtils
.get((Node
) element
, SLC_OPTIONAL
);
316 final Table table
= viewer
.getTable();
317 table
.setHeaderVisible(true);
318 table
.setLinesVisible(true);
319 GridData gd
= new GridData(SWT
.LEFT
, SWT
.TOP
, true, true);
321 table
.setLayoutData(gd
);
323 viewer
.setContentProvider(new TableContentProvider(
324 SLC_IMPORTED_PACKAGE
, SLC_NAME
));
325 headerSection
.setClient(viewer
.getTable());
327 viewer
.setInput("Initialize");
330 /** Required Bundle Section */
331 private void createReqBundleSection(Composite parent
)
332 throws RepositoryException
{
334 // Define the TableViewer
335 Section headerSection
= addSection(parent
, "Required bundles");
336 TableViewer viewer
= new TableViewer(headerSection
, SWT
.MULTI
337 | SWT
.H_SCROLL
| SWT
.V_SCROLL
| SWT
.FULL_SELECTION
| SWT
.BORDER
);
340 TableViewerColumn col
= new TableViewerColumn(viewer
, SWT
.NONE
);
341 col
.getColumn().setWidth(300);
342 col
.getColumn().setText("Name");
343 col
.setLabelProvider(new ColumnLabelProvider() {
345 public String
getText(Object element
) {
346 return JcrUtils
.get((Node
) element
, SLC_SYMBOLIC_NAME
);
350 public Image
getImage(Object element
) {
351 return DistImages
.IMG_BUNDLE
;
356 col
= new TableViewerColumn(viewer
, SWT
.NONE
);
357 col
.getColumn().setWidth(140);
358 col
.getColumn().setText("Version");
359 col
.setLabelProvider(new ColumnLabelProvider() {
361 public String
getText(Object element
) {
362 return JcrUtils
.get((Node
) element
, SLC_BUNDLE_VERSION
);
367 col
= new TableViewerColumn(viewer
, SWT
.NONE
);
368 col
.getColumn().setWidth(100);
369 col
.getColumn().setText("Optional");
370 col
.setLabelProvider(new ColumnLabelProvider() {
372 public String
getText(Object element
) {
373 return JcrUtils
.get((Node
) element
, SLC_OPTIONAL
);
377 final Table table
= viewer
.getTable();
378 table
.setHeaderVisible(true);
379 table
.setLinesVisible(true);
381 viewer
.setContentProvider(new TableContentProvider(SLC_REQUIRED_BUNDLE
,
383 headerSection
.setClient(viewer
.getTable());
385 viewer
.setInput("Initialize");
389 * Build repository request
391 * FIXME Workaround for remote repository, the path to bundleartifact (for
393 * .../org/argeo/slc/org.argeo.slc.client.ui.dist/1.1.12/org.argeo.slc
394 * .client.ui.dist-1.1.12/ ) is not valid for method factory.childNode(); it
395 * fails parsing the "1.1.12" part, trying to cast it as a BigDecimal
398 private NodeIterator
listNodes(Node parent
, String nodeType
, String orderBy
)
399 throws RepositoryException
{
400 // QueryManager queryManager = currBundle.getSession().getWorkspace()
401 // .getQueryManager();
402 // QueryObjectModelFactory factory = queryManager.getQOMFactory();
404 // final String nodeSelector = "nodes";
405 // Selector source = factory.selector(nodeType, nodeSelector);
407 // Constraint childOf = factory.childNode(nodeSelector,
408 // parent.getPath());
411 // factory.ascending(factory.propertyValue(nodeSelector,
413 // Ordering[] orderings = { order };
415 // QueryObjectModel query = factory.createQuery(source, childOf,
418 // QueryResult result = query.execute();
420 String pattern
= null;
421 if (SlcTypes
.SLC_EXPORTED_PACKAGE
.equals(nodeType
))
422 pattern
= "slc:Export-Package*";
423 else if (SlcTypes
.SLC_JAVA_PACKAGE
.equals(nodeType
))
424 pattern
= "slc:uses*";
425 else if (SlcTypes
.SLC_IMPORTED_PACKAGE
.equals(nodeType
))
426 pattern
= "slc:Import-Package*";
427 else if (SlcTypes
.SLC_REQUIRED_BUNDLE
.equals(nodeType
))
428 pattern
= "slc:Require-Bundle*";
430 return parent
.getNodes(pattern
);
433 private class TableContentProvider
implements IStructuredContentProvider
{
434 private String nodeType
;
435 private String orderBy
;
437 TableContentProvider(String nodeType
, String orderBy
) {
438 this.nodeType
= nodeType
;
439 this.orderBy
= orderBy
;
442 public void dispose() {
445 public void inputChanged(Viewer viewer
, Object oldInput
, Object newInput
) {
448 public Object
[] getElements(Object arg0
) {
450 List
<Node
> nodes
= JcrUtils
.nodeIteratorToList(listNodes(
451 currBundle
, nodeType
, orderBy
));
452 return nodes
.toArray();
453 } catch (RepositoryException e
) {
454 ErrorFeedback
.show("Cannot list children Nodes", e
);
461 private void createField(Composite parent
, String label
, String jcrPropName
)
462 throws RepositoryException
{
463 toolkit
.createLabel(parent
, label
, SWT
.NONE
);
464 Text txt
= toolkit
.createText(parent
, "", SWT
.SINGLE
);
465 txt
.setText(currBundle
.hasProperty(jcrPropName
) ? currBundle
466 .getProperty(jcrPropName
).getString() : "");
467 txt
.setEditable(false);
468 GridData gd
= new GridData(SWT
.FILL
, SWT
.TOP
, true, false);
469 txt
.setLayoutData(gd
);
472 private Section
addSection(Composite parent
, String title
) {
473 Section section
= toolkit
.createSection(parent
, Section
.TWISTIE
);
474 section
.setText(title
);
475 section
.setExpanded(false);
476 GridData gd
= new GridData(SWT
.FILL
, SWT
.FILL
, false, false);
477 section
.setLayoutData(gd
);
478 Composite body
= new Composite(section
, SWT
.FILL
);
479 section
.setClient(body
);
481 body
.setLayout(new TableLayout());
485 private void createHyperlink(Composite parent
, String label
,
486 String jcrPropName
) throws RepositoryException
{
487 toolkit
.createLabel(parent
, label
, SWT
.NONE
);
488 if (currBundle
.hasProperty(jcrPropName
)) {
489 final Hyperlink link
= toolkit
.createHyperlink(parent
, currBundle
490 .getProperty(jcrPropName
).getString(), SWT
.NONE
);
491 link
.addHyperlinkListener(new AbstractHyperlinkListener() {
493 public void linkActivated(HyperlinkEvent e
) {
495 IWorkbenchBrowserSupport browserSupport
= PlatformUI
496 .getWorkbench().getBrowserSupport();
497 IWebBrowser browser
= browserSupport
499 IWorkbenchBrowserSupport
.LOCATION_BAR
500 | IWorkbenchBrowserSupport
.NAVIGATION_BAR
,
501 "SLC Distribution browser",
502 "SLC Distribution browser",
504 browser
.openURL(new URL(link
.getText()));
505 } catch (Exception ex
) {
506 throw new SlcException("error opening browser", ex
); //$NON-NLS-1$
511 toolkit
.createLabel(parent
, "", SWT
.NONE
);
514 /** Creates a text area with corresponding maven snippet */
515 private void createMavenSnipet(Composite parent
) {
516 mavenSnippet
= new Text(parent
, SWT
.MULTI
| SWT
.WRAP
| SWT
.BORDER
);
517 GridData gd
= new GridData(GridData
.FILL_HORIZONTAL
);
518 gd
.grabExcessHorizontalSpace
= true;
520 mavenSnippet
.setLayoutData(gd
);
521 mavenSnippet
.setText(generateXmlSnippet());
525 private String
generateXmlSnippet() {
527 StringBuffer sb
= new StringBuffer();
528 sb
.append("<dependency>\n");
529 sb
.append("\t<groupeId>");
530 sb
.append(currBundle
.getProperty(SLC_GROUP_ID
).getString());
531 sb
.append("</groupeId>\n");
532 sb
.append("\t<artifactId>");
533 sb
.append(currBundle
.getProperty(SLC_ARTIFACT_ID
).getString());
534 sb
.append("</artifactId>\n");
535 sb
.append("\t<version>");
536 sb
.append(currBundle
.getProperty(SLC_ARTIFACT_VERSION
).getString());
537 sb
.append("</version>\n");
538 sb
.append("</dependency>");
539 return sb
.toString();
540 } catch (RepositoryException re
) {
541 throw new ArgeoException(
542 "unexpected error while generating maven snippet");