1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.shared.osgi;
20
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.util.Enumeration;
25 import java.util.HashSet;
26 import java.util.Iterator;
27 import java.util.Map;
28 import java.util.Set;
29 import java.util.jar.JarFile;
30 import java.util.regex.Matcher;
31 import java.util.regex.Pattern;
32 import java.util.zip.ZipEntry;
33
34 import org.apache.maven.artifact.Artifact;
35
36 import aQute.lib.osgi.Analyzer;
37
38
39
40
41
42
43
44
45
46
47 public class DefaultMaven2OsgiConverter implements Maven2OsgiConverter
48 {
49
50 private static final String FILE_SEPARATOR = System.getProperty( "file.separator" );
51
52
53 private String getBundleSymbolicName( String groupId, String artifactId )
54 {
55 return groupId + "." + artifactId;
56 }
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 public String getBundleSymbolicName( Artifact artifact )
74 {
75 if ( ( artifact.getFile() != null ) && artifact.getFile().isFile() )
76 {
77 Analyzer analyzer = new Analyzer();
78
79 JarFile jar = null;
80 try
81 {
82 jar = new JarFile( artifact.getFile(), false );
83
84 if ( jar.getManifest() != null )
85 {
86 String symbolicNameAttribute = jar.getManifest().getMainAttributes()
87 .getValue( Analyzer.BUNDLE_SYMBOLICNAME );
88 Map bundleSymbolicNameHeader = analyzer.parseHeader( symbolicNameAttribute );
89
90 Iterator it = bundleSymbolicNameHeader.keySet().iterator();
91 if ( it.hasNext() )
92 {
93 return ( String ) it.next();
94 }
95 }
96 }
97 catch ( IOException e )
98 {
99 throw new ManifestReadingException( "Error reading manifest in jar "
100 + artifact.getFile().getAbsolutePath(), e );
101 }
102 finally
103 {
104 if ( jar != null )
105 {
106 try
107 {
108 jar.close();
109 }
110 catch ( IOException e )
111 {
112 }
113 }
114 }
115 }
116
117 int i = artifact.getGroupId().lastIndexOf( '.' );
118 if ( ( i < 0 ) && ( artifact.getFile() != null ) && artifact.getFile().isFile() )
119 {
120 String groupIdFromPackage = getGroupIdFromPackage( artifact.getFile() );
121 if ( groupIdFromPackage != null )
122 {
123 return groupIdFromPackage;
124 }
125 }
126 String lastSection = artifact.getGroupId().substring( ++i );
127 if ( artifact.getArtifactId().equals( lastSection ) )
128 {
129 return artifact.getGroupId();
130 }
131 if ( artifact.getArtifactId().startsWith( lastSection ) )
132 {
133 String artifactId = artifact.getArtifactId().substring( lastSection.length() );
134 if ( Character.isLetterOrDigit( artifactId.charAt( 0 ) ) )
135 {
136 return getBundleSymbolicName( artifact.getGroupId(), artifactId );
137 }
138 else
139 {
140 return getBundleSymbolicName( artifact.getGroupId(), artifactId.substring( 1 ) );
141 }
142 }
143 return getBundleSymbolicName( artifact.getGroupId(), artifact.getArtifactId() );
144 }
145
146
147 private String getGroupIdFromPackage( File artifactFile )
148 {
149 try
150 {
151
152 Set packageNames = new HashSet();
153 JarFile jar = new JarFile( artifactFile, false );
154 Enumeration entries = jar.entries();
155 while ( entries.hasMoreElements() )
156 {
157 ZipEntry entry = ( ZipEntry ) entries.nextElement();
158 if ( entry.getName().endsWith( ".class" ) )
159 {
160 File f = new File( entry.getName() );
161 String packageName = f.getParent();
162 if ( packageName != null )
163 {
164 packageNames.add( packageName );
165 }
166 }
167 }
168 jar.close();
169
170
171 String[] groupIdSections = null;
172 for ( Iterator it = packageNames.iterator(); it.hasNext(); )
173 {
174 String packageName = ( String ) it.next();
175
176 String[] packageNameSections = packageName.split( "\\" + FILE_SEPARATOR );
177 if ( groupIdSections == null )
178 {
179
180 groupIdSections = packageNameSections;
181 }
182 else
183
184 {
185
186
187
188 int i;
189 for ( i = 0; ( i < packageNameSections.length ) && ( i < groupIdSections.length ); i++ )
190 {
191 if ( !packageNameSections[i].equals( groupIdSections[i] ) )
192 {
193 break;
194 }
195 }
196 groupIdSections = new String[i];
197 System.arraycopy( packageNameSections, 0, groupIdSections, 0, i );
198 }
199 }
200
201 if ( ( groupIdSections == null ) || ( groupIdSections.length == 0 ) )
202 {
203 return null;
204 }
205
206
207 if ( groupIdSections.length == 1 )
208 {
209 return null;
210 }
211
212 StringBuffer sb = new StringBuffer();
213 for ( int i = 0; i < groupIdSections.length; i++ )
214 {
215 sb.append( groupIdSections[i] );
216 if ( i < groupIdSections.length - 1 )
217 {
218 sb.append( '.' );
219 }
220 }
221 return sb.toString();
222 }
223 catch ( IOException e )
224 {
225
226 throw new RuntimeException( e );
227 }
228 }
229
230
231 public String getBundleFileName( Artifact artifact )
232 {
233 return getBundleSymbolicName( artifact ) + "_" + getVersion( artifact.getVersion() ) + ".jar";
234 }
235
236
237 public String getVersion( Artifact artifact )
238 {
239 return getVersion( artifact.getVersion() );
240 }
241
242
243 public String getVersion( String version )
244 {
245 return cleanupVersion( version );
246 }
247
248
249
250
251
252
253
254
255
256 static final Pattern FUZZY_VERSION = Pattern.compile( "(\\d+)(\\.(\\d+)(\\.(\\d+))?)?([^a-zA-Z0-9](.*))?",
257 Pattern.DOTALL );
258
259
260 static public String cleanupVersion( String version )
261 {
262 StringBuffer result = new StringBuffer();
263 Matcher m = FUZZY_VERSION.matcher( version );
264 if ( m.matches() )
265 {
266 String major = m.group( 1 );
267 String minor = m.group( 3 );
268 String micro = m.group( 5 );
269 String qualifier = m.group( 7 );
270
271 if ( major != null )
272 {
273 result.append( major );
274 if ( minor != null )
275 {
276 result.append( "." );
277 result.append( minor );
278 if ( micro != null )
279 {
280 result.append( "." );
281 result.append( micro );
282 if ( qualifier != null )
283 {
284 result.append( "." );
285 cleanupModifier( result, qualifier );
286 }
287 }
288 else if ( qualifier != null )
289 {
290 result.append( ".0." );
291 cleanupModifier( result, qualifier );
292 }
293 else
294 {
295 result.append( ".0" );
296 }
297 }
298 else if ( qualifier != null )
299 {
300 result.append( ".0.0." );
301 cleanupModifier( result, qualifier );
302 }
303 else
304 {
305 result.append( ".0.0" );
306 }
307 }
308 }
309 else
310 {
311 result.append( "0.0.0." );
312 cleanupModifier( result, version );
313 }
314 return result.toString();
315 }
316
317
318 static void cleanupModifier( StringBuffer result, String modifier )
319 {
320 for ( int i = 0; i < modifier.length(); i++ )
321 {
322 char c = modifier.charAt( i );
323 if ( ( c >= '0' && c <= '9' ) || ( c >= 'a' && c <= 'z' ) || ( c >= 'A' && c <= 'Z' ) || c == '_'
324 || c == '-' )
325 result.append( c );
326 else
327 result.append( '_' );
328 }
329 }
330
331 }