1 package org
.argeo
.slc
.repo
;
3 import java
.io
.ByteArrayOutputStream
;
5 import java
.io
.FileInputStream
;
6 import java
.io
.IOException
;
7 import java
.io
.InputStream
;
8 import java
.io
.OutputStream
;
9 import java
.util
.Enumeration
;
10 import java
.util
.Iterator
;
11 import java
.util
.StringTokenizer
;
12 import java
.util
.jar
.Attributes
;
13 import java
.util
.jar
.JarEntry
;
14 import java
.util
.jar
.JarFile
;
15 import java
.util
.jar
.JarInputStream
;
16 import java
.util
.jar
.JarOutputStream
;
17 import java
.util
.jar
.Manifest
;
19 import javax
.jcr
.Node
;
20 import javax
.jcr
.RepositoryException
;
22 import org
.apache
.commons
.io
.FilenameUtils
;
23 import org
.apache
.commons
.io
.IOUtils
;
24 import org
.apache
.commons
.logging
.Log
;
25 import org
.apache
.commons
.logging
.LogFactory
;
26 import org
.argeo
.slc
.BasicNameVersion
;
27 import org
.argeo
.slc
.NameVersion
;
28 import org
.argeo
.slc
.SlcException
;
29 import org
.argeo
.slc
.jcr
.SlcNames
;
30 import org
.argeo
.slc
.jcr
.SlcTypes
;
31 import org
.osgi
.framework
.Constants
;
32 import org
.sonatype
.aether
.artifact
.Artifact
;
33 import org
.sonatype
.aether
.util
.artifact
.DefaultArtifact
;
35 /** Utilities around repo */
36 public class RepoUtils
implements SlcNames
{
37 private final static Log log
= LogFactory
.getLog(RepoUtils
.class);
39 /** Packages a regular sources jar as PDE source. */
40 public static void packagesAsPdeSource(File sourceFile
,
41 NameVersion nameVersion
, OutputStream out
) throws IOException
{
42 if (isAlreadyPdeSource(sourceFile
)) {
43 FileInputStream in
= new FileInputStream(sourceFile
);
44 IOUtils
.copy(in
, out
);
45 IOUtils
.closeQuietly(in
);
47 String sourceSymbolicName
= nameVersion
.getName() + ".source";
49 Manifest sourceManifest
= null;
50 sourceManifest
= new Manifest();
51 sourceManifest
.getMainAttributes().put(
52 Attributes
.Name
.MANIFEST_VERSION
, "1.0");
53 sourceManifest
.getMainAttributes().putValue("Bundle-SymbolicName",
55 sourceManifest
.getMainAttributes().putValue("Bundle-Version",
56 nameVersion
.getVersion());
57 sourceManifest
.getMainAttributes().putValue(
58 "Eclipse-SourceBundle",
59 nameVersion
.getName() + ";version="
60 + nameVersion
.getVersion());
61 copyJar(sourceFile
, out
, sourceManifest
);
65 public static byte[] packageAsPdeSource(InputStream sourceJar
,
66 NameVersion nameVersion
) {
67 String sourceSymbolicName
= nameVersion
.getName() + ".source";
69 Manifest sourceManifest
= null;
70 sourceManifest
= new Manifest();
71 sourceManifest
.getMainAttributes().put(
72 Attributes
.Name
.MANIFEST_VERSION
, "1.0");
73 sourceManifest
.getMainAttributes().putValue("Bundle-SymbolicName",
75 sourceManifest
.getMainAttributes().putValue("Bundle-Version",
76 nameVersion
.getVersion());
77 sourceManifest
.getMainAttributes().putValue("Eclipse-SourceBundle",
78 nameVersion
.getName() + ";version=" + nameVersion
.getVersion());
80 return modifyManifest(sourceJar
, sourceManifest
);
84 * Check whether the file as already been packaged as PDE source, in order
85 * not to mess with Jar signing
87 private static boolean isAlreadyPdeSource(File sourceFile
) {
88 JarInputStream jarInputStream
= null;
91 jarInputStream
= new JarInputStream(new FileInputStream(sourceFile
));
93 Manifest manifest
= jarInputStream
.getManifest();
94 Iterator
<?
> it
= manifest
.getMainAttributes().keySet().iterator();
96 // containsKey() does not work, iterating...
98 if (it
.next().toString().equals("Eclipse-SourceBundle")) {
102 // boolean res = manifest.getMainAttributes().get(
103 // "Eclipse-SourceBundle") != null;
105 log
.info(sourceFile
+ " is already a PDE source");
107 } catch (Exception e
) {
108 // probably not a jar, skipping
109 if (log
.isDebugEnabled())
110 log
.debug("Skipping " + sourceFile
+ " because of "
114 IOUtils
.closeQuietly(jarInputStream
);
119 * Copy a jar, replacing its manifest with the provided one
124 private static void copyJar(File source
, OutputStream out
, Manifest manifest
)
126 JarFile sourceJar
= null;
127 JarOutputStream output
= null;
129 output
= manifest
!= null ?
new JarOutputStream(out
, manifest
)
130 : new JarOutputStream(out
);
131 sourceJar
= new JarFile(source
);
133 entries
: for (Enumeration
<?
> entries
= sourceJar
.entries(); entries
134 .hasMoreElements();) {
135 JarEntry entry
= (JarEntry
) entries
.nextElement();
137 && entry
.getName().equals("META-INF/MANIFEST.MF"))
140 InputStream entryStream
= sourceJar
.getInputStream(entry
);
141 JarEntry newEntry
= new JarEntry(entry
.getName());
142 // newEntry.setMethod(JarEntry.DEFLATED);
143 output
.putNextEntry(newEntry
);
144 IOUtils
.copy(entryStream
, output
);
147 IOUtils
.closeQuietly(output
);
149 if (sourceJar
!= null)
151 } catch (IOException e
) {
157 /** Copy a jar changing onlythe manifest */
158 public static void copyJar(InputStream in
, OutputStream out
,
160 JarInputStream jarIn
= null;
161 JarOutputStream jarOut
= null;
163 jarIn
= new JarInputStream(in
);
164 jarOut
= new JarOutputStream(out
, manifest
);
165 JarEntry jarEntry
= null;
166 while ((jarEntry
= jarIn
.getNextJarEntry()) != null) {
167 jarOut
.putNextEntry(jarEntry
);
168 IOUtils
.copy(jarIn
, jarOut
);
172 } catch (IOException e
) {
173 throw new SlcException("Could not copy jar with MANIFEST "
174 + manifest
.getMainAttributes(), e
);
176 IOUtils
.closeQuietly(jarIn
);
177 IOUtils
.closeQuietly(jarOut
);
181 /** Reads a jar file, modify its manifest */
182 public static byte[] modifyManifest(InputStream in
, Manifest manifest
) {
183 ByteArrayOutputStream out
= new ByteArrayOutputStream(200 * 1024);
185 copyJar(in
, out
, manifest
);
186 return out
.toByteArray();
188 IOUtils
.closeQuietly(out
);
192 /** Read the OSGi {@link NameVersion} */
193 public static NameVersion
readNameVersion(Artifact artifact
) {
194 File artifactFile
= artifact
.getFile();
195 if (artifact
.getExtension().equals("pom")) {
196 // hack to process jars which weirdly appear as POMs
197 File jarFile
= new File(artifactFile
.getParentFile(),
198 FilenameUtils
.getBaseName(artifactFile
.getPath()) + ".jar");
199 if (jarFile
.exists()) {
200 log
.warn("Use " + jarFile
+ " instead of " + artifactFile
201 + " for " + artifact
);
202 artifactFile
= jarFile
;
205 return readNameVersion(artifactFile
);
208 /** Read the OSGi {@link NameVersion} */
209 public static NameVersion
readNameVersion(File artifactFile
) {
210 JarInputStream jarInputStream
= null;
212 jarInputStream
= new JarInputStream(new FileInputStream(
214 return readNameVersion(jarInputStream
.getManifest());
215 } catch (Exception e
) {
216 // probably not a jar, skipping
217 if (log
.isDebugEnabled()) {
218 log
.debug("Skipping " + artifactFile
+ " because of " + e
);
219 // e.printStackTrace();
222 IOUtils
.closeQuietly(jarInputStream
);
227 /** Read the OSGi {@link NameVersion} */
228 public static NameVersion
readNameVersion(Manifest manifest
) {
229 BasicNameVersion nameVersion
= new BasicNameVersion();
230 nameVersion
.setName(manifest
.getMainAttributes().getValue(
231 Constants
.BUNDLE_SYMBOLICNAME
));
233 // Skip additional specs such as
235 if (nameVersion
.getName().indexOf(';') > -1) {
237 .setName(new StringTokenizer(nameVersion
.getName(), " ;")
241 nameVersion
.setVersion(manifest
.getMainAttributes().getValue(
242 Constants
.BUNDLE_VERSION
));
250 /** The artifact described by this node */
251 public static Artifact
asArtifact(Node node
) throws RepositoryException
{
252 if (node
.isNodeType(SlcTypes
.SLC_ARTIFACT_VERSION_BASE
)) {
253 // FIXME update data model to store packaging at this level
254 String extension
= "jar";
255 return new DefaultArtifact(node
.getProperty(SLC_GROUP_ID
)
257 node
.getProperty(SLC_ARTIFACT_ID
).getString(), extension
,
258 node
.getProperty(SLC_ARTIFACT_VERSION
).getString());
259 } else if (node
.isNodeType(SlcTypes
.SLC_ARTIFACT
)) {
260 return new DefaultArtifact(node
.getProperty(SLC_GROUP_ID
)
262 node
.getProperty(SLC_ARTIFACT_ID
).getString(), node
263 .getProperty(SLC_ARTIFACT_CLASSIFIER
).getString(),
264 node
.getProperty(SLC_ARTIFACT_EXTENSION
).getString(), node
265 .getProperty(SLC_ARTIFACT_VERSION
).getString());
267 throw new SlcException("Unsupported node type for " + node
);
271 private RepoUtils() {