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
.HashMap
;
22 import javax
.jcr
.Node
;
23 import javax
.jcr
.RepositoryException
;
25 import org
.apache
.commons
.logging
.Log
;
26 import org
.apache
.commons
.logging
.LogFactory
;
27 import org
.argeo
.ArgeoException
;
28 import org
.argeo
.eclipse
.ui
.workbench
.CommandUtils
;
29 import org
.argeo
.slc
.SlcException
;
30 import org
.argeo
.slc
.build
.License
;
31 import org
.argeo
.slc
.client
.ui
.dist
.DistConstants
;
32 import org
.argeo
.slc
.client
.ui
.dist
.utils
.AbstractHyperlinkListener
;
33 import org
.argeo
.slc
.client
.ui
.specific
.OpenJcrFile
;
34 import org
.argeo
.slc
.client
.ui
.specific
.OpenJcrFileCmdId
;
35 import org
.argeo
.slc
.jcr
.SlcNames
;
36 import org
.argeo
.slc
.repo
.RepoConstants
;
37 import org
.argeo
.slc
.repo
.RepoUtils
;
38 import org
.eclipse
.jface
.dialogs
.IMessageProvider
;
39 import org
.eclipse
.swt
.SWT
;
40 import org
.eclipse
.swt
.layout
.GridData
;
41 import org
.eclipse
.swt
.layout
.GridLayout
;
42 import org
.eclipse
.swt
.layout
.RowLayout
;
43 import org
.eclipse
.swt
.widgets
.Composite
;
44 import org
.eclipse
.swt
.widgets
.Label
;
45 import org
.eclipse
.swt
.widgets
.Text
;
46 import org
.eclipse
.ui
.PlatformUI
;
47 import org
.eclipse
.ui
.browser
.IWebBrowser
;
48 import org
.eclipse
.ui
.browser
.IWorkbenchBrowserSupport
;
49 import org
.eclipse
.ui
.forms
.IManagedForm
;
50 import org
.eclipse
.ui
.forms
.editor
.FormEditor
;
51 import org
.eclipse
.ui
.forms
.editor
.FormPage
;
52 import org
.eclipse
.ui
.forms
.events
.HyperlinkEvent
;
53 import org
.eclipse
.ui
.forms
.widgets
.FormToolkit
;
54 import org
.eclipse
.ui
.forms
.widgets
.Hyperlink
;
55 import org
.eclipse
.ui
.forms
.widgets
.ScrolledForm
;
56 import org
.eclipse
.ui
.forms
.widgets
.Section
;
59 * Show the details for a given bundle.
61 public class BundleDetailPage
extends FormPage
implements SlcNames
{
62 private final static Log log
= LogFactory
.getLog(BundleDetailPage
.class);
64 final static String PAGE_ID
= "BundleDetailPage";
70 private FormToolkit tk
;
72 public BundleDetailPage(FormEditor formEditor
, String title
, Node bundle
) {
73 super(formEditor
, PAGE_ID
, title
);
78 protected void createFormContent(IManagedForm managedForm
) {
79 // General settings for this page
80 ScrolledForm form
= managedForm
.getForm();
81 tk
= managedForm
.getToolkit();
82 Composite body
= form
.getBody();
84 GridLayout layout
= new GridLayout(1, false);
85 layout
.marginWidth
= 5;
86 layout
.marginRight
= 15;
87 layout
.verticalSpacing
= 0;
88 body
.setLayout(layout
);
90 form
.setText(bundle
.hasProperty(SlcNames
.SLC_SYMBOLIC_NAME
) ? bundle
91 .getProperty(SlcNames
.SLC_SYMBOLIC_NAME
).getString() : "");
92 form
.setMessage(bundle
93 .hasProperty(DistConstants
.SLC_BUNDLE_DESCRIPTION
) ? bundle
94 .getProperty(DistConstants
.SLC_BUNDLE_DESCRIPTION
)
95 .getString() : "", IMessageProvider
.NONE
);
96 } catch (RepositoryException re
) {
97 throw new SlcException("Unable to get bundle name for node "
102 Composite header
= tk
.createComposite(body
);
103 header
.setLayoutData(new GridData(SWT
.FILL
, SWT
.TOP
, true, false));
104 populateHeaderPart(header
);
106 Composite mavenSnipet
= tk
.createComposite(body
);
107 mavenSnipet
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
108 populateMavenSnippetPart(mavenSnipet
);
111 private void populateHeaderPart(Composite parent
) {
112 GridLayout layout
= new GridLayout(6, false);
113 // layout.marginWidth = layout.horizontalSpacing = layout.marginHeight =
115 layout
.horizontalSpacing
= 10;
116 parent
.setLayout(layout
);
118 // 1st Line: Category, name version
119 createLT(parent
, "Category",
120 bundle
.hasProperty(SlcNames
.SLC_GROUP_ID
) ? bundle
121 .getProperty(SlcNames
.SLC_GROUP_ID
).getString()
123 createLT(parent
, "Name",
124 bundle
.hasProperty(SlcNames
.SLC_ARTIFACT_ID
) ? bundle
125 .getProperty(SlcNames
.SLC_ARTIFACT_ID
).getString()
127 createLT(parent
, "Version",
128 bundle
.hasProperty(SlcNames
.SLC_ARTIFACT_VERSION
) ? bundle
129 .getProperty(SlcNames
.SLC_ARTIFACT_VERSION
)
132 // 3rd Line: Vendor, licence, sources
136 bundle
.hasProperty(DistConstants
.SLC_BUNDLE_VENDOR
) ? bundle
137 .getProperty(DistConstants
.SLC_BUNDLE_VENDOR
)
138 .getString() : "N/A");
140 createLicencesLink(parent
, "Licence",
141 DistConstants
.SLC_BUNDLE_LICENCE
);
142 addSourceLink(parent
);
144 // 2nd Line: The Jar itself and the Manifest
145 createJarLink(parent
);
146 createManifestLink(parent
);
149 createPomLink(parent
);
151 } catch (RepositoryException re
) {
152 throw new SlcException("Unable to get bundle name for node "
158 private void populateMavenSnippetPart(Composite parent
) {
159 GridLayout layout
= new GridLayout(1, false);
160 layout
.marginWidth
= layout
.horizontalSpacing
= layout
.horizontalSpacing
= layout
.marginHeight
= 0;
161 parent
.setLayout(layout
);
163 Section section
= tk
.createSection(parent
, Section
.TITLE_BAR
164 | Section
.DESCRIPTION
);
165 section
.setText("Maven");
166 section
.setDescription("Add the below tag to your Artifact pom dependencies");
167 section
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
168 Text snippetTxt
= createMavenSnippet(section
);
169 section
.setClient(snippetTxt
);
172 // /////////////////////
175 private Text
createLT(Composite parent
, String labelValue
, String textValue
) {
176 Label label
= tk
.createLabel(parent
, labelValue
, SWT
.RIGHT
);
177 // label.setFont(EclipseUiUtils.getBoldFont(parent));
178 label
.setLayoutData(new GridData(SWT
.RIGHT
, SWT
.CENTER
, false, false));
179 // Add a trailing space to workaround a display glitch in RAP 1.3
180 Text text
= new Text(parent
, SWT
.LEFT
);
181 text
.setText(textValue
+ " ");
182 text
.setLayoutData(new GridData(SWT
.FILL
, SWT
.CENTER
, true, false));
183 text
.setEditable(false);
187 private void createLicencesLink(Composite parent
, String label
,
188 String jcrPropName
) throws RepositoryException
{
189 tk
.createLabel(parent
, label
, SWT
.NONE
);
190 if (bundle
.hasProperty(jcrPropName
)) {
192 String licenceLinkVal
= bundle
.getProperty(jcrPropName
).getString();
194 // FIXME Hack until license generation is done cleanly
195 // Problem is with description that contains a "," like "Apache License, Version 2"
196 String
[] licenceVals
;
197 if (licenceLinkVal
.contains("description="))
198 licenceVals
= new String
[] { licenceLinkVal
};
200 // multiple license, form non-regenerated manifests
201 licenceVals
= licenceLinkVal
.split(", ");
203 Composite body
= tk
.createComposite(parent
);
204 body
.setLayout(new RowLayout(SWT
.WRAP
));
206 for (final String value
: licenceVals
) {
207 final License currLicense
= parseLicenseString(value
);
209 Hyperlink link
= tk
.createHyperlink(body
,
210 currLicense
.getName(), SWT
.NONE
);
211 link
.addHyperlinkListener(new AbstractHyperlinkListener() {
213 public void linkActivated(HyperlinkEvent e
) {
215 IWorkbenchBrowserSupport browserSupport
= PlatformUI
216 .getWorkbench().getBrowserSupport();
217 IWebBrowser browser
= browserSupport
219 IWorkbenchBrowserSupport
.LOCATION_BAR
220 | IWorkbenchBrowserSupport
.NAVIGATION_BAR
,
221 "SLC Distribution browser",
222 "SLC Distribution browser",
224 browser
.openURL(new URL(currLicense
.getUri()));
225 } catch (Exception ex
) {
226 throw new SlcException("error opening browser", ex
); //$NON-NLS-1$
232 tk
.createLabel(parent
, "N/A", SWT
.NONE
);
235 // TODO this must be moved to a better place once the standard has been
237 // Enable licence encoding in a single JCR Value
238 private final static String LICENSE_SEPARATOR
= ";";
239 // The human readable name of the licence
240 private final static String LICENSE_NAME
= "description";
241 // A link on the internet with some more info on this licence
242 private final static String LICENSE_LINK
= "link";
244 private License
parseLicenseString(String licenseStr
) {
245 String uri
= null, name
= null, link
= null, text
= null;
247 String
[] values
= licenseStr
.split(LICENSE_SEPARATOR
);
248 for (String value
: values
) {
249 if (value
.startsWith(LICENSE_NAME
))
250 name
= value
.substring(LICENSE_NAME
.length() + 1); // +1 for the
252 else if (value
.startsWith(LICENSE_LINK
))
253 link
= value
.substring(LICENSE_LINK
.length() + 1);
254 else if (uri
== null)
258 return new SimpleLicense(name
, uri
, link
, text
);
261 class SimpleLicense
implements License
{
262 private final String name
;
263 private final String uri
;
264 private final String link
;
265 private final String text
;
267 public SimpleLicense(String name
, String uri
, String link
, String text
) {
269 throw new SlcException(
270 "Cannot manage a licence with a null URI ");
278 public String
getUri() {
282 public String
getText() {
286 public String
getName() {
287 return name
!= null ? name
: uri
;
290 public String
getLink() {
295 private void createJarLink(Composite parent
) throws RepositoryException
{
296 Label label
= tk
.createLabel(parent
, "Jar", SWT
.RIGHT
);
297 label
.setLayoutData(new GridData(SWT
.RIGHT
, SWT
.CENTER
, false, false));
299 Composite body
= tk
.createComposite(parent
);
300 RowLayout rl
= new RowLayout(SWT
.HORIZONTAL
);
303 body
.setLayoutData(new GridData(SWT
.FILL
, SWT
.CENTER
, true, false, 3, 1));
305 Hyperlink jarLink
= tk
306 .createHyperlink(body
, bundle
.getName(), SWT
.NONE
);
307 jarLink
.addHyperlinkListener(new OpenFileLinkListener(bundle
.getPath()));
309 // Corresponding check sums
311 String name
= bundle
.getName() + ".md5";
312 if (bundle
.getParent().hasNode(name
)) {
313 Node md5
= bundle
.getParent().getNode(name
);
314 Hyperlink md5Link
= tk
.createHyperlink(body
, "MD5", SWT
.NONE
);
315 md5Link
.addHyperlinkListener(new OpenFileLinkListener(md5
.getPath()));
318 name
= bundle
.getName() + ".sha1";
319 if (bundle
.getParent().hasNode(name
)) {
320 Node sha1
= bundle
.getParent().getNode(name
);
321 Hyperlink sha1Link
= tk
.createHyperlink(body
, "SHA1", SWT
.NONE
);
322 sha1Link
.addHyperlinkListener(new OpenFileLinkListener(sha1
327 private void createPomLink(Composite parent
) throws RepositoryException
{
328 Label label
= tk
.createLabel(parent
, "Pom", SWT
.RIGHT
);
329 label
.setLayoutData(new GridData(SWT
.RIGHT
, SWT
.CENTER
, false, false));
331 String name
= bundle
.getName().substring(0,
332 bundle
.getName().length() - "jar".length())
335 if (bundle
.getParent().hasNode(name
)) {
336 Node pom
= bundle
.getParent().getNode(name
);
338 Composite body
= tk
.createComposite(parent
);
339 RowLayout rl
= new RowLayout(SWT
.HORIZONTAL
);
342 body
.setLayoutData(new GridData(SWT
.FILL
, SWT
.CENTER
, true, false,
345 Hyperlink pomLink
= tk
.createHyperlink(body
, "pom.xml", SWT
.NONE
);
346 pomLink
.addHyperlinkListener(new OpenFileLinkListener(pom
.getPath()));
348 // Corresponding check sums
349 name
= pom
.getName() + ".md5";
350 if (pom
.getParent().hasNode(name
)) {
351 Node md5
= pom
.getParent().getNode(name
);
352 Hyperlink md5Link
= tk
.createHyperlink(body
, "MD5", SWT
.NONE
);
353 md5Link
.addHyperlinkListener(new OpenFileLinkListener(md5
357 name
= pom
.getName() + ".sha1";
358 if (pom
.getParent().hasNode(name
)) {
359 Node sha1
= pom
.getParent().getNode(name
);
360 Hyperlink sha1Link
= tk
.createHyperlink(body
, "SHA1", SWT
.NONE
);
361 sha1Link
.addHyperlinkListener(new OpenFileLinkListener(sha1
365 tk
.createLabel(parent
, "N/A", SWT
.NONE
);
368 private void createManifestLink(Composite parent
)
369 throws RepositoryException
{
370 tk
.createLabel(parent
, "Manifest", SWT
.NONE
);
372 // TODO fix this when file download has been implemented for the
374 tk
.createHyperlink(parent
, "MANIFEST.MF", SWT
.NONE
);
375 // link.addHyperlinkListener(new
376 // OpenFileLinkListener(bundle.getPath()));
379 // private void createHyperlink(Composite parent, String label,
380 // String jcrPropName) throws RepositoryException {
381 // tk.createLabel(parent, label, SWT.NONE);
382 // if (bundle.hasProperty(jcrPropName)) {
383 // final Hyperlink link = tk.createHyperlink(parent, bundle
384 // .getProperty(jcrPropName).getString(), SWT.NONE);
385 // link.addHyperlinkListener(new AbstractHyperlinkListener() {
387 // public void linkActivated(HyperlinkEvent e) {
389 // IWorkbenchBrowserSupport browserSupport = PlatformUI
390 // .getWorkbench().getBrowserSupport();
391 // IWebBrowser browser = browserSupport
393 // IWorkbenchBrowserSupport.LOCATION_BAR
394 // | IWorkbenchBrowserSupport.NAVIGATION_BAR,
395 // "SLC Distribution browser",
396 // "SLC Distribution browser",
398 // browser.openURL(new URL(link.getText()));
399 // } catch (Exception ex) {
400 // throw new SlcException("error opening browser", ex); //$NON-NLS-1$
405 // tk.createLabel(parent, "N/A", SWT.NONE);
408 // helper to check if sources are available
409 private void addSourceLink(Composite parent
) {
411 String srcPath
= RepoUtils
.relatedPdeSourcePath(
412 RepoConstants
.DEFAULT_ARTIFACTS_BASE_PATH
, bundle
);
413 if (!bundle
.getSession().nodeExists(srcPath
)) {
414 createLT(parent
, "Sources", "N/A");
416 final Node sourcesNode
= bundle
.getSession().getNode(srcPath
);
418 String srcName
= null;
419 if (sourcesNode
.hasProperty(SlcNames
.SLC_SYMBOLIC_NAME
))
420 srcName
= sourcesNode
.getProperty(
421 SlcNames
.SLC_SYMBOLIC_NAME
).getString();
423 srcName
= sourcesNode
.getName();
424 Label label
= tk
.createLabel(parent
, "Sources", SWT
.RIGHT
);
425 label
.setLayoutData(new GridData(SWT
.RIGHT
, SWT
.CENTER
, false,
427 final Hyperlink link
= tk
.createHyperlink(parent
, srcName
,
429 link
.addHyperlinkListener(new OpenFileLinkListener(sourcesNode
434 // public void linkActivated(HyperlinkEvent e) {
436 // ModuleEditorInput editorInput = (ModuleEditorInput)
438 // Map<String, String> params = new HashMap<String, String>();
439 // params.put(OpenJcrFile.PARAM_REPO_NODE_PATH,
440 // editorInput.getRepoNodePath());
441 // params.put(OpenJcrFile.PARAM_REPO_URI,
442 // editorInput.getUri());
443 // params.put(OpenJcrFile.PARAM_WORKSPACE_NAME,
444 // editorInput.getWorkspaceName());
445 // params.put(OpenJcrFile.PARAM_FILE_PATH,
447 // CommandUtils.callCommand(OpenJcrFile.ID, params);
448 // } catch (Exception ex) {
449 // throw new SlcException("error opening browser", ex); //$NON-NLS-1$
455 } catch (RepositoryException e
) {
456 throw new SlcException("Unable to configure sources link for "
461 private class OpenFileLinkListener
extends AbstractHyperlinkListener
{
462 final private String path
;
464 public OpenFileLinkListener(String path
) {
469 public void linkActivated(HyperlinkEvent e
) {
471 ModuleEditorInput editorInput
= (ModuleEditorInput
) getEditorInput();
472 Map
<String
, String
> params
= new HashMap
<String
, String
>();
473 params
.put(OpenJcrFile
.PARAM_REPO_NODE_PATH
,
474 editorInput
.getRepoNodePath());
475 params
.put(OpenJcrFile
.PARAM_REPO_URI
, editorInput
.getUri());
476 params
.put(OpenJcrFile
.PARAM_WORKSPACE_NAME
,
477 editorInput
.getWorkspaceName());
478 params
.put(OpenJcrFile
.PARAM_FILE_PATH
, path
);
480 String cmdId
= (new OpenJcrFileCmdId()).getCmdId();
481 if (log
.isTraceEnabled())
482 log
.debug("Retrieved openFile Cmd ID: " + cmdId
);
483 CommandUtils
.callCommand(cmdId
, params
);
484 } catch (Exception ex
) {
485 throw new SlcException("error opening browser", ex
); //$NON-NLS-1$
490 /** Creates a text area with corresponding maven snippet */
491 private Text
createMavenSnippet(Composite parent
) {
492 Text mavenSnippet
= new Text(parent
, SWT
.MULTI
| SWT
.WRAP
);
493 GridData gd
= new GridData(GridData
.FILL_HORIZONTAL
);
494 gd
.grabExcessHorizontalSpace
= true;
496 mavenSnippet
.setLayoutData(gd
);
497 mavenSnippet
.setText(generateXmlSnippet());
501 private String
generateXmlSnippet() {
503 StringBuffer sb
= new StringBuffer();
504 sb
.append("<dependency>\n");
505 sb
.append("\t<groupId>");
506 sb
.append(bundle
.getProperty(SLC_GROUP_ID
).getString());
507 sb
.append("</groupId>\n");
508 sb
.append("\t<artifactId>");
509 sb
.append(bundle
.getProperty(SLC_ARTIFACT_ID
).getString());
510 sb
.append("</artifactId>\n");
511 sb
.append("\t<version>");
512 sb
.append(bundle
.getProperty(SLC_ARTIFACT_VERSION
).getString());
513 sb
.append("</version>\n");
514 sb
.append("</dependency>");
515 return sb
.toString();
516 } catch (RepositoryException re
) {
517 throw new ArgeoException(
518 "unexpected error while generating maven snippet");