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