1 package org
.argeo
.slc
.client
.ui
.dist
.editors
;
6 import javax
.jcr
.RepositoryException
;
8 import org
.apache
.commons
.logging
.Log
;
9 import org
.apache
.commons
.logging
.LogFactory
;
10 import org
.argeo
.slc
.SlcException
;
11 import org
.argeo
.slc
.SlcNames
;
12 import org
.argeo
.slc
.build
.License
;
13 import org
.argeo
.slc
.client
.ui
.dist
.DistConstants
;
14 import org
.argeo
.slc
.client
.ui
.dist
.utils
.HyperlinkAdapter
;
15 import org
.argeo
.slc
.repo
.RepoConstants
;
16 import org
.argeo
.slc
.repo
.RepoUtils
;
17 import org
.eclipse
.jface
.dialogs
.IMessageProvider
;
18 import org
.eclipse
.swt
.SWT
;
19 import org
.eclipse
.swt
.layout
.GridData
;
20 import org
.eclipse
.swt
.layout
.GridLayout
;
21 import org
.eclipse
.swt
.layout
.RowLayout
;
22 import org
.eclipse
.swt
.widgets
.Composite
;
23 import org
.eclipse
.swt
.widgets
.Label
;
24 import org
.eclipse
.swt
.widgets
.Text
;
25 import org
.eclipse
.ui
.PlatformUI
;
26 import org
.eclipse
.ui
.browser
.IWebBrowser
;
27 import org
.eclipse
.ui
.browser
.IWorkbenchBrowserSupport
;
28 import org
.eclipse
.ui
.forms
.IManagedForm
;
29 import org
.eclipse
.ui
.forms
.editor
.FormEditor
;
30 import org
.eclipse
.ui
.forms
.editor
.FormPage
;
31 import org
.eclipse
.ui
.forms
.events
.HyperlinkEvent
;
32 import org
.eclipse
.ui
.forms
.widgets
.FormToolkit
;
33 import org
.eclipse
.ui
.forms
.widgets
.Hyperlink
;
34 import org
.eclipse
.ui
.forms
.widgets
.ScrolledForm
;
35 import org
.eclipse
.ui
.forms
.widgets
.Section
;
37 /** Show details for a given bundle. */
38 public class BundleDetailPage
extends FormPage
implements SlcNames
{
39 private final static Log log
= LogFactory
.getLog(BundleDetailPage
.class);
41 final static String PAGE_ID
= "BundleDetailPage";
47 private FormToolkit tk
;
49 public BundleDetailPage(FormEditor formEditor
, String title
, Node bundle
) {
50 super(formEditor
, PAGE_ID
, title
);
55 protected void createFormContent(IManagedForm managedForm
) {
56 // General settings for this page
57 ScrolledForm form
= managedForm
.getForm();
58 tk
= managedForm
.getToolkit();
59 Composite body
= form
.getBody();
61 GridLayout layout
= new GridLayout(1, false);
62 layout
.marginWidth
= 5;
63 layout
.marginRight
= 15;
64 layout
.verticalSpacing
= 0;
65 body
.setLayout(layout
);
67 form
.setText(bundle
.hasProperty(SlcNames
.SLC_SYMBOLIC_NAME
) ? bundle
68 .getProperty(SlcNames
.SLC_SYMBOLIC_NAME
).getString() : "");
69 form
.setMessage(bundle
70 .hasProperty(DistConstants
.SLC_BUNDLE_DESCRIPTION
) ? bundle
71 .getProperty(DistConstants
.SLC_BUNDLE_DESCRIPTION
)
72 .getString() : "", IMessageProvider
.NONE
);
73 } catch (RepositoryException re
) {
74 throw new SlcException("Unable to get bundle name for node "
79 Composite header
= tk
.createComposite(body
);
80 header
.setLayoutData(new GridData(SWT
.FILL
, SWT
.TOP
, true, false));
81 populateHeaderPart(header
);
83 Composite mavenSnipet
= tk
.createComposite(body
);
84 mavenSnipet
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
85 populateMavenSnippetPart(mavenSnipet
);
88 private void populateHeaderPart(Composite parent
) {
89 GridLayout layout
= new GridLayout(6, false);
90 // layout.marginWidth = layout.horizontalSpacing = layout.marginHeight =
92 layout
.horizontalSpacing
= 10;
93 parent
.setLayout(layout
);
95 // 1st Line: Category, name version
96 createLT(parent
, "Category",
97 bundle
.hasProperty(SlcNames
.SLC_GROUP_ID
) ? bundle
98 .getProperty(SlcNames
.SLC_GROUP_ID
).getString()
100 createLT(parent
, "Name",
101 bundle
.hasProperty(SlcNames
.SLC_ARTIFACT_ID
) ? bundle
102 .getProperty(SlcNames
.SLC_ARTIFACT_ID
).getString()
104 createLT(parent
, "Version",
105 bundle
.hasProperty(SlcNames
.SLC_ARTIFACT_VERSION
) ? bundle
106 .getProperty(SlcNames
.SLC_ARTIFACT_VERSION
)
109 // 3rd Line: Vendor, licence, sources
113 bundle
.hasProperty(DistConstants
.SLC_BUNDLE_VENDOR
) ? bundle
114 .getProperty(DistConstants
.SLC_BUNDLE_VENDOR
)
115 .getString() : "N/A");
117 createLicencesLink(parent
, "Licence",
118 DistConstants
.SLC_BUNDLE_LICENCE
);
119 addSourceLink(parent
);
121 // 2nd Line: The Jar itself and the Manifest
122 createJarLink(parent
);
123 createManifestLink(parent
);
126 createPomLink(parent
);
128 } catch (RepositoryException re
) {
129 throw new SlcException("Unable to get bundle name for node "
135 private void populateMavenSnippetPart(Composite parent
) {
136 GridLayout layout
= new GridLayout(1, false);
137 layout
.marginWidth
= layout
.horizontalSpacing
= layout
.horizontalSpacing
= layout
.marginHeight
= 0;
138 parent
.setLayout(layout
);
140 Section section
= tk
.createSection(parent
, Section
.TITLE_BAR
141 | Section
.DESCRIPTION
);
142 section
.setText("Maven");
143 section
.setDescription("Add the below tag to your Artifact pom dependencies");
144 section
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
145 Text snippetTxt
= createMavenSnippet(section
);
146 section
.setClient(snippetTxt
);
149 // /////////////////////
152 private Text
createLT(Composite parent
, String labelValue
, String textValue
) {
153 Label label
= tk
.createLabel(parent
, labelValue
, SWT
.RIGHT
);
154 // label.setFont(EclipseUiUtils.getBoldFont(parent));
155 label
.setLayoutData(new GridData(SWT
.RIGHT
, SWT
.CENTER
, false, false));
156 // Add a trailing space to workaround a display glitch in RAP 1.3
157 Text text
= new Text(parent
, SWT
.LEFT
);
158 text
.setText(textValue
+ " ");
159 text
.setLayoutData(new GridData(SWT
.FILL
, SWT
.CENTER
, true, false));
160 text
.setEditable(false);
164 private void createLicencesLink(Composite parent
, String label
,
165 String jcrPropName
) throws RepositoryException
{
166 tk
.createLabel(parent
, label
, SWT
.NONE
);
167 if (bundle
.hasProperty(jcrPropName
)) {
169 String licenceLinkVal
= bundle
.getProperty(jcrPropName
).getString();
171 // FIXME Hack until license generation is done cleanly
172 // Problem is with description that contains a "," like
173 // "Apache License, Version 2"
174 String
[] licenceVals
;
175 if (licenceLinkVal
.contains("description="))
176 licenceVals
= new String
[] { licenceLinkVal
};
178 // multiple license, form non-regenerated manifests
179 licenceVals
= licenceLinkVal
.split(", ");
181 Composite body
= tk
.createComposite(parent
);
182 body
.setLayout(new RowLayout(SWT
.WRAP
));
184 for (final String value
: licenceVals
) {
185 final License currLicense
= parseLicenseString(value
);
187 Hyperlink link
= tk
.createHyperlink(body
,
188 currLicense
.getName(), SWT
.NONE
);
189 link
.addHyperlinkListener(new HyperlinkAdapter() {
191 public void linkActivated(HyperlinkEvent e
) {
193 IWorkbenchBrowserSupport browserSupport
= PlatformUI
194 .getWorkbench().getBrowserSupport();
195 IWebBrowser browser
= browserSupport
197 IWorkbenchBrowserSupport
.LOCATION_BAR
198 | IWorkbenchBrowserSupport
.NAVIGATION_BAR
,
199 "SLC Distribution browser",
200 "SLC Distribution browser",
202 browser
.openURL(new URL(currLicense
.getUri()));
203 } catch (Exception ex
) {
204 throw new SlcException("error opening browser", ex
); //$NON-NLS-1$
210 tk
.createLabel(parent
, "N/A", SWT
.NONE
);
213 // TODO this must be moved to a better place once the standard has been
215 // Enable licence encoding in a single JCR Value
216 private final static String LICENSE_SEPARATOR
= ";";
217 // The human readable name of the licence
218 private final static String LICENSE_NAME
= "description";
219 // A link on the internet with some more info on this licence
220 private final static String LICENSE_LINK
= "link";
222 private License
parseLicenseString(String licenseStr
) {
223 String uri
= null, name
= null, link
= null, text
= null;
225 String
[] values
= licenseStr
.split(LICENSE_SEPARATOR
);
226 for (String value
: values
) {
227 if (value
.startsWith(LICENSE_NAME
))
228 name
= value
.substring(LICENSE_NAME
.length() + 1); // +1 for the
230 else if (value
.startsWith(LICENSE_LINK
))
231 link
= value
.substring(LICENSE_LINK
.length() + 1);
232 else if (uri
== null)
236 return new SimpleLicense(name
, uri
, link
, text
);
239 class SimpleLicense
implements License
{
240 private final String name
;
241 private final String uri
;
242 private final String link
;
243 private final String text
;
245 public SimpleLicense(String name
, String uri
, String link
, String text
) {
247 throw new SlcException(
248 "Cannot manage a licence with a null URI ");
256 public String
getUri() {
260 public String
getText() {
264 public String
getName() {
265 return name
!= null ? name
: uri
;
268 public String
getLink() {
273 private void createJarLink(Composite parent
) throws RepositoryException
{
274 Label label
= tk
.createLabel(parent
, "Jar", SWT
.RIGHT
);
275 label
.setLayoutData(new GridData(SWT
.RIGHT
, SWT
.CENTER
, false, false));
277 Composite body
= tk
.createComposite(parent
);
278 RowLayout rl
= new RowLayout(SWT
.HORIZONTAL
);
281 body
.setLayoutData(new GridData(SWT
.FILL
, SWT
.CENTER
, true, false, 3, 1));
283 Hyperlink jarLink
= tk
284 .createHyperlink(body
, bundle
.getName(), SWT
.NONE
);
285 jarLink
.addHyperlinkListener(new OpenFileLinkListener(bundle
.getPath()));
287 // Corresponding check sums
289 String name
= bundle
.getName() + ".md5";
290 if (bundle
.getParent().hasNode(name
)) {
291 Node md5
= bundle
.getParent().getNode(name
);
292 Hyperlink md5Link
= tk
.createHyperlink(body
, "MD5", SWT
.NONE
);
293 md5Link
.addHyperlinkListener(new OpenFileLinkListener(md5
.getPath()));
296 name
= bundle
.getName() + ".sha1";
297 if (bundle
.getParent().hasNode(name
)) {
298 Node sha1
= bundle
.getParent().getNode(name
);
299 Hyperlink sha1Link
= tk
.createHyperlink(body
, "SHA1", SWT
.NONE
);
300 sha1Link
.addHyperlinkListener(new OpenFileLinkListener(sha1
305 private void createPomLink(Composite parent
) throws RepositoryException
{
306 Label label
= tk
.createLabel(parent
, "Pom", SWT
.RIGHT
);
307 label
.setLayoutData(new GridData(SWT
.RIGHT
, SWT
.CENTER
, false, false));
309 String name
= bundle
.getName().substring(0,
310 bundle
.getName().length() - "jar".length())
313 if (bundle
.getParent().hasNode(name
)) {
314 Node pom
= bundle
.getParent().getNode(name
);
316 Composite body
= tk
.createComposite(parent
);
317 RowLayout rl
= new RowLayout(SWT
.HORIZONTAL
);
320 body
.setLayoutData(new GridData(SWT
.FILL
, SWT
.CENTER
, true, false,
323 Hyperlink pomLink
= tk
.createHyperlink(body
, "pom.xml", SWT
.NONE
);
324 pomLink
.addHyperlinkListener(new OpenFileLinkListener(pom
.getPath()));
326 // Corresponding check sums
327 name
= pom
.getName() + ".md5";
328 if (pom
.getParent().hasNode(name
)) {
329 Node md5
= pom
.getParent().getNode(name
);
330 Hyperlink md5Link
= tk
.createHyperlink(body
, "MD5", SWT
.NONE
);
331 md5Link
.addHyperlinkListener(new OpenFileLinkListener(md5
335 name
= pom
.getName() + ".sha1";
336 if (pom
.getParent().hasNode(name
)) {
337 Node sha1
= pom
.getParent().getNode(name
);
338 Hyperlink sha1Link
= tk
.createHyperlink(body
, "SHA1", SWT
.NONE
);
339 sha1Link
.addHyperlinkListener(new OpenFileLinkListener(sha1
343 tk
.createLabel(parent
, "N/A", SWT
.NONE
);
346 private void createManifestLink(Composite parent
)
347 throws RepositoryException
{
348 tk
.createLabel(parent
, "Manifest", SWT
.NONE
);
350 // TODO fix this when file download has been implemented for the
352 tk
.createHyperlink(parent
, "MANIFEST.MF", SWT
.NONE
);
353 // link.addHyperlinkListener(new
354 // OpenFileLinkListener(bundle.getPath()));
357 // private void createHyperlink(Composite parent, String label,
358 // String jcrPropName) throws RepositoryException {
359 // tk.createLabel(parent, label, SWT.NONE);
360 // if (bundle.hasProperty(jcrPropName)) {
361 // final Hyperlink link = tk.createHyperlink(parent, bundle
362 // .getProperty(jcrPropName).getString(), SWT.NONE);
363 // link.addHyperlinkListener(new AbstractHyperlinkListener() {
365 // public void linkActivated(HyperlinkEvent e) {
367 // IWorkbenchBrowserSupport browserSupport = PlatformUI
368 // .getWorkbench().getBrowserSupport();
369 // IWebBrowser browser = browserSupport
371 // IWorkbenchBrowserSupport.LOCATION_BAR
372 // | IWorkbenchBrowserSupport.NAVIGATION_BAR,
373 // "SLC Distribution browser",
374 // "SLC Distribution browser",
376 // browser.openURL(new URL(link.getText()));
377 // } catch (Exception ex) {
378 // throw new SlcException("error opening browser", ex); //$NON-NLS-1$
383 // tk.createLabel(parent, "N/A", SWT.NONE);
386 // helper to check if sources are available
387 private void addSourceLink(Composite parent
) {
389 String srcPath
= RepoUtils
.relatedPdeSourcePath(
390 RepoConstants
.DEFAULT_ARTIFACTS_BASE_PATH
, bundle
);
391 if (!bundle
.getSession().nodeExists(srcPath
)) {
392 createLT(parent
, "Sources", "N/A");
394 final Node sourcesNode
= bundle
.getSession().getNode(srcPath
);
396 String srcName
= null;
397 if (sourcesNode
.hasProperty(SlcNames
.SLC_SYMBOLIC_NAME
))
398 srcName
= sourcesNode
.getProperty(
399 SlcNames
.SLC_SYMBOLIC_NAME
).getString();
401 srcName
= sourcesNode
.getName();
402 Label label
= tk
.createLabel(parent
, "Sources", SWT
.RIGHT
);
403 label
.setLayoutData(new GridData(SWT
.RIGHT
, SWT
.CENTER
, false,
405 final Hyperlink link
= tk
.createHyperlink(parent
, srcName
,
407 link
.addHyperlinkListener(new OpenFileLinkListener(sourcesNode
412 // public void linkActivated(HyperlinkEvent e) {
414 // ModuleEditorInput editorInput = (ModuleEditorInput)
416 // Map<String, String> params = new HashMap<String, String>();
417 // params.put(OpenJcrFile.PARAM_REPO_NODE_PATH,
418 // editorInput.getRepoNodePath());
419 // params.put(OpenJcrFile.PARAM_REPO_URI,
420 // editorInput.getUri());
421 // params.put(OpenJcrFile.PARAM_WORKSPACE_NAME,
422 // editorInput.getWorkspaceName());
423 // params.put(OpenJcrFile.PARAM_FILE_PATH,
425 // CommandUtils.callCommand(OpenJcrFile.ID, params);
426 // } catch (Exception ex) {
427 // throw new SlcException("error opening browser", ex); //$NON-NLS-1$
433 } catch (RepositoryException e
) {
434 throw new SlcException("Unable to configure sources link for "
439 private class OpenFileLinkListener
extends HyperlinkAdapter
{
440 final private String path
;
442 public OpenFileLinkListener(String path
) {
447 public void linkActivated(HyperlinkEvent e
) {
448 log
.warn("File download must be implemented. Cannot provide access to "
452 // ModuleEditorInput editorInput = (ModuleEditorInput)
454 // Map<String, String> params = new HashMap<String, String>();
455 // params.put(OpenJcrFile.PARAM_REPO_NODE_PATH,
456 // editorInput.getRepoNodePath());
457 // params.put(OpenJcrFile.PARAM_REPO_URI, editorInput.getUri());
458 // params.put(OpenJcrFile.PARAM_WORKSPACE_NAME,
459 // editorInput.getWorkspaceName());
460 // params.put(OpenJcrFile.PARAM_FILE_PATH, path);
462 // String cmdId = (new OpenJcrFileCmdId()).getCmdId();
463 // if (log.isTraceEnabled())
464 // log.debug("Retrieved openFile Cmd ID: " + cmdId);
465 // CommandUtils.callCommand(cmdId, params);
466 // } catch (Exception ex) {
467 // throw new SlcException("error opening browser", ex); //$NON-NLS-1$
472 /** Creates a text area with corresponding maven snippet */
473 private Text
createMavenSnippet(Composite parent
) {
474 Text mavenSnippet
= new Text(parent
, SWT
.MULTI
| SWT
.WRAP
);
475 GridData gd
= new GridData(GridData
.FILL_HORIZONTAL
);
476 gd
.grabExcessHorizontalSpace
= true;
478 mavenSnippet
.setLayoutData(gd
);
479 mavenSnippet
.setText(generateXmlSnippet());
483 private String
generateXmlSnippet() {
485 StringBuffer sb
= new StringBuffer();
486 sb
.append("<dependency>\n");
487 sb
.append("\t<groupId>");
488 sb
.append(bundle
.getProperty(SLC_GROUP_ID
).getString());
489 sb
.append("</groupId>\n");
490 sb
.append("\t<artifactId>");
491 sb
.append(bundle
.getProperty(SLC_ARTIFACT_ID
).getString());
492 sb
.append("</artifactId>\n");
493 sb
.append("\t<version>");
494 sb
.append(bundle
.getProperty(SLC_ARTIFACT_VERSION
).getString());
495 sb
.append("</version>\n");
496 sb
.append("</dependency>");
497 return sb
.toString();
498 } catch (RepositoryException re
) {
499 throw new SlcException(
500 "unexpected error while generating maven snippet");