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
.commands
;
18 import javax
.jcr
.Binary
;
19 import javax
.jcr
.Credentials
;
20 import javax
.jcr
.Node
;
21 import javax
.jcr
.NodeIterator
;
22 import javax
.jcr
.Property
;
23 import javax
.jcr
.Repository
;
24 import javax
.jcr
.RepositoryException
;
25 import javax
.jcr
.Session
;
26 import javax
.jcr
.nodetype
.NodeType
;
27 import javax
.jcr
.query
.Query
;
28 import javax
.jcr
.query
.QueryResult
;
29 import javax
.jcr
.util
.TraversingItemVisitor
;
31 import org
.apache
.commons
.logging
.Log
;
32 import org
.apache
.commons
.logging
.LogFactory
;
33 import org
.argeo
.ArgeoMonitor
;
34 import org
.argeo
.eclipse
.ui
.EclipseArgeoMonitor
;
35 import org
.argeo
.jcr
.JcrUtils
;
36 import org
.argeo
.slc
.NameVersion
;
37 import org
.argeo
.slc
.SlcException
;
38 import org
.argeo
.slc
.aether
.AetherUtils
;
39 import org
.argeo
.slc
.client
.ui
.dist
.DistPlugin
;
40 import org
.argeo
.slc
.client
.ui
.dist
.views
.DistributionsView
;
41 import org
.argeo
.slc
.client
.ui
.dist
.views
.DistributionsView
.DistributionViewSelectedElement
;
42 import org
.argeo
.slc
.jcr
.SlcNames
;
43 import org
.argeo
.slc
.jcr
.SlcTypes
;
44 import org
.argeo
.slc
.repo
.ArtifactIndexer
;
45 import org
.argeo
.slc
.repo
.JarFileIndexer
;
46 import org
.argeo
.slc
.repo
.RepoUtils
;
47 import org
.argeo
.slc
.repo
.maven
.MavenConventionsUtils
;
48 import org
.argeo
.slc
.repo
.osgi
.NormalizeGroup
;
49 import org
.eclipse
.core
.commands
.AbstractHandler
;
50 import org
.eclipse
.core
.commands
.ExecutionEvent
;
51 import org
.eclipse
.core
.commands
.ExecutionException
;
52 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
53 import org
.eclipse
.core
.runtime
.IStatus
;
54 import org
.eclipse
.core
.runtime
.Status
;
55 import org
.eclipse
.core
.runtime
.jobs
.Job
;
56 import org
.eclipse
.jface
.dialogs
.Dialog
;
57 import org
.eclipse
.jface
.dialogs
.IMessageProvider
;
58 import org
.eclipse
.jface
.dialogs
.TitleAreaDialog
;
59 import org
.eclipse
.swt
.SWT
;
60 import org
.eclipse
.swt
.graphics
.Point
;
61 import org
.eclipse
.swt
.layout
.GridData
;
62 import org
.eclipse
.swt
.layout
.GridLayout
;
63 import org
.eclipse
.swt
.widgets
.Button
;
64 import org
.eclipse
.swt
.widgets
.Composite
;
65 import org
.eclipse
.swt
.widgets
.Control
;
66 import org
.eclipse
.swt
.widgets
.Label
;
67 import org
.eclipse
.swt
.widgets
.Shell
;
68 import org
.eclipse
.swt
.widgets
.Text
;
69 import org
.eclipse
.ui
.IWorkbenchPart
;
70 import org
.eclipse
.ui
.IWorkbenchWindow
;
71 import org
.eclipse
.ui
.handlers
.HandlerUtil
;
72 import org
.sonatype
.aether
.artifact
.Artifact
;
73 import org
.sonatype
.aether
.util
.artifact
.DefaultArtifact
;
75 /** Make sure than Maven and OSGi metadata are consistent */
76 public class NormalizeDistribution
extends AbstractHandler
implements SlcNames
{
77 public final static String ID
= DistPlugin
.ID
+ ".normalizeDistribution";
78 public final static String DEFAULT_LABEL
= "Normalize...";
79 public final static String DEFAULT_ICON_PATH
= "icons/normalize.gif";
81 private final static Log log
= LogFactory
82 .getLog(NormalizeDistribution
.class);
84 private Repository repository
;
85 private Credentials credentials
;
86 private String wkspName
;
87 private String artifactBasePath
= "/";
89 private ArtifactIndexer artifactIndexer
= new ArtifactIndexer();
90 private JarFileIndexer jarFileIndexer
= new JarFileIndexer();
92 public Object
execute(ExecutionEvent event
) throws ExecutionException
{
94 IWorkbenchWindow iww
= DistPlugin
.getDefault().getWorkbench()
95 .getActiveWorkbenchWindow();
96 IWorkbenchPart view
= iww
.getActivePage().getActivePart();
97 if (view
instanceof DistributionsView
) {
98 DistributionViewSelectedElement dvse
= ((DistributionsView
) view
)
99 .getSelectedElement();
100 if (dvse
!= null && (dvse
.isWorkspace
)) {
101 repository
= dvse
.repository
;
102 credentials
= dvse
.credentials
;
103 wkspName
= dvse
.wkspName
;
106 if (repository
== null || wkspName
== null)
109 NormalizationDialog dialog
= new NormalizationDialog(
110 HandlerUtil
.getActiveShell(event
));
111 if (dialog
.open() != Dialog
.OK
)
114 String version
= dialog
.getVersion();
115 Boolean overridePoms
= dialog
.getOverridePoms();
119 job
= new NormalizeJob(repository
.login(credentials
, wkspName
),
120 version
, overridePoms
);
121 } catch (RepositoryException e
) {
122 throw new SlcException("Cannot normalize " + wkspName
, e
);
129 protected void packageSourcesAsPdeSource(Node sourcesNode
) {
130 Binary origBinary
= null;
131 Binary osgiBinary
= null;
133 Session session
= sourcesNode
.getSession();
134 Artifact sourcesArtifact
= AetherUtils
.convertPathToArtifact(
135 sourcesNode
.getPath(), null);
137 // read name version from manifest
138 Artifact osgiArtifact
= new DefaultArtifact(
139 sourcesArtifact
.getGroupId(),
140 sourcesArtifact
.getArtifactId(),
141 sourcesArtifact
.getExtension(),
142 sourcesArtifact
.getVersion());
143 String osgiPath
= MavenConventionsUtils
.artifactPath(
144 artifactBasePath
, osgiArtifact
);
145 osgiBinary
= session
.getNode(osgiPath
).getNode(Node
.JCR_CONTENT
)
146 .getProperty(Property
.JCR_DATA
).getBinary();
148 NameVersion nameVersion
= RepoUtils
.readNameVersion(osgiBinary
151 // create PDe sources artifact
152 Artifact pdeSourceArtifact
= new DefaultArtifact(
153 sourcesArtifact
.getGroupId(),
154 sourcesArtifact
.getArtifactId() + ".source",
155 sourcesArtifact
.getExtension(),
156 sourcesArtifact
.getVersion());
157 String targetSourceParentPath
= MavenConventionsUtils
158 .artifactParentPath(artifactBasePath
, pdeSourceArtifact
);
159 String targetSourceFileName
= MavenConventionsUtils
160 .artifactFileName(pdeSourceArtifact
);
161 String targetSourceJarPath
= targetSourceParentPath
+ '/'
162 + targetSourceFileName
;
164 Node targetSourceParentNode
= JcrUtils
.mkfolders(session
,
165 targetSourceParentPath
);
166 origBinary
= sourcesNode
.getNode(Node
.JCR_CONTENT
)
167 .getProperty(Property
.JCR_DATA
).getBinary();
168 byte[] targetJarBytes
= RepoUtils
.packageAsPdeSource(
169 origBinary
.getStream(), nameVersion
);
170 JcrUtils
.copyBytesAsFile(targetSourceParentNode
,
171 targetSourceFileName
, targetJarBytes
);
174 Node targetSourceJarNode
= session
.getNode(targetSourceJarPath
);
175 artifactIndexer
.index(targetSourceJarNode
);
176 jarFileIndexer
.index(targetSourceJarNode
);
177 } catch (RepositoryException e
) {
178 throw new SlcException("Cannot add PDE sources for " + sourcesNode
,
181 JcrUtils
.closeQuietly(origBinary
);
182 JcrUtils
.closeQuietly(osgiBinary
);
187 public void setRepository(Repository repository
) {
188 this.repository
= repository
;
191 private class NormalizeJob
extends Job
{
192 private Session session
;
193 private String version
;
194 private Boolean overridePoms
;
196 public NormalizeJob(Session session
, String version
,
197 Boolean overridePoms
) {
198 super("Normalize Distribution");
199 this.session
= session
;
200 this.version
= version
;
201 this.overridePoms
= overridePoms
;
205 protected IStatus
run(IProgressMonitor progressMonitor
) {
208 ArgeoMonitor monitor
= new EclipseArgeoMonitor(progressMonitor
);
209 // normalize artifacts
210 Query countQuery
= session
213 .createQuery("select file from [nt:file] as file",
215 QueryResult result
= countQuery
.execute();
216 Long expectedCount
= result
.getNodes().getSize();
217 monitor
.beginTask("Normalize artifacts of "
218 + session
.getWorkspace().getName(),
219 expectedCount
.intValue());
220 NormalizingTraverser tiv
= new NormalizingTraverser(monitor
);
221 session
.getNode(artifactBasePath
).accept(tiv
);
224 Query groupQuery
= session
228 "select group from [" + SlcTypes
.SLC_GROUP_BASE
229 + "] as group", Query
.JCR_SQL2
);
230 NodeIterator groups
= groupQuery
.execute().getNodes();
231 monitor
.beginTask("Normalize groups of "
232 + session
.getWorkspace().getName(),
233 (int) groups
.getSize());
234 while (groups
.hasNext()) {
235 NormalizeGroup
.processGroupNode(groups
.nextNode(), version
,
236 overridePoms
, monitor
);
238 } catch (Exception e
) {
239 return new Status(IStatus
.ERROR
, DistPlugin
.ID
,
240 "Cannot normalize distribution "
241 + session
.getWorkspace().getName(), e
);
243 JcrUtils
.logoutQuietly(session
);
245 return Status
.OK_STATUS
;
250 private class NormalizingTraverser
extends TraversingItemVisitor
{
251 ArgeoMonitor monitor
;
253 public NormalizingTraverser(ArgeoMonitor monitor
) {
255 this.monitor
= monitor
;
259 protected void entering(Property property
, int level
)
260 throws RepositoryException
{
264 protected void entering(Node node
, int level
)
265 throws RepositoryException
{
266 if (node
.isNodeType(NodeType
.NT_FILE
)) {
267 if (node
.getName().endsWith("-sources.jar")) {
268 monitor
.subTask(node
.getName());
269 packageSourcesAsPdeSource(node
);
270 node
.getSession().save();
272 if (log
.isDebugEnabled())
273 log
.debug("Processed source artifact " + node
.getPath());
274 } else if (node
.getName().endsWith(".jar")) {
275 if (jarFileIndexer
.support(node
.getPath()))
276 if (artifactIndexer
.support(node
.getPath())) {
277 monitor
.subTask(node
.getName());
278 artifactIndexer
.index(node
);
279 jarFileIndexer
.index(node
);
280 node
.getSession().save();
282 if (log
.isDebugEnabled())
283 log
.debug("Processed artifact "
293 protected void leaving(Property property
, int level
)
294 throws RepositoryException
{
298 protected void leaving(Node node
, int level
) throws RepositoryException
{
303 public class NormalizationDialog
extends TitleAreaDialog
{
304 private Text versionT
;
305 private String version
;
306 private Button overridePomsC
;
307 private Boolean overridePoms
;
309 public NormalizationDialog(Shell parentShell
) {
313 protected Point
getInitialSize() {
314 return new Point(300, 250);
317 protected Control
createDialogArea(Composite parent
) {
318 Composite dialogarea
= (Composite
) super.createDialogArea(parent
);
319 dialogarea
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true,
321 Composite composite
= new Composite(dialogarea
, SWT
.NONE
);
322 composite
.setLayout(new GridLayout(2, false));
323 composite
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true,
325 versionT
= createLT(composite
, "Version");
326 overridePomsC
= createLC(composite
, "Override POMs");
327 setMessage("Configure normalization", IMessageProvider
.NONE
);
334 protected void okPressed() {
335 version
= versionT
.getText();
336 overridePoms
= overridePomsC
.getSelection();
340 /** Creates label and text. */
341 protected Text
createLT(Composite parent
, String label
) {
342 new Label(parent
, SWT
.NONE
).setText(label
);
343 Text text
= new Text(parent
, SWT
.SINGLE
| SWT
.LEAD
| SWT
.BORDER
345 text
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
349 /** Creates label and check. */
350 protected Button
createLC(Composite parent
, String label
) {
351 new Label(parent
, SWT
.NONE
).setText(label
);
352 Button check
= new Button(parent
, SWT
.CHECK
);
353 check
.setSelection(false);
354 check
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
358 protected void configureShell(Shell shell
) {
359 super.configureShell(shell
);
360 shell
.setText("Normalize...");
363 public String
getVersion() {
367 public Boolean
getOverridePoms() {