maven-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ol...@apache.org
Subject [2/2] maven-indexer git commit: use maven codestyle format, just to reduce checkstyle errors number...
Date Mon, 24 Jul 2017 06:59:11 GMT
use maven codestyle format, just to reduce checkstyle errors number...

Signed-off-by: olivier lamy <olamy@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/maven-indexer/repo
Commit: http://git-wip-us.apache.org/repos/asf/maven-indexer/commit/8d096a88
Tree: http://git-wip-us.apache.org/repos/asf/maven-indexer/tree/8d096a88
Diff: http://git-wip-us.apache.org/repos/asf/maven-indexer/diff/8d096a88

Branch: refs/heads/master
Commit: 8d096a88bc0c74b6315d4166805a2457bff86b33
Parents: 0bbcad1
Author: olivier lamy <olamy@apache.org>
Authored: Mon Jul 24 16:51:06 2017 +1000
Committer: olivier lamy <olamy@apache.org>
Committed: Mon Jul 24 16:51:06 2017 +1000

----------------------------------------------------------------------
 .../DownloadRemoteIndexerManagerTest.java       |  15 +-
 .../apache/maven/index/reader/ChunkReader.java  | 411 +++++-----
 .../apache/maven/index/reader/ChunkWriter.java  | 283 +++----
 .../apache/maven/index/reader/IndexReader.java  | 438 ++++++-----
 .../apache/maven/index/reader/IndexWriter.java  | 308 ++++----
 .../org/apache/maven/index/reader/Record.java   | 761 ++++++++++---------
 .../maven/index/reader/RecordCompactor.java     | 341 +++++----
 .../maven/index/reader/RecordExpander.java      | 388 +++++-----
 .../maven/index/reader/ResourceHandler.java     |  28 +-
 .../index/reader/WritableResourceHandler.java   |  40 +-
 10 files changed, 1586 insertions(+), 1427 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/maven-indexer/blob/8d096a88/indexer-core/src/test/java/org/apache/maven/index/updater/DownloadRemoteIndexerManagerTest.java
----------------------------------------------------------------------
diff --git a/indexer-core/src/test/java/org/apache/maven/index/updater/DownloadRemoteIndexerManagerTest.java b/indexer-core/src/test/java/org/apache/maven/index/updater/DownloadRemoteIndexerManagerTest.java
index 5dfa7ad..7e0b0c3 100644
--- a/indexer-core/src/test/java/org/apache/maven/index/updater/DownloadRemoteIndexerManagerTest.java
+++ b/indexer-core/src/test/java/org/apache/maven/index/updater/DownloadRemoteIndexerManagerTest.java
@@ -26,6 +26,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.ServerSocket;
+import java.nio.file.Files;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.Properties;
@@ -175,16 +176,18 @@ public class DownloadRemoteIndexerManagerTest
         assertTrue( lastMod < lastMod2 );
 
         Properties p = new Properties();
-        InputStream input = new FileInputStream( indexProperties );
-        p.load( input );
-        input.close();
+        try (InputStream input = Files.newInputStream( indexProperties.toPath() ))
+        {
+            p.load( input );
+        }
 
         p.setProperty( "nexus.index.time", format( new Date() ) );
         p.setProperty( "nexus.index.timestamp", format( new Date() ) );
 
-        OutputStream output = new FileOutputStream( indexProperties );
-        p.store( output, null );
-        output.close();
+        try (OutputStream output = Files.newOutputStream( indexProperties.toPath() ))
+        {
+            p.store( output, null );
+        }
     }
 
     private String format( Date d )

