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