View Javadoc
1   package org.apache.maven.index.reader;
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 java.util.Map;
23  import java.util.Objects;
24  
25  /**
26   * Maven 2 Index record.
27   *
28   * @since 5.1.2
29   */
30  public final class Record
31  {
32      /**
33       * Entry key is field key with some metadata.
34       *
35       * @param <T> The type of the value belonging to this key instance.
36       */
37      public static final class EntryKey<T>
38      {
39          private final String name;
40  
41          private final Class<T> proto;
42  
43          public EntryKey( final String name, final Class<T> proto )
44          {
45              Objects.requireNonNull( name, "name is null" );
46              Objects.requireNonNull( proto, "proto is null" );
47              this.name = name;
48              this.proto = proto;
49          }
50  
51          public T coerce( final Object object )
52          {
53              return proto.cast( object );
54          }
55  
56          public String getName()
57          {
58              return name;
59          }
60  
61          @Override
62          public boolean equals( Object o )
63          {
64              if ( this == o )
65              {
66                  return true;
67              }
68              if ( o == null || getClass() != o.getClass() )
69              {
70                  return false;
71              }
72              EntryKey<?> entryKey = (EntryKey<?>) o;
73              return Objects.equals( name, entryKey.name );
74          }
75  
76          @Override
77          public int hashCode()
78          {
79              return Objects.hash( name );
80          }
81  
82          @Override
83          public String toString()
84          {
85              return "Key{" + "name='" + name + '\'' + ", type=" + proto.getSimpleName() + '}';
86          }
87      }
88  
89      /**
90       * Key of repository ID entry, that contains {@link String}.
91       */
92      public static final EntryKey<String> REPOSITORY_ID = new EntryKey<>( "repositoryId", String.class );
93  
94      /**
95       * Key of all groups list entry, that contains {@link java.util.List<String>}.
96       */
97      public static final EntryKey<String[]> ALL_GROUPS = new EntryKey<>( "allGroups", String[].class );
98  
99      /**
100      * Key of root groups list entry, that contains {@link java.util.List<String>}.
101      */
102     public static final EntryKey<String[]> ROOT_GROUPS = new EntryKey<>( "rootGroups", String[].class );
103 
104     /**
105      * Key of index record modification (added to index or removed from index) timestamp entry, that contains {@link
106      * Long}.
107      */
108     public static final EntryKey<Long> REC_MODIFIED = new EntryKey<>( "recordModified", Long.class );
109 
110     /**
111      * Key of artifact groupId entry, that contains {@link String}.
112      */
113     public static final EntryKey<String> GROUP_ID = new EntryKey<>( "groupId", String.class );
114 
115     /**
116      * Key of artifact artifactId entry, that contains {@link String}.
117      */
118     public static final EntryKey<String> ARTIFACT_ID = new EntryKey<>( "artifactId", String.class );
119 
120     /**
121      * Key of artifact version entry, that contains {@link String}.
122      */
123     public static final EntryKey<String> VERSION = new EntryKey<>( "version", String.class );
124 
125     /**
126      * Key of artifact classifier entry, that contains {@link String}.
127      */
128     public static final EntryKey<String> CLASSIFIER = new EntryKey<>( "classifier", String.class );
129 
130     /**
131      * Key of artifact packaging entry, that contains {@link String}.
132      */
133     public static final EntryKey<String> PACKAGING = new EntryKey<>( "packaging", String.class );
134 
135     /**
136      * Key of artifact file extension, that contains {@link String}.
137      */
138     public static final EntryKey<String> FILE_EXTENSION = new EntryKey<>( "fileExtension", String.class );
139 
140     /**
141      * Key of artifact file last modified timestamp, that contains {@link Long}.
142      */
143     public static final EntryKey<Long> FILE_MODIFIED = new EntryKey<>( "fileModified", Long.class );
144 
145     /**
146      * Key of artifact file size in bytes, that contains {@link Long}.
147      */
148     public static final EntryKey<Long> FILE_SIZE = new EntryKey<>( "fileSize", Long.class );
149 
150     /**
151      * Key of artifact Sources presence flag, that contains {@link Boolean}.
152      */
153     public static final EntryKey<Boolean> HAS_SOURCES = new EntryKey<>( "hasSources", Boolean.class );
154 
155     /**
156      * Key of artifact Javadoc presence flag, that contains {@link Boolean}.
157      */
158     public static final EntryKey<Boolean> HAS_JAVADOC = new EntryKey<>( "hasJavadoc", Boolean.class );
159 
160     /**
161      * Key of artifact signature presence flag, that contains {@link Boolean}.
162      */
163     public static final EntryKey<Boolean> HAS_SIGNATURE = new EntryKey<>( "hasSignature", Boolean.class );
164 
165     /**
166      * Key of artifact name (as set in POM), that contains {@link String}.
167      */
168     public static final EntryKey<String> NAME = new EntryKey<>( "name", String.class );
169 
170     /**
171      * Key of artifact description (as set in POM), that contains {@link String}.
172      */
173     public static final EntryKey<String> DESCRIPTION = new EntryKey<>( "description", String.class );
174 
175     /**
176      * Key of artifact SHA1 digest, that contains {@link String}.
177      */
178     public static final EntryKey<String> SHA1 = new EntryKey<>( "sha1", String.class );
179 
180     /**
181      * Key of artifact contained class names, that contains {@link java.util.List<String>}. Extracted by {@code
182      * JarFileContentsIndexCreator}.
183      */
184     public static final EntryKey<String[]> CLASSNAMES = new EntryKey<>( "classNames", String[].class );
185 
186     /**
187      * Key of plugin artifact prefix, that contains {@link String}. Extracted by {@code
188      * MavenPluginArtifactInfoIndexCreator}.
189      */
190     public static final EntryKey<String> PLUGIN_PREFIX = new EntryKey<>( "pluginPrefix", String.class );
191 
192     /**
193      * Key of plugin artifact goals, that contains {@link java.util.List<String>}. Extracted by {@code
194      * MavenPluginArtifactInfoIndexCreator}.
195      */
196     public static final EntryKey<String[]> PLUGIN_GOALS = new EntryKey<>( "pluginGoals", String[].class );
197 
198     /**
199      * Key of OSGi "Bundle-SymbolicName" manifest entry, that contains {@link String}. Extracted by {@code
200      * OsgiArtifactIndexCreator}.
201      */
202     public static final EntryKey<String> OSGI_BUNDLE_SYMBOLIC_NAME = new EntryKey<>( "Bundle-SymbolicName",
203             String.class );
204 
205     /**
206      * Key of OSGi "Bundle-Version" manifest entry, that contains {@link String}. Extracted by {@code
207      * OsgiArtifactIndexCreator}.
208      */
209     public static final EntryKey<String> OSGI_BUNDLE_VERSION = new EntryKey<>( "Bundle-Version", String.class );
210 
211     /**
212      * Key of OSGi "Export-Package" manifest entry, that contains {@link String}. Extracted by {@code
213      * OsgiArtifactIndexCreator}.
214      */
215     public static final EntryKey<String> OSGI_EXPORT_PACKAGE = new EntryKey<>( "Export-Package", String.class );
216 
217     /**
218      * Key of OSGi "Export-Service" manifest entry, that contains {@link String}. Extracted by {@code
219      * OsgiArtifactIndexCreator}.
220      */
221     public static final EntryKey<String> OSGI_EXPORT_SERVICE = new EntryKey<>( "Export-Service", String.class );
222 
223     /**
224      * Key of OSGi "Bundle-Description" manifest entry, that contains {@link String}. Extracted by {@code
225      * OsgiArtifactIndexCreator}.
226      */
227     public static final EntryKey<String> OSGI_BUNDLE_DESCRIPTION = new EntryKey<>( "Bundle-Description", String.class );
228 
229     /**
230      * Key of OSGi "Bundle-Name" manifest entry, that contains {@link String}. Extracted by {@code
231      * OsgiArtifactIndexCreator}.
232      */
233     public static final EntryKey<String> OSGI_BUNDLE_NAME = new EntryKey<>( "Bundle-Name", String.class );
234 
235     /**
236      * Key of OSGi "Bundle-License" manifest entry, that contains {@link String}. Extracted by {@code
237      * OsgiArtifactIndexCreator}.
238      */
239     public static final EntryKey<String> OSGI_BUNDLE_LICENSE = new EntryKey<>( "Bundle-License", String.class );
240 
241     /**
242      * Key of OSGi "Bundle-DocURL" manifest entry, that contains {@link String}. Extracted by {@code
243      * OsgiArtifactIndexCreator}.
244      */
245     public static final EntryKey<String> OSGI_EXPORT_DOCURL = new EntryKey<>( "Bundle-DocURL", String.class );
246 
247     /**
248      * Key of OSGi "Import-Package" manifest entry, that contains {@link String}. Extracted by {@code
249      * OsgiArtifactIndexCreator}.
250      */
251     public static final EntryKey<String> OSGI_IMPORT_PACKAGE = new EntryKey<>( "Import-Package", String.class );
252 
253     /**
254      * Key of OSGi "Require-Bundle" manifest entry, that contains {@link String}. Extracted by {@code
255      * OsgiArtifactIndexCreator}.
256      */
257     public static final EntryKey<String> OSGI_REQUIRE_BUNDLE = new EntryKey<>( "Require-Bundle", String.class );
258 
259     /**
260      * Key of OSGi "Provide-Capability" manifest entry, that contains {@link String}. Extracted by {@code
261      * OsgiArtifactIndexCreator}.
262      */
263     public static final EntryKey<String> OSGI_PROVIDE_CAPABILITY = new EntryKey<>( "Provide-Capability", String.class );
264 
265     /**
266      * Key of OSGi "Require-Capability" manifest entry, that contains {@link String}. Extracted by {@code
267      * OsgiArtifactIndexCreator}.
268      */
269     public static final EntryKey<String> OSGI_REQUIRE_CAPABILITY = new EntryKey<>( "Require-Capability", String.class );
270 
271     /**
272      * Key of OSGi "Fragment-Host" manifest entry, that contains {@link String}. Extracted by {@code
273      * OsgiArtifactIndexCreator}.
274      */
275     public static final EntryKey<String> OSGI_FRAGMENT_HOST = new EntryKey<>( "Fragment-Host", String.class );
276 
277     /**
278      * Key of deprecated OSGi "Bundle-RequiredExecutionEnvironment" manifest entry, that contains {@link String}.
279      * Extracted by {@code OsgiArtifactIndexCreator}.
280      */
281     public static final EntryKey<String> OSGI_BREE = new EntryKey<>( "Bundle-RequiredExecutionEnvironment",
282             String.class );
283 
284     /**
285      * Key for SHA-256 checksum  needed for OSGI content capability that contains {@link String}. Extracted by {@code
286      * OsgiArtifactIndexCreator}.
287      */
288     public static final EntryKey<String> SHA_256 = new EntryKey<>( "sha256", String.class );
289 
290 
291     /**
292      * Types of returned records returned from index.
293      */
294     public enum Type
295     {
296         /**
297          * Descriptor record. Can be safely ignored.
298          * Contains following entries:
299          * <ul>
300          * <li>{@link #REPOSITORY_ID}</li>
301          * </ul>
302          */
303         DESCRIPTOR,
304 
305         /**
306          * Artifact ADD record. Records of this type should be added to your indexing system.
307          * Contains following entries:
308          * <ul>
309          * <li>{@link #REC_MODIFIED} (when record was added/modified on index)</li>
310          * <li>{@link #GROUP_ID}</li>
311          * <li>{@link #ARTIFACT_ID}</li>
312          * <li>{@link #VERSION}</li>
313          * <li>{@link #CLASSIFIER} (optional)</li>
314          * <li>{@link #FILE_EXTENSION}</li>
315          * <li>{@link #FILE_MODIFIED}</li>
316          * <li>{@link #FILE_SIZE}</li>
317          * <li>{@link #PACKAGING}</li>
318          * <li>{@link #HAS_SOURCES}</li>
319          * <li>{@link #HAS_JAVADOC}</li>
320          * <li>{@link #HAS_SIGNATURE}</li>
321          * <li>{@link #NAME}</li>
322          * <li>{@link #DESCRIPTION}</li>
323          * <li>{@link #SHA1}</li>
324          * <li>{@link #CLASSNAMES} (optional)</li>
325          * <li>{@link #PLUGIN_PREFIX} (optional, for maven-plugins only)</li>
326          * <li>{@link #PLUGIN_GOALS} (optional, for maven-plugins only)</li>
327          * </ul>
328          */
329         ARTIFACT_ADD,
330 
331         /**
332          * Artifact REMOVE record. In case of incremental updates, signals that this artifact was removed. Records of
333          * this type should be removed from your indexing system.
334          * Contains following entries:
335          * <ul>
336          * <li>{@link #REC_MODIFIED} (when record was deleted from index)</li>
337          * <li>{@link #GROUP_ID}</li>
338          * <li>{@link #ARTIFACT_ID}</li>
339          * <li>{@link #VERSION}</li>
340          * <li>{@link #CLASSIFIER} (optional)</li>
341          * <li>{@link #FILE_EXTENSION} (if {@link #CLASSIFIER} present)</li>
342          * <li>{@link #PACKAGING} (optional)</li>
343          * </ul>
344          */
345         ARTIFACT_REMOVE,
346 
347         /**
348          * Special record, containing all the Maven "groupId"s that are enlisted on the index. Can be safely ignored.
349          * Contains following entries:
350          * <ul>
351          * <li>{@link #ALL_GROUPS}</li>
352          * </ul>
353          */
354         ALL_GROUPS,
355 
356         /**
357          * Special record, containing all the root groups of Maven "groupId"s that are enlisted on the index. Can be
358          * safely ignored.
359          * Contains following entries:
360          * <ul>
361          * <li>{@link #ROOT_GROUPS}</li>
362          * </ul>
363          */
364         ROOT_GROUPS
365     }
366 
367     private final Type type;
368 
369     private final Map<EntryKey, Object> expanded;
370 
371     public Record( final Type type, final Map<EntryKey, Object> expanded )
372     {
373         this.type = type;
374         this.expanded = expanded;
375     }
376 
377     /**
378      * Returns the {@link Type} of this record. Usually users would be interested in {@link Type#ARTIFACT_ADD} and
379      * {@link Type#ARTIFACT_REMOVE} types only to maintain their own index. Still, indexer offers extra records too,
380      * see {@link Type} for all existing types.
381      */
382     public Type getType()
383     {
384         return type;
385     }
386 
387     /**
388      * Returns the expanded (processed and expanded synthetic fields) record as {@link Map} ready for consumption.
389      */
390     public Map<EntryKey, Object> getExpanded()
391     {
392         return expanded;
393     }
394 
395     /**
396      * Returns {@code true} if this record contains given {@link EntryKey}.
397      */
398     boolean containsKey( final EntryKey<?> entryKey )
399     {
400         return expanded.containsKey( entryKey );
401     }
402 
403     /**
404      * Type safe handy method to get value from expanded map.
405      */
406     public <T> T get( final EntryKey<T> entryKey )
407     {
408         return entryKey.coerce( expanded.get( entryKey ) );
409     }
410 
411     /**
412      * Type safe handy method to put value to expanded map. Accepts {@code null} values, that removes the mapping.
413      */
414     public <T> T put( final EntryKey<T> entryKey, final T value )
415     {
416         if ( value == null )
417         {
418             return entryKey.coerce( expanded.remove( entryKey ) );
419         }
420         else
421         {
422             if ( !entryKey.proto.isAssignableFrom( value.getClass() ) )
423             {
424                 throw new IllegalArgumentException( "Key " + entryKey + " does not accepts value " + value );
425             }
426             return entryKey.coerce( expanded.put( entryKey, value ) );
427         }
428     }
429 
430     @Override
431     public String toString()
432     {
433         return "Record{" + "type=" + type + ", expanded=" + expanded + '}';
434     }
435 }