View Javadoc

1   package org.apache.maven.index.creator;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.lucene.document.Document;
23  import org.apache.lucene.document.Field;
24  import org.apache.maven.index.ArtifactContext;
25  import org.apache.maven.index.ArtifactInfo;
26  import org.apache.maven.index.IndexerField;
27  import org.apache.maven.index.IndexerFieldVersion;
28  import org.apache.maven.index.OSGI;
29  import org.apache.maven.index.context.IndexCreator;
30  import org.apache.maven.index.util.zip.ZipFacade;
31  import org.apache.maven.index.util.zip.ZipHandle;
32  import org.codehaus.plexus.component.annotations.Component;
33  import org.codehaus.plexus.util.StringUtils;
34  
35  import java.io.File;
36  import java.io.IOException;
37  import java.util.Arrays;
38  import java.util.Collection;
39  import java.util.List;
40  import java.util.jar.Attributes;
41  import java.util.jar.Manifest;
42  
43  /**
44   * This indexCreator will index some OSGI metadatas.
45   * <br/>
46   * All jars are indexed and not only the ones with packaging bundle.
47   * <br/>
48   * <p>
49   * OSGI metadatas indexed :
50   * <ul>
51   * <li>Bundle-SymbolicName</li>
52   * <li>Bundle-Version</li>
53   * <li>Export-Package</li>
54   * <li>Export-Service</li>
55   * </ul>
56   * </p>
57   *
58   * @author Olivier Lamy
59   * @since 4.1.2
60   */
61  @Component( role = IndexCreator.class, hint = OsgiArtifactIndexCreator.ID )
62  public class OsgiArtifactIndexCreator
63      extends AbstractIndexCreator
64  {
65      public static final String ID = "osgi-metadatas";
66  
67      private static final String BSN = "Bundle-SymbolicName";
68  
69      public static final IndexerField FLD_BUNDLE_SYMBOLIC_NAME =
70          new IndexerField( OSGI.SYMBOLIC_NAME, IndexerFieldVersion.V4, BSN, "Bundle-SymbolicName (indexed, stored)",
71                            Field.Store.YES, Field.Index.ANALYZED );
72  
73  
74      private static final String BV = "Bundle-Version";
75  
76      public static final IndexerField FLD_BUNDLE_VERSION =
77          new IndexerField( OSGI.VERSION, IndexerFieldVersion.V4, BV, "Bundle-Version (indexed, stored)", Field.Store.YES,
78                            Field.Index.ANALYZED );
79  
80  
81      private static final String BEP = "Export-Package";
82  
83      public static final IndexerField FLD_BUNDLE_EXPORT_PACKAGE =
84          new IndexerField( OSGI.EXPORT_PACKAGE, IndexerFieldVersion.V4, BEP, "Export-Package (indexed, stored)",
85                            Field.Store.YES, Field.Index.ANALYZED );
86  
87      private static final String BES = "Export-Service";
88  
89      public static final IndexerField FLD_BUNDLE_EXPORT_SERVIVE =
90          new IndexerField( OSGI.EXPORT_SERVICE, IndexerFieldVersion.V4, BES, "Export-Service (indexed, stored)",
91                            Field.Store.YES, Field.Index.ANALYZED );
92  
93  
94      private static final String BD = "Bundle-Description";
95  
96      public static final IndexerField FLD_BUNDLE_DESCRIPTION =
97          new IndexerField( OSGI.DESCRIPTION, IndexerFieldVersion.V4, BD, "Bundle-Description (indexed, stored)",
98                            Field.Store.YES, Field.Index.ANALYZED );
99  
100     private static final String BN = "Bundle-Name";
101 
102     public static final IndexerField FLD_BUNDLE_NAME =
103         new IndexerField( OSGI.NAME, IndexerFieldVersion.V4, BN, "Bundle-Name (indexed, stored)", Field.Store.YES,
104                           Field.Index.ANALYZED );
105 
106     private static final String BL = "Bundle-License";
107 
108     public static final IndexerField FLD_BUNDLE_LICENSE =
109         new IndexerField( OSGI.LICENSE, IndexerFieldVersion.V4, BL, "Bundle-License (indexed, stored)", Field.Store.YES,
110                           Field.Index.ANALYZED );
111 
112     private static final String BDU = "Bundle-DocURL";
113 
114     public static final IndexerField FLD_BUNDLE_DOCURL =
115         new IndexerField( OSGI.DOCURL, IndexerFieldVersion.V4, BDU, "Bundle-DocURL (indexed, stored)", Field.Store.YES,
116                           Field.Index.ANALYZED );
117 
118     private static final String BIP = "Import-Package";
119 
120     public static final IndexerField FLD_BUNDLE_IMPORT_PACKAGE =
121         new IndexerField( OSGI.IMPORT_PACKAGE, IndexerFieldVersion.V4, BIP, "Import-Package (indexed, stored)",
122                           Field.Store.YES, Field.Index.ANALYZED );
123 
124 
125     private static final String BRB = "Require-Bundle";
126 
127     public static final IndexerField FLD_BUNDLE_REQUIRE_BUNDLE =
128         new IndexerField( OSGI.REQUIRE_BUNDLE, IndexerFieldVersion.V4, BRB, "Require-Bundle (indexed, stored)",
129                           Field.Store.YES, Field.Index.ANALYZED );
130 
131 
132 
133 
134     public Collection<IndexerField> getIndexerFields()
135     {
136         return Arrays.asList( FLD_BUNDLE_SYMBOLIC_NAME, FLD_BUNDLE_VERSION, FLD_BUNDLE_EXPORT_PACKAGE,
137                               FLD_BUNDLE_EXPORT_SERVIVE, FLD_BUNDLE_DESCRIPTION, FLD_BUNDLE_NAME, FLD_BUNDLE_LICENSE,
138                               FLD_BUNDLE_DOCURL, FLD_BUNDLE_IMPORT_PACKAGE, FLD_BUNDLE_REQUIRE_BUNDLE );
139     }
140 
141     public OsgiArtifactIndexCreator()
142     {
143         super( ID );
144     }
145 
146     public void populateArtifactInfo( ArtifactContext artifactContext )
147         throws IOException
148     {
149         ArtifactInfo ai = artifactContext.getArtifactInfo();
150 
151         File artifactFile = artifactContext.getArtifact();
152 
153         // TODO : olamy : supports only jars ?
154 
155         if ( artifactFile != null && artifactFile.isFile() && artifactFile.getName().endsWith( ".jar" ) )
156         {
157             updateArtifactInfo( ai, artifactFile );
158         }
159     }
160 
161     public void updateDocument( ArtifactInfo artifactInfo, Document document )
162     {
163 
164         if ( artifactInfo.bundleSymbolicName != null )
165         {
166             document.add( FLD_BUNDLE_SYMBOLIC_NAME.toField( artifactInfo.bundleSymbolicName ) );
167         }
168 
169         if ( artifactInfo.bundleVersion != null )
170         {
171             document.add( FLD_BUNDLE_VERSION.toField( artifactInfo.bundleVersion ) );
172         }
173 
174         if ( artifactInfo.bundleExportPackage != null )
175         {
176             document.add( FLD_BUNDLE_EXPORT_PACKAGE.toField( artifactInfo.bundleExportPackage ) );
177         }
178 
179         if ( artifactInfo.bundleExportService != null )
180         {
181             document.add( FLD_BUNDLE_EXPORT_SERVIVE.toField( artifactInfo.bundleExportService ) );
182         }
183 
184         if ( artifactInfo.bundleDescription != null )
185         {
186             document.add( FLD_BUNDLE_DESCRIPTION.toField( artifactInfo.bundleDescription ) );
187         }
188 
189         if ( artifactInfo.bundleName != null )
190         {
191             document.add( FLD_BUNDLE_NAME.toField( artifactInfo.bundleName ) );
192         }
193 
194         if ( artifactInfo.bundleLicense != null )
195         {
196             document.add( FLD_BUNDLE_LICENSE.toField( artifactInfo.bundleLicense ) );
197         }
198 
199         if ( artifactInfo.bundleDocUrl != null )
200         {
201             document.add( FLD_BUNDLE_DOCURL.toField( artifactInfo.bundleDocUrl ) );
202         }
203 
204         if ( artifactInfo.bundleImportPackage != null )
205         {
206             document.add( FLD_BUNDLE_IMPORT_PACKAGE.toField( artifactInfo.bundleImportPackage ) );
207         }
208 
209         if ( artifactInfo.bundleRequireBundle != null )
210         {
211             document.add( FLD_BUNDLE_REQUIRE_BUNDLE.toField( artifactInfo.bundleRequireBundle ) );
212         }
213     }
214 
215     public boolean updateArtifactInfo( Document document, ArtifactInfo artifactInfo )
216     {
217         boolean updated = false;
218 
219         String bundleSymbolicName = document.get( FLD_BUNDLE_SYMBOLIC_NAME.getKey() );
220 
221         if ( bundleSymbolicName != null )
222         {
223             artifactInfo.bundleSymbolicName = bundleSymbolicName;
224 
225             updated = true;
226         }
227 
228         String bundleVersion = document.get( FLD_BUNDLE_VERSION.getKey() );
229 
230         if ( bundleVersion != null )
231         {
232             artifactInfo.bundleVersion = bundleVersion;
233 
234             updated = true;
235         }
236 
237         String bundleExportPackage = document.get( FLD_BUNDLE_EXPORT_PACKAGE.getKey() );
238 
239         if ( bundleExportPackage != null )
240         {
241             artifactInfo.bundleExportPackage = bundleExportPackage;
242 
243             updated = true;
244 
245         }
246 
247         String bundleExportService = document.get( FLD_BUNDLE_EXPORT_SERVIVE.getKey() );
248 
249         if ( bundleExportService != null )
250         {
251             artifactInfo.bundleExportService = bundleExportService;
252 
253             updated = true;
254 
255         }
256 
257         String bundleDescription = document.get( FLD_BUNDLE_DESCRIPTION.getKey() );
258 
259         if ( bundleDescription != null )
260         {
261             artifactInfo.bundleDescription = bundleDescription;
262 
263             updated = true;
264 
265         }
266 
267 
268         String bundleName = document.get( FLD_BUNDLE_NAME.getKey() );
269 
270         if ( bundleName != null )
271         {
272             artifactInfo.bundleName = bundleName;
273 
274             updated = true;
275 
276         }
277 
278 
279         String bundleLicense = document.get( FLD_BUNDLE_LICENSE.getKey() );
280 
281         if ( bundleLicense != null )
282         {
283             artifactInfo.bundleLicense = bundleLicense;
284 
285             updated = true;
286 
287         }
288 
289         String bundleDocUrl = document.get( FLD_BUNDLE_DOCURL.getKey() );
290 
291         if ( bundleDocUrl != null )
292         {
293             artifactInfo.bundleDocUrl = bundleDocUrl;
294 
295             updated = true;
296 
297         }
298 
299         String bundleImportPackage = document.get( FLD_BUNDLE_IMPORT_PACKAGE.getKey() );
300 
301         if ( bundleImportPackage != null )
302         {
303             artifactInfo.bundleImportPackage = bundleImportPackage;
304 
305             updated = true;
306 
307         }
308 
309         String bundleRequireBundle = document.get( FLD_BUNDLE_REQUIRE_BUNDLE.getKey() );
310 
311         if ( bundleRequireBundle != null )
312         {
313             artifactInfo.bundleRequireBundle = bundleRequireBundle;
314 
315             updated = true;
316 
317         }
318 
319 
320         return updated;
321     }
322 
323     private boolean updateArtifactInfo( ArtifactInfo ai, File f )
324         throws IOException
325     {
326         ZipHandle handle = null;
327 
328         boolean updated = false;
329 
330         try
331         {
332             handle = ZipFacade.getZipHandle( f );
333 
334             final List<String> entries = handle.getEntries();
335 
336             for ( String name : entries )
337             {
338                 if ( name.equals( "META-INF/MANIFEST.MF" ) )
339                 {
340                     Manifest manifest = new Manifest( handle.getEntryContent( name ) );
341 
342                     Attributes mainAttributes = manifest.getMainAttributes();
343 
344                     if ( mainAttributes != null )
345                     {
346                         String attValue = mainAttributes.getValue( BSN );
347                         if ( StringUtils.isNotBlank( attValue ) )
348                         {
349                             ai.bundleSymbolicName = attValue;
350                             updated = true;
351                         }
352                         else
353                         {
354                             ai.bundleSymbolicName = null;
355                         }
356 
357                         attValue = mainAttributes.getValue( BV );
358                         if ( StringUtils.isNotBlank( attValue ) )
359                         {
360                             ai.bundleVersion = attValue;
361                             updated = true;
362                         }
363                         else
364                         {
365                             ai.bundleVersion = null;
366                         }
367 
368                         attValue = mainAttributes.getValue( BEP );
369                         if ( StringUtils.isNotBlank( attValue ) )
370                         {
371                             ai.bundleExportPackage = attValue;
372                             updated = true;
373                         }
374                         else
375                         {
376                             ai.bundleExportPackage = null;
377                         }
378 
379                         attValue = mainAttributes.getValue( BES );
380                         if ( StringUtils.isNotBlank( attValue ) )
381                         {
382                             ai.bundleExportService = attValue;
383                             updated = true;
384                         }
385                         else
386                         {
387                             ai.bundleExportService = null;
388                         }
389 
390                         attValue = mainAttributes.getValue( BD );
391                         if ( StringUtils.isNotBlank( attValue ) )
392                         {
393                             ai.bundleDescription = attValue;
394                             updated = true;
395                         }
396                         else
397                         {
398                             ai.bundleDescription = null;
399                         }
400 
401                         attValue = mainAttributes.getValue( BN );
402                         if ( StringUtils.isNotBlank( attValue ) )
403                         {
404                             ai.bundleName = attValue;
405                             updated = true;
406                         }
407                         else
408                         {
409                             ai.bundleName = null;
410                         }
411 
412                         attValue = mainAttributes.getValue( BL );
413                         if ( StringUtils.isNotBlank( attValue ) )
414                         {
415                             ai.bundleLicense = attValue;
416                             updated = true;
417                         }
418                         else
419                         {
420                             ai.bundleLicense = null;
421                         }
422 
423                         attValue = mainAttributes.getValue( BDU );
424                         if ( StringUtils.isNotBlank( attValue ) )
425                         {
426                             ai.bundleDocUrl = attValue;
427                             updated = true;
428                         }
429                         else
430                         {
431                             ai.bundleDocUrl = null;
432                         }
433 
434                         attValue = mainAttributes.getValue( BIP );
435                         if ( StringUtils.isNotBlank( attValue ) )
436                         {
437                             ai.bundleImportPackage = attValue;
438                             updated = true;
439                         }
440                         else
441                         {
442                             ai.bundleImportPackage = null;
443                         }
444 
445                         attValue = mainAttributes.getValue( BRB );
446                         if ( StringUtils.isNotBlank( attValue ) )
447                         {
448                             ai.bundleRequireBundle = attValue;
449                             updated = true;
450                         }
451                         else
452                         {
453                             ai.bundleRequireBundle = null;
454                         }
455 
456                     }
457                 }
458             }
459 
460         }
461         finally
462         {
463             try
464             {
465                 ZipFacade.close( handle );
466             }
467             catch ( Exception e )
468             {
469                 getLogger().error( "Could not close jar file properly.", e );
470             }
471         }
472         return updated;
473     }
474 
475     @Override
476     public String toString()
477     {
478         return ID;
479     }
480 }