Remove Transform, let user use any lib it wants to for iterable manipulation
Also, UTs got new TestUtils based on Guava
diff --git a/indexer-reader/pom.xml b/indexer-reader/pom.xml
index 95d821f..49e4c6c 100644
--- a/indexer-reader/pom.xml
+++ b/indexer-reader/pom.xml
@@ -44,6 +44,12 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <version>18.0</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
diff --git a/indexer-reader/src/main/java/org/apache/maven/index/reader/RecordCompactor.java b/indexer-reader/src/main/java/org/apache/maven/index/reader/RecordCompactor.java
index 47ca80b..76fc1e5 100644
--- a/indexer-reader/src/main/java/org/apache/maven/index/reader/RecordCompactor.java
+++ b/indexer-reader/src/main/java/org/apache/maven/index/reader/RecordCompactor.java
@@ -22,7 +22,6 @@
import java.util.HashMap;
import java.util.Map;
-import org.apache.maven.index.reader.Transform.Function;
import org.apache.maven.index.reader.Record.Type;
import static org.apache.maven.index.reader.Utils.FIELD_SEPARATOR;
@@ -36,8 +35,11 @@
* @since 5.1.2
*/
public class RecordCompactor
- implements Function<Record, Map<String, String>>
{
+ /**
+ * Compacts {@link Record} into low level MI record with all the encoded fields as physically present in MI binary
+ * chunk.
+ */
public Map<String, String> apply(final Record record) {
if (Type.DESCRIPTOR == record.getType()) {
return compactDescriptor(record);
diff --git a/indexer-reader/src/main/java/org/apache/maven/index/reader/RecordExpander.java b/indexer-reader/src/main/java/org/apache/maven/index/reader/RecordExpander.java
index 1de965f..6d7f4be 100644
--- a/indexer-reader/src/main/java/org/apache/maven/index/reader/RecordExpander.java
+++ b/indexer-reader/src/main/java/org/apache/maven/index/reader/RecordExpander.java
@@ -22,7 +22,6 @@
import java.util.HashMap;
import java.util.Map;
-import org.apache.maven.index.reader.Transform.Function;
import org.apache.maven.index.reader.Record.EntryKey;
import org.apache.maven.index.reader.Record.Type;
@@ -39,8 +38,10 @@
* @since 5.1.2
*/
public class RecordExpander
- implements Function<Map<String, String>, Record>
{
+ /**
+ * Expands MI low level record into {@link Record}.
+ */
public Record apply(final Map<String, String> recordMap) {
if (recordMap.containsKey("DESCRIPTOR")) {
return expandDescriptor(recordMap);
diff --git a/indexer-reader/src/main/java/org/apache/maven/index/reader/Transform.java b/indexer-reader/src/main/java/org/apache/maven/index/reader/Transform.java
deleted file mode 100644
index 50821bd..0000000
--- a/indexer-reader/src/main/java/org/apache/maven/index/reader/Transform.java
+++ /dev/null
@@ -1,212 +0,0 @@
-package org.apache.maven.index.reader;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.TreeSet;
-
-import org.apache.maven.index.reader.Record.EntryKey;
-import org.apache.maven.index.reader.Record.Type;
-
-/**
- * Helpers to transform records from one to another representation, and, some helpers for publishing.
- *
- * @since 5.1.2
- */
-public final class Transform
-{
- private Transform() {
- // nothing
- }
-
- /**
- * Transforming function.
- */
- public interface Function<I, O>
- {
- O apply(I rec);
- }
-
- /**
- * Applies {@link Function} to an {@link Iterable} on the fly.
- */
- public static <I, O> Iterable<O> transform(final Iterable<I> iterable, final Function<I, O> function) {
- return new Iterable<O>()
- {
- public Iterator<O> iterator() {
- return new TransformIterator<I, O>(iterable.iterator(), function);
- }
- };
- }
-
- /**
- * Helper method, that "decorates" the stream of records to be written out with "special" Maven Indexer records, so
- * all the caller is needed to provide {@link Iterable} or {@link Record}s <strong>to be</strong> on the index, with
- * record type {@link Record.Type#ARTIFACT_ADD}. This method will create the output as "proper" Maven Indexer record
- * streeam, by adding the {@link Type#DESCRIPTOR}, {@link Type#ROOT_GROUPS} and {@link Type#ALL_GROUPS} special
- * records.
- */
- public static Iterable<Map<String, String>> decorateAndTransform(final Iterable<Record> iterable,
- final String repoId)
- {
- final RecordCompactor recordCompactor = new RecordCompactor();
- final TreeSet<String> allGroups = new TreeSet<String>();
- final TreeSet<String> rootGroups = new TreeSet<String>();
- final ArrayList<Iterator<Record>> iterators = new ArrayList<Iterator<Record>>();
- iterators.add(Collections.singletonList(descriptor(repoId)).iterator());
- iterators.add(iterable.iterator());
- iterators.add(Collections.singletonList(allGroups(allGroups)).iterator());
- iterators.add(Collections.singletonList(rootGroups(rootGroups)).iterator());
- return transform(
- new Iterable<Record>()
- {
- public Iterator<Record> iterator() {
- return new ConcatIterator<Record>(iterators.iterator());
- }
- },
- new Function<Record, Map<String, String>>()
- {
- public Map<String, String> apply(final Record rec) {
- if (Type.DESCRIPTOR == rec.getType()) {
- return recordCompactor.apply(descriptor(repoId));
- }
- else if (Type.ALL_GROUPS == rec.getType()) {
- return recordCompactor.apply(allGroups(allGroups));
- }
- else if (Type.ROOT_GROUPS == rec.getType()) {
- return recordCompactor.apply(rootGroups(rootGroups));
- }
- else {
- final String groupId = rec.get(Record.GROUP_ID);
- if (groupId != null) {
- allGroups.add(groupId);
- rootGroups.add(Utils.rootGroup(groupId));
- }
- return recordCompactor.apply(rec);
- }
- }
- }
- );
- }
-
- private static Record descriptor(final String repoId) {
- HashMap<EntryKey, Object> entries = new HashMap<EntryKey, Object>();
- entries.put(Record.REPOSITORY_ID, repoId);
- return new Record(Type.DESCRIPTOR, entries);
- }
-
- private static Record allGroups(final Collection<String> allGroups) {
- HashMap<EntryKey, Object> entries = new HashMap<EntryKey, Object>();
- entries.put(Record.ALL_GROUPS, allGroups.toArray(new String[allGroups.size()]));
- return new Record(Type.ALL_GROUPS, entries);
- }
-
- private static Record rootGroups(final Collection<String> rootGroups) {
- HashMap<EntryKey, Object> entries = new HashMap<EntryKey, Object>();
- entries.put(Record.ROOT_GROUPS, rootGroups.toArray(new String[rootGroups.size()]));
- return new Record(Type.ROOT_GROUPS, entries);
- }
-
- // ==
-
- private static final class TransformIterator<I, O>
- implements Iterator<O>
- {
- private final Iterator<I> iterator;
-
- private final Function<I, O> function;
-
- private TransformIterator(final Iterator<I> iterator, final Function<I, O> function) {
- this.iterator = iterator;
- this.function = function;
- }
-
- public boolean hasNext() {
- return iterator.hasNext();
- }
-
- public O next() {
- return function.apply(iterator.next());
- }
-
- public void remove() {
- throw new UnsupportedOperationException("remove");
- }
- }
-
- private static final class ConcatIterator<T>
- implements Iterator<T>
- {
- private final Iterator<Iterator<T>> iterators;
-
- private Iterator<T> current;
-
- private T nextElement;
-
- private ConcatIterator(final Iterator<Iterator<T>> iterators) {
- this.iterators = iterators;
- this.nextElement = getNextElement();
- }
-
- public boolean hasNext() {
- return nextElement != null;
- }
-
- public T next() {
- if (nextElement == null) {
- throw new NoSuchElementException();
- }
- T result = nextElement;
- nextElement = getNextElement();
- return result;
- }
-
- public void remove() {
- throw new UnsupportedOperationException("remove");
- }
-
- protected T getNextElement() {
- if ((current == null || !current.hasNext()) && iterators.hasNext()) {
- current = iterators.next();
- }
- while (current != null && !current.hasNext()) {
- if (!iterators.hasNext()) {
- current = null;
- break;
- }
- current = iterators.next();
- }
- if (current != null) {
- return current.next();
- }
- else {
- return null;
- }
- }
- }
-}
diff --git a/indexer-reader/src/main/java/org/apache/maven/index/reader/Utils.java b/indexer-reader/src/main/java/org/apache/maven/index/reader/Utils.java
index c978bd6..c5b210a 100644
--- a/indexer-reader/src/main/java/org/apache/maven/index/reader/Utils.java
+++ b/indexer-reader/src/main/java/org/apache/maven/index/reader/Utils.java
@@ -24,10 +24,14 @@
import java.io.OutputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
+import java.util.Collection;
+import java.util.HashMap;
import java.util.Properties;
import java.util.TimeZone;
import java.util.regex.Pattern;
+import org.apache.maven.index.reader.Record.EntryKey;
+import org.apache.maven.index.reader.Record.Type;
import org.apache.maven.index.reader.ResourceHandler.Resource;
import org.apache.maven.index.reader.WritableResourceHandler.WritableResource;
@@ -42,29 +46,29 @@
// nothing
}
- static final String INDEX_FILE_PREFIX = "nexus-maven-repository-index";
+ public static final String INDEX_FILE_PREFIX = "nexus-maven-repository-index";
- static final DateFormat INDEX_DATE_FORMAT;
+ public static final DateFormat INDEX_DATE_FORMAT;
static {
INDEX_DATE_FORMAT = new SimpleDateFormat("yyyyMMddHHmmss.SSS Z");
INDEX_DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT"));
}
- static final String FIELD_SEPARATOR = "|";
+ public static final String FIELD_SEPARATOR = "|";
- static final String NOT_AVAILABLE = "NA";
+ public static final String NOT_AVAILABLE = "NA";
- static final String UINFO = "u";
+ public static final String UINFO = "u";
- static final String INFO = "i";
+ public static final String INFO = "i";
- static final Pattern FS_PATTERN = Pattern.compile(Pattern.quote(FIELD_SEPARATOR));
+ public static final Pattern FS_PATTERN = Pattern.compile(Pattern.quote(FIELD_SEPARATOR));
/**
* Creates and loads {@link Properties} from provided {@link InputStream} and closes the stream.
*/
- static Properties loadProperties(final InputStream inputStream) throws IOException {
+ public static Properties loadProperties(final InputStream inputStream) throws IOException {
try {
final Properties properties = new Properties();
properties.load(inputStream);
@@ -79,7 +83,7 @@
* Creates and loads {@link Properties} from provided {@link Resource} if exists, and closes the resource. If not
* exists, returns {@code null}.
*/
- static Properties loadProperties(final Resource resource) throws IOException {
+ public static Properties loadProperties(final Resource resource) throws IOException {
final InputStream inputStream = resource.read();
if (inputStream == null) {
return null;
@@ -90,7 +94,7 @@
/**
* Saves {@link Properties} to provided {@link OutputStream} and closes the stream.
*/
- static void storeProperties(final OutputStream outputStream, final Properties properties) throws IOException {
+ public static void storeProperties(final OutputStream outputStream, final Properties properties) throws IOException {
try {
properties.store(outputStream, "Maven Indexer Writer");
}
@@ -103,7 +107,7 @@
/**
* Saves {@link Properties} to provided {@link WritableResource} and closes the resource.
*/
- static void storeProperties(final WritableResource writableResource, final Properties properties) throws IOException {
+ public static void storeProperties(final WritableResource writableResource, final Properties properties) throws IOException {
try {
storeProperties(writableResource.write(), properties);
}
@@ -113,23 +117,50 @@
}
/**
+ * Creates a record of type {@link Type#DESCRIPTOR}.
+ */
+ public static Record descriptor(final String repoId) {
+ HashMap<EntryKey, Object> entries = new HashMap<EntryKey, Object>();
+ entries.put(Record.REPOSITORY_ID, repoId);
+ return new Record(Type.DESCRIPTOR, entries);
+ }
+
+ /**
+ * Creates a record of type {@link Type#ALL_GROUPS}.
+ */
+ public static Record allGroups(final Collection<String> allGroups) {
+ HashMap<EntryKey, Object> entries = new HashMap<EntryKey, Object>();
+ entries.put(Record.ALL_GROUPS, allGroups.toArray(new String[allGroups.size()]));
+ return new Record(Type.ALL_GROUPS, entries);
+ }
+
+ /**
+ * Creates a record of type {@link Type#ROOT_GROUPS}.
+ */
+ public static Record rootGroups(final Collection<String> rootGroups) {
+ HashMap<EntryKey, Object> entries = new HashMap<EntryKey, Object>();
+ entries.put(Record.ROOT_GROUPS, rootGroups.toArray(new String[rootGroups.size()]));
+ return new Record(Type.ROOT_GROUPS, entries);
+ }
+
+ /**
* Helper to translate the "NA" (not available) input into {@code null} value.
*/
- static String renvl(final String v) {
+ public static String renvl(final String v) {
return NOT_AVAILABLE.equals(v) ? null : v;
}
/**
* Helper to translate {@code null} into "NA" (not available) value.
*/
- static String nvl(final String v) {
+ public static String nvl(final String v) {
return v == null ? NOT_AVAILABLE : v;
}
/**
* Returns the "root group" of given groupId.
*/
- static String rootGroup(final String groupId) {
+ public static String rootGroup(final String groupId) {
int n = groupId.indexOf('.');
if (n > -1) {
return groupId.substring(0, n);
diff --git a/indexer-reader/src/test/java/org/apache/maven/index/reader/IndexReaderTest.java b/indexer-reader/src/test/java/org/apache/maven/index/reader/IndexReaderTest.java
index c091317..8fc4c34 100644
--- a/indexer-reader/src/test/java/org/apache/maven/index/reader/IndexReaderTest.java
+++ b/indexer-reader/src/test/java/org/apache/maven/index/reader/IndexReaderTest.java
@@ -31,6 +31,8 @@
import org.junit.Ignore;
import org.junit.Test;
+import static org.apache.maven.index.reader.TestUtils.expandFunction;
+import static com.google.common.collect.Iterables.transform;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.hamcrest.core.IsNot.not;
import static org.hamcrest.core.IsNull.nullValue;
@@ -60,7 +62,7 @@
assertThat(chunkReader.getName(), equalTo("nexus-maven-repository-index.gz"));
assertThat(chunkReader.getVersion(), equalTo(1));
assertThat(chunkReader.getTimestamp().getTime(), equalTo(1243533418015L));
- for (Record record : Transform.transform(chunkReader, new RecordExpander())) {
+ for (Record record : transform(chunkReader, expandFunction)) {
records++;
}
}
@@ -92,7 +94,7 @@
assertThat(chunkReader.getName(), equalTo("nexus-maven-repository-index.gz"));
assertThat(chunkReader.getVersion(), equalTo(1));
assertThat(chunkReader.getTimestamp().getTime(), equalTo(1243533418015L));
- for (Record record : Transform.transform(chunkReader, new RecordExpander())) {
+ for (Record record : transform(chunkReader, expandFunction)) {
records++;
}
}
@@ -149,7 +151,7 @@
assertThat(chunkReader.getName(), equalTo("nexus-maven-repository-index.gz"));
assertThat(chunkReader.getVersion(), equalTo(1));
// assertThat(chunkReader.getTimestamp().getTime(), equalTo(1243533418015L));
- for (Record record : Transform.transform(chunkReader, new RecordExpander())) {
+ for (Record record : transform(chunkReader, expandFunction)) {
records++;
}
}
diff --git a/indexer-reader/src/test/java/org/apache/maven/index/reader/IndexWriterTest.java b/indexer-reader/src/test/java/org/apache/maven/index/reader/IndexWriterTest.java
index 7573e07..d1e9bc4 100644
--- a/indexer-reader/src/test/java/org/apache/maven/index/reader/IndexWriterTest.java
+++ b/indexer-reader/src/test/java/org/apache/maven/index/reader/IndexWriterTest.java
@@ -24,6 +24,8 @@
import org.junit.Test;
+import static org.apache.maven.index.reader.TestUtils.expandFunction;
+import static com.google.common.collect.Iterables.transform;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertThat;
@@ -76,7 +78,7 @@
assertThat(chunkReader.getName(), equalTo("nexus-maven-repository-index.gz"));
assertThat(chunkReader.getVersion(), equalTo(1));
// assertThat(chunkReader.getTimestamp().getTime(), equalTo(1243533418015L));
- for (Record record : Transform.transform(chunkReader, new RecordExpander())) {
+ for (Record record : transform(chunkReader, expandFunction)) {
records++;
}
}
diff --git a/indexer-reader/src/test/java/org/apache/maven/index/reader/TestUtils.java b/indexer-reader/src/test/java/org/apache/maven/index/reader/TestUtils.java
new file mode 100644
index 0000000..348d199
--- /dev/null
+++ b/indexer-reader/src/test/java/org/apache/maven/index/reader/TestUtils.java
@@ -0,0 +1,108 @@
+package org.apache.maven.index.reader;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Map;
+import java.util.TreeSet;
+
+import com.google.common.base.Function;
+import org.apache.maven.index.reader.Record.Type;
+
+import static com.google.common.collect.Iterables.concat;
+import static com.google.common.collect.Iterables.transform;
+import static java.util.Collections.singletonList;
+import static org.apache.maven.index.reader.Utils.allGroups;
+import static org.apache.maven.index.reader.Utils.descriptor;
+import static org.apache.maven.index.reader.Utils.rootGroup;
+import static org.apache.maven.index.reader.Utils.rootGroups;
+
+/**
+ * Helpers to transform records from one to another representation, and, some helpers for publishing using Guava.
+ */
+public final class TestUtils
+{
+ private TestUtils() {
+ // nothing
+ }
+
+ private static final RecordCompactor RECORD_COMPACTOR = new RecordCompactor();
+
+ private static final RecordExpander RECORD_EXPANDER = new RecordExpander();
+
+ public static Function<Record, Map<String, String>> compactFunction =
+ new Function<Record, Map<String, String>>()
+ {
+ public Map<String, String> apply(final Record input) {
+ return RECORD_COMPACTOR.apply(input);
+ }
+ };
+
+ public static Function<Map<String, String>, Record> expandFunction =
+ new Function<Map<String, String>, Record>()
+ {
+ public Record apply(final Map<String, String> input) {
+ return RECORD_EXPANDER.apply(input);
+ }
+ };
+
+ /**
+ * Helper method, that "decorates" the stream of records to be written out with "special" Maven Indexer records, so
+ * all the caller is needed to provide {@link Iterable} or {@link Record}s <strong>to be</strong> on the index, with
+ * record type {@link Type#ARTIFACT_ADD}. This method will create the output as "proper" Maven Indexer record
+ * stream, by adding the {@link Type#DESCRIPTOR}, {@link Type#ROOT_GROUPS} and {@link Type#ALL_GROUPS} special
+ * records.
+ */
+ public static Iterable<Record> decorate(final Iterable<Record> iterable,
+ final String repoId)
+ {
+ final TreeSet<String> allGroupsSet = new TreeSet<String>();
+ final TreeSet<String> rootGroupsSet = new TreeSet<String>();
+ return transform(
+ concat(
+ singletonList(descriptor(repoId)),
+ iterable,
+ singletonList(allGroups(allGroupsSet)), // placeholder, will be recreated at the end with proper content
+ singletonList(rootGroups(rootGroupsSet)) // placeholder, will be recreated at the end with proper content
+ ),
+ new Function<Record, Record>()
+ {
+ public Record apply(final Record rec) {
+ if (Type.DESCRIPTOR == rec.getType()) {
+ return rec;
+ }
+ else if (Type.ALL_GROUPS == rec.getType()) {
+ return allGroups(allGroupsSet);
+ }
+ else if (Type.ROOT_GROUPS == rec.getType()) {
+ return rootGroups(rootGroupsSet);
+ }
+ else {
+ final String groupId = rec.get(Record.GROUP_ID);
+ if (groupId != null) {
+ allGroupsSet.add(groupId);
+ rootGroupsSet.add(rootGroup(groupId));
+ }
+ return rec;
+ }
+ }
+ }
+ );
+ }
+}
diff --git a/indexer-reader/src/test/java/org/apache/maven/index/reader/TransformTest.java b/indexer-reader/src/test/java/org/apache/maven/index/reader/TransformTest.java
index 0eb302b..7d48154 100644
--- a/indexer-reader/src/test/java/org/apache/maven/index/reader/TransformTest.java
+++ b/indexer-reader/src/test/java/org/apache/maven/index/reader/TransformTest.java
@@ -29,12 +29,15 @@
import org.apache.maven.index.reader.Record.Type;
import org.junit.Test;
+import static org.apache.maven.index.reader.TestUtils.decorate;
+import static org.apache.maven.index.reader.TestUtils.compactFunction;
+import static com.google.common.collect.Iterables.transform;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertThat;
/**
- * UT for {@link Transform}
+ * UT for {@link RecordCompactor} and {@linl RecordExpander}.
*/
public class TransformTest
extends TestSupport
@@ -45,7 +48,10 @@
final Record r1 = new Record(Type.ARTIFACT_ADD, artifactMap("org.apache"));
final Record r2 = new Record(Type.ARTIFACT_ADD, artifactMap("org.foo"));
final Record r3 = new Record(Type.ARTIFACT_ADD, artifactMap("com.bar"));
- Iterable<Map<String, String>> iterable = Transform.decorateAndTransform(Arrays.asList(r1, r2, r3), indexId);
+ Iterable<Map<String, String>> iterable = transform(
+ decorate(Arrays.asList(r1, r2, r3), indexId),
+ compactFunction
+ );
WritableResourceHandler writableResourceHandler = createWritableResourceHandler();
try {