http://git-wip-us.apache.org/repos/asf/maven-indexer/blob/8d096a88/indexer-reader/src/main/java/org/apache/maven/index/reader/ChunkReader.java
----------------------------------------------------------------------
diff --git a/indexer-reader/src/main/java/org/apache/maven/index/reader/ChunkReader.java b/indexer-reader/src/main/java/org/apache/maven/index/reader/ChunkReader.java
index a6c75ac..9ce6bfa 100644
--- a/indexer-reader/src/main/java/org/apache/maven/index/reader/ChunkReader.java
+++ b/indexer-reader/src/main/java/org/apache/maven/index/reader/ChunkReader.java
@@ -41,219 +41,250 @@ import java.util.zip.GZIPInputStream;
 public class ChunkReader
     implements Closeable, Iterable<Map<String, String>>
 {
-  private final String chunkName;
-
-  private final DataInputStream dataInputStream;
-
-  private final int version;
-
-  private final Date timestamp;
-
-  public ChunkReader(final String chunkName, final InputStream inputStream) throws IOException
-  {
-    this.chunkName = chunkName.trim();
-    this.dataInputStream = new DataInputStream(new GZIPInputStream(inputStream, 2 * 1024));
-    this.version = ((int) dataInputStream.readByte()) & 0xff;
-    this.timestamp = new Date(dataInputStream.readLong());
-  }
-
-  /**
-   * Returns the chunk name.
-   */
-  public String getName() {
-    return chunkName;
-  }
-
-  /**
-   * Returns index version. All releases so far always returned {@code 1}.
-   */
-  public int getVersion() {
-    return version;
-  }
-
-  /**
-   * Returns the index timestamp of last update of the index.
-   */
-  public Date getTimestamp() {
-    return timestamp;
-  }
-
-  /**
-   * Returns the {@link Record} iterator.
-   */
-  public Iterator<Map<String, String>> iterator() {
-    try {
-      return new IndexIterator(dataInputStream);
-    }
-    catch (IOException e) {
-      throw new RuntimeException("error", e);
-    }
-  }
-
-  /**
-   * Closes this reader and it's underlying input.
-   */
-  public void close() throws IOException {
-    dataInputStream.close();
-  }
-
-  /**
-   * Low memory footprint index iterator that incrementally parses the underlying stream.
-   */
-  private static class IndexIterator
-      implements Iterator<Map<String, String>>
-  {
+    private final String chunkName;
+
     private final DataInputStream dataInputStream;
 
-    private Map<String, String> nextRecord;
+    private final int version;
 
-    public IndexIterator(final DataInputStream dataInputStream) throws IOException {
-      this.dataInputStream = dataInputStream;
-      this.nextRecord = nextRecord();
-    }
+    private final Date timestamp;
 
-    public boolean hasNext() {
-      return nextRecord != null;
+    public ChunkReader( final String chunkName, final InputStream inputStream )
+        throws IOException
+    {
+        this.chunkName = chunkName.trim();
+        this.dataInputStream = new DataInputStream( new GZIPInputStream( inputStream, 2 * 1024 ) );
+        this.version = ( (int) dataInputStream.readByte() ) & 0xff;
+        this.timestamp = new Date( dataInputStream.readLong() );
     }
 
-    public Map<String, String> next() {
-      if (nextRecord == null) {
-        throw new NoSuchElementException("chunk depleted");
-      }
-      Map<String, String> result = nextRecord;
-      nextRecord = nextRecord();
-      return result;
+    /**
+     * Returns the chunk name.
+     */
+    public String getName()
+    {
+        return chunkName;
     }
 
-    public void remove() {
-      throw new UnsupportedOperationException("remove");
+    /**
+     * Returns index version. All releases so far always returned {@code 1}.
+     */
+    public int getVersion()
+    {
+        return version;
     }
 
-    private Map<String, String> nextRecord() {
-      try {
-        return readRecord(dataInputStream);
-      }
-      catch (IOException e) {
-        throw new RuntimeException("read error", e);
-      }
-    }
-  }
-
-  /**
-   * Reads and returns next record from the underlying stream, or {@code null} if no more records.
-   */
-  private static Map<String, String> readRecord(final DataInput dataInput)
-      throws IOException
-  {
-    int fieldCount;
-    try {
-      fieldCount = dataInput.readInt();
-    }
-    catch (EOFException ex) {
-      return null; // no more documents
+    /**
+     * Returns the index timestamp of last update of the index.
+     */
+    public Date getTimestamp()
+    {
+        return timestamp;
     }
 
-    Map<String, String> recordMap = new HashMap<String, String>();
-    for (int i = 0; i < fieldCount; i++) {
-      readField(recordMap, dataInput);
+    /**
+     * Returns the {@link Record} iterator.
+     */
+    public Iterator<Map<String, String>> iterator()
+    {
+        try
+        {
+            return new IndexIterator( dataInputStream );
+        }
+        catch ( IOException e )
+        {
+            throw new RuntimeException( "error", e );
+        }
     }
-    return recordMap;
-  }
-
-  private static void readField(final Map<String, String> record, final DataInput dataInput)
-      throws IOException
-  {
-    dataInput.readByte(); // flags: neglect them
-    String name = dataInput.readUTF();
-    String value = readUTF(dataInput);
-    record.put(name, value);
-  }
-
-  private static String readUTF(final DataInput dataInput)
-      throws IOException
-  {
-    int utflen = dataInput.readInt();
-
-    byte[] bytearr;
-    char[] chararr;
-
-    try {
-      bytearr = new byte[utflen];
-      chararr = new char[utflen];
-    }
-    catch (OutOfMemoryError e) {
-      IOException ioex = new IOException("Index data content is corrupt");
-      ioex.initCause(e);
-      throw ioex;
+
+    /**
+     * Closes this reader and it's underlying input.
+     */
+    public void close()
+        throws IOException
+    {
+        dataInputStream.close();
     }
 
-    int c, char2, char3;
-    int count = 0;
-    int chararr_count = 0;
+    /**
+     * Low memory footprint index iterator that incrementally parses the underlying stream.
+     */
+    private static class IndexIterator
+        implements Iterator<Map<String, String>>
+    {
+        private final DataInputStream dataInputStream;
+
+        private Map<String, String> nextRecord;
+
+        public IndexIterator( final DataInputStream dataInputStream )
+            throws IOException
+        {
+            this.dataInputStream = dataInputStream;
+            this.nextRecord = nextRecord();
+        }
+
+        public boolean hasNext()
+        {
+            return nextRecord != null;
+        }
+
+        public Map<String, String> next()
+        {
+            if ( nextRecord == null )
+            {
+                throw new NoSuchElementException( "chunk depleted" );
+            }
+            Map<String, String> result = nextRecord;
+            nextRecord = nextRecord();
+            return result;
+        }
+
+        public void remove()
+        {
+            throw new UnsupportedOperationException( "remove" );
+        }
+
+        private Map<String, String> nextRecord()
+        {
+            try
+            {
+                return readRecord( dataInputStream );
+            }
+            catch ( IOException e )
+            {
+                throw new RuntimeException( "read error", e );
+            }
+        }
+    }
 
-    dataInput.readFully(bytearr, 0, utflen);
+    /**
+     * Reads and returns next record from the underlying stream, or {@code null} if no more records.
+     */
+    private static Map<String, String> readRecord( final DataInput dataInput )
+        throws IOException
+    {
+        int fieldCount;
+        try
+        {
+            fieldCount = dataInput.readInt();
+        }
+        catch ( EOFException ex )
+        {
+            return null; // no more documents
+        }
+
+        Map<String, String> recordMap = new HashMap<String, String>();
+        for ( int i = 0; i < fieldCount; i++ )
+        {
+            readField( recordMap, dataInput );
+        }
+        return recordMap;
+    }
 
-    while (count < utflen) {
-      c = bytearr[count] & 0xff;
-      if (c > 127) {
-        break;
-      }
-      count++;
-      chararr[chararr_count++] = (char) c;
+    private static void readField( final Map<String, String> record, final DataInput dataInput )
+        throws IOException
+    {
+        dataInput.readByte(); // flags: neglect them
+        String name = dataInput.readUTF();
+        String value = readUTF( dataInput );
+        record.put( name, value );
     }
 
-    while (count < utflen) {
-      c = bytearr[count] & 0xff;
-      switch (c >> 4) {
-        case 0:
-        case 1:
-        case 2:
-        case 3:
-        case 4:
-        case 5:
-        case 6:
-        case 7:
+    private static String readUTF( final DataInput dataInput )
+        throws IOException
+    {
+        int utflen = dataInput.readInt();
+
+        byte[] bytearr;
+        char[] chararr;
+
+        try
+        {
+            bytearr = new byte[utflen];
+            chararr = new char[utflen];
+        }
+        catch ( OutOfMemoryError e )
+        {
+            IOException ioex = new IOException( "Index data content is corrupt" );
+            ioex.initCause( e );
+            throw ioex;
+        }
+
+        int c, char2, char3;
+        int count = 0;
+        int chararr_count = 0;
+
+        dataInput.readFully( bytearr, 0, utflen );
+
+        while ( count < utflen )
+        {
+            c = bytearr[count] & 0xff;
+            if ( c > 127 )
+            {
+                break;
+            }
+            count++;
+            chararr[chararr_count++] = (char) c;
+        }
+
+        while ( count < utflen )
+        {
+            c = bytearr[count] & 0xff;
+            switch ( c >> 4 )
+            {
+                case 0:
+                case 1:
+                case 2:
+                case 3:
+                case 4:
+                case 5:
+                case 6:
+                case 7:
                     /* 0xxxxxxx */
-          count++;
-          chararr[chararr_count++] = (char) c;
-          break;
+                    count++;
+                    chararr[chararr_count++] = (char) c;
+                    break;
 
-        case 12:
-        case 13:
+                case 12:
+                case 13:
                     /* 110x xxxx 10xx xxxx */
-          count += 2;
-          if (count > utflen) {
-            throw new UTFDataFormatException("malformed input: partial character at end");
-          }
-          char2 = bytearr[count - 1];
-          if ((char2 & 0xC0) != 0x80) {
-            throw new UTFDataFormatException("malformed input around byte " + count);
-          }
-          chararr[chararr_count++] = (char) (((c & 0x1F) << 6) | (char2 & 0x3F));
-          break;
-
-        case 14:
+                    count += 2;
+                    if ( count > utflen )
+                    {
+                        throw new UTFDataFormatException( "malformed input: partial character at end" );
+                    }
+                    char2 = bytearr[count - 1];
+                    if ( ( char2 & 0xC0 ) != 0x80 )
+                    {
+                        throw new UTFDataFormatException( "malformed input around byte " + count );
+                    }
+                    chararr[chararr_count++] = (char) ( ( ( c & 0x1F ) << 6 ) | ( char2 & 0x3F ) );
+                    break;
+
+                case 14:
                     /* 1110 xxxx 10xx xxxx 10xx xxxx */
-          count += 3;
-          if (count > utflen) {
-            throw new UTFDataFormatException("malformed input: partial character at end");
-          }
-          char2 = bytearr[count - 2];
-          char3 = bytearr[count - 1];
-          if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80)) {
-            throw new UTFDataFormatException("malformed input around byte " + (count - 1));
-          }
-          chararr[chararr_count++] =
-              (char) (((c & 0x0F) << 12) | ((char2 & 0x3F) << 6) | (char3 & 0x3F));
-          break;
-
-        default:
+                    count += 3;
+                    if ( count > utflen )
+                    {
+                        throw new UTFDataFormatException( "malformed input: partial character at end" );
+                    }
+                    char2 = bytearr[count - 2];
+                    char3 = bytearr[count - 1];
+                    if ( ( ( char2 & 0xC0 ) != 0x80 ) || ( ( char3 & 0xC0 ) != 0x80 ) )
+                    {
+                        throw new UTFDataFormatException( "malformed input around byte " + ( count - 1 ) );
+                    }
+                    chararr[chararr_count++] =
+                        (char) ( ( ( c & 0x0F ) << 12 ) | ( ( char2 & 0x3F ) << 6 ) | ( char3 & 0x3F ) );
+                    break;
+
+                default:
                     /* 10xx xxxx, 1111 xxxx */
-          throw new UTFDataFormatException("malformed input around byte " + count);
-      }
-    }
+                    throw new UTFDataFormatException( "malformed input around byte " + count );
+            }
+        }
 
-    // The number of chars produced may be less than utflen
-    return new String(chararr, 0, chararr_count);
-  }
+        // The number of chars produced may be less than utflen
+        return new String( chararr, 0, chararr_count );
+    }
 }

http://git-wip-us.apache.org/repos/asf/maven-indexer/blob/8d096a88/indexer-reader/src/main/java/org/apache/maven/index/reader/ChunkWriter.java
----------------------------------------------------------------------
diff --git a/indexer-reader/src/main/java/org/apache/maven/index/reader/ChunkWriter.java b/indexer-reader/src/main/java/org/apache/maven/index/reader/ChunkWriter.java
index 24e4701..7d1275c 100644
--- a/indexer-reader/src/main/java/org/apache/maven/index/reader/ChunkWriter.java
+++ b/indexer-reader/src/main/java/org/apache/maven/index/reader/ChunkWriter.java
@@ -37,141 +37,160 @@ import java.util.zip.GZIPOutputStream;
 public class ChunkWriter
     implements Closeable
 {
-  private static final int F_INDEXED = 1;
-
-  private static final int F_TOKENIZED = 2;
-
-  private static final int F_STORED = 4;
-
-  private final String chunkName;
-
-  private final DataOutputStream dataOutputStream;
-
-  private final int version;
-
-  private final Date timestamp;
-
-  public ChunkWriter(final String chunkName, final OutputStream outputStream, final int version, final Date timestamp)
-      throws IOException
-  {
-    this.chunkName = chunkName.trim();
-    this.dataOutputStream = new DataOutputStream(new GZIPOutputStream(outputStream, 2 * 1024));
-    this.version = version;
-    this.timestamp = timestamp;
-
-    dataOutputStream.writeByte(version);
-    dataOutputStream.writeLong(timestamp == null ? -1 : timestamp.getTime());
-  }
-
-  /**
-   * Returns the chunk name.
-   */
-  public String getName() {
-    return chunkName;
-  }
-
-  /**
-   * Returns index version. All releases so far always returned {@code 1}.
-   */
-  public int getVersion() {
-    return version;
-  }
-
-  /**
-   * Returns the index timestamp of last update of the index.
-   */
-  public Date getTimestamp() {
-    return timestamp;
-  }
-
-  /**
-   * Writes out the record iterator and returns the written record count.
-   */
-  public int writeChunk(final Iterator<Map<String, String>> iterator) throws IOException {
-    int written = 0;
-    while (iterator.hasNext()) {
-      writeRecord(iterator.next(), dataOutputStream);
-      written++;
+    private static final int F_INDEXED = 1;
+
+    private static final int F_TOKENIZED = 2;
+
+    private static final int F_STORED = 4;
+
+    private final String chunkName;
+
+    private final DataOutputStream dataOutputStream;
+
+    private final int version;
+
+    private final Date timestamp;
+
+    public ChunkWriter( final String chunkName, final OutputStream outputStream, final int version,
+                        final Date timestamp )
+        throws IOException
+    {
+        this.chunkName = chunkName.trim();
+        this.dataOutputStream = new DataOutputStream( new GZIPOutputStream( outputStream, 2 * 1024 ) );
+        this.version = version;
+        this.timestamp = timestamp;
+
+        dataOutputStream.writeByte( version );
+        dataOutputStream.writeLong( timestamp == null ? -1 : timestamp.getTime() );
+    }
+
+    /**
+     * Returns the chunk name.
+     */
+    public String getName()
+    {
+        return chunkName;
     }
-    return written;
-  }
-
-  /**
-   * Closes this reader and it's underlying input.
-   */
-  public void close() throws IOException {
-    dataOutputStream.close();
-  }
-
-  private static void writeRecord(final Map<String, String> record, final DataOutput dataOutput)
-      throws IOException
-  {
-    dataOutput.writeInt(record.size());
-    for (Map.Entry<String, String> entry : record.entrySet()) {
-      writeField(entry.getKey(), entry.getValue(), dataOutput);
+
+    /**
+     * Returns index version. All releases so far always returned {@code 1}.
+     */
+    public int getVersion()
+    {
+        return version;
+    }
+
+    /**
+     * Returns the index timestamp of last update of the index.
+     */
+    public Date getTimestamp()
+    {
+        return timestamp;
+    }
+
+    /**
+     * Writes out the record iterator and returns the written record count.
+     */
+    public int writeChunk( final Iterator<Map<String, String>> iterator )
+        throws IOException
+    {
+        int written = 0;
+        while ( iterator.hasNext() )
+        {
+            writeRecord( iterator.next(), dataOutputStream );
+            written++;
+        }
+        return written;
     }
-  }
-
-  private static void writeField(final String fieldName, final String fieldValue, final DataOutput dataOutput)
-      throws IOException
-  {
-    boolean isIndexed = !(fieldName.equals("i") || fieldName.equals("m"));
-    boolean isTokenized = !(fieldName.equals("i")
-        || fieldName.equals("m")
-        || fieldName.equals("1")
-        || fieldName.equals("px"));
-    int flags = (isIndexed ? F_INDEXED : 0) + (isTokenized ? F_TOKENIZED : 0) + F_STORED;
-    dataOutput.writeByte(flags);
-    dataOutput.writeUTF(fieldName);
-    writeUTF(fieldValue, dataOutput);
-  }
-
-  private static void writeUTF(final String str, final DataOutput dataOutput)
-      throws IOException
-  {
-    int strlen = str.length();
-    int utflen = 0;
-    int c;
-    // use charAt instead of copying String to char array
-    for (int i = 0; i < strlen; i++) {
-      c = str.charAt(i);
-      if ((c >= 0x0001) && (c <= 0x007F)) {
-        utflen++;
-      }
-      else if (c > 0x07FF) {
-        utflen += 3;
-      }
-      else {
-        utflen += 2;
-      }
+
+    /**
+     * Closes this reader and it's underlying input.
+     */
+    public void close()
+        throws IOException
+    {
+        dataOutputStream.close();
     }
-    dataOutput.writeInt(utflen);
-    byte[] bytearr = new byte[utflen];
-    int count = 0;
-    int i = 0;
-    for (; i < strlen; i++) {
-      c = str.charAt(i);
-      if (!((c >= 0x0001) && (c <= 0x007F))) {
-        break;
-      }
-      bytearr[count++] = (byte) c;
+
+    private static void writeRecord( final Map<String, String> record, final DataOutput dataOutput )
+        throws IOException
+    {
+        dataOutput.writeInt( record.size() );
+        for ( Map.Entry<String, String> entry : record.entrySet() )
+        {
+            writeField( entry.getKey(), entry.getValue(), dataOutput );
+        }
     }
-    for (; i < strlen; i++) {
-      c = str.charAt(i);
-      if ((c >= 0x0001) && (c <= 0x007F)) {
-        bytearr[count++] = (byte) c;
-
-      }
-      else if (c > 0x07FF) {
-        bytearr[count++] = (byte) (0xE0 | ((c >> 12) & 0x0F));
-        bytearr[count++] = (byte) (0x80 | ((c >> 6) & 0x3F));
-        bytearr[count++] = (byte) (0x80 | ((c >> 0) & 0x3F));
-      }
-      else {
-        bytearr[count++] = (byte) (0xC0 | ((c >> 6) & 0x1F));
-        bytearr[count++] = (byte) (0x80 | ((c >> 0) & 0x3F));
-      }
+
+    private static void writeField( final String fieldName, final String fieldValue, final DataOutput dataOutput )
+        throws IOException
+    {
+        boolean isIndexed = !( fieldName.equals( "i" ) || fieldName.equals( "m" ) );
+        boolean isTokenized =
+            !( fieldName.equals( "i" ) || fieldName.equals( "m" ) || fieldName.equals( "1" ) || fieldName.equals(
+                "px" ) );
+        int flags = ( isIndexed ? F_INDEXED : 0 ) + ( isTokenized ? F_TOKENIZED : 0 ) + F_STORED;
+        dataOutput.writeByte( flags );
+        dataOutput.writeUTF( fieldName );
+        writeUTF( fieldValue, dataOutput );
+    }
+
+    private static void writeUTF( final String str, final DataOutput dataOutput )
+        throws IOException
+    {
+        int strlen = str.length();
+        int utflen = 0;
+        int c;
+        // use charAt instead of copying String to char array
+        for ( int i = 0; i < strlen; i++ )
+        {
+            c = str.charAt( i );
+            if ( ( c >= 0x0001 ) && ( c <= 0x007F ) )
+            {
+                utflen++;
+            }
+            else if ( c > 0x07FF )
+            {
+                utflen += 3;
+            }
+            else
+            {
+                utflen += 2;
+            }
+        }
+        dataOutput.writeInt( utflen );
+        byte[] bytearr = new byte[utflen];
+        int count = 0;
+        int i = 0;
+        for ( ; i < strlen; i++ )
+        {
+            c = str.charAt( i );
+            if ( !( ( c >= 0x0001 ) && ( c <= 0x007F ) ) )
+            {
+                break;
+            }
+            bytearr[count++] = (byte) c;
+        }
+        for ( ; i < strlen; i++ )
+        {
+            c = str.charAt( i );
+            if ( ( c >= 0x0001 ) && ( c <= 0x007F ) )
+            {
+                bytearr[count++] = (byte) c;
+
+            }
+            else if ( c > 0x07FF )
+            {
+                bytearr[count++] = (byte) ( 0xE0 | ( ( c >> 12 ) & 0x0F ) );
+                bytearr[count++] = (byte) ( 0x80 | ( ( c >> 6 ) & 0x3F ) );
+                bytearr[count++] = (byte) ( 0x80 | ( ( c >> 0 ) & 0x3F ) );
+            }
+            else
+            {
+                bytearr[count++] = (byte) ( 0xC0 | ( ( c >> 6 ) & 0x1F ) );
+                bytearr[count++] = (byte) ( 0x80 | ( ( c >> 0 ) & 0x3F ) );
+            }
+        }
+        dataOutput.write( bytearr, 0, utflen );
     }
-    dataOutput.write(bytearr, 0, utflen);
-  }
 }

http://git-wip-us.apache.org/repos/asf/maven-indexer/blob/8d096a88/indexer-reader/src/main/java/org/apache/maven/index/reader/IndexReader.java
----------------------------------------------------------------------
diff --git a/indexer-reader/src/main/java/org/apache/maven/index/reader/IndexReader.java b/indexer-reader/src/main/java/org/apache/maven/index/reader/IndexReader.java
index 1f75864..8f3ee2a 100644
--- a/indexer-reader/src/main/java/org/apache/maven/index/reader/IndexReader.java
+++ b/indexer-reader/src/main/java/org/apache/maven/index/reader/IndexReader.java
@@ -19,6 +19,8 @@ package org.apache.maven.index.reader;
  * under the License.
  */
 
+import org.apache.maven.index.reader.ResourceHandler.Resource;
+
 import java.io.Closeable;
 import java.io.IOException;
 import java.text.ParseException;
@@ -29,8 +31,6 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Properties;
 
-import org.apache.maven.index.reader.ResourceHandler.Resource;
-
 import static org.apache.maven.index.reader.Utils.loadProperties;
 import static org.apache.maven.index.reader.Utils.storeProperties;
 
@@ -43,230 +43,272 @@ import static org.apache.maven.index.reader.Utils.storeProperties;
 public class IndexReader
     implements Iterable<ChunkReader>, Closeable
 {
-  private final WritableResourceHandler local;
+    private final WritableResourceHandler local;
 
-  private final ResourceHandler remote;
+    private final ResourceHandler remote;
 
-  private final Properties localIndexProperties;
+    private final Properties localIndexProperties;
 
-  private final Properties remoteIndexProperties;
+    private final Properties remoteIndexProperties;
 
-  private final String indexId;
+    private final String indexId;
 
-  private final Date publishedTimestamp;
+    private final Date publishedTimestamp;
 
-  private final boolean incremental;
+    private final boolean incremental;
 
-  private final List<String> chunkNames;
+    private final List<String> chunkNames;
 
-  public IndexReader(final WritableResourceHandler local, final ResourceHandler remote) throws IOException {
-    if (remote == null) {
-      throw new NullPointerException("remote resource handler null");
-    }
-    this.local = local;
-    this.remote = remote;
-    remoteIndexProperties = loadProperties(remote.locate(Utils.INDEX_FILE_PREFIX + ".properties"));
-    if (remoteIndexProperties == null) {
-      throw new IllegalArgumentException("Non-existent remote index");
-    }
-    try {
-      if (local != null) {
-        Properties localProperties = loadProperties(local.locate(Utils.INDEX_FILE_PREFIX + ".properties"));
-        if (localProperties != null) {
-          this.localIndexProperties = localProperties;
-          String remoteIndexId = remoteIndexProperties.getProperty("nexus.index.id");
-          String localIndexId = localIndexProperties.getProperty("nexus.index.id");
-          if (remoteIndexId == null || localIndexId == null || !remoteIndexId.equals(localIndexId)) {
-            throw new IllegalArgumentException(
-                "local and remote index IDs does not match or is null: " + localIndexId + ", " +
-                    remoteIndexId);
-          }
-          this.indexId = localIndexId;
-          this.incremental = canRetrieveAllChunks();
+    public IndexReader( final WritableResourceHandler local, final ResourceHandler remote )
+        throws IOException
+    {
+        if ( remote == null )
+        {
+            throw new NullPointerException( "remote resource handler null" );
+        }
+        this.local = local;
+        this.remote = remote;
+        remoteIndexProperties = loadProperties( remote.locate( Utils.INDEX_FILE_PREFIX + ".properties" ) );
+        if ( remoteIndexProperties == null )
+        {
+            throw new IllegalArgumentException( "Non-existent remote index" );
+        }
+        try
+        {
+            if ( local != null )
+            {
+                Properties localProperties = loadProperties( local.locate( Utils.INDEX_FILE_PREFIX + ".properties" ) );
+                if ( localProperties != null )
+                {
+                    this.localIndexProperties = localProperties;
+                    String remoteIndexId = remoteIndexProperties.getProperty( "nexus.index.id" );
+                    String localIndexId = localIndexProperties.getProperty( "nexus.index.id" );
+                    if ( remoteIndexId == null || localIndexId == null || !remoteIndexId.equals( localIndexId ) )
+                    {
+                        throw new IllegalArgumentException(
+                            "local and remote index IDs does not match or is null: " + localIndexId + ", "
+                                + remoteIndexId );
+                    }
+                    this.indexId = localIndexId;
+                    this.incremental = canRetrieveAllChunks();
+                }
+                else
+                {
+                    localIndexProperties = null;
+                    this.indexId = remoteIndexProperties.getProperty( "nexus.index.id" );
+                    this.incremental = false;
+                }
+            }
+            else
+            {
+                localIndexProperties = null;
+                this.indexId = remoteIndexProperties.getProperty( "nexus.index.id" );
+                this.incremental = false;
+            }
+            this.publishedTimestamp =
+                Utils.INDEX_DATE_FORMAT.parse( remoteIndexProperties.getProperty( "nexus.index.timestamp" ) );
+            this.chunkNames = calculateChunkNames();
         }
-        else {
-          localIndexProperties = null;
-          this.indexId = remoteIndexProperties.getProperty("nexus.index.id");
-          this.incremental = false;
+        catch ( ParseException e )
+        {
+            IOException ex = new IOException( "Index properties corrupted" );
+            ex.initCause( e );
+            throw ex;
         }
-      }
-      else {
-        localIndexProperties = null;
-        this.indexId = remoteIndexProperties.getProperty("nexus.index.id");
-        this.incremental = false;
-      }
-      this.publishedTimestamp = Utils.INDEX_DATE_FORMAT.parse(remoteIndexProperties.getProperty("nexus.index.timestamp"));
-      this.chunkNames = calculateChunkNames();
     }
-    catch (ParseException e) {
-      IOException ex = new IOException("Index properties corrupted");
-      ex.initCause(e);
-      throw ex;
+
+    /**
+     * Returns the index context ID that published index has set. Usually it is equal to "repository ID" used in {@link
+     * Record.Type#DESCRIPTOR} but does not have to be.
+     */
+    public String getIndexId()
+    {
+        return indexId;
+    }
+
+    /**
+     * Returns the {@link Date} when remote index was last published.
+     */
+    public Date getPublishedTimestamp()
+    {
+        return publishedTimestamp;
     }
-  }
-
-  /**
-   * Returns the index context ID that published index has set. Usually it is equal to "repository ID" used in {@link
-   * Record.Type#DESCRIPTOR} but does not have to be.
-   */
-  public String getIndexId() {
-    return indexId;
-  }
-
-  /**
-   * Returns the {@link Date} when remote index was last published.
-   */
-  public Date getPublishedTimestamp() {
-    return publishedTimestamp;
-  }
-
-  /**
-   * Returns {@code true} if incremental update is about to happen. If incremental update, the {@link #iterator()} will
-   * return only the diff from the last update.
-   */
-  public boolean isIncremental() {
-    return incremental;
-  }
-
-  /**
-   * Returns unmodifiable list of actual chunks that needs to be pulled from remote {@link ResourceHandler}. Those are
-   * incremental chunks or the big main file, depending on result of {@link #isIncremental()}. Empty list means local
-   * index is up to date, and {@link #iterator()} will return empty iterator.
-   */
-  public List<String> getChunkNames() {
-    return chunkNames;
-  }
-
-  /**
-   * Closes the underlying {@link ResourceHandler}s. In case of incremental update use, it also assumes that user
-   * consumed all the iterator and integrated it, hence, it will update the {@link WritableResourceHandler} contents to
-   * prepare it for future incremental update. If this is not desired (ie. due to aborted update), then this method
-   * should NOT be invoked, but rather the {@link ResourceHandler}s that caller provided in constructor of
-   * this class should be closed manually.
-   */
-  public void close() throws IOException {
-    remote.close();
-    if (local != null) {
-      try {
-        syncLocalWithRemote();
-      }
-      finally {
-        local.close();
-      }
+
+    /**
+     * Returns {@code true} if incremental update is about to happen. If incremental update, the {@link #iterator()} will
+     * return only the diff from the last update.
+     */
+    public boolean isIncremental()
+    {
+        return incremental;
     }
-  }
-
-  /**
-   * Returns an {@link Iterator} of {@link ChunkReader}s, that if read in sequence, provide all the (incremental)
-   * updates from the index. It is caller responsibility to either consume fully this iterator, or to close current
-   * {@link ChunkReader} if aborting.
-   */
-  public Iterator<ChunkReader> iterator() {
-    return new ChunkReaderIterator(remote, chunkNames.iterator());
-  }
-
-  /**
-   * Stores the remote index properties into local index properties, preparing local {@link WritableResourceHandler}
-   * for future incremental updates.
-   */
-  private void syncLocalWithRemote() throws IOException {
-    storeProperties(local.locate(Utils.INDEX_FILE_PREFIX + ".properties"), remoteIndexProperties);
-  }
-
-  /**
-   * Calculates the chunk names that needs to be fetched.
-   */
-  private List<String> calculateChunkNames() {
-    if (incremental) {
-      ArrayList<String> chunkNames = new ArrayList<>();
-      int maxCounter = Integer.parseInt(remoteIndexProperties.getProperty("nexus.index.last-incremental"));
-      int currentCounter = Integer.parseInt(localIndexProperties.getProperty("nexus.index.last-incremental"));
-      currentCounter++;
-      while (currentCounter <= maxCounter) {
-        chunkNames.add(Utils.INDEX_FILE_PREFIX + "." + currentCounter++ + ".gz");
-      }
-      return Collections.unmodifiableList(chunkNames);
+
+    /**
+     * Returns unmodifiable list of actual chunks that needs to be pulled from remote {@link ResourceHandler}. Those are
+     * incremental chunks or the big main file, depending on result of {@link #isIncremental()}. Empty list means local
+     * index is up to date, and {@link #iterator()} will return empty iterator.
+     */
+    public List<String> getChunkNames()
+    {
+        return chunkNames;
+    }
+
+    /**
+     * Closes the underlying {@link ResourceHandler}s. In case of incremental update use, it also assumes that user
+     * consumed all the iterator and integrated it, hence, it will update the {@link WritableResourceHandler} contents to
+     * prepare it for future incremental update. If this is not desired (ie. due to aborted update), then this method
+     * should NOT be invoked, but rather the {@link ResourceHandler}s that caller provided in constructor of
+     * this class should be closed manually.
+     */
+    public void close()
+        throws IOException
+    {
+        remote.close();
+        if ( local != null )
+        {
+            try
+            {
+                syncLocalWithRemote();
+            }
+            finally
+            {
+                local.close();
+            }
+        }
     }
-    else {
-      return Collections.singletonList(Utils.INDEX_FILE_PREFIX + ".gz");
+
+    /**
+     * Returns an {@link Iterator} of {@link ChunkReader}s, that if read in sequence, provide all the (incremental)
+     * updates from the index. It is caller responsibility to either consume fully this iterator, or to close current
+     * {@link ChunkReader} if aborting.
+     */
+    public Iterator<ChunkReader> iterator()
+    {
+        return new ChunkReaderIterator( remote, chunkNames.iterator() );
     }
-  }
-
-  /**
-   * Verifies incremental update is possible, as all the diff chunks we need are still enlisted in remote properties.
-   */
-  private boolean canRetrieveAllChunks()
-  {
-    String localChainId = localIndexProperties.getProperty("nexus.index.chain-id");
-    String remoteChainId = remoteIndexProperties.getProperty("nexus.index.chain-id");
-
-    // If no chain id, or not the same, do full update
-    if (localChainId == null || remoteChainId == null || !localChainId.equals(remoteChainId)) {
-      return false;
+
+    /**
+     * Stores the remote index properties into local index properties, preparing local {@link WritableResourceHandler}
+     * for future incremental updates.
+     */
+    private void syncLocalWithRemote()
+        throws IOException
+    {
+        storeProperties( local.locate( Utils.INDEX_FILE_PREFIX + ".properties" ), remoteIndexProperties );
     }
 
-    try {
-      int localLastIncremental = Integer.parseInt(localIndexProperties.getProperty("nexus.index.last-incremental"));
-      String currentLocalCounter = String.valueOf(localLastIncremental);
-      String nextLocalCounter = String.valueOf(localLastIncremental + 1);
-      // check remote props for existence of current or next chunk after local
-      for (Object key : remoteIndexProperties.keySet()) {
-        String sKey = (String) key;
-        if (sKey.startsWith("nexus.index.incremental-")) {
-          String value = remoteIndexProperties.getProperty(sKey);
-          if (currentLocalCounter.equals(value) || nextLocalCounter.equals(value)) {
-            return true;
-          }
+    /**
+     * Calculates the chunk names that needs to be fetched.
+     */
+    private List<String> calculateChunkNames()
+    {
+        if ( incremental )
+        {
+            ArrayList<String> chunkNames = new ArrayList<>();
+            int maxCounter = Integer.parseInt( remoteIndexProperties.getProperty( "nexus.index.last-incremental" ) );
+            int currentCounter = Integer.parseInt( localIndexProperties.getProperty( "nexus.index.last-incremental" ) );
+            currentCounter++;
+            while ( currentCounter <= maxCounter )
+            {
+                chunkNames.add( Utils.INDEX_FILE_PREFIX + "." + currentCounter++ + ".gz" );
+            }
+            return Collections.unmodifiableList( chunkNames );
+        }
+        else
+        {
+            return Collections.singletonList( Utils.INDEX_FILE_PREFIX + ".gz" );
         }
-      }
     }
-    catch (NumberFormatException e) {
-      // fall through
+
+    /**
+     * Verifies incremental update is possible, as all the diff chunks we need are still enlisted in remote properties.
+     */
+    private boolean canRetrieveAllChunks()
+    {
+        String localChainId = localIndexProperties.getProperty( "nexus.index.chain-id" );
+        String remoteChainId = remoteIndexProperties.getProperty( "nexus.index.chain-id" );
+
+        // If no chain id, or not the same, do full update
+        if ( localChainId == null || remoteChainId == null || !localChainId.equals( remoteChainId ) )
+        {
+            return false;
+        }
+
+        try
+        {
+            int localLastIncremental =
+                Integer.parseInt( localIndexProperties.getProperty( "nexus.index.last-incremental" ) );
+            String currentLocalCounter = String.valueOf( localLastIncremental );
+            String nextLocalCounter = String.valueOf( localLastIncremental + 1 );
+            // check remote props for existence of current or next chunk after local
+            for ( Object key : remoteIndexProperties.keySet() )
+            {
+                String sKey = (String) key;
+                if ( sKey.startsWith( "nexus.index.incremental-" ) )
+                {
+                    String value = remoteIndexProperties.getProperty( sKey );
+                    if ( currentLocalCounter.equals( value ) || nextLocalCounter.equals( value ) )
+                    {
+                        return true;
+                    }
+                }
+            }
+        }
+        catch ( NumberFormatException e )
+        {
+            // fall through
+        }
+        return false;
     }
-    return false;
-  }
 
-  /**
-   * Internal iterator implementation that lazily opens and closes the returned {@link ChunkReader}s as this iterator
-   * is being consumed.
-   */
-  private static class ChunkReaderIterator
-      implements Iterator<ChunkReader>
-  {
-    private final ResourceHandler resourceHandler;
+    /**
+     * Internal iterator implementation that lazily opens and closes the returned {@link ChunkReader}s as this iterator
+     * is being consumed.
+     */
+    private static class ChunkReaderIterator
+        implements Iterator<ChunkReader>
+    {
+        private final ResourceHandler resourceHandler;
 
-    private final Iterator<String> chunkNamesIterator;
+        private final Iterator<String> chunkNamesIterator;
 
-    private Resource currentResource;
+        private Resource currentResource;
 
-    private ChunkReader currentChunkReader;
+        private ChunkReader currentChunkReader;
 
-    private ChunkReaderIterator(final ResourceHandler resourceHandler, final Iterator<String> chunkNamesIterator) {
-      this.resourceHandler = resourceHandler;
-      this.chunkNamesIterator = chunkNamesIterator;
-    }
+        private ChunkReaderIterator( final ResourceHandler resourceHandler, final Iterator<String> chunkNamesIterator )
+        {
+            this.resourceHandler = resourceHandler;
+            this.chunkNamesIterator = chunkNamesIterator;
+        }
 
-    public boolean hasNext() {
-      return chunkNamesIterator.hasNext();
-    }
+        public boolean hasNext()
+        {
+            return chunkNamesIterator.hasNext();
+        }
 
-    public ChunkReader next() {
-      String chunkName = chunkNamesIterator.next();
-      try {
-        if (currentChunkReader != null) {
-          currentChunkReader.close();
+        public ChunkReader next()
+        {
+            String chunkName = chunkNamesIterator.next();
+            try
+            {
+                if ( currentChunkReader != null )
+                {
+                    currentChunkReader.close();
+                }
+                currentResource = resourceHandler.locate( chunkName );
+                currentChunkReader = new ChunkReader( chunkName, currentResource.read() );
+                return currentChunkReader;
+            }
+            catch ( IOException e )
+            {
+                throw new RuntimeException( "IO problem while switching chunk readers", e );
+            }
         }
-        currentResource = resourceHandler.locate(chunkName);
-        currentChunkReader = new ChunkReader(chunkName, currentResource.read());
-        return currentChunkReader;
-      }
-      catch (IOException e) {
-        throw new RuntimeException("IO problem while switching chunk readers", e);
-      }
-    }
 
-    public void remove() {
-      throw new UnsupportedOperationException("remove");
+        public void remove()
+        {
+            throw new UnsupportedOperationException( "remove" );
+        }
     }
-  }
 }

http://git-wip-us.apache.org/repos/asf/maven-indexer/blob/8d096a88/indexer-reader/src/main/java/org/apache/maven/index/reader/IndexWriter.java
----------------------------------------------------------------------
diff --git a/indexer-reader/src/main/java/org/apache/maven/index/reader/IndexWriter.java b/indexer-reader/src/main/java/org/apache/maven/index/reader/IndexWriter.java
index 68d4abb..e997b67 100644
--- a/indexer-reader/src/main/java/org/apache/maven/index/reader/IndexWriter.java
+++ b/indexer-reader/src/main/java/org/apache/maven/index/reader/IndexWriter.java
@@ -19,6 +19,8 @@ package org.apache.maven.index.reader;
  * under the License.
  */
 
+import org.apache.maven.index.reader.WritableResourceHandler.WritableResource;
+
 import java.io.Closeable;
 import java.io.IOException;
 import java.text.ParseException;
@@ -28,8 +30,6 @@ import java.util.Map;
 import java.util.Properties;
 import java.util.UUID;
 
-import org.apache.maven.index.reader.WritableResourceHandler.WritableResource;
-
 import static org.apache.maven.index.reader.Utils.loadProperties;
 import static org.apache.maven.index.reader.Utils.storeProperties;
 
@@ -44,153 +44,177 @@ import static org.apache.maven.index.reader.Utils.storeProperties;
 public class IndexWriter
     implements Closeable
 {
-  private static final int INDEX_V1 = 1;
-
-  private final WritableResourceHandler local;
-
-  private final Properties localIndexProperties;
-
-  private final boolean incremental;
-
-  private final String nextChunkCounter;
-
-  private final String nextChunkName;
-
-  public IndexWriter(final WritableResourceHandler local, final String indexId, final boolean incrementalSupported)
-      throws IOException
-  {
-    if (local == null) {
-      throw new NullPointerException("local resource handler null");
-    }
-    if (indexId == null) {
-      throw new NullPointerException("indexId null");
+    private static final int INDEX_V1 = 1;
+
+    private final WritableResourceHandler local;
+
+    private final Properties localIndexProperties;
+
+    private final boolean incremental;
+
+    private final String nextChunkCounter;
+
+    private final String nextChunkName;
+
+    public IndexWriter( final WritableResourceHandler local, final String indexId, final boolean incrementalSupported )
+        throws IOException
+    {
+        if ( local == null )
+        {
+            throw new NullPointerException( "local resource handler null" );
+        }
+        if ( indexId == null )
+        {
+            throw new NullPointerException( "indexId null" );
+        }
+        this.local = local;
+        Properties indexProperties = loadProperties( local.locate( Utils.INDEX_FILE_PREFIX + ".properties" ) );
+        if ( incrementalSupported && indexProperties != null )
+        {
+            this.localIndexProperties = indexProperties;
+            // existing index, this is incremental publish, and we will add new chunk
+            String localIndexId = localIndexProperties.getProperty( "nexus.index.id" );
+            if ( localIndexId == null || !localIndexId.equals( indexId ) )
+            {
+                throw new IllegalArgumentException(
+                    "index already exists and indexId mismatch or unreadable: " + localIndexId + ", " + indexId );
+            }
+            this.incremental = true;
+            this.nextChunkCounter = calculateNextChunkCounter();
+            this.nextChunkName = Utils.INDEX_FILE_PREFIX + "." + nextChunkCounter + ".gz";
+        }
+        else
+        {
+            // non-existing index, create published index from scratch
+            this.localIndexProperties = new Properties();
+            this.localIndexProperties.setProperty( "nexus.index.id", indexId );
+            this.localIndexProperties.setProperty( "nexus.index.chain-id", UUID.randomUUID().toString() );
+            this.incremental = false;
+            this.nextChunkCounter = null;
+            this.nextChunkName = Utils.INDEX_FILE_PREFIX + ".gz";
+        }
     }
-    this.local = local;
-    Properties indexProperties = loadProperties(local.locate(Utils.INDEX_FILE_PREFIX + ".properties"));
-    if (incrementalSupported && indexProperties != null) {
-      this.localIndexProperties = indexProperties;
-      // existing index, this is incremental publish, and we will add new chunk
-      String localIndexId = localIndexProperties.getProperty("nexus.index.id");
-      if (localIndexId == null || !localIndexId.equals(indexId)) {
-        throw new IllegalArgumentException(
-            "index already exists and indexId mismatch or unreadable: " + localIndexId + ", " +
-                indexId);
-      }
-      this.incremental = true;
-      this.nextChunkCounter = calculateNextChunkCounter();
-      this.nextChunkName = Utils.INDEX_FILE_PREFIX + "." + nextChunkCounter + ".gz";
-    }
-    else {
-      // non-existing index, create published index from scratch
-      this.localIndexProperties = new Properties();
-      this.localIndexProperties.setProperty("nexus.index.id", indexId);
-      this.localIndexProperties.setProperty("nexus.index.chain-id", UUID.randomUUID().toString());
-      this.incremental = false;
-      this.nextChunkCounter = null;
-      this.nextChunkName = Utils.INDEX_FILE_PREFIX + ".gz";
-    }
-  }
-
-  /**
-   * Returns the index context ID that published index has set.
-   */
-  public String getIndexId() {
-    return localIndexProperties.getProperty("nexus.index.id");
-  }
-
-  /**
-   * Returns the {@link Date} when index was last published or {@code null} if this is first publishing. In other
-   * words,returns {@code null} when {@link #isIncremental()} returns {@code false}. After this writer is closed, the
-   * return value is updated to "now" (in {@link #close() method}.
-   */
-  public Date getPublishedTimestamp() {
-    try {
-      String timestamp = localIndexProperties.getProperty("nexus.index.timestamp");
-      if (timestamp != null) {
-        return Utils.INDEX_DATE_FORMAT.parse(timestamp);
-      }
-      return null;
+
+    /**
+     * Returns the index context ID that published index has set.
+     */
+    public String getIndexId()
+    {
+        return localIndexProperties.getProperty( "nexus.index.id" );
     }
-    catch (ParseException e) {
-      throw new RuntimeException("Corrupt date", e);
+
+    /**
+     * Returns the {@link Date} when index was last published or {@code null} if this is first publishing. In other
+     * words,returns {@code null} when {@link #isIncremental()} returns {@code false}. After this writer is closed, the
+     * return value is updated to "now" (in {@link #close() method}.
+     */
+    public Date getPublishedTimestamp()
+    {
+        try
+        {
+            String timestamp = localIndexProperties.getProperty( "nexus.index.timestamp" );
+            if ( timestamp != null )
+            {
+                return Utils.INDEX_DATE_FORMAT.parse( timestamp );
+            }
+            return null;
+        }
+        catch ( ParseException e )
+        {
+            throw new RuntimeException( "Corrupt date", e );
+        }
     }
-  }
-
-  /**
-   * Returns {@code true} if incremental publish is about to happen.
-   */
-  public boolean isIncremental() {
-    return incremental;
-  }
-
-  /**
-   * Returns the chain id of published index. If {@link #isIncremental()} is {@code false}, this is the newly generated
-   * chain ID.
-   */
-  public String getChainId() {
-    return localIndexProperties.getProperty("nexus.index.chain-id");
-  }
-
-  /**
-   * Returns the next chunk name about to be published.
-   */
-  public String getNextChunkName() {
-    return nextChunkName;
-  }
-
-  /**
-   * Writes out the record iterator and returns the written record count.
-   */
-  public int writeChunk(final Iterator<Map<String, String>> iterator) throws IOException {
-    int written;
-    WritableResource writableResource = local.locate(nextChunkName);
-    try {
-      final ChunkWriter chunkWriter = new ChunkWriter(nextChunkName, writableResource.write(), INDEX_V1, new Date());
-      try {
-        written = chunkWriter.writeChunk(iterator);
-      }
-      finally {
-        chunkWriter.close();
-      }
-      if (incremental) {
-        // TODO: update main gz file
-      }
-      return written;
+
+    /**
+     * Returns {@code true} if incremental publish is about to happen.
+     */
+    public boolean isIncremental()
+    {
+        return incremental;
     }
-    finally {
-      writableResource.close();
+
+    /**
+     * Returns the chain id of published index. If {@link #isIncremental()} is {@code false}, this is the newly generated
+     * chain ID.
+     */
+    public String getChainId()
+    {
+        return localIndexProperties.getProperty( "nexus.index.chain-id" );
     }
-  }
-
-  /**
-   * Closes the underlying {@link ResourceHandler} and synchronizes published index properties, so remote clients
-   * becomes able to consume newly published index. If sync is not desired (ie. due to aborted publish), then this
-   * method should NOT be invoked, but rather the {@link ResourceHandler} that caller provided in constructor of
-   * this class should be closed manually.
-   */
-  public void close() throws IOException {
-    try {
-      if (incremental) {
-        localIndexProperties.setProperty("nexus.index.last-incremental", nextChunkCounter);
-      }
-      localIndexProperties.setProperty("nexus.index.timestamp", Utils.INDEX_DATE_FORMAT.format(new Date()));
-      storeProperties(local.locate(Utils.INDEX_FILE_PREFIX + ".properties"), localIndexProperties);
+
+    /**
+     * Returns the next chunk name about to be published.
+     */
+    public String getNextChunkName()
+    {
+        return nextChunkName;
     }
-    finally {
-      local.close();
+
+    /**
+     * Writes out the record iterator and returns the written record count.
+     */
+    public int writeChunk( final Iterator<Map<String, String>> iterator )
+        throws IOException
+    {
+        int written;
+
+        try (WritableResource writableResource = local.locate( nextChunkName ))
+        {
+            final ChunkWriter chunkWriter =
+                new ChunkWriter( nextChunkName, writableResource.write(), INDEX_V1, new Date() );
+            try
+            {
+                written = chunkWriter.writeChunk( iterator );
+            }
+            finally
+            {
+                chunkWriter.close();
+            }
+            if ( incremental )
+            {
+                // TODO: update main gz file
+            }
+            return written;
+        }
     }
-  }
-
-  /**
-   * Calculates the chunk names that needs to be fetched.
-   */
-  private String calculateNextChunkCounter() {
-    String lastChunkCounter = localIndexProperties.getProperty("nexus.index.last-incremental");
-    if (lastChunkCounter != null) {
-      return String.valueOf(Integer.parseInt(lastChunkCounter) + 1);
+
+    /**
+     * Closes the underlying {@link ResourceHandler} and synchronizes published index properties, so remote clients
+     * becomes able to consume newly published index. If sync is not desired (ie. due to aborted publish), then this
+     * method should NOT be invoked, but rather the {@link ResourceHandler} that caller provided in constructor of
+     * this class should be closed manually.
+     */
+    public void close()
+        throws IOException
+    {
+        try
+        {
+            if ( incremental )
+            {
+                localIndexProperties.setProperty( "nexus.index.last-incremental", nextChunkCounter );
+            }
+            localIndexProperties.setProperty( "nexus.index.timestamp", Utils.INDEX_DATE_FORMAT.format( new Date() ) );
+            storeProperties( local.locate( Utils.INDEX_FILE_PREFIX + ".properties" ), localIndexProperties );
+        }
+        finally
+        {
+            local.close();
+        }
     }
-    else {
-      return "1";
+
+    /**
+     * Calculates the chunk names that needs to be fetched.
+     */
+    private String calculateNextChunkCounter()
+    {
+        String lastChunkCounter = localIndexProperties.getProperty( "nexus.index.last-incremental" );
+        if ( lastChunkCounter != null )
+        {
+            return String.valueOf( Integer.parseInt( lastChunkCounter ) + 1 );
+        }
+        else
+        {
+            return "1";
+        }
     }
-  }
 }

http://git-wip-us.apache.org/repos/asf/maven-indexer/blob/8d096a88/indexer-reader/src/main/java/org/apache/maven/index/reader/Record.java
----------------------------------------------------------------------
diff --git a/indexer-reader/src/main/java/org/apache/maven/index/reader/Record.java b/indexer-reader/src/main/java/org/apache/maven/index/reader/Record.java
index fce1a19..e636ff1 100644
--- a/indexer-reader/src/main/java/org/apache/maven/index/reader/Record.java
+++ b/indexer-reader/src/main/java/org/apache/maven/index/reader/Record.java
@@ -28,385 +28,406 @@ import java.util.Map;
  */
 public final class Record
 {
-  public static final class EntryKey<T>
-  {
-    private final String name;
-
-    private final Class<T> proto;
-
-    public EntryKey(final String name, final Class<T> proto) {
-      if (name == null) {
-        throw new NullPointerException("name is null");
-      }
-      if (proto == null) {
-        throw new NullPointerException("proto is null");
-      }
-      this.name = name;
-      this.proto = proto;
+    public static final class EntryKey<T>
+    {
+        private final String name;
+
+        private final Class<T> proto;
+
+        public EntryKey( final String name, final Class<T> proto )
+        {
+            if ( name == null )
+            {
+                throw new NullPointerException( "name is null" );
+            }
+            if ( proto == null )
+            {
+                throw new NullPointerException( "proto is null" );
+            }
+            this.name = name;
+            this.proto = proto;
+        }
+
+        public T coerce( final Object object )
+        {
+            return (T) proto.cast( object );
+        }
+
+        @Override
+        public boolean equals( final Object o )
+        {
+            if ( this == o )
+            {
+                return true;
+            }
+            if ( !( o instanceof EntryKey ) )
+            {
+                return false;
+            }
+            EntryKey entryKey = (EntryKey) o;
+            return name.equals( entryKey.name );
+        }
+
+        @Override
+        public int hashCode()
+        {
+            return name.hashCode();
+        }
+
+        @Override
+        public String toString()
+        {
+            return "Key{" + "name='" + name + '\'' + ", type=" + proto.getSimpleName() + '}';
+        }
     }
 
-    public T coerce(final Object object) {
-      return (T) proto.cast(object);
+    /**
+     * Key of repository ID entry, that contains {@link String}.
+     */
+    public static final EntryKey<String> REPOSITORY_ID = new EntryKey<String>( "repositoryId", String.class );
+
+    /**
+     * Key of all groups list entry, that contains {@link java.util.List<String>}.
+     */
+    public static final EntryKey<String[]> ALL_GROUPS = new EntryKey<String[]>( "allGroups", String[].class );
+
+    /**
+     * Key of root groups list entry, that contains {@link java.util.List<String>}.
+     */
+    public static final EntryKey<String[]> ROOT_GROUPS = new EntryKey<String[]>( "rootGroups", String[].class );
+
+    /**
+     * Key of index record modification (added to index or removed from index) timestamp entry, that contains {@link
+     * Long}.
+     */
+    public static final EntryKey<Long> REC_MODIFIED = new EntryKey<Long>( "recordModified", Long.class );
+
+    /**
+     * Key of artifact groupId entry, that contains {@link String}.
+     */
+    public static final EntryKey<String> GROUP_ID = new EntryKey<String>( "groupId", String.class );
+
+    /**
+     * Key of artifact artifactId entry, that contains {@link String}.
+     */
+    public static final EntryKey<String> ARTIFACT_ID = new EntryKey<String>( "artifactId", String.class );
+
+    /**
+     * Key of artifact version entry, that contains {@link String}.
+     */
+    public static final EntryKey<String> VERSION = new EntryKey<String>( "version", String.class );
+
+    /**
+     * Key of artifact classifier entry, that contains {@link String}.
+     */
+    public static final EntryKey<String> CLASSIFIER = new EntryKey<String>( "classifier", String.class );
+
+    /**
+     * Key of artifact packaging entry, that contains {@link String}.
+     */
+    public static final EntryKey<String> PACKAGING = new EntryKey<String>( "packaging", String.class );
+
+    /**
+     * Key of artifact file extension, that contains {@link String}.
+     */
+    public static final EntryKey<String> FILE_EXTENSION = new EntryKey<String>( "fileExtension", String.class );
+
+    /**
+     * Key of artifact file last modified timestamp, that contains {@link Long}.
+     */
+    public static final EntryKey<Long> FILE_MODIFIED = new EntryKey<Long>( "fileModified", Long.class );
+
+    /**
+     * Key of artifact file size in bytes, that contains {@link Long}.
+     */
+    public static final EntryKey<Long> FILE_SIZE = new EntryKey<Long>( "fileSize", Long.class );
+
+    /**
+     * Key of artifact Sources presence flag, that contains {@link Boolean}.
+     */
+    public static final EntryKey<Boolean> HAS_SOURCES = new EntryKey<Boolean>( "hasSources", Boolean.class );
+
+    /**
+     * Key of artifact Javadoc presence flag, that contains {@link Boolean}.
+     */
+    public static final EntryKey<Boolean> HAS_JAVADOC = new EntryKey<Boolean>( "hasJavadoc", Boolean.class );
+
+    /**
+     * Key of artifact signature presence flag, that contains {@link Boolean}.
+     */
+    public static final EntryKey<Boolean> HAS_SIGNATURE = new EntryKey<Boolean>( "hasSignature", Boolean.class );
+
+    /**
+     * Key of artifact name (as set in POM), that contains {@link String}.
+     */
+    public static final EntryKey<String> NAME = new EntryKey<String>( "name", String.class );
+
+    /**
+     * Key of artifact description (as set in POM), that contains {@link String}.
+     */
+    public static final EntryKey<String> DESCRIPTION = new EntryKey<String>( "description", String.class );
+
+    /**
+     * Key of artifact SHA1 digest, that contains {@link String}.
+     */
+    public static final EntryKey<String> SHA1 = new EntryKey<String>( "sha1", String.class );
+
+    /**
+     * Key of artifact contained class names, that contains {@link java.util.List<String>}. Extracted by {@code
+     * JarFileContentsIndexCreator}.
+     */
+    public static final EntryKey<String[]> CLASSNAMES = new EntryKey<String[]>( "classNames", String[].class );
+
+    /**
+     * Key of plugin artifact prefix, that contains {@link String}. Extracted by {@code
+     * MavenPluginArtifactInfoIndexCreator}.
+     */
+    public static final EntryKey<String> PLUGIN_PREFIX = new EntryKey<String>( "pluginPrefix", String.class );
+
+    /**
+     * Key of plugin artifact goals, that contains {@link java.util.List<String>}. Extracted by {@code
+     * MavenPluginArtifactInfoIndexCreator}.
+     */
+    public static final EntryKey<String[]> PLUGIN_GOALS = new EntryKey<String[]>( "pluginGoals", String[].class );
+
+    /**
+     * Key of OSGi "Bundle-SymbolicName" manifest entry, that contains {@link String}. Extracted by {@code
+     * OsgiArtifactIndexCreator}.
+     */
+    public static final EntryKey<String> OSGI_BUNDLE_SYMBOLIC_NAME =
+        new EntryKey<String>( "Bundle-SymbolicName", String.class );
+
+    /**
+     * Key of OSGi "Bundle-Version" manifest entry, that contains {@link String}. Extracted by {@code
+     * OsgiArtifactIndexCreator}.
+     */
+    public static final EntryKey<String> OSGI_BUNDLE_VERSION = new EntryKey<String>( "Bundle-Version", String.class );
+
+    /**
+     * Key of OSGi "Export-Package" manifest entry, that contains {@link String}. Extracted by {@code
+     * OsgiArtifactIndexCreator}.
+     */
+    public static final EntryKey<String> OSGI_EXPORT_PACKAGE = new EntryKey<String>( "Export-Package", String.class );
+
+    /**
+     * Key of OSGi "Export-Service" manifest entry, that contains {@link String}. Extracted by {@code
+     * OsgiArtifactIndexCreator}.
+     */
+    public static final EntryKey<String> OSGI_EXPORT_SERVICE = new EntryKey<String>( "Export-Service", String.class );
+
+    /**
+     * Key of OSGi "Bundle-Description" manifest entry, that contains {@link String}. Extracted by {@code
+     * OsgiArtifactIndexCreator}.
+     */
+    public static final EntryKey<String> OSGI_BUNDLE_DESCRIPTION =
+        new EntryKey<String>( "Bundle-Description", String.class );
+
+    /**
+     * Key of OSGi "Bundle-Name" manifest entry, that contains {@link String}. Extracted by {@code
+     * OsgiArtifactIndexCreator}.
+     */
+    public static final EntryKey<String> OSGI_BUNDLE_NAME = new EntryKey<String>( "Bundle-Name", String.class );
+
+    /**
+     * Key of OSGi "Bundle-License" manifest entry, that contains {@link String}. Extracted by {@code
+     * OsgiArtifactIndexCreator}.
+     */
+    public static final EntryKey<String> OSGI_BUNDLE_LICENSE = new EntryKey<String>( "Bundle-License", String.class );
+
+    /**
+     * Key of OSGi "Bundle-DocURL" manifest entry, that contains {@link String}. Extracted by {@code
+     * OsgiArtifactIndexCreator}.
+     */
+    public static final EntryKey<String> OSGI_EXPORT_DOCURL = new EntryKey<String>( "Bundle-DocURL", String.class );
+
+    /**
+     * Key of OSGi "Import-Package" manifest entry, that contains {@link String}. Extracted by {@code
+     * OsgiArtifactIndexCreator}.
+     */
+    public static final EntryKey<String> OSGI_IMPORT_PACKAGE = new EntryKey<String>( "Import-Package", String.class );
+
+    /**
+     * Key of OSGi "Require-Bundle" manifest entry, that contains {@link String}. Extracted by {@code
+     * OsgiArtifactIndexCreator}.
+     */
+    public static final EntryKey<String> OSGI_REQUIRE_BUNDLE = new EntryKey<String>( "Require-Bundle", String.class );
+
+    /**
+     * Key of OSGi "Provide-Capability" manifest entry, that contains {@link String}. Extracted by {@code
+     * OsgiArtifactIndexCreator}.
+     */
+    public static final EntryKey<String> OSGI_PROVIDE_CAPABILITY =
+        new EntryKey<String>( "Provide-Capability", String.class );
+
+    /**
+     * Key of OSGi "Require-Capability" manifest entry, that contains {@link String}. Extracted by {@code
+     * OsgiArtifactIndexCreator}.
+     */
+    public static final EntryKey<String> OSGI_REQUIRE_CAPABILITY =
+        new EntryKey<String>( "Require-Capability", String.class );
+
+    /**
+     * Key of OSGi "Fragment-Host" manifest entry, that contains {@link String}. Extracted by {@code
+     * OsgiArtifactIndexCreator}.
+     */
+    public static final EntryKey<String> OSGI_FRAGMENT_HOST = new EntryKey<String>( "Fragment-Host", String.class );
+
+    /**
+     * Key of deprecated OSGi "Bundle-RequiredExecutionEnvironment" manifest entry, that contains {@link String}. Extracted by {@code
+     * OsgiArtifactIndexCreator}.
+     */
+    public static final EntryKey<String> OSGI_BREE =
+        new EntryKey<String>( "Bundle-RequiredExecutionEnvironment", String.class );
+
+    /**
+     * Key for SHA-256 checksum  needed for OSGI content capability that contains {@link String}. Extracted by {@code
+     * OsgiArtifactIndexCreator}.
+     */
+    public static final EntryKey<String> SHA_256 = new EntryKey<String>( "sha256", String.class );
+
+
+    /**
+     * Types of returned records returned from index.
+     */
+    public enum Type
+    {
+        /**
+         * Descriptor record. Can be safely ignored.
+         * Contains following entries:
+         * <ul>
+         * <li>{@link #REPOSITORY_ID}</li>
+         * </ul>
+         */
+        DESCRIPTOR,
+
+        /**
+         * Artifact ADD record. Records of this type should be added to your indexing system.
+         * Contains following entries:
+         * <ul>
+         * <li>{@link #REC_MODIFIED} (when record was added/modified on index)</li>
+         * <li>{@link #GROUP_ID}</li>
+         * <li>{@link #ARTIFACT_ID}</li>
+         * <li>{@link #VERSION}</li>
+         * <li>{@link #CLASSIFIER} (optional)</li>
+         * <li>{@link #FILE_EXTENSION}</li>
+         * <li>{@link #FILE_MODIFIED}</li>
+         * <li>{@link #FILE_SIZE}</li>
+         * <li>{@link #PACKAGING}</li>
+         * <li>{@link #HAS_SOURCES}</li>
+         * <li>{@link #HAS_JAVADOC}</li>
+         * <li>{@link #HAS_SIGNATURE}</li>
+         * <li>{@link #NAME}</li>
+         * <li>{@link #DESCRIPTION}</li>
+         * <li>{@link #SHA1}</li>
+         * <li>{@link #CLASSNAMES} (optional)</li>
+         * <li>{@link #PLUGIN_PREFIX} (optional, for maven-plugins only)</li>
+         * <li>{@link #PLUGIN_GOALS} (optional, for maven-plugins only)</li>
+         * </ul>
+         */
+        ARTIFACT_ADD,
+
+        /**
+         * Artifact REMOVE record. In case of incremental updates, signals that this artifact was removed. Records of this
+         * type should be removed from your indexing system.
+         * Contains following entries:
+         * <ul>
+         * <li>{@link #REC_MODIFIED} (when record was deleted from index)</li>
+         * <li>{@link #GROUP_ID}</li>
+         * <li>{@link #ARTIFACT_ID}</li>
+         * <li>{@link #VERSION}</li>
+         * <li>{@link #CLASSIFIER} (optional)</li>
+         * <li>{@link #FILE_EXTENSION} (if {@link #CLASSIFIER} present)</li>
+         * <li>{@link #PACKAGING} (optional)</li>
+         * </ul>
+         */
+        ARTIFACT_REMOVE,
+
+        /**
+         * Special record, containing all the Maven "groupId"s that are enlisted on the index. Can be safely ignored.
+         * Contains following entries:
+         * <ul>
+         * <li>{@link #ALL_GROUPS}</li>
+         * </ul>
+         */
+        ALL_GROUPS,
+
+        /**
+         * Special record, containing all the root groups of Maven "groupId"s that are enlisted on the index. Can be safely
+         * ignored.
+         * Contains following entries:
+         * <ul>
+         * <li>{@link #ROOT_GROUPS}</li>
+         * </ul>
+         */
+        ROOT_GROUPS
     }
 
-    @Override
-    public boolean equals(final Object o) {
-      if (this == o) {
-        return true;
-      }
-      if (!(o instanceof EntryKey)) {
-        return false;
-      }
-      EntryKey entryKey = (EntryKey) o;
-      return name.equals(entryKey.name);
+    private final Type type;
+
+    private final Map<EntryKey, Object> expanded;
+
+    public Record( final Type type, final Map<EntryKey, Object> expanded )
+    {
+        this.type = type;
+        this.expanded = expanded;
     }
 
-    @Override
-    public int hashCode() {
-      return name.hashCode();
+    /**
+     * Returns the {@link Type} of this record. Usually users would be interested in {@link Type#ARTIFACT_ADD} and {@link
+     * Type#ARTIFACT_REMOVE} types only to maintain their own index. Still, indexer offers extra records too, see {@link
+     * Type} for all existing types.
+     */
+    public Type getType()
+    {
+        return type;
     }
 
-    @Override
-    public String toString() {
-      return "Key{" +
-          "name='" + name + '\'' +
-          ", type=" + proto.getSimpleName() +
-          '}';
+    /**
+     * Returns the expanded (processed and expanded synthetic fields) record as {@link Map} ready for consumption.
+     */
+    public Map<EntryKey, Object> getExpanded()
+    {
+        return expanded;
+    }
+
+    /**
+     * Returns {@code true} if this record contains given {@link EntryKey}.
+     */
+    boolean containsKey( final EntryKey<?> entryKey )
+    {
+        return expanded.containsKey( entryKey );
+    }
+
+    /**
+     * Type safe handy method to get value from expanded map.
+     */
+    public <T> T get( final EntryKey<T> entryKey )
+    {
+        return entryKey.coerce( expanded.get( entryKey ) );
     }
-  }
-
-  /**
-   * Key of repository ID entry, that contains {@link String}.
-   */
-  public static final EntryKey<String> REPOSITORY_ID = new EntryKey<String>("repositoryId", String.class);
-
-  /**
-   * Key of all groups list entry, that contains {@link java.util.List<String>}.
-   */
-  public static final EntryKey<String[]> ALL_GROUPS = new EntryKey<String[]>("allGroups", String[].class);
-
-  /**
-   * Key of root groups list entry, that contains {@link java.util.List<String>}.
-   */
-  public static final EntryKey<String[]> ROOT_GROUPS = new EntryKey<String[]>("rootGroups", String[].class);
-
-  /**
-   * Key of index record modification (added to index or removed from index) timestamp entry, that contains {@link
-   * Long}.
-   */
-  public static final EntryKey<Long> REC_MODIFIED = new EntryKey<Long>("recordModified", Long.class);
-
-  /**
-   * Key of artifact groupId entry, that contains {@link String}.
-   */
-  public static final EntryKey<String> GROUP_ID = new EntryKey<String>("groupId", String.class);
-
-  /**
-   * Key of artifact artifactId entry, that contains {@link String}.
-   */
-  public static final EntryKey<String> ARTIFACT_ID = new EntryKey<String>("artifactId", String.class);
-
-  /**
-   * Key of artifact version entry, that contains {@link String}.
-   */
-  public static final EntryKey<String> VERSION = new EntryKey<String>("version", String.class);
-
-  /**
-   * Key of artifact classifier entry, that contains {@link String}.
-   */
-  public static final EntryKey<String> CLASSIFIER = new EntryKey<String>("classifier", String.class);
-
-  /**
-   * Key of artifact packaging entry, that contains {@link String}.
-   */
-  public static final EntryKey<String> PACKAGING = new EntryKey<String>("packaging", String.class);
-
-  /**
-   * Key of artifact file extension, that contains {@link String}.
-   */
-  public static final EntryKey<String> FILE_EXTENSION = new EntryKey<String>("fileExtension", String.class);
-
-  /**
-   * Key of artifact file last modified timestamp, that contains {@link Long}.
-   */
-  public static final EntryKey<Long> FILE_MODIFIED = new EntryKey<Long>("fileModified", Long.class);
-
-  /**
-   * Key of artifact file size in bytes, that contains {@link Long}.
-   */
-  public static final EntryKey<Long> FILE_SIZE = new EntryKey<Long>("fileSize", Long.class);
-
-  /**
-   * Key of artifact Sources presence flag, that contains {@link Boolean}.
-   */
-  public static final EntryKey<Boolean> HAS_SOURCES = new EntryKey<Boolean>("hasSources", Boolean.class);
-
-  /**
-   * Key of artifact Javadoc presence flag, that contains {@link Boolean}.
-   */
-  public static final EntryKey<Boolean> HAS_JAVADOC = new EntryKey<Boolean>("hasJavadoc", Boolean.class);
-
-  /**
-   * Key of artifact signature presence flag, that contains {@link Boolean}.
-   */
-  public static final EntryKey<Boolean> HAS_SIGNATURE = new EntryKey<Boolean>("hasSignature", Boolean.class);
-
-  /**
-   * Key of artifact name (as set in POM), that contains {@link String}.
-   */
-  public static final EntryKey<String> NAME = new EntryKey<String>("name", String.class);
-
-  /**
-   * Key of artifact description (as set in POM), that contains {@link String}.
-   */
-  public static final EntryKey<String> DESCRIPTION = new EntryKey<String>("description", String.class);
-
-  /**
-   * Key of artifact SHA1 digest, that contains {@link String}.
-   */
-  public static final EntryKey<String> SHA1 = new EntryKey<String>("sha1", String.class);
-
-  /**
-   * Key of artifact contained class names, that contains {@link java.util.List<String>}. Extracted by {@code
-   * JarFileContentsIndexCreator}.
-   */
-  public static final EntryKey<String[]> CLASSNAMES = new EntryKey<String[]>("classNames", String[].class);
-
-  /**
-   * Key of plugin artifact prefix, that contains {@link String}. Extracted by {@code
-   * MavenPluginArtifactInfoIndexCreator}.
-   */
-  public static final EntryKey<String> PLUGIN_PREFIX = new EntryKey<String>("pluginPrefix", String.class);
-
-  /**
-   * Key of plugin artifact goals, that contains {@link java.util.List<String>}. Extracted by {@code
-   * MavenPluginArtifactInfoIndexCreator}.
-   */
-  public static final EntryKey<String[]> PLUGIN_GOALS = new EntryKey<String[]>("pluginGoals", String[].class);
-
-  /**
-   * Key of OSGi "Bundle-SymbolicName" manifest entry, that contains {@link String}. Extracted by {@code
-   * OsgiArtifactIndexCreator}.
-   */
-  public static final EntryKey<String> OSGI_BUNDLE_SYMBOLIC_NAME = new EntryKey<String>("Bundle-SymbolicName",
-      String.class);
-
-  /**
-   * Key of OSGi "Bundle-Version" manifest entry, that contains {@link String}. Extracted by {@code
-   * OsgiArtifactIndexCreator}.
-   */
-  public static final EntryKey<String> OSGI_BUNDLE_VERSION = new EntryKey<String>("Bundle-Version", String.class);
-
-  /**
-   * Key of OSGi "Export-Package" manifest entry, that contains {@link String}. Extracted by {@code
-   * OsgiArtifactIndexCreator}.
-   */
-  public static final EntryKey<String> OSGI_EXPORT_PACKAGE = new EntryKey<String>("Export-Package", String.class);
-
-  /**
-   * Key of OSGi "Export-Service" manifest entry, that contains {@link String}. Extracted by {@code
-   * OsgiArtifactIndexCreator}.
-   */
-  public static final EntryKey<String> OSGI_EXPORT_SERVICE = new EntryKey<String>("Export-Service", String.class);
-
-  /**
-   * Key of OSGi "Bundle-Description" manifest entry, that contains {@link String}. Extracted by {@code
-   * OsgiArtifactIndexCreator}.
-   */
-  public static final EntryKey<String> OSGI_BUNDLE_DESCRIPTION = new EntryKey<String>("Bundle-Description",
-      String.class);
-
-  /**
-   * Key of OSGi "Bundle-Name" manifest entry, that contains {@link String}. Extracted by {@code
-   * OsgiArtifactIndexCreator}.
-   */
-  public static final EntryKey<String> OSGI_BUNDLE_NAME = new EntryKey<String>("Bundle-Name", String.class);
-
-  /**
-   * Key of OSGi "Bundle-License" manifest entry, that contains {@link String}. Extracted by {@code
-   * OsgiArtifactIndexCreator}.
-   */
-  public static final EntryKey<String> OSGI_BUNDLE_LICENSE = new EntryKey<String>("Bundle-License", String.class);
-
-  /**
-   * Key of OSGi "Bundle-DocURL" manifest entry, that contains {@link String}. Extracted by {@code
-   * OsgiArtifactIndexCreator}.
-   */
-  public static final EntryKey<String> OSGI_EXPORT_DOCURL = new EntryKey<String>("Bundle-DocURL", String.class);
-
-  /**
-   * Key of OSGi "Import-Package" manifest entry, that contains {@link String}. Extracted by {@code
-   * OsgiArtifactIndexCreator}.
-   */
-  public static final EntryKey<String> OSGI_IMPORT_PACKAGE = new EntryKey<String>("Import-Package", String.class);
-
-  /**
-   * Key of OSGi "Require-Bundle" manifest entry, that contains {@link String}. Extracted by {@code
-   * OsgiArtifactIndexCreator}.
-   */
-  public static final EntryKey<String> OSGI_REQUIRE_BUNDLE = new EntryKey<String>("Require-Bundle", String.class);
-
-  /**
-   * Key of OSGi "Provide-Capability" manifest entry, that contains {@link String}. Extracted by {@code
-   * OsgiArtifactIndexCreator}.
-   */
-  public static final EntryKey<String> OSGI_PROVIDE_CAPABILITY = new EntryKey<String>("Provide-Capability", String.class);
-  /**
-   * Key of OSGi "Require-Capability" manifest entry, that contains {@link String}. Extracted by {@code
-   * OsgiArtifactIndexCreator}.
-   */
-  public static final EntryKey<String> OSGI_REQUIRE_CAPABILITY = new EntryKey<String>("Require-Capability", String.class);
-  /**
-   * Key of OSGi "Fragment-Host" manifest entry, that contains {@link String}. Extracted by {@code
-   * OsgiArtifactIndexCreator}.
-   */
-  public static final EntryKey<String> OSGI_FRAGMENT_HOST = new EntryKey<String>("Fragment-Host", String.class);
-  /**
-   * Key of deprecated OSGi "Bundle-RequiredExecutionEnvironment" manifest entry, that contains {@link String}. Extracted by {@code
-   * OsgiArtifactIndexCreator}.
-   */
-  public static final EntryKey<String> OSGI_BREE = new EntryKey<String>("Bundle-RequiredExecutionEnvironment", String.class);
-
-  /**
-   * Key for SHA-256 checksum  needed for OSGI content capability that contains {@link String}. Extracted by {@code
-   * OsgiArtifactIndexCreator}.
-   */
-  public static final EntryKey<String> SHA_256 = new EntryKey<String>("sha256", String.class);
-
-
-  /**
-   * Types of returned records returned from index.
-   */
-  public enum Type
-  {
-    /**
-     * Descriptor record. Can be safely ignored.
-     * Contains following entries:
-     * <ul>
-     * <li>{@link #REPOSITORY_ID}</li>
-     * </ul>
-     */
-    DESCRIPTOR,
-
-    /**
-     * Artifact ADD record. Records of this type should be added to your indexing system.
-     * Contains following entries:
-     * <ul>
-     * <li>{@link #REC_MODIFIED} (when record was added/modified on index)</li>
-     * <li>{@link #GROUP_ID}</li>
-     * <li>{@link #ARTIFACT_ID}</li>
-     * <li>{@link #VERSION}</li>
-     * <li>{@link #CLASSIFIER} (optional)</li>
-     * <li>{@link #FILE_EXTENSION}</li>
-     * <li>{@link #FILE_MODIFIED}</li>
-     * <li>{@link #FILE_SIZE}</li>
-     * <li>{@link #PACKAGING}</li>
-     * <li>{@link #HAS_SOURCES}</li>
-     * <li>{@link #HAS_JAVADOC}</li>
-     * <li>{@link #HAS_SIGNATURE}</li>
-     * <li>{@link #NAME}</li>
-     * <li>{@link #DESCRIPTION}</li>
-     * <li>{@link #SHA1}</li>
-     * <li>{@link #CLASSNAMES} (optional)</li>
-     * <li>{@link #PLUGIN_PREFIX} (optional, for maven-plugins only)</li>
-     * <li>{@link #PLUGIN_GOALS} (optional, for maven-plugins only)</li>
-     * </ul>
-     */
-    ARTIFACT_ADD,
-
-    /**
-     * Artifact REMOVE record. In case of incremental updates, signals that this artifact was removed. Records of this
-     * type should be removed from your indexing system.
-     * Contains following entries:
-     * <ul>
-     * <li>{@link #REC_MODIFIED} (when record was deleted from index)</li>
-     * <li>{@link #GROUP_ID}</li>
-     * <li>{@link #ARTIFACT_ID}</li>
-     * <li>{@link #VERSION}</li>
-     * <li>{@link #CLASSIFIER} (optional)</li>
-     * <li>{@link #FILE_EXTENSION} (if {@link #CLASSIFIER} present)</li>
-     * <li>{@link #PACKAGING} (optional)</li>
-     * </ul>
-     */
-    ARTIFACT_REMOVE,
-
-    /**
-     * Special record, containing all the Maven "groupId"s that are enlisted on the index. Can be safely ignored.
-     * Contains following entries:
-     * <ul>
-     * <li>{@link #ALL_GROUPS}</li>
-     * </ul>
-     */
-    ALL_GROUPS,
-
-    /**
-     * Special record, containing all the root groups of Maven "groupId"s that are enlisted on the index. Can be safely
-     * ignored.
-     * Contains following entries:
-     * <ul>
-     * <li>{@link #ROOT_GROUPS}</li>
-     * </ul>
-     */
-    ROOT_GROUPS
-  }
-
-  private final Type type;
-
-  private final Map<EntryKey, Object> expanded;
-
-  public Record(final Type type, final Map<EntryKey, Object> expanded) {
-    this.type = type;
-    this.expanded = expanded;
-  }
-
-  /**
-   * Returns the {@link Type} of this record. Usually users would be interested in {@link Type#ARTIFACT_ADD} and {@link
-   * Type#ARTIFACT_REMOVE} types only to maintain their own index. Still, indexer offers extra records too, see {@link
-   * Type} for all existing types.
-   */
-  public Type getType() {
-    return type;
-  }
-
-  /**
-   * Returns the expanded (processed and expanded synthetic fields) record as {@link Map} ready for consumption.
-   */
-  public Map<EntryKey, Object> getExpanded() {
-    return expanded;
-  }
-
-  /**
-   * Returns {@code true} if this record contains given {@link EntryKey}.
-   */
-  boolean containsKey(final EntryKey<?> entryKey) { return expanded.containsKey(entryKey); }
-
-  /**
-   * Type safe handy method to get value from expanded map.
-   */
-  public <T> T get(final EntryKey<T> entryKey) {
-    return entryKey.coerce(expanded.get(entryKey));
-  }
-
-  /**
-   * Type safe handy method to put value to expanded map. Accepts {@code null} values, that removes the mapping.
-   */
-  public <T> T put(final EntryKey<T> entryKey, final T value) {
-    if (value == null) {
-      return entryKey.coerce(expanded.remove(entryKey));
+
+    /**
+     * Type safe handy method to put value to expanded map. Accepts {@code null} values, that removes the mapping.
+     */
+    public <T> T put( final EntryKey<T> entryKey, final T value )
+    {
+        if ( value == null )
+        {
+            return entryKey.coerce( expanded.remove( entryKey ) );
+        }
+        else
+        {
+            if ( !entryKey.proto.isAssignableFrom( value.getClass() ) )
+            {
+                throw new IllegalArgumentException( "Key " + entryKey + " does not accepts value " + value );
+            }
+            return entryKey.coerce( expanded.put( entryKey, value ) );
+        }
     }
-    else {
-      if (!entryKey.proto.isAssignableFrom(value.getClass())) {
-        throw new IllegalArgumentException("Key " + entryKey + " does not accepts value " + value);
-      }
-      return entryKey.coerce(expanded.put(entryKey, value));
+
+    @Override
+    public String toString()
+    {
+        return "Record{" + "type=" + type + ", expanded=" + expanded + '}';
     }
-  }
-
-  @Override
-  public String toString() {
-    return "Record{" +
-        "type=" + type +
-        ", expanded=" + expanded +
-        '}';
-  }
 }


Mime
View raw message