1 package org
.argeo
.slc
.repo
.osgi
;
3 import java
.io
.ByteArrayInputStream
;
4 import java
.io
.ByteArrayOutputStream
;
5 import java
.util
.ArrayList
;
6 import java
.util
.HashMap
;
7 import java
.util
.Iterator
;
11 import java
.util
.TreeSet
;
12 import java
.util
.zip
.ZipEntry
;
13 import java
.util
.zip
.ZipInputStream
;
15 import javax
.jcr
.Node
;
16 import javax
.jcr
.Property
;
17 import javax
.jcr
.RepositoryException
;
18 import javax
.jcr
.Session
;
20 import org
.apache
.commons
.io
.FilenameUtils
;
21 import org
.apache
.commons
.io
.IOUtils
;
22 import org
.apache
.commons
.logging
.Log
;
23 import org
.apache
.commons
.logging
.LogFactory
;
24 import org
.argeo
.jcr
.JcrUtils
;
25 import org
.argeo
.slc
.DefaultNameVersion
;
26 import org
.argeo
.slc
.ModuleSet
;
27 import org
.argeo
.slc
.NameVersion
;
28 import org
.argeo
.slc
.SlcException
;
29 import org
.argeo
.slc
.aether
.ArtifactIdComparator
;
30 import org
.argeo
.slc
.build
.Distribution
;
31 import org
.argeo
.slc
.repo
.OsgiFactory
;
32 import org
.argeo
.slc
.repo
.RepoUtils
;
33 import org
.sonatype
.aether
.artifact
.Artifact
;
34 import org
.sonatype
.aether
.util
.artifact
.DefaultArtifact
;
35 import org
.springframework
.util
.AntPathMatcher
;
36 import org
.springframework
.util
.PathMatcher
;
39 * Download a software distribution and generates the related OSGi bundles from
40 * the jars, or import them directly if they are already OSGi bundles and don't
41 * need further modification.
43 public class ArchiveWrapper
implements Runnable
, ModuleSet
, Distribution
{
44 private final static Log log
= LogFactory
.getLog(ArchiveWrapper
.class);
46 private OsgiFactory osgiFactory
;
47 private String version
;
51 /** Jars to wrap as OSGi bundles */
52 private Map
<String
, BndWrapper
> wrappers
= new HashMap
<String
, BndWrapper
>();
54 // pattern of OSGi bundles to import
55 private PathMatcher pathMatcher
= new AntPathMatcher();
56 private Map
<String
, String
> includes
= new HashMap
<String
, String
>();
57 private List
<String
> excludes
= new ArrayList
<String
>();
59 private Boolean mavenGroupIndexes
= false;
63 for (BndWrapper wrapper
: wrappers
.values()) {
64 if (wrapper
.getVersion() == null)
65 wrapper
.setVersion(version
);
66 wrapper
.setFactory(this);
70 public void destroy() {
74 public String
getDistributionId() {
78 public Iterator
<?
extends NameVersion
> nameVersions() {
79 return wrappers
.values().iterator();
83 if (mavenGroupIndexes
&& (version
== null))
84 throw new SlcException(
85 "'mavenGroupIndexes' requires 'version' to be set");
87 Map
<String
, Set
<Artifact
>> binaries
= new HashMap
<String
, Set
<Artifact
>>();
88 Map
<String
, Set
<Artifact
>> sources
= new HashMap
<String
, Set
<Artifact
>>();
90 Session distSession
= null;
91 Session javaSession
= null;
92 ZipInputStream zin
= null;
94 javaSession
= osgiFactory
.openJavaSession();
95 distSession
= osgiFactory
.openDistSession();
97 if (log
.isDebugEnabled())
98 log
.debug("Wrapping " + uri
);
100 Node distNode
= osgiFactory
.getDist(distSession
, uri
);
101 zin
= new ZipInputStream(distNode
.getNode(Node
.JCR_CONTENT
)
102 .getProperty(Property
.JCR_DATA
).getBinary().getStream());
104 ZipEntry zentry
= null;
105 entries
: while ((zentry
= zin
.getNextEntry()) != null) {
106 String name
= zentry
.getName();
108 // sources autodetect
109 String baseName
= FilenameUtils
.getBaseName(name
);
110 if (baseName
.endsWith("-sources")) {
111 String bundle
= baseName
.substring(0, baseName
.length()
112 - "-sources".length());
113 log
.debug(name
+ "," + baseName
+ ", " + bundle
);
114 String bundlePath
= FilenameUtils
.getPath(name
) + bundle
116 if (wrappers
.containsKey(bundlePath
)) {
117 BndWrapper wrapper
= wrappers
.get(bundlePath
);
118 NameVersion bundleNv
= new DefaultNameVersion(
119 wrapper
.getName(), wrapper
.getVersion());
120 byte[] pdeSource
= RepoUtils
.packageAsPdeSource(zin
,
122 Node pdeSourceNode
= RepoUtils
.copyBytesAsArtifact(
123 javaSession
.getRootNode(),
124 new DefaultArtifact(wrapper
.getCategory(),
125 wrapper
.getName() + ".source", "jar",
126 wrapper
.getVersion()), pdeSource
);
127 osgiFactory
.indexNode(pdeSourceNode
);
129 } else if (baseName
.endsWith(".source")) {
130 // TODO Eclipse source already available
134 if (wrappers
.containsKey(name
)) {
135 BndWrapper wrapper
= (BndWrapper
) wrappers
.get(name
);
136 // we must copy since the stream is closed by BND
137 byte[] sourceJarBytes
= IOUtils
.toByteArray(zin
);
138 Artifact artifact
= wrapZipEntry(javaSession
, zentry
,
139 sourceJarBytes
, wrapper
);
140 addArtifactToIndex(binaries
, wrapper
.getGroupId(), artifact
);
142 for (String wrapperKey
: wrappers
.keySet())
143 if (pathMatcher
.match(wrapperKey
, name
)) {
144 // first matched is taken
145 BndWrapper wrapper
= (BndWrapper
) wrappers
147 // we must copy since the stream is closed by BND
148 byte[] sourceJarBytes
= IOUtils
.toByteArray(zin
);
149 Artifact artifact
= wrapZipEntry(javaSession
,
150 zentry
, sourceJarBytes
, wrapper
);
151 addArtifactToIndex(binaries
, wrapper
.getGroupId(),
155 if (log
.isTraceEnabled())
156 log
.trace(name
+ " not matched by "
160 for (String exclude
: excludes
)
161 if (pathMatcher
.match(exclude
, name
))
164 for (String include
: includes
.keySet()) {
165 if (pathMatcher
.match(include
, name
)) {
166 String groupId
= includes
.get(include
);
167 byte[] sourceJarBytes
= IOUtils
.toByteArray(zin
);
168 Artifact artifact
= importZipEntry(javaSession
,
169 zentry
, sourceJarBytes
, groupId
);
170 if (artifact
.getArtifactId().endsWith(".source"))
171 addArtifactToIndex(sources
, groupId
, artifact
);
173 addArtifactToIndex(binaries
, groupId
, artifact
);
180 if (mavenGroupIndexes
&& version
!= null) {
181 for (String groupId
: binaries
.keySet()) {
182 RepoUtils
.writeGroupIndexes(javaSession
, "/", groupId
,
183 version
, binaries
.get(groupId
),
184 sources
.containsKey(groupId
) ? sources
.get(groupId
)
189 } catch (Exception e
) {
190 throw new SlcException("Cannot wrap distribution " + uri
, e
);
192 IOUtils
.closeQuietly(zin
);
193 JcrUtils
.logoutQuietly(distSession
);
194 JcrUtils
.logoutQuietly(javaSession
);
198 protected Artifact
wrapZipEntry(Session javaSession
, ZipEntry zentry
,
199 byte[] sourceJarBytes
, BndWrapper wrapper
)
200 throws RepositoryException
{
201 ByteArrayOutputStream out
= null;
202 ByteArrayInputStream in
= null;
205 out
= new ByteArrayOutputStream((int) zentry
.getSize());
206 in
= new ByteArrayInputStream(sourceJarBytes
);
207 wrapper
.wrapJar(in
, out
);
209 Artifact artifact
= wrapper
.getArtifact();
210 newJarNode
= RepoUtils
.copyBytesAsArtifact(
211 javaSession
.getRootNode(), artifact
, out
.toByteArray());
212 osgiFactory
.indexNode(newJarNode
);
213 newJarNode
.getSession().save();
214 if (log
.isDebugEnabled())
215 log
.debug("Wrapped jar " + zentry
.getName() + " to "
216 + newJarNode
.getPath());
219 IOUtils
.closeQuietly(in
);
220 IOUtils
.closeQuietly(out
);
224 protected Artifact
importZipEntry(Session javaSession
, ZipEntry zentry
,
225 byte[] sourceJarBytes
, String groupId
) throws RepositoryException
{
226 ByteArrayInputStream in
= null;
229 in
= new ByteArrayInputStream(sourceJarBytes
);
230 NameVersion nameVersion
= RepoUtils
.readNameVersion(in
);
231 Artifact artifact
= new DefaultArtifact(groupId
,
232 nameVersion
.getName(), "jar", nameVersion
.getVersion());
233 newJarNode
= RepoUtils
.copyBytesAsArtifact(
234 javaSession
.getRootNode(), artifact
, sourceJarBytes
);
235 osgiFactory
.indexNode(newJarNode
);
236 newJarNode
.getSession().save();
237 if (log
.isDebugEnabled())
238 log
.debug("Imported OSGi bundle " + zentry
.getName() + " to "
239 + newJarNode
.getPath());
242 IOUtils
.closeQuietly(in
);
246 private void addArtifactToIndex(Map
<String
, Set
<Artifact
>> index
,
247 String groupId
, Artifact artifact
) {
248 if (!index
.containsKey(groupId
))
250 new TreeSet
<Artifact
>(new ArtifactIdComparator()));
251 index
.get(groupId
).add(artifact
);
254 public void setUri(String uri
) {
258 public void setWrappers(Map
<String
, BndWrapper
> wrappers
) {
259 this.wrappers
= wrappers
;
262 public void setOsgiFactory(OsgiFactory osgiFactory
) {
263 this.osgiFactory
= osgiFactory
;
266 public void setVersion(String version
) {
267 this.version
= version
;
270 public void setPathMatcher(PathMatcher pathMatcher
) {
271 this.pathMatcher
= pathMatcher
;
274 public void setIncludes(Map
<String
, String
> includes
) {
275 this.includes
= includes
;
278 public void setExcludes(List
<String
> excludes
) {
279 this.excludes
= excludes
;
282 public void setMavenGroupIndexes(Boolean mavenGroupIndexes
) {
283 this.mavenGroupIndexes
= mavenGroupIndexes
;