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
.sonatype
.aether
.artifact
.Artifact
;
32 import org
.sonatype
.aether
.util
.artifact
.DefaultArtifact
;
34 /** Utilities around repo */
35 public class RepoUtils
implements SlcNames
{
36 private final static Log log
= LogFactory
.getLog(RepoUtils
.class);
38 /** Packages a regular sources jar as PDE source. */
39 public static void packagesAsPdeSource(File sourceFile
,
40 NameVersion nameVersion
, OutputStream out
) throws IOException
{
41 if (isAlreadyPdeSource(sourceFile
)) {
42 FileInputStream in
= new FileInputStream(sourceFile
);
43 IOUtils
.copy(in
, out
);
44 IOUtils
.closeQuietly(in
);
46 String sourceSymbolicName
= nameVersion
.getName() + ".source";
48 Manifest sourceManifest
= null;
49 sourceManifest
= new Manifest();
50 sourceManifest
.getMainAttributes().put(
51 Attributes
.Name
.MANIFEST_VERSION
, "1.0");
52 sourceManifest
.getMainAttributes().putValue("Bundle-SymbolicName",
54 sourceManifest
.getMainAttributes().putValue("Bundle-Version",
55 nameVersion
.getVersion());
56 sourceManifest
.getMainAttributes().putValue(
57 "Eclipse-SourceBundle",
58 nameVersion
.getName() + ";version="
59 + nameVersion
.getVersion());
60 copyJar(sourceFile
, out
, sourceManifest
);
65 * Check whether the file as already been packaged as PDE source, in order
66 * not to mess with Jar signing
68 private static boolean isAlreadyPdeSource(File sourceFile
) {
69 JarInputStream jarInputStream
= null;
72 jarInputStream
= new JarInputStream(new FileInputStream(sourceFile
));
74 Manifest manifest
= jarInputStream
.getManifest();
75 Iterator
<?
> it
= manifest
.getMainAttributes().keySet().iterator();
77 // containsKey() does not work, iterating...
79 if (it
.next().toString().equals("Eclipse-SourceBundle")) {
83 // boolean res = manifest.getMainAttributes().get(
84 // "Eclipse-SourceBundle") != null;
86 log
.info(sourceFile
+ " is already a PDE source");
88 } catch (Exception e
) {
89 // probably not a jar, skipping
90 if (log
.isDebugEnabled())
91 log
.debug("Skipping " + sourceFile
+ " because of "
95 IOUtils
.closeQuietly(jarInputStream
);
100 * Copy a jar, replacing its manifest with the provided one
105 private static void copyJar(File source
, OutputStream out
, Manifest manifest
)
107 JarFile sourceJar
= null;
108 JarOutputStream output
= null;
110 output
= manifest
!= null ?
new JarOutputStream(out
, manifest
)
111 : new JarOutputStream(out
);
112 sourceJar
= new JarFile(source
);
114 entries
: for (Enumeration
<?
> entries
= sourceJar
.entries(); entries
115 .hasMoreElements();) {
116 JarEntry entry
= (JarEntry
) entries
.nextElement();
118 && entry
.getName().equals("META-INF/MANIFEST.MF"))
121 InputStream entryStream
= sourceJar
.getInputStream(entry
);
122 JarEntry newEntry
= new JarEntry(entry
.getName());
123 // newEntry.setMethod(JarEntry.DEFLATED);
124 output
.putNextEntry(newEntry
);
125 IOUtils
.copy(entryStream
, output
);
128 IOUtils
.closeQuietly(output
);
130 if (sourceJar
!= null)
132 } catch (IOException e
) {
138 /** Copy a jar changing onlythe manifest */
139 public static void copyJar(InputStream in
, OutputStream out
,
141 JarInputStream jarIn
= null;
142 JarOutputStream jarOut
= null;
144 jarIn
= new JarInputStream(in
);
145 jarOut
= new JarOutputStream(out
, manifest
);
146 JarEntry jarEntry
= null;
147 while ((jarEntry
= jarIn
.getNextJarEntry()) != null) {
148 jarOut
.putNextEntry(jarEntry
);
149 IOUtils
.copy(jarIn
, jarOut
);
153 } catch (IOException e
) {
154 throw new SlcException("Could not copy jar with MANIFEST "
155 + manifest
.getMainAttributes(), e
);
157 IOUtils
.closeQuietly(jarIn
);
158 IOUtils
.closeQuietly(jarOut
);
162 /** Reads a jar file, modify its manifest */
163 public static byte[] modifyManifest(InputStream in
, Manifest manifest
) {
164 ByteArrayOutputStream out
= new ByteArrayOutputStream(200 * 1024);
166 copyJar(in
, out
, manifest
);
167 return out
.toByteArray();
169 IOUtils
.closeQuietly(out
);
173 /** Read the OSGi {@link NameVersion} */
174 public static NameVersion
readNameVersion(Artifact artifact
) {
175 File artifactFile
= artifact
.getFile();
176 if (artifact
.getExtension().equals("pom")) {
177 // hack to process jars which weirdly appear as POMs
178 File jarFile
= new File(artifactFile
.getParentFile(),
179 FilenameUtils
.getBaseName(artifactFile
.getPath()) + ".jar");
180 if (jarFile
.exists()) {
181 log
.warn("Use " + jarFile
+ " instead of " + artifactFile
182 + " for " + artifact
);
183 artifactFile
= jarFile
;
186 return readNameVersion(artifactFile
);
189 /** Read the OSGi {@link NameVersion} */
190 public static NameVersion
readNameVersion(File artifactFile
) {
191 JarInputStream jarInputStream
= null;
194 BasicNameVersion nameVersion
= new BasicNameVersion();
195 jarInputStream
= new JarInputStream(new FileInputStream(
197 nameVersion
.setName(jarInputStream
.getManifest()
198 .getMainAttributes().getValue("Bundle-SymbolicName"));
200 // Skip additional specs such as
202 if (nameVersion
.getName().indexOf(';') > -1) {
203 nameVersion
.setName(new StringTokenizer(nameVersion
.getName(),
207 nameVersion
.setVersion(jarInputStream
.getManifest()
208 .getMainAttributes().getValue("Bundle-Version"));
211 } catch (Exception e
) {
212 // probably not a jar, skipping
213 if (log
.isDebugEnabled()) {
214 log
.debug("Skipping " + artifactFile
+ " because of " + e
);
215 // e.printStackTrace();
218 IOUtils
.closeQuietly(jarInputStream
);
226 /** The artifact described by this node */
227 public static Artifact
asArtifact(Node node
) throws RepositoryException
{
228 if (node
.isNodeType(SlcTypes
.SLC_ARTIFACT_VERSION_BASE
)) {
229 // FIXME update data model to store packaging at this level
230 String extension
= "jar";
231 return new DefaultArtifact(node
.getProperty(SLC_GROUP_ID
)
233 node
.getProperty(SLC_ARTIFACT_ID
).getString(), extension
,
234 node
.getProperty(SLC_ARTIFACT_VERSION
).getString());
235 } else if (node
.isNodeType(SlcTypes
.SLC_ARTIFACT
)) {
236 return new DefaultArtifact(node
.getProperty(SLC_GROUP_ID
)
238 node
.getProperty(SLC_ARTIFACT_ID
).getString(), node
239 .getProperty(SLC_ARTIFACT_CLASSIFIER
).getString(),
240 node
.getProperty(SLC_ARTIFACT_EXTENSION
).getString(), node
241 .getProperty(SLC_ARTIFACT_VERSION
).getString());
243 throw new SlcException("Unsupported node type for " + node
);
247 private RepoUtils() {