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