You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by nt...@apache.org on 2017/08/21 09:29:14 UTC

[1/9] cayenne git commit: CAY-2351 Remove commons-collections usage completely replace commons-collections with plain java

Repository: cayenne
Updated Branches:
  refs/heads/master de0969a08 -> afb42ed4c


CAY-2351 Remove commons-collections usage completely
  replace commons-collections with plain java


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/10e07069
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/10e07069
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/10e07069

Branch: refs/heads/master
Commit: 10e070695d6ecd60976e3812630df8dd38b219cd
Parents: fddb229
Author: Nikita Timofeev <st...@gmail.com>
Authored: Fri Aug 4 12:16:16 2017 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Thu Aug 17 12:41:56 2017 +0300

----------------------------------------------------------------------
 .../access/jdbc/RowDescriptorBuilder.java       |  2 +-
 .../cayenne/ashwood/graph/DepthFirstSearch.java |  7 ++--
 .../ashwood/graph/FilterArcIterator.java        | 20 +++++------
 .../cayenne/ashwood/graph/FilterIteration.java  | 31 ++++++++---------
 .../cayenne/ashwood/graph/StrongConnection.java | 28 +++++++--------
 .../unit/di/server/ConnectionProperties.java    | 36 +++++++++++++-------
 .../ServerCaseDataSourceInfoProvider.java       | 14 +++++---
 .../velocity/SQLTemplateResourceManager.java    |  4 +--
 .../apache/cayenne/wocompat/EOModelHelper.java  |  7 ++--
 9 files changed, 80 insertions(+), 69 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/10e07069/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/RowDescriptorBuilder.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/RowDescriptorBuilder.java b/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/RowDescriptorBuilder.java
index 39d39cf..3f4c2c8 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/RowDescriptorBuilder.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/RowDescriptorBuilder.java
@@ -135,7 +135,7 @@ public class RowDescriptorBuilder {
         }
 
         if(validateDuplicateColumnNames && !duplicates.isEmpty()) {
-            logger.warn("Found duplicated columns '" + Util.join(duplicates, "', '") + "' in row descriptor. " +
+            logger.warn("Found duplicated columns '" + String.join("', '", duplicates) + "' in row descriptor. " +
                     "This can lead to errors when converting result to persistent objects.");
         }
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/10e07069/cayenne-server/src/main/java/org/apache/cayenne/ashwood/graph/DepthFirstSearch.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/ashwood/graph/DepthFirstSearch.java b/cayenne-server/src/main/java/org/apache/cayenne/ashwood/graph/DepthFirstSearch.java
index 9aecb1e..31a8f95 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/ashwood/graph/DepthFirstSearch.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/ashwood/graph/DepthFirstSearch.java
@@ -59,12 +59,11 @@
  */
 package org.apache.cayenne.ashwood.graph;
 
+import java.util.ArrayDeque;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Set;
 
-import org.apache.commons.collections.ArrayStack;
-
 /**
  * @since 3.1
  */
@@ -72,12 +71,12 @@ public class DepthFirstSearch<E> implements Iterator<E> {
 
 	protected DigraphIteration<E, ?> factory;
 	protected E firstVertex;
-	protected ArrayStack stack;
+	protected ArrayDeque<ArcIterator<E, ?>> stack;
 	protected Set<E> seen;
 
 	public DepthFirstSearch(DigraphIteration<E, ?> factory, E firstVertex) {
 
-		this.stack = new ArrayStack();
+		this.stack = new ArrayDeque<>();
 		this.seen = new HashSet<>();
 		this.factory = factory;
 		this.firstVertex = firstVertex;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/10e07069/cayenne-server/src/main/java/org/apache/cayenne/ashwood/graph/FilterArcIterator.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/ashwood/graph/FilterArcIterator.java b/cayenne-server/src/main/java/org/apache/cayenne/ashwood/graph/FilterArcIterator.java
index 47c4744..81653ab 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/ashwood/graph/FilterArcIterator.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/ashwood/graph/FilterArcIterator.java
@@ -60,8 +60,8 @@
 package org.apache.cayenne.ashwood.graph;
 
 import java.util.NoSuchElementException;
+import java.util.function.Predicate;
 
-import org.apache.commons.collections.Predicate;
 
 /**
  * @since 3.1
@@ -69,25 +69,25 @@ import org.apache.commons.collections.Predicate;
 public class FilterArcIterator<E, V> implements ArcIterator<E, V> {
 
     private ArcIterator<E, V> iterator;
-    private Predicate acceptOrigin, acceptDestination;
-    private Predicate acceptArc;
+    private Predicate<E> acceptOrigin, acceptDestination;
+    private Predicate<V> acceptArc;
 
     private E nextOrigin, nextDst;
     private V nextArc;
     private boolean nextObjectSet = false;
 
-    public FilterArcIterator(ArcIterator<E, V> iterator, Predicate acceptOrigin,
-            Predicate acceptDestination, Predicate acceptArc) {
+    public FilterArcIterator(ArcIterator<E, V> iterator, Predicate<E> acceptOrigin,
+            Predicate<E> acceptDestination, Predicate<V> acceptArc) {
 
         this.iterator = iterator;
         this.acceptOrigin = acceptOrigin;
         this.acceptDestination = acceptDestination;
         this.acceptArc = acceptArc;
         nextOrigin = iterator.getOrigin();
-        if (!acceptOrigin.evaluate(nextOrigin))
+        if (!acceptOrigin.test(nextOrigin))
             nextOrigin = null;
         nextDst = iterator.getDestination();
-        if (!acceptDestination.evaluate(nextDst))
+        if (!acceptDestination.test(nextDst))
             nextDst = null;
     }
 
@@ -128,9 +128,9 @@ public class FilterArcIterator<E, V> implements ArcIterator<E, V> {
             V arc = iterator.next();
             E origin = iterator.getOrigin();
             E dst = iterator.getDestination();
-            if (acceptOrigin.evaluate(origin)
-                    && acceptArc.evaluate(arc)
-                    && acceptDestination.evaluate(dst)) {
+            if (acceptOrigin.test(origin)
+                    && acceptArc.test(arc)
+                    && acceptDestination.test(dst)) {
                 nextArc = arc;
                 nextOrigin = origin;
                 nextDst = dst;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/10e07069/cayenne-server/src/main/java/org/apache/cayenne/ashwood/graph/FilterIteration.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/ashwood/graph/FilterIteration.java b/cayenne-server/src/main/java/org/apache/cayenne/ashwood/graph/FilterIteration.java
index 16d0e77..e679c22 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/ashwood/graph/FilterIteration.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/ashwood/graph/FilterIteration.java
@@ -60,10 +60,8 @@
 package org.apache.cayenne.ashwood.graph;
 
 import java.util.Iterator;
-
-import org.apache.commons.collections.IteratorUtils;
-import org.apache.commons.collections.Predicate;
-import org.apache.commons.collections.functors.TruePredicate;
+import java.util.function.Predicate;
+import java.util.stream.StreamSupport;
 
 /**
  * @since 3.1
@@ -71,22 +69,23 @@ import org.apache.commons.collections.functors.TruePredicate;
 public class FilterIteration<E, V> implements DigraphIteration<E, V> {
 
     private DigraphIteration<E, V> digraph;
-    private Predicate acceptVertex;
-    private Predicate acceptArc;
+    private Predicate<E> acceptVertex;
+    private Predicate<V> acceptArc;
 
-    public FilterIteration(DigraphIteration<E, V> digraph, Predicate acceptVertex,
-            Predicate acceptArc) {
+    public FilterIteration(DigraphIteration<E, V> digraph, Predicate<E> acceptVertex,
+            Predicate<V> acceptArc) {
         this.digraph = digraph;
         this.acceptVertex = acceptVertex;
         this.acceptArc = acceptArc;
     }
 
     public Iterator<E> vertexIterator() {
-        return IteratorUtils.filteredIterator(digraph.vertexIterator(), acceptVertex);
+        Iterable<E> iterable = () -> digraph.vertexIterator();
+        return StreamSupport.stream(iterable.spliterator(), false).filter(acceptVertex).iterator();
     }
 
     public ArcIterator<E, V> arcIterator() {
-        return new FilterArcIterator<E, V>(
+        return new FilterArcIterator<>(
                 digraph.arcIterator(),
                 acceptVertex,
                 acceptVertex,
@@ -94,22 +93,22 @@ public class FilterIteration<E, V> implements DigraphIteration<E, V> {
     }
 
     public ArcIterator<E, V> outgoingIterator(E vertex) {
-        if (!acceptVertex.evaluate(vertex))
+        if (!acceptVertex.test(vertex))
             return EmptyIterator.instance();
-        return new FilterArcIterator<E, V>(
+        return new FilterArcIterator<>(
                 digraph.outgoingIterator(vertex),
-                TruePredicate.INSTANCE,
+                v -> true,
                 acceptVertex,
                 acceptArc);
     }
 
     public ArcIterator<E, V> incomingIterator(E vertex) {
-        if (!acceptVertex.evaluate(vertex))
+        if (!acceptVertex.test(vertex))
             return EmptyIterator.instance();
-        return new FilterArcIterator<E, V>(
+        return new FilterArcIterator<>(
                 digraph.incomingIterator(vertex),
                 acceptVertex,
-                TruePredicate.INSTANCE,
+                v -> true,
                 acceptArc);
     }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/10e07069/cayenne-server/src/main/java/org/apache/cayenne/ashwood/graph/StrongConnection.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/ashwood/graph/StrongConnection.java b/cayenne-server/src/main/java/org/apache/cayenne/ashwood/graph/StrongConnection.java
index 756b1b3..d099ea1 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/ashwood/graph/StrongConnection.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/ashwood/graph/StrongConnection.java
@@ -59,11 +59,7 @@
  */
 package org.apache.cayenne.ashwood.graph;
 
-import org.apache.commons.collections.ArrayStack;
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.collections.Predicate;
-import org.apache.commons.collections.functors.TruePredicate;
-
+import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -72,6 +68,7 @@ import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
+import java.util.function.Predicate;
 
 /**
  * @since 3.1
@@ -85,17 +82,16 @@ public class StrongConnection<E, V> implements Iterator<Collection<E>> {
 	private DepthFirstSearch<E> reverseDfs;
 	private Set<E> seen = new HashSet<E>();
 	private Iterator<E> vertexIterator;
-	private ArrayStack dfsStack;
+	private ArrayDeque<E> dfsStack;
 	private DFSSeenVerticesPredicate reverseDFSFilter;
 
 	public StrongConnection(DigraphIteration<E, V> digraph) {
 
-		this.dfsStack = new ArrayStack();
+		this.dfsStack = new ArrayDeque<>();
 		this.reverseDFSFilter = new DFSSeenVerticesPredicate();
 		this.digraph = digraph;
-		this.filteredDigraph = new FilterIteration<>(digraph, new NotSeenPredicate(), TruePredicate.INSTANCE);
-		this.reverseDigraph = new FilterIteration<>(new ReversedIteration<>(digraph), reverseDFSFilter,
-				TruePredicate.INSTANCE);
+		this.filteredDigraph = new FilterIteration<>(digraph, new NotSeenPredicate(), arc -> true);
+		this.reverseDigraph = new FilterIteration<>(new ReversedIteration<>(digraph), reverseDFSFilter, arc -> true);
 		this.vertexIterator = filteredDigraph.vertexIterator();
 
 		runDirectDFS();
@@ -123,7 +119,9 @@ public class StrongConnection<E, V> implements Iterator<Collection<E>> {
 	public Digraph<Collection<E>, Collection<V>> contract(Digraph<Collection<E>, Collection<V>> contractedDigraph) {
 
 		Collection<Collection<E>> components = new ArrayList<>();
-		CollectionUtils.addAll(components, this);
+		while (this.hasNext()) {
+			components.add(this.next());
+		}
 
 		Map<E, Collection<E>> memberToComponent = new HashMap<>();
 
@@ -221,20 +219,20 @@ public class StrongConnection<E, V> implements Iterator<Collection<E>> {
 		return component;
 	}
 
-	private class DFSSeenVerticesPredicate implements Predicate {
+	private class DFSSeenVerticesPredicate implements Predicate<E> {
 
 		private Set<E> seenVertices = new HashSet<>();
 
 		@Override
-		public boolean evaluate(Object vertex) {
+		public boolean test(E vertex) {
 			return seenVertices.contains(vertex);
 		}
 	}
 
-	private class NotSeenPredicate implements Predicate {
+	private class NotSeenPredicate implements Predicate<E> {
 
 		@Override
-		public boolean evaluate(Object vertex) {
+		public boolean test(E vertex) {
 			return !seen.contains(vertex);
 		}
 	}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/10e07069/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ConnectionProperties.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ConnectionProperties.java b/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ConnectionProperties.java
index 525fc39..22b91fb 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ConnectionProperties.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ConnectionProperties.java
@@ -20,13 +20,13 @@
 package org.apache.cayenne.unit.di.server;
 
 import org.apache.cayenne.conn.DataSourceInfo;
-import org.apache.commons.collections.ExtendedProperties;
 
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * ConnectionProperties handles a set of DataSourceInfo objects using
@@ -50,10 +50,20 @@ class ConnectionProperties {
 	/**
 	 * Constructor for ConnectionProperties.
 	 */
-	ConnectionProperties(ExtendedProperties props) {
+	ConnectionProperties(Map<String, String> props) {
 		connectionInfos = new HashMap<>();
 		for (String name : extractNames(props)) {
-			DataSourceInfo dsi = buildDataSourceInfo(props.subset(name));
+			DataSourceInfo dsi = buildDataSourceInfo(
+					props.entrySet().stream()
+							.filter(e -> e.getKey().startsWith(name + '.'))
+							.collect(Collectors.toMap(
+									e -> {
+										String key = e.getKey();
+										return key.substring(key.indexOf('.') + 1);
+									},
+									Map.Entry::getValue
+							))
+			);
 			connectionInfos.put(name, dsi);
 		}
 	}
@@ -73,21 +83,21 @@ class ConnectionProperties {
 	/**
 	 * Creates a DataSourceInfo object from a set of properties.
 	 */
-	private DataSourceInfo buildDataSourceInfo(ExtendedProperties props) {
+	private DataSourceInfo buildDataSourceInfo(Map<String, String> props) {
 		DataSourceInfo dsi = new DataSourceInfo();
 
-		String adapter = props.getString(ADAPTER_KEY);
+		String adapter = props.get(ADAPTER_KEY);
 
 		// try legacy adapter key
 		if (adapter == null) {
-			adapter = props.getString(ADAPTER20_KEY);
+			adapter = props.get(ADAPTER20_KEY);
 		}
 
 		dsi.setAdapterClassName(adapter);
-		dsi.setUserName(props.getString(USER_NAME_KEY));
-		dsi.setPassword(props.getString(PASSWORD_KEY));
-		dsi.setDataSourceUrl(props.getString(URL_KEY));
-		dsi.setJdbcDriver(props.getString(DRIVER_KEY));
+		dsi.setUserName(props.get(USER_NAME_KEY));
+		dsi.setPassword(props.get(PASSWORD_KEY));
+		dsi.setDataSourceUrl(props.get(URL_KEY));
+		dsi.setJdbcDriver(props.get(DRIVER_KEY));
 		dsi.setMinConnections(MIN_CONNECTIONS);
 		dsi.setMaxConnections(MAX_CONNECTIONS);
 
@@ -97,9 +107,9 @@ class ConnectionProperties {
 	/**
 	 * Returns a list of connection names configured in the properties object.
 	 */
-	private List<String> extractNames(ExtendedProperties props) {
-		Iterator<?> it = props.getKeys();
-		List<String> list = new ArrayList<String>();
+	private List<String> extractNames(Map<String, String> props) {
+		Iterator<?> it = props.keySet().iterator();
+		List<String> list = new ArrayList<>();
 
 		while (it.hasNext()) {
 			String key = (String) it.next();

http://git-wip-us.apache.org/repos/asf/cayenne/blob/10e07069/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseDataSourceInfoProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseDataSourceInfoProvider.java b/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseDataSourceInfoProvider.java
index d861a1b..7258fba 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseDataSourceInfoProvider.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseDataSourceInfoProvider.java
@@ -25,14 +25,15 @@ import org.apache.cayenne.dba.h2.H2Adapter;
 import org.apache.cayenne.dba.hsqldb.HSQLDBAdapter;
 import org.apache.cayenne.dba.sqlite.SQLiteAdapter;
 import org.apache.cayenne.di.Provider;
-import org.apache.commons.collections.ExtendedProperties;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.io.File;
+import java.io.FileReader;
 import java.io.IOException;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Properties;
 
 public class ServerCaseDataSourceInfoProvider implements Provider<DataSourceInfo> {
 
@@ -52,11 +53,16 @@ public class ServerCaseDataSourceInfoProvider implements Provider<DataSourceInfo
 
     public ServerCaseDataSourceInfoProvider() throws IOException {
 
+        Map<String, String> propertiesMap = new HashMap<>();
+
         File file = connectionPropertiesFile();
-        ExtendedProperties properties = file.exists() ? new ExtendedProperties(file.getAbsolutePath())
-                : new ExtendedProperties();
+        if(file.exists()) {
+            Properties properties = new Properties();
+            properties.load(new FileReader(file));
+            properties.forEach((k, v) -> propertiesMap.put(k.toString(), v.toString()));
+        }
 
-        this.connectionProperties = new ConnectionProperties(properties);
+        this.connectionProperties = new ConnectionProperties(propertiesMap);
         logger.info("Loaded  " + connectionProperties.size() + " DataSource configurations from properties file");
 
         this.inMemoryDataSources = new HashMap<>();

http://git-wip-us.apache.org/repos/asf/cayenne/blob/10e07069/cayenne-velocity/src/main/java/org/apache/cayenne/velocity/SQLTemplateResourceManager.java
----------------------------------------------------------------------
diff --git a/cayenne-velocity/src/main/java/org/apache/cayenne/velocity/SQLTemplateResourceManager.java b/cayenne-velocity/src/main/java/org/apache/cayenne/velocity/SQLTemplateResourceManager.java
index 085e2be..97da483 100644
--- a/cayenne-velocity/src/main/java/org/apache/cayenne/velocity/SQLTemplateResourceManager.java
+++ b/cayenne-velocity/src/main/java/org/apache/cayenne/velocity/SQLTemplateResourceManager.java
@@ -23,8 +23,8 @@ import java.io.ByteArrayInputStream;
 import java.io.InputStream;
 import java.util.Map;
 
+import org.apache.cayenne.util.concurrentlinkedhashmap.ConcurrentLinkedHashMap;
 import org.apache.commons.collections.ExtendedProperties;
-import org.apache.commons.collections.map.LRUMap;
 import org.apache.velocity.Template;
 import org.apache.velocity.exception.ParseErrorException;
 import org.apache.velocity.exception.ResourceNotFoundException;
@@ -48,7 +48,7 @@ public class SQLTemplateResourceManager
 
     public void initialize(RuntimeServices rs) {
         super.rsvc = rs;
-        this.templateCache = new LRUMap(100);
+        this.templateCache = new ConcurrentLinkedHashMap.Builder<String, Template>().maximumWeightedCapacity(100).build();
     }
 
     public void clearCache() {

http://git-wip-us.apache.org/repos/asf/cayenne/blob/10e07069/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelHelper.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelHelper.java b/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelHelper.java
index fd05744..31a9567 100644
--- a/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelHelper.java
+++ b/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelHelper.java
@@ -33,7 +33,6 @@ import java.util.Map;
 
 import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.wocompat.parser.Parser;
-import org.apache.commons.collections.IteratorUtils;
 
 /**
  * Helper class used by EOModelProcessor. EOModelHelper loads an EOModel from
@@ -252,7 +251,7 @@ public class EOModelHelper {
 	 * @since 1.1
 	 */
 	public List modelNamesAsList() {
-		return new ArrayList(entityClassIndex.keySet());
+		return new ArrayList<>(entityClassIndex.keySet());
 	}
 
 	public Map getPrototypeAttributeMapFor(String aPrototypeAttributeName) {
@@ -262,7 +261,7 @@ public class EOModelHelper {
 
 			// no prototypes
 			if (eoPrototypesEntityMap == null) {
-				prototypeValues = Collections.EMPTY_MAP;
+				prototypeValues = Collections.emptyMap();
 			} else {
 				List eoPrototypeAttributes = (List) eoPrototypesEntityMap.get("attributes");
 
@@ -310,7 +309,7 @@ public class EOModelHelper {
 	public Iterator queryNames(String entityName) {
 		Map queryPlist = (Map) entityQueryIndex.get(entityName);
 		if (queryPlist == null || queryPlist.isEmpty()) {
-			return IteratorUtils.EMPTY_ITERATOR;
+			return Collections.emptyIterator();
 		}
 
 		return queryPlist.keySet().iterator();


[4/9] cayenne git commit: CAY-2351 Remove commons-collections usage completely Own ReferenceMap implementation

Posted by nt...@apache.org.
CAY-2351 Remove commons-collections usage completely
  Own ReferenceMap implementation


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/bc7399a3
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/bc7399a3
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/bc7399a3

Branch: refs/heads/master
Commit: bc7399a313b4fa55f3f083106cbe2012c9397e97
Parents: 4e623e3
Author: Nikita Timofeev <st...@gmail.com>
Authored: Thu Aug 10 18:27:21 2017 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Thu Aug 17 12:41:57 2017 +0300

----------------------------------------------------------------------
 .../org/apache/cayenne/util/ReferenceMap.java   | 135 ++++++++++--
 .../apache/cayenne/util/WeakValueMapTest.java   | 203 +++++++++++++++++++
 2 files changed, 321 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/bc7399a3/cayenne-server/src/main/java/org/apache/cayenne/util/ReferenceMap.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/util/ReferenceMap.java b/cayenne-server/src/main/java/org/apache/cayenne/util/ReferenceMap.java
index e441f86..530ea30 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/util/ReferenceMap.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/util/ReferenceMap.java
@@ -25,34 +25,69 @@ import java.io.ObjectOutputStream;
 import java.io.Serializable;
 import java.lang.ref.Reference;
 import java.lang.ref.ReferenceQueue;
+import java.util.AbstractMap;
+import java.util.AbstractSet;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
 
 /**
  * Map that transparently stores values as references and resolves them as needed.
+ * Though this implementation try to follow general {@link Map} contract (including equals() and hashCode())
+ * it is not intended for general usage.
  * <p>
- * This implementation supports serialization.
+ * There is no HardReferenceMap as simple HashMap can be used for that.
  * <p>
- * Internally data stored in HashMap thus this class and all implementations are not thread safe.
+ * This map doesn't guaranties that value will be there even right after put(), as GC can remove it at any time.
+ * <p>
+ * This implementation supports proper serialization, concrete classes should use {@link #writeObjectInternal(ObjectOutputStream)}
+ * and {@link #readObjectInternal(ObjectInputStream)} methods to support it too.
+ * <p>
+ *
+ * @param <K> key type
+ * @param <V> value type
+ * @param <R> reference type that will be used to store values
  *
- * @see WeakValueMap
- * @see SoftValueMap
+ * @see WeakValueMap implementation that uses WeakReference to store values
+ * @see SoftValueMap implementation that uses SoftReference to store values
  *
  * @since 4.1
  */
-public abstract class ReferenceMap<K, V, R extends Reference<V>> implements Map<K, V>, Serializable {
+abstract class ReferenceMap<K, V, R extends Reference<V>> extends AbstractMap<K, V> implements Serializable {
+
+    /*
+     * Implementation notes:
+     *  - internally data stored in HashMap thus this class and all implementations are not thread safe;
+     *  - to track references that were cleared ReferenceQueue is used;
+     *  - this map stores not only direct key => ref map but also a reverse ref => key to be able
+     *  effectively clear data that was removed by GC;
+     *  - this map is abstract, all that required for the concrete implementation is
+     *  to define newReference(Object) method;
+     *  - all accessors/modifiers should call checkReferenceQueue() to clear all stale data
+     */
 
     private static final long serialVersionUID = -3365744592038165092L;
 
+    /**
+     * This is a main data storage used for most operations
+     */
     protected transient Map<K, R> map;
 
+    /**
+     * This is aux storage to faster remove cleared references
+     */
     protected transient Map<R, K> reverseMap;
 
     protected transient ReferenceQueue<V> referenceQueue;
 
+    /**
+     * This is a lazily created set of entries that is essentially a view to actual data
+     */
+    protected transient Set<Entry<K, V>> entrySet;
+
     public ReferenceMap() {
         map = new HashMap<>();
         reverseMap = new HashMap<>();
@@ -163,13 +198,12 @@ public abstract class ReferenceMap<K, V, R extends Reference<V>> implements Map<
     @Override
     public Collection<V> values() {
         checkReferenceQueue();
-        Collection<V> values = new ArrayList<>();
-        for(R v : map.values()) {
+        // this can be optimized by creating view instead of new heavyweight collection
+        Collection<R> referenceValues = map.values();
+        Collection<V> values = new ArrayList<>(referenceValues.size());
+        for(R v : referenceValues) {
             if(v != null) {
-                V value = v.get();
-                if(value != null) {
-                    values.add(value);
-                }
+                values.add(v.get());
             }
         }
         return values;
@@ -177,11 +211,17 @@ public abstract class ReferenceMap<K, V, R extends Reference<V>> implements Map<
 
     @Override
     public Set<Entry<K, V>> entrySet() {
-        throw new UnsupportedOperationException();
+        checkReferenceQueue();
+        // lazily create entry set view
+        Set<Entry<K, V>> es = entrySet;
+        if(es == null) {
+            entrySet = es = new ReferenceEntrySet();
+        }
+        return es;
     }
 
     /**
-     * Cleanup all collected references
+     * Cleanup all references collected by GC so far
      */
     protected void checkReferenceQueue() {
         Reference<? extends V> reference;
@@ -212,7 +252,6 @@ public abstract class ReferenceMap<K, V, R extends Reference<V>> implements Map<
         writeObjectInternal(out);
     }
 
-    @SuppressWarnings("unchecked")
     private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
         readObjectInternal(in);
     }
@@ -235,8 +274,70 @@ public abstract class ReferenceMap<K, V, R extends Reference<V>> implements Map<
         reverseMap = new HashMap<>(replacement.size());
         referenceQueue = new ReferenceQueue<>();
         putAll(replacement);
-        map.forEach((k, v) -> {
-            reverseMap.put(v, k);
-        });
+        map.forEach((k, v) -> reverseMap.put(v, k));
+    }
+
+    /**
+     * View over {@link #map} entry set
+     */
+    class ReferenceEntrySet extends AbstractSet<Entry<K, V>> {
+
+        @Override
+        public Iterator<Entry<K, V>> iterator() {
+            return new ReferenceEntryIterator();
+        }
+
+        @Override
+        public int size() {
+            return map.size();
+        }
+    }
+
+    /**
+     * Iterator used by entrySet. Wrapper around {@link #map} iterator
+     */
+    class ReferenceEntryIterator implements Iterator<Entry<K, V>> {
+
+        Iterator<Entry<K, R>> internalIterator;
+
+        ReferenceEntryIterator() {
+            internalIterator = map.entrySet().iterator();
+        }
+
+        @Override
+        public boolean hasNext() {
+            return internalIterator.hasNext();
+        }
+
+        @Override
+        public Entry<K, V> next() {
+            return new ReferenceEntry(internalIterator.next());
+        }
+    }
+
+    /**
+     * View over {@link Map.Entry} that transparently resolves Reference
+     */
+    class ReferenceEntry extends SimpleEntry<K, V> {
+
+        private static final long serialVersionUID = -1795136249842496011L;
+
+        Entry<K, R> refEntry;
+
+        public ReferenceEntry(Entry<K, R> refEntry) {
+            super(refEntry.getKey(), refEntry.getValue() != null ? refEntry.getValue().get() : null);
+            this.refEntry = refEntry;
+        }
+
+        @Override
+        public V setValue(V value) {
+            R newRef = newReference(value);
+            R oldRef = refEntry.setValue(newRef);
+            reverseMap.put(newRef, reverseMap.remove(oldRef));
+            if(oldRef != null) {
+                return oldRef.get();
+            }
+            return null;
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/bc7399a3/cayenne-server/src/test/java/org/apache/cayenne/util/WeakValueMapTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/util/WeakValueMapTest.java b/cayenne-server/src/test/java/org/apache/cayenne/util/WeakValueMapTest.java
new file mode 100644
index 0000000..e5a29f6
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/util/WeakValueMapTest.java
@@ -0,0 +1,203 @@
+/*****************************************************************
+ *   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.
+ ****************************************************************/
+
+package org.apache.cayenne.util;
+
+import java.util.ConcurrentModificationException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * As WeakValueMap and SoftValueMap share almost all code from their super class
+ * only one test is present for both of them.
+ *
+ * @since 4.1
+ */
+public class WeakValueMapTest {
+
+    @Test
+    public void testEmptyConstructor() {
+        Map<String, Integer> map = new WeakValueMap<>();
+
+        assertTrue(map.isEmpty());
+        assertEquals(0, map.size());
+        assertFalse(map.containsKey("nonexistent_key1"));
+        assertFalse(map.containsValue(42));
+        assertNull(map.get("nonexistent_key2"));
+        assertEquals(new Integer(42), map.getOrDefault("nonexistent_key2", 42));
+
+        assertEquals(0, map.values().size());
+        assertEquals(0, map.keySet().size());
+        assertEquals(0, map.entrySet().size());
+    }
+
+    @Test
+    public void testCapacityConstructor() {
+        Map<String, Integer> map = new WeakValueMap<>(42);
+
+        assertTrue(map.isEmpty());
+        assertEquals(0, map.size());
+        assertFalse(map.containsKey("nonexistent_key1"));
+        assertFalse(map.containsValue(42));
+        assertNull(map.get("nonexistent_key2"));
+        assertEquals(new Integer(42), map.getOrDefault("nonexistent_key2", 42));
+
+        assertEquals(0, map.values().size());
+        assertEquals(0, map.keySet().size());
+        assertEquals(0, map.entrySet().size());
+    }
+
+    @Test
+    public void testMapConstructor() {
+        Map<String, Integer> data = new HashMap<>();
+        data.put("key_1", 123);
+        data.put("key_2", 42);
+        data.put("key_3", null);
+
+        Map<String, Integer> map = new WeakValueMap<>(data);
+
+        assertFalse(map.isEmpty());
+        assertEquals(data.size(), map.size());
+        assertFalse(map.containsKey("nonexistent_key1"));
+        assertTrue(map.containsKey("key_3"));
+        assertFalse(map.containsValue(321));
+        assertTrue(map.containsValue(42));
+        assertNull(map.get("nonexistent_key2"));
+        assertNull(map.get("key_3"));
+        assertEquals(new Integer(123), map.getOrDefault("key_1", 42));
+
+        assertEquals(data.size(), map.values().size());
+        assertEquals(data.size(), map.keySet().size());
+        assertEquals(data.size(), map.entrySet().size());
+
+        assertTrue(map.values().containsAll(data.values()));
+        assertTrue(map.keySet().containsAll(data.keySet()));
+        assertTrue(map.entrySet().containsAll(data.entrySet()));
+    }
+
+    @Test
+    public void testSimpleOperations() {
+        Map<String, Integer> data = new HashMap<>();
+        data.put("key_1", 123);
+        data.put("key_2", 42);
+        data.put("key_3", null);
+
+        Map<String, Integer> map = new WeakValueMap<>(data);
+
+        map.put("key_4", 44);
+        assertEquals(new Integer(44), map.get("key_4"));
+        assertEquals(4, map.size());
+        assertTrue(map.containsKey("key_4"));
+        assertTrue(map.containsValue(44));
+
+        int old = map.remove("key_4");
+        assertEquals(44, old);
+        assertEquals(3, map.size());
+        assertFalse(map.containsKey("key_4"));
+        assertFalse(map.containsValue(44));
+    }
+
+    @Test
+    public void testEntrySetUpdateValue() {
+        Map<String, Integer> map = new WeakValueMap<>();
+        map.put("key_1", 123);
+        map.put("key_2", 42);
+        map.put("key_3", null);
+        assertEquals(3, map.size());
+
+        int counter = 0;
+        for(Map.Entry<String, Integer> entry : map.entrySet()) {
+            if("key_2".equals(entry.getKey())) {
+                int old = entry.setValue(24);
+                assertEquals(42, old);
+            }
+            counter++;
+        }
+
+        assertEquals(3, counter);
+        assertEquals(new Integer(24), map.get("key_2"));
+    }
+
+    @Test
+    public void testSerializationSupport() throws Exception {
+        WeakValueMap<String, Integer> map = new WeakValueMap<>();
+        map.put("key_1", 123);
+        map.put("key_2", 42);
+        map.put("key_3", null);
+        assertEquals(3, map.size());
+
+        WeakValueMap<String, Integer> clone = Util.cloneViaSerialization(map);
+
+        assertEquals(3, clone.size());
+        assertEquals(new Integer(42), clone.get("key_2"));
+        assertTrue(clone.containsKey("key_3"));
+        assertTrue(clone.containsValue(123));
+    }
+
+    @Test
+    public void testEqualsAndHashCode() throws Exception {
+        Map<String, Integer> map1 = new WeakValueMap<>();
+        map1.put("key_1", 123);
+        map1.put("key_2", 42);
+        map1.put("key_3", null);
+        assertEquals(3, map1.size());
+
+        Map<String, Integer> map2 = new HashMap<>();
+        map2.put("key_1", 123);
+        map2.put("key_2", 42);
+        map2.put("key_3", null);
+
+        assertEquals(map1, map2);
+        assertEquals(map1.hashCode(), map2.hashCode());
+    }
+
+    @Test(expected = ConcurrentModificationException.class)
+    public void testConcurrentModification() {
+        Map<String, Integer> map = new WeakValueMap<>(3);
+        map.put("key_1", 123);
+        map.put("key_2", 42);
+        map.put("key_3", null);
+        assertEquals(3, map.size());
+
+        for(Map.Entry<String, Integer> entry : map.entrySet()) {
+            if("key_2".equals(entry.getKey())) {
+                map.remove("key_2");
+            }
+        }
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testUnsupportedEntryIteratorRemoval() {
+        Map<String, Integer> map = new WeakValueMap<>(3);
+        map.put("key_1", 123);
+        map.put("key_2", 42);
+        map.put("key_3", null);
+        assertEquals(3, map.size());
+
+        Iterator<Map.Entry<String, Integer>> iterator = map.entrySet().iterator();
+        while(iterator.hasNext()) {
+            iterator.remove();
+        }
+    }
+}
\ No newline at end of file


[5/9] cayenne git commit: CAY-2351 Remove commons-collections usage completely own ReferenceMap implementation copy of CompositeCollection

Posted by nt...@apache.org.
CAY-2351 Remove commons-collections usage completely
  own ReferenceMap implementation
  copy of CompositeCollection


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/e70c5a51
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/e70c5a51
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/e70c5a51

Branch: refs/heads/master
Commit: e70c5a51174e63e4a36f83fb6aa877c3f85e0729
Parents: 10e0706
Author: Nikita Timofeev <st...@gmail.com>
Authored: Fri Aug 4 17:58:18 2017 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Thu Aug 17 12:41:57 2017 +0300

----------------------------------------------------------------------
 .../access/DefaultObjectMapRetainStrategy.java  |  15 +-
 .../org/apache/cayenne/event/EventSubject.java  |   6 +-
 .../org/apache/cayenne/map/MappingCache.java    |  14 +-
 .../org/apache/cayenne/util/ReferenceMap.java   | 242 ++++++++++++++
 .../org/apache/cayenne/util/SoftValueMap.java   |  64 ++++
 .../org/apache/cayenne/util/WeakValueMap.java   |  63 ++++
 .../util/commons/CompositeCollection.java       | 328 +++++++++++++++++++
 .../cayenne/util/commons/IteratorChain.java     | 195 +++++++++++
 .../cayenne/wocompat/EOModelProcessor.java      |  45 +--
 9 files changed, 925 insertions(+), 47 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/e70c5a51/cayenne-server/src/main/java/org/apache/cayenne/access/DefaultObjectMapRetainStrategy.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/DefaultObjectMapRetainStrategy.java b/cayenne-server/src/main/java/org/apache/cayenne/access/DefaultObjectMapRetainStrategy.java
index 7fe338c..9e8213f 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/DefaultObjectMapRetainStrategy.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/DefaultObjectMapRetainStrategy.java
@@ -18,6 +18,7 @@
  ****************************************************************/
 package org.apache.cayenne.access;
 
+import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.cayenne.CayenneRuntimeException;
@@ -25,8 +26,8 @@ import org.apache.cayenne.Persistent;
 import org.apache.cayenne.configuration.Constants;
 import org.apache.cayenne.configuration.RuntimeProperties;
 import org.apache.cayenne.di.Inject;
-import org.apache.commons.collections.map.AbstractReferenceMap;
-import org.apache.commons.collections.map.ReferenceMap;
+import org.apache.cayenne.util.SoftValueMap;
+import org.apache.cayenne.util.WeakValueMap;
 
 /**
  * Default implementation of {@link ObjectMapRetainStrategy}.
@@ -45,17 +46,15 @@ public class DefaultObjectMapRetainStrategy implements ObjectMapRetainStrategy {
         this.runtimeProperties = runtimeProperties;
     }
 
-    @SuppressWarnings("unchecked")
     public Map<Object, Persistent> createObjectMap() {
-        String strategy = runtimeProperties
-                .get(Constants.SERVER_OBJECT_RETAIN_STRATEGY_PROPERTY);
+        String strategy = runtimeProperties.get(Constants.SERVER_OBJECT_RETAIN_STRATEGY_PROPERTY);
 
         if (strategy == null || WEAK_RETAIN_STRATEGY.equals(strategy)) {
-            return new ReferenceMap(AbstractReferenceMap.HARD, AbstractReferenceMap.WEAK);
+            return new WeakValueMap<>();
         } else if (SOFT_RETAIN_STRATEGY.equals(strategy)) {
-            return new ReferenceMap(AbstractReferenceMap.HARD, AbstractReferenceMap.SOFT);
+            return new SoftValueMap<>();
         } else if (HARD_RETAIN_STRATEGY.equals(strategy)) {
-            return new ReferenceMap(AbstractReferenceMap.HARD, AbstractReferenceMap.HARD);
+            return new HashMap<>();
         } else {
             throw new CayenneRuntimeException("Unsupported retain strategy %s", strategy);
         }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e70c5a51/cayenne-server/src/main/java/org/apache/cayenne/event/EventSubject.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/event/EventSubject.java b/cayenne-server/src/main/java/org/apache/cayenne/event/EventSubject.java
index 4122e12..fe90b58 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/event/EventSubject.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/event/EventSubject.java
@@ -23,7 +23,7 @@ import java.io.Serializable;
 import java.util.Map;
 
 import org.apache.cayenne.util.HashCodeBuilder;
-import org.apache.commons.collections.map.ReferenceMap;
+import org.apache.cayenne.util.WeakValueMap;
 
 /**
  * This class encapsulates the String that is used to identify the <em>subject</em> that
@@ -41,9 +41,7 @@ public class EventSubject implements Serializable {
 
     // a Map that will allow the values to be GC'ed
     @SuppressWarnings("unchecked")
-    private static Map<String, EventSubject> _registeredSubjects = new ReferenceMap(
-            ReferenceMap.HARD,
-            ReferenceMap.WEAK);
+    private static Map<String, EventSubject> _registeredSubjects = new WeakValueMap<>();
 
     // Subject identifier in the form "com.foo.bar/SubjectName"
     private String _fullyQualifiedSubjectName;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e70c5a51/cayenne-server/src/main/java/org/apache/cayenne/map/MappingCache.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/map/MappingCache.java b/cayenne-server/src/main/java/org/apache/cayenne/map/MappingCache.java
index c8b2b2c..f5c0d12 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/map/MappingCache.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/map/MappingCache.java
@@ -26,7 +26,7 @@ import java.util.Map;
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.ObjectId;
 import org.apache.cayenne.Persistent;
-import org.apache.commons.collections.collection.CompositeCollection;
+import org.apache.cayenne.util.commons.CompositeCollection;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -206,7 +206,7 @@ class MappingCache implements MappingNamespace {
             return maps.iterator().next().getDbEntities();
         }
 
-        CompositeCollection c = new CompositeCollection();
+        CompositeCollection<DbEntity> c = new CompositeCollection<>();
         for (DataMap map : maps) {
             c.addComposited(map.getDbEntities());
         }
@@ -228,7 +228,7 @@ class MappingCache implements MappingNamespace {
             return maps.iterator().next().getProcedures();
         }
         
-        CompositeCollection c = new CompositeCollection();
+        CompositeCollection<Procedure> c = new CompositeCollection<>();
         for (DataMap map : maps) {
             c.addComposited(map.getProcedures());
         }
@@ -250,7 +250,7 @@ class MappingCache implements MappingNamespace {
             return maps.iterator().next().getQueryDescriptors();
         }
 
-        CompositeCollection c = new CompositeCollection();
+        CompositeCollection<QueryDescriptor> c = new CompositeCollection<>();
         for (DataMap map : maps) {
             c.addComposited(map.getQueryDescriptors());
         }
@@ -272,7 +272,7 @@ class MappingCache implements MappingNamespace {
             return maps.iterator().next().getObjEntities();
         }
         
-        CompositeCollection c = new CompositeCollection();
+        CompositeCollection<ObjEntity> c = new CompositeCollection<>();
         for (DataMap map : maps) {
             c.addComposited(map.getObjEntities());
         }
@@ -294,7 +294,7 @@ class MappingCache implements MappingNamespace {
             return maps.iterator().next().getEmbeddables();
         }
         
-        CompositeCollection c = new CompositeCollection();
+        CompositeCollection<Embeddable> c = new CompositeCollection<>();
         for (DataMap map : maps) {
             c.addComposited(map.getEmbeddables());
         }
@@ -317,7 +317,7 @@ class MappingCache implements MappingNamespace {
             return maps.iterator().next().getResults();
         }
         
-        CompositeCollection c = new CompositeCollection();
+        CompositeCollection<SQLResult> c = new CompositeCollection<>();
         for (DataMap map : maps) {
             c.addComposited(map.getResults());
         }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e70c5a51/cayenne-server/src/main/java/org/apache/cayenne/util/ReferenceMap.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/util/ReferenceMap.java b/cayenne-server/src/main/java/org/apache/cayenne/util/ReferenceMap.java
new file mode 100644
index 0000000..e441f86
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/util/ReferenceMap.java
@@ -0,0 +1,242 @@
+/*****************************************************************
+ *   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.
+ ****************************************************************/
+
+package org.apache.cayenne.util;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Map that transparently stores values as references and resolves them as needed.
+ * <p>
+ * This implementation supports serialization.
+ * <p>
+ * Internally data stored in HashMap thus this class and all implementations are not thread safe.
+ *
+ * @see WeakValueMap
+ * @see SoftValueMap
+ *
+ * @since 4.1
+ */
+public abstract class ReferenceMap<K, V, R extends Reference<V>> implements Map<K, V>, Serializable {
+
+    private static final long serialVersionUID = -3365744592038165092L;
+
+    protected transient Map<K, R> map;
+
+    protected transient Map<R, K> reverseMap;
+
+    protected transient ReferenceQueue<V> referenceQueue;
+
+    public ReferenceMap() {
+        map = new HashMap<>();
+        reverseMap = new HashMap<>();
+        referenceQueue = new ReferenceQueue<>();
+    }
+
+    public ReferenceMap(int initialCapacity) {
+        map = new HashMap<>(initialCapacity);
+        reverseMap = new HashMap<>(initialCapacity);
+        referenceQueue = new ReferenceQueue<>();
+    }
+
+    public ReferenceMap(Map<? extends K, ? extends V> m) {
+        this(m.size());
+        putAll(m);
+    }
+
+    @Override
+    public int size() {
+        checkReferenceQueue();
+        return map.size();
+    }
+
+    @Override
+    public boolean isEmpty() {
+        checkReferenceQueue();
+        return map.isEmpty();
+    }
+
+    @Override
+    public boolean containsKey(Object key) {
+        checkReferenceQueue();
+        return map.containsKey(key);
+    }
+
+    @Override
+    public boolean containsValue(Object value) {
+        checkReferenceQueue();
+        for(R ref : map.values()) {
+            if(ref != null) {
+                V v = ref.get();
+                if(v != null) {
+                    if(v.equals(value)) {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public V get(Object key) {
+        checkReferenceQueue();
+        R ref = map.get(key);
+        if(ref == null) {
+            return null;
+        }
+        return ref.get();
+    }
+
+    @Override
+    public V put(K key, V value) {
+        checkReferenceQueue();
+        R refValue = newReference(value);
+        R oldValue = map.put(key, refValue);
+        reverseMap.put(refValue, key);
+        if(oldValue == null) {
+            return null;
+        }
+        return oldValue.get();
+    }
+
+    @Override
+    public V remove(Object key) {
+        checkReferenceQueue();
+        R oldValue = map.remove(key);
+        if(oldValue == null) {
+            return null;
+        }
+        reverseMap.remove(oldValue);
+        return oldValue.get();
+    }
+
+    @Override
+    public void putAll(Map<? extends K, ? extends V> m) {
+        checkReferenceQueue();
+        for(Map.Entry<? extends K, ? extends V> entry : m.entrySet()) {
+            R value = newReference(entry.getValue());
+            map.put(entry.getKey(), value);
+            reverseMap.put(value, entry.getKey());
+        }
+    }
+
+    @Override
+    public void clear() {
+        map.clear();
+        reverseMap.clear();
+        resetReferenceQueue();
+    }
+
+    @Override
+    public Set<K> keySet() {
+        checkReferenceQueue();
+        return map.keySet();
+    }
+
+    @Override
+    public Collection<V> values() {
+        checkReferenceQueue();
+        Collection<V> values = new ArrayList<>();
+        for(R v : map.values()) {
+            if(v != null) {
+                V value = v.get();
+                if(value != null) {
+                    values.add(value);
+                }
+            }
+        }
+        return values;
+    }
+
+    @Override
+    public Set<Entry<K, V>> entrySet() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Cleanup all collected references
+     */
+    protected void checkReferenceQueue() {
+        Reference<? extends V> reference;
+
+        while((reference = referenceQueue.poll()) != null) {
+            K keyToRemove = reverseMap.remove(reference);
+            if(keyToRemove != null) {
+                map.remove(keyToRemove);
+            }
+        }
+    }
+
+    private void resetReferenceQueue() {
+        while(referenceQueue.poll() != null) {
+            // just purge this queue
+        }
+    }
+
+    /**
+     * This method should be implemented by concrete implementations of this abstract class.
+     *
+     * @param value to be wrapped into reference
+     * @return new reference to the value
+     */
+    abstract R newReference(V value);
+
+    private void writeObject(ObjectOutputStream out) throws IOException {
+        writeObjectInternal(out);
+    }
+
+    @SuppressWarnings("unchecked")
+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+        readObjectInternal(in);
+    }
+
+    protected void writeObjectInternal(ObjectOutputStream out) throws IOException {
+        checkReferenceQueue();
+        Map<K, V> replacementMap = new HashMap<>();
+        for(Entry<K, R> entry : map.entrySet()) {
+            if(entry.getValue() != null) {
+                replacementMap.put(entry.getKey(), entry.getValue().get());
+            }
+        }
+        out.writeObject(replacementMap);
+    }
+
+    protected void readObjectInternal(ObjectInputStream in) throws IOException, ClassNotFoundException {
+        @SuppressWarnings("unchecked")
+        Map<K, V> replacement = (Map<K, V>) in.readObject();
+        map = new HashMap<>(replacement.size());
+        reverseMap = new HashMap<>(replacement.size());
+        referenceQueue = new ReferenceQueue<>();
+        putAll(replacement);
+        map.forEach((k, v) -> {
+            reverseMap.put(v, k);
+        });
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e70c5a51/cayenne-server/src/main/java/org/apache/cayenne/util/SoftValueMap.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/util/SoftValueMap.java b/cayenne-server/src/main/java/org/apache/cayenne/util/SoftValueMap.java
new file mode 100644
index 0000000..6955a56
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/util/SoftValueMap.java
@@ -0,0 +1,64 @@
+/*****************************************************************
+ *   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.
+ ****************************************************************/
+
+package org.apache.cayenne.util;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.lang.ref.SoftReference;
+import java.lang.ref.WeakReference;
+import java.util.Map;
+
+/**
+ * Map that stores values wrapped into {@link WeakReference}
+ *
+ * @since 4.1
+ */
+public class SoftValueMap<K, V> extends ReferenceMap<K, V, SoftReference<V>> implements Serializable {
+
+    private static final long serialVersionUID = 8146103761927411986L;
+
+    public SoftValueMap() {
+        super();
+    }
+
+    public SoftValueMap(int initialCapacity) {
+        super(initialCapacity);
+    }
+
+    public SoftValueMap(Map<? extends K, ? extends V> m) {
+        super(m);
+    }
+
+    @Override
+    SoftReference<V> newReference(V value) {
+        return new SoftReference<>(value, referenceQueue);
+    }
+
+    private void writeObject(ObjectOutputStream out) throws IOException {
+        writeObjectInternal(out);
+    }
+
+    @SuppressWarnings("unchecked")
+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+        readObjectInternal(in);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e70c5a51/cayenne-server/src/main/java/org/apache/cayenne/util/WeakValueMap.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/util/WeakValueMap.java b/cayenne-server/src/main/java/org/apache/cayenne/util/WeakValueMap.java
new file mode 100644
index 0000000..76a1610
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/util/WeakValueMap.java
@@ -0,0 +1,63 @@
+/*****************************************************************
+ *   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.
+ ****************************************************************/
+
+package org.apache.cayenne.util;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.lang.ref.WeakReference;
+import java.util.Map;
+
+/**
+ * Map that stores values wrapped into {@link WeakReference}
+ *
+ * @since 4.1
+ */
+public class WeakValueMap<K, V> extends ReferenceMap<K, V, WeakReference<V>> implements Serializable {
+
+    private static final long serialVersionUID = -6911881597843322446L;
+
+    public WeakValueMap() {
+        super();
+    }
+
+    public WeakValueMap(int initialCapacity) {
+        super(initialCapacity);
+    }
+
+    public WeakValueMap(Map<? extends K, ? extends V> m) {
+        super(m);
+    }
+
+    @Override
+    WeakReference<V> newReference(V value) {
+        return new WeakReference<>(value, referenceQueue);
+    }
+
+    private void writeObject(ObjectOutputStream out) throws IOException {
+        writeObjectInternal(out);
+    }
+
+    @SuppressWarnings("unchecked")
+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+        readObjectInternal(in);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e70c5a51/cayenne-server/src/main/java/org/apache/cayenne/util/commons/CompositeCollection.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/util/commons/CompositeCollection.java b/cayenne-server/src/main/java/org/apache/cayenne/util/commons/CompositeCollection.java
new file mode 100644
index 0000000..6b5fb36
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/util/commons/CompositeCollection.java
@@ -0,0 +1,328 @@
+/*****************************************************************
+ *   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.
+ ****************************************************************/
+
+package org.apache.cayenne.util.commons;
+
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+
+/**
+ * Decorates a collection of other collections to provide a single unified view.
+ * <p>
+ * Changes made to this collection will actually be made on the decorated collection.
+ * Add and remove operations require the use of a pluggable strategy. If no
+ * strategy is provided then add and remove are unsupported.
+ *
+ * @author Brian McCallister
+ * @author Stephen Colebourne
+ * @author Phil Steitz
+ *
+ * @since 4.1
+ *
+ * NOTE: this is a simplified and type-safe version of CompositeCollection found in commons-collections v3.2.1
+ */
+public class CompositeCollection<E> implements Collection<E> {
+
+    /** Collections in the composite */
+    protected ArrayList<Collection<E>> all;
+
+    /**
+     * Create an empty CompositeCollection.
+     */
+    public CompositeCollection() {
+        super();
+        this.all = new ArrayList<>();
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Gets the size of this composite collection.
+     * <p>
+     * This implementation calls <code>size()</code> on each collection.
+     *
+     * @return total number of elements in all contained containers
+     */
+    @Override
+    public int size() {
+        int size = 0;
+        for(Collection<E> collection : this.all) {
+            size += collection.size();
+        }
+        return size;
+    }
+
+    /**
+     * Checks whether this composite collection is empty.
+     * <p>
+     * This implementation calls <code>isEmpty()</code> on each collection.
+     *
+     * @return true if all of the contained collections are empty
+     */
+    @Override
+    public boolean isEmpty() {
+        for(Collection<E> collection : this.all) {
+            if(!collection.isEmpty()){
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Checks whether this composite collection contains the object.
+     * <p>
+     * This implementation calls <code>contains()</code> on each collection.
+     *
+     * @param obj  the object to search for
+     * @return true if obj is contained in any of the contained collections
+     */
+    @Override
+    public boolean contains(Object obj) {
+        for(Collection<E> collection : this.all) {
+            if(!collection.contains(obj)){
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Gets an iterator over all the collections in this composite.
+     * <p>
+     * This implementation uses an <code>IteratorChain</code>.
+     *
+     * @return an <code>IteratorChain</code> instance which supports
+     *  <code>remove()</code>. Iteration occurs over contained collections in
+     *  the order they were added, but this behavior should not be relied upon.
+     * @see IteratorChain
+     */
+    @Override
+    public Iterator<E> iterator() {
+        if (this.all.isEmpty()) {
+            return Collections.emptyIterator();
+        }
+        IteratorChain<E> chain = new IteratorChain<>();
+        for (Collection<E> collection : this.all) {
+            chain.addIterator(collection.iterator());
+        }
+        return chain;
+    }
+
+    /**
+     * Returns an array containing all of the elements in this composite.
+     *
+     * @return an object array of all the elements in the collection
+     */
+    @Override
+    public Object[] toArray() {
+        final Object[] result = new Object[this.size()];
+        int i = 0;
+        for (Collection<E> collection : this.all) {
+            for(E o : collection) {
+                result[i++] = o;
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Returns an object array, populating the supplied array if possible.
+     * See <code>Collection</code> interface for full details.
+     *
+     * @param array  the array to use, populating if possible
+     * @return an array of all the elements in the collection
+     */
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T> T[] toArray(T[] array) {
+        int size = this.size();
+        Object[] result;
+        if (array.length >= size) {
+            result = array;
+        } else {
+            result = (T[]) Array.newInstance(array.getClass().getComponentType(), size);
+        }
+
+        int offset = 0;
+        for (Collection<E> collection : this.all) {
+            for (E e : collection) {
+                result[offset++] = e;
+            }
+        }
+        if (result.length > size) {
+            result[size] = null;
+        }
+        return (T[])result;
+    }
+
+    /**
+     * Adds an object to the collection, throwing UnsupportedOperationException
+     * unless a CollectionMutator strategy is specified.
+     *
+     * @param obj  the object to add
+     * @return true if the collection was modified
+     * @throws UnsupportedOperationException if CollectionMutator hasn't been set
+     * @throws UnsupportedOperationException if add is unsupported
+     * @throws ClassCastException if the object cannot be added due to its type
+     * @throws NullPointerException if the object cannot be added because its null
+     * @throws IllegalArgumentException if the object cannot be added
+     */
+    @Override
+    public boolean add(Object obj) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Removes an object from the collection, throwing UnsupportedOperationException
+     * unless a CollectionMutator strategy is specified.
+     *
+     * @param obj  the object being removed
+     * @return true if the collection is changed
+     * @throws UnsupportedOperationException if removed is unsupported
+     * @throws ClassCastException if the object cannot be removed due to its type
+     * @throws NullPointerException if the object cannot be removed because its null
+     * @throws IllegalArgumentException if the object cannot be removed
+     */
+    @Override
+    public boolean remove(Object obj) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Checks whether this composite contains all the elements in the specified collection.
+     * <p>
+     * This implementation calls <code>contains()</code> for each element in the
+     * specified collection.
+     *
+     * @param coll  the collection to check for
+     * @return true if all elements contained
+     */
+    @Override
+    public boolean containsAll(Collection<?> coll) {
+        for (Object o : coll) {
+            if (!this.contains(o)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Adds a collection of elements to this collection, throwing
+     * UnsupportedOperationException unless a CollectionMutator strategy is specified.
+     *
+     * @param coll  the collection to add
+     * @return true if the collection was modified
+     * @throws UnsupportedOperationException if CollectionMutator hasn't been set
+     * @throws UnsupportedOperationException if add is unsupported
+     * @throws ClassCastException if the object cannot be added due to its type
+     * @throws NullPointerException if the object cannot be added because its null
+     * @throws IllegalArgumentException if the object cannot be added
+     */
+    @Override
+    public boolean addAll(Collection<? extends E> coll) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Removes the elements in the specified collection from this composite collection.
+     * <p>
+     * This implementation calls <code>removeAll</code> on each collection.
+     *
+     * @param coll  the collection to remove
+     * @return true if the collection was modified
+     * @throws UnsupportedOperationException if removeAll is unsupported
+     */
+    @Override
+    public boolean removeAll(Collection<?> coll) {
+        if (coll.size() == 0) {
+            return false;
+        }
+        boolean changed = false;
+        for(Collection<E> collection : this.all) {
+            changed = (collection.removeAll(coll) || changed);
+        }
+        return changed;
+    }
+
+    /**
+     * Retains all the elements in the specified collection in this composite collection,
+     * removing all others.
+     * <p>
+     * This implementation calls <code>retainAll()</code> on each collection.
+     *
+     * @param coll  the collection to remove
+     * @return true if the collection was modified
+     * @throws UnsupportedOperationException if retainAll is unsupported
+     */
+    @Override
+    public boolean retainAll(final Collection<?> coll) {
+        boolean changed = false;
+        for(Collection<E> collection : this.all) {
+            changed = (collection.retainAll(coll) || changed);
+        }
+        return changed;
+    }
+
+    /**
+     * Removes all of the elements from this collection .
+     * <p>
+     * This implementation calls <code>clear()</code> on each collection.
+     *
+     * @throws UnsupportedOperationException if clear is unsupported
+     */
+    @Override
+    public void clear() {
+        for (Collection<E> collection : this.all) {
+            collection.clear();
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Add an additional collection to this composite.
+     *
+     * @param c  the collection to add
+     */
+    public void addComposited(Collection<E> c) {
+        all.add(c);
+    }
+
+    /**
+     * Removes a collection from the those being decorated in this composite.
+     *
+     * @param coll  collection to be removed
+     */
+    public void removeComposited(Collection<E> coll) {
+        all.remove(coll);
+    }
+
+    /**
+     * Gets the collections being decorated.
+     *
+     * @return Unmodifiable collection of all collections in this composite.
+     */
+    public Collection<Collection<E>> getCollections() {
+        return Collections.unmodifiableCollection(this.all);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e70c5a51/cayenne-server/src/main/java/org/apache/cayenne/util/commons/IteratorChain.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/util/commons/IteratorChain.java b/cayenne-server/src/main/java/org/apache/cayenne/util/commons/IteratorChain.java
new file mode 100644
index 0000000..05b1f2e
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/util/commons/IteratorChain.java
@@ -0,0 +1,195 @@
+/*
+ *  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.
+ */
+
+package org.apache.cayenne.util.commons;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Objects;
+
+
+/**
+ * An IteratorChain is an Iterator that wraps a number of Iterators.
+ * <p>
+ * This class makes multiple iterators look like one to the caller
+ * When any method from the Iterator interface is called, the IteratorChain
+ * will delegate to a single underlying Iterator. The IteratorChain will
+ * invoke the Iterators in sequence until all Iterators are exhausted.
+ * <p>
+ * Under many circumstances, linking Iterators together in this manner is
+ * more efficient (and convenient) than reading out the contents of each
+ * Iterator into a List and creating a new Iterator.
+ * <p>
+ * Calling a method that adds new Iterator<i>after a method in the Iterator
+ * interface has been called</i> will result in an UnsupportedOperationException.
+ * Subclasses should <i>take care</i> to not alter the underlying List of Iterators.
+ * <p>
+ *
+ * @since 4.1
+ *
+ * @author Morgan Delagrange
+ * @author Stephen Colebourne
+ *
+ * NOTE: this is a simplified version of ItertatorChain class found in commons-collections v3.2.1
+ * used only by {@link CompositeCollection}.
+ */
+class IteratorChain<E> implements Iterator<E> {
+
+    /** The chain of iterators */
+    protected final List<Iterator<E>> iteratorChain = new ArrayList<>();
+    /** The index of the current iterator */
+    protected int currentIteratorIndex = 0;
+    /** The current iterator */
+    protected Iterator<E> currentIterator = null;
+    /**
+     * The "last used" Iterator is the Iterator upon which
+     * next() or hasNext() was most recently called
+     * used for the remove() operation only
+     */
+    protected Iterator<E> lastUsedIterator = null;
+    /**
+     * ComparatorChain is "locked" after the first time
+     * compare(Object,Object) is called
+     */
+    protected boolean isLocked = false;
+
+    //-----------------------------------------------------------------------
+    /**
+     * Construct an IteratorChain with no Iterators.
+     * <p>
+     * You will normally use {@link #addIterator(Iterator)} to add
+     * some iterators after using this constructor.
+     */
+    public IteratorChain() {
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Add an Iterator to the end of the chain
+     *
+     * @param iterator Iterator to add
+     * @throws IllegalStateException if I've already started iterating
+     * @throws NullPointerException if the iterator is null
+     */
+    public void addIterator(Iterator<E> iterator) {
+        checkLocked();
+        iteratorChain.add(Objects.requireNonNull(iterator));
+    }
+
+    /**
+     * Number of Iterators in the current IteratorChain.
+     *
+     * @return Iterator count
+     */
+    public int size() {
+        return iteratorChain.size();
+    }
+
+    /**
+     * Checks whether the iterator chain is now locked and in use.
+     */
+    private void checkLocked() {
+        if (isLocked) {
+            throw new UnsupportedOperationException("IteratorChain cannot be changed after the first use of a method from the Iterator interface");
+        }
+    }
+
+    /**
+     * Lock the chain so no more iterators can be added.
+     * This must be called from all Iterator interface methods.
+     */
+    private void lockChain() {
+        if (!isLocked) {
+            isLocked = true;
+        }
+    }
+
+    /**
+     * Updates the current iterator field to ensure that the current Iterator
+     * is not exhausted
+     */
+    protected void updateCurrentIterator() {
+        if (currentIterator == null) {
+            if (iteratorChain.isEmpty()) {
+                currentIterator = Collections.emptyIterator();
+            } else {
+                currentIterator = iteratorChain.get(0);
+            }
+            // set last used iterator here, in case the user calls remove
+            // before calling hasNext() or next() (although they shouldn't)
+            lastUsedIterator = currentIterator;
+        }
+
+        while (!currentIterator.hasNext() && currentIteratorIndex < iteratorChain.size() - 1) {
+            currentIteratorIndex++;
+            currentIterator = iteratorChain.get(currentIteratorIndex);
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Return true if any Iterator in the IteratorChain has a remaining element.
+     *
+     * @return true if elements remain
+     */
+    public boolean hasNext() {
+        lockChain();
+        updateCurrentIterator();
+        lastUsedIterator = currentIterator;
+
+        return currentIterator.hasNext();
+    }
+
+    /**
+     * Returns the next Object of the current Iterator
+     *
+     * @return Object from the current Iterator
+     * @throws java.util.NoSuchElementException if all the Iterators are exhausted
+     */
+    public E next() {
+        lockChain();
+        updateCurrentIterator();
+        lastUsedIterator = currentIterator;
+
+        return currentIterator.next();
+    }
+
+    /**
+     * Removes from the underlying collection the last element
+     * returned by the Iterator.  As with next() and hasNext(),
+     * this method calls remove() on the underlying Iterator.
+     * Therefore, this method may throw an
+     * UnsupportedOperationException if the underlying
+     * Iterator does not support this method.
+     *
+     * @throws UnsupportedOperationException
+     *   if the remove operator is not supported by the underlying Iterator
+     * @throws IllegalStateException
+     *   if the next method has not yet been called, or the remove method has
+     *   already been called after the last call to the next method.
+     */
+    public void remove() {
+        lockChain();
+        if (currentIterator == null) {
+            updateCurrentIterator();
+        }
+        lastUsedIterator.remove();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e70c5a51/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelProcessor.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelProcessor.java b/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelProcessor.java
index d320559..ac2e9f0 100644
--- a/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelProcessor.java
+++ b/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelProcessor.java
@@ -35,9 +35,6 @@ import org.apache.cayenne.query.Ordering;
 import org.apache.cayenne.query.QueryMetadata;
 import org.apache.cayenne.query.SortOrder;
 import org.apache.cayenne.wocompat.parser.Parser;
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.collections.Predicate;
-import org.apache.commons.collections.PredicateUtils;
 import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -54,6 +51,8 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.StringTokenizer;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
 
 /**
  * Class for converting stored Apple EOModel mapping files to Cayenne DataMaps.
@@ -62,21 +61,15 @@ public class EOModelProcessor {
 
 	private static final Logger logger = LoggerFactory.getLogger(EOModelProcessor.class);
 
-	protected Predicate prototypeChecker;
+	protected Predicate<String> prototypeChecker;
 
 	public EOModelProcessor() {
-		prototypeChecker = new Predicate() {
-
-			@Override
-			public boolean evaluate(Object object) {
-				if (object == null) {
-					return false;
-				}
-
-				String entityName = object.toString();
-				return entityName.startsWith("EO") && entityName.endsWith("Prototypes");
-			}
-		};
+		prototypeChecker = entityName -> {
+            if (entityName == null) {
+                return false;
+            }
+            return entityName.startsWith("EO") && entityName.endsWith("Prototypes");
+        };
 	}
 
 	/**
@@ -154,24 +147,20 @@ public class EOModelProcessor {
 		DataMap dataMap = helper.getDataMap();
 
 		// process enitities ... throw out prototypes ... for now
-		List modelNames = new ArrayList(helper.modelNamesAsList());
-		CollectionUtils.filter(modelNames, PredicateUtils.notPredicate(prototypeChecker));
-
-		Iterator it = modelNames.iterator();
-		while (it.hasNext()) {
-			String name = (String) it.next();
-
+		List<String> modelNames = new ArrayList<>(helper.modelNamesAsList());
+		modelNames = modelNames.stream().filter(prototypeChecker.negate()).collect(Collectors.toList());
+		modelNames.forEach( name -> {
 			// create and register entity
 			makeEntity(helper, name, generateClientClass);
-		}
+		});
 
 		// now sort following inheritance hierarchy
-		Collections.sort(modelNames, new InheritanceComparator(dataMap));
+		modelNames.sort(new InheritanceComparator(dataMap));
 
 		// after all entities are loaded, process attributes
-		it = modelNames.iterator();
+		Iterator<String> it = modelNames.iterator();
 		while (it.hasNext()) {
-			String name = (String) it.next();
+			String name = it.next();
 
 			EOObjEntity e = (EOObjEntity) dataMap.getObjEntity(name);
 			// process entity attributes
@@ -228,7 +217,7 @@ public class EOModelProcessor {
 	 * @since 1.1
 	 */
 	protected boolean isPrototypesEntity(String entityName) {
-		return prototypeChecker.evaluate(entityName);
+		return prototypeChecker.test(entityName);
 	}
 
 	/**


[8/9] cayenne git commit: CAY-2351 Remove dependency on commons-collection release notes final cleanup

Posted by nt...@apache.org.
CAY-2351 Remove dependency on commons-collection
  release notes
  final cleanup


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/3c215ef1
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/3c215ef1
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/3c215ef1

Branch: refs/heads/master
Commit: 3c215ef168b93d2185e3fae61e820ab20ec28b1f
Parents: 7f7aca8
Author: Nikita Timofeev <st...@gmail.com>
Authored: Thu Aug 17 12:44:46 2017 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Thu Aug 17 12:44:46 2017 +0300

----------------------------------------------------------------------
 cayenne-server/pom.xml                            |  5 -----
 .../cayenne/access/jdbc/RowDescriptorBuilder.java |  1 -
 docs/doc/src/main/resources/RELEASE-NOTES.txt     |  1 +
 modeler/cayenne-wocompat/pom.xml                  |  4 ----
 .../apache/cayenne/wocompat/EOModelProcessor.java | 18 +++++++++++++++---
 pom.xml                                           | 10 ----------
 6 files changed, 16 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/3c215ef1/cayenne-server/pom.xml
----------------------------------------------------------------------
diff --git a/cayenne-server/pom.xml b/cayenne-server/pom.xml
index 3644697..97847ca 100644
--- a/cayenne-server/pom.xml
+++ b/cayenne-server/pom.xml
@@ -44,11 +44,6 @@
 			<version>${project.version}</version>
 			<scope>compile</scope>
 		</dependency>
-		<dependency>
-			<groupId>commons-collections</groupId>
-			<artifactId>commons-collections</artifactId>
-			<scope>compile</scope>
-		</dependency>
 		<!-- Optional dependencies... things that might have been placed in submodules... -->
 		<dependency>
 			<groupId>com.caucho</groupId>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/3c215ef1/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/RowDescriptorBuilder.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/RowDescriptorBuilder.java b/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/RowDescriptorBuilder.java
index 3f4c2c8..4831dc3 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/RowDescriptorBuilder.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/RowDescriptorBuilder.java
@@ -32,7 +32,6 @@ import java.util.function.Function;
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.access.types.ExtendedType;
 import org.apache.cayenne.access.types.ExtendedTypeMap;
-import org.apache.cayenne.util.Util;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/3c215ef1/docs/doc/src/main/resources/RELEASE-NOTES.txt
----------------------------------------------------------------------
diff --git a/docs/doc/src/main/resources/RELEASE-NOTES.txt b/docs/doc/src/main/resources/RELEASE-NOTES.txt
index 48cfa84..224dbdb 100644
--- a/docs/doc/src/main/resources/RELEASE-NOTES.txt
+++ b/docs/doc/src/main/resources/RELEASE-NOTES.txt
@@ -21,6 +21,7 @@ CAY-2336 Support for comments in Modeler
 CAY-2339 Compatibility module to support old versions of projects at runtime
 CAY-2345 Own template renderer as a replacement for Velocity
 CAY-2346 Field-based data object with Map-based storage fallback
+CAY-2351 Remove commons-collections usage completely
 
 Bug Fixes:
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/3c215ef1/modeler/cayenne-wocompat/pom.xml
----------------------------------------------------------------------
diff --git a/modeler/cayenne-wocompat/pom.xml b/modeler/cayenne-wocompat/pom.xml
index fccfedd..590d236 100644
--- a/modeler/cayenne-wocompat/pom.xml
+++ b/modeler/cayenne-wocompat/pom.xml
@@ -40,10 +40,6 @@
 			<artifactId>cayenne-dbsync</artifactId>
 			<version>${project.version}</version>
 		</dependency>
-		<dependency>
-			<groupId>commons-lang</groupId>
-			<artifactId>commons-lang</artifactId>
-		</dependency>
 
 		<dependency>
 			<groupId>junit</groupId>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/3c215ef1/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelProcessor.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelProcessor.java b/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelProcessor.java
index ac2e9f0..18fc903 100644
--- a/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelProcessor.java
+++ b/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelProcessor.java
@@ -35,7 +35,6 @@ import org.apache.cayenne.query.Ordering;
 import org.apache.cayenne.query.QueryMetadata;
 import org.apache.cayenne.query.SortOrder;
 import org.apache.cayenne.wocompat.parser.Parser;
-import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -265,7 +264,7 @@ public class EOModelProcessor {
 				if (fetchLimit instanceof Number) {
 					descriptor.setProperty(QueryMetadata.FETCH_LIMIT_PROPERTY,
 							String.valueOf(((Number) fetchLimit).intValue()));
-				} else if (StringUtils.isNumeric(fetchLimit.toString())) {
+				} else if (isNumeric(fetchLimit.toString())) {
 					descriptor.setProperty(QueryMetadata.FETCH_LIMIT_PROPERTY, fetchLimit.toString());
 				}
 			} catch (NumberFormatException nfex) {
@@ -320,7 +319,7 @@ public class EOModelProcessor {
 				if (fetchLimit instanceof Number) {
 					descriptor.setProperty(QueryMetadata.FETCH_LIMIT_PROPERTY,
 							String.valueOf(((Number) fetchLimit).intValue()));
-				} else if (StringUtils.isNumeric(fetchLimit.toString())) {
+				} else if (isNumeric(fetchLimit.toString())) {
 					descriptor.setProperty(QueryMetadata.FETCH_LIMIT_PROPERTY, fetchLimit.toString());
 				}
 			} catch (NumberFormatException nfex) {
@@ -813,6 +812,19 @@ public class EOModelProcessor {
 		return null;
 	}
 
+	static boolean isNumeric(String str) {
+		if (str == null) {
+			return false;
+		}
+
+		for(int i = 0; i < str.length(); ++i) {
+			if (!Character.isDigit(str.charAt(i))) {
+				return false;
+			}
+		}
+		return true;
+	}
+
 	// sorts ObjEntities so that subentities in inheritance hierarchy are shown
 	// last
 	final class InheritanceComparator implements Comparator {

http://git-wip-us.apache.org/repos/asf/cayenne/blob/3c215ef1/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index e3be55c..788e211 100644
--- a/pom.xml
+++ b/pom.xml
@@ -316,16 +316,6 @@
 				<scope>test</scope>
 			</dependency>
 			<dependency>
-				<groupId>commons-collections</groupId>
-				<artifactId>commons-collections</artifactId>
-				<version>3.2.1</version>
-			</dependency>
-			<dependency>
-				<groupId>commons-lang</groupId>
-				<artifactId>commons-lang</artifactId>
-				<version>2.4</version>
-			</dependency>
-			<dependency>
                 <groupId>org.apache.commons</groupId>
                 <artifactId>commons-dbcp2</artifactId>
                 <version>2.1.1</version>


[9/9] cayenne git commit: Merge remote-tracking branch 'remotes/parent/pr/239' into asf-master

Posted by nt...@apache.org.
Merge remote-tracking branch 'remotes/parent/pr/239' into asf-master


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/afb42ed4
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/afb42ed4
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/afb42ed4

Branch: refs/heads/master
Commit: afb42ed4c9772d81cc5f5c768ae02d0bb4ab67a6
Parents: de0969a 3c215ef
Author: Nikita Timofeev <st...@gmail.com>
Authored: Mon Aug 21 12:20:53 2017 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Mon Aug 21 12:20:53 2017 +0300

----------------------------------------------------------------------
 .travis.yml                                     |   2 -
 .../org/apache/cayenne/gen/DataMapUtils.java    |   5 +-
 cayenne-client/pom.xml                          |   5 -
 cayenne-lifecycle/pom.xml                       |   7 +
 .../ObjectIdPropagatedValueFactory.java         |   8 +-
 cayenne-server/pom.xml                          |  13 +-
 .../cayenne/access/DataDomainSyncBucket.java    |   6 +-
 .../access/DataNodeSyncQualifierDescriptor.java |  49 +--
 .../access/DefaultObjectMapRetainStrategy.java  |  15 +-
 .../access/jdbc/RowDescriptorBuilder.java       |  27 +-
 .../cayenne/access/jdbc/SQLTemplateAction.java  |  18 +-
 .../access/translator/select/JoinStack.java     |   7 +-
 .../translator/select/QualifierTranslator.java  |  10 +-
 .../cayenne/ashwood/AshwoodEntitySorter.java    |   5 +-
 .../ashwood/WeightedAshwoodEntitySorter.java    |   5 +-
 .../cayenne/ashwood/graph/DepthFirstSearch.java |   7 +-
 .../ashwood/graph/FilterArcIterator.java        |  20 +-
 .../cayenne/ashwood/graph/FilterIteration.java  |  31 +-
 .../cayenne/ashwood/graph/StrongConnection.java |  28 +-
 .../org/apache/cayenne/cache/MapQueryCache.java |   5 +-
 .../dba/oracle/OracleQualifierTranslator.java   |   6 +-
 .../org/apache/cayenne/event/EventSubject.java  |   6 +-
 .../java/org/apache/cayenne/exp/Expression.java |  16 +-
 .../org/apache/cayenne/exp/parser/ASTIn.java    |   5 +-
 .../org/apache/cayenne/exp/parser/ASTNotIn.java |   5 +-
 .../exp/parser/AggregateConditionNode.java      |   5 +-
 .../java/org/apache/cayenne/map/DbEntity.java   |   6 +-
 .../org/apache/cayenne/map/DbRelationship.java  |  24 +-
 .../org/apache/cayenne/map/MappingCache.java    |  14 +-
 .../org/apache/cayenne/map/ObjAttribute.java    |  12 +-
 .../java/org/apache/cayenne/map/ObjEntity.java  |   6 +-
 .../org/apache/cayenne/query/BatchQueryRow.java |   6 +-
 .../apache/cayenne/query/InsertBatchQuery.java  |   2 +-
 .../java/org/apache/cayenne/query/Ordering.java |  10 +-
 .../org/apache/cayenne/query/SQLTemplate.java   |  17 +-
 .../org/apache/cayenne/util/ReferenceMap.java   | 345 +++++++++++++++++++
 .../org/apache/cayenne/util/SoftValueMap.java   |  64 ++++
 .../org/apache/cayenne/util/WeakValueMap.java   |  63 ++++
 .../util/commons/CompositeCollection.java       | 328 ++++++++++++++++++
 .../cayenne/util/commons/IteratorChain.java     | 195 +++++++++++
 .../java/org/apache/cayenne/ObjectIdTest.java   |  10 +-
 .../unit/di/server/ConnectionProperties.java    |  36 +-
 .../ServerCaseDataSourceInfoProvider.java       |  14 +-
 .../apache/cayenne/util/WeakValueMapTest.java   | 203 +++++++++++
 .../velocity/SQLTemplateResourceManager.java    |   4 +-
 docs/doc/pom.xml                                |   5 -
 docs/doc/src/main/resources/RELEASE-NOTES.txt   |   1 +
 modeler/cayenne-modeler/pom.xml                 |  12 +
 .../org/apache/cayenne/modeler/Application.java |  17 +-
 .../modeler/action/ImportEOModelAction.java     |  66 ++--
 .../InferRelationshipsControllerBase.java       |  11 +-
 .../InferRelationshipsTabController.java        |  11 +-
 .../dialog/codegen/ClassesTabController.java    |   8 +-
 .../dialog/codegen/ClientModeController.java    |  21 +-
 .../dialog/codegen/CodeGeneratorController.java |   7 +-
 .../codegen/CodeGeneratorControllerBase.java    |  28 +-
 .../dialog/codegen/GeneratorController.java     |  48 +--
 .../dialog/pref/DataSourcePreferences.java      |  17 +-
 .../cayenne/modeler/editor/ObjEntityTab.java    |  27 +-
 .../cayenne/pref/UpgradeCayennePreference.java  |  46 ++-
 .../org/apache/cayenne/swing/TableBinding.java  |   4 +-
 modeler/cayenne-wocompat/pom.xml                |  16 +-
 .../apache/cayenne/wocompat/EOModelHelper.java  |   7 +-
 .../cayenne/wocompat/EOModelProcessor.java      |  63 ++--
 .../apache/cayenne/wocompat/EOObjEntity.java    |   6 +-
 pom.xml                                         |  10 -
 66 files changed, 1592 insertions(+), 514 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/afb42ed4/docs/doc/src/main/resources/RELEASE-NOTES.txt
----------------------------------------------------------------------


[2/9] cayenne git commit: CAY-2351 Remove commons-collections usage completely enable java 8 by default replace commons-collections with plain java

Posted by nt...@apache.org.
http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/pref/UpgradeCayennePreference.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/pref/UpgradeCayennePreference.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/pref/UpgradeCayennePreference.java
index 6861534..cf6d313 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/pref/UpgradeCayennePreference.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/pref/UpgradeCayennePreference.java
@@ -20,15 +20,15 @@ package org.apache.cayenne.pref;
 
 import java.io.File;
 import java.io.FileInputStream;
-import java.io.FileNotFoundException;
 import java.io.IOException;
-import java.util.Vector;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Properties;
 import java.util.prefs.BackingStoreException;
 import java.util.prefs.Preferences;
 
 import org.apache.cayenne.modeler.ModelerPreferences;
 import org.apache.cayenne.modeler.util.CayenneUserDir;
-import org.apache.commons.collections.ExtendedProperties;
 
 public class UpgradeCayennePreference extends PreferenceDecorator {
 
@@ -45,6 +45,8 @@ public class UpgradeCayennePreference extends PreferenceDecorator {
     public static final String EDITOR_LOGFILE_ENABLED_OLD = "Editor.logfileEnabled";
     public static final String EDITOR_LOGFILE_OLD = "Editor.logfile";
 
+    public static final String DELIMITER = ",";
+
     public UpgradeCayennePreference(Preference delegate) {
         super(delegate);
     }
@@ -56,48 +58,40 @@ public class UpgradeCayennePreference extends PreferenceDecorator {
 
                 File prefsFile = new File(preferencesDirectory(), PREFERENCES_NAME_OLD);
                 if (prefsFile.exists()) {
-                    ExtendedProperties ep = new ExtendedProperties();
+                    Properties ep = new Properties();
                     try {
                         ep.load(new FileInputStream(prefsFile));
 
-                        Preferences prefEditor = Preferences.userRoot().node(
-                                CAYENNE_PREFERENCES_PATH).node(EDITOR);
+                        Preferences prefEditor = Preferences.userRoot().node(CAYENNE_PREFERENCES_PATH).node(EDITOR);
 
-                        prefEditor.putBoolean(
-                                ModelerPreferences.EDITOR_LOGFILE_ENABLED,
-                                ep.getBoolean(EDITOR_LOGFILE_ENABLED_OLD));
-                        prefEditor.put(ModelerPreferences.EDITOR_LOGFILE, ep
-                                .getString(EDITOR_LOGFILE_OLD));
+                        prefEditor.putBoolean(ModelerPreferences.EDITOR_LOGFILE_ENABLED,
+                                Boolean.valueOf(ep.getProperty(EDITOR_LOGFILE_ENABLED_OLD)));
+                        prefEditor.put(ModelerPreferences.EDITOR_LOGFILE,
+                                ep.getProperty(EDITOR_LOGFILE_OLD));
 
                         Preferences frefLastProjFiles = prefEditor.node(LAST_PROJ_FILES);
 
-                        Vector arr = ep.getVector(LAST_PROJ_FILES_OLD);
-
+                        List<String> arr = getVector(ep.getProperty(LAST_PROJ_FILES_OLD));
                         while (arr.size() > ModelerPreferences.LAST_PROJ_FILES_SIZE) {
                             arr.remove(arr.size() - 1);
                         }
 
                         frefLastProjFiles.clear();
-                        int size = arr.size();
 
-                        for (int i = 0; i < size; i++) {
-                            frefLastProjFiles.put(String.valueOf(i), arr
-                                    .get(i)
-                                    .toString());
+                        for (int i = 0; i < arr.size(); i++) {
+                            frefLastProjFiles.put(String.valueOf(i), arr.get(i));
                         }
-                    }
-                    catch (FileNotFoundException e) {
-                        e.printStackTrace();
-                    }
-                    catch (IOException e) {
+                    } catch (IOException e) {
                         e.printStackTrace();
                     }
                 }
             }
+        } catch (BackingStoreException ignored) {
         }
-        catch (BackingStoreException e) {
-            // do nothing
-        }
+    }
+
+    private List<String> getVector(String value) {
+        return Arrays.asList(value.split(DELIMITER));
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/swing/TableBinding.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/swing/TableBinding.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/swing/TableBinding.java
index eb5235e..efbd2f5 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/swing/TableBinding.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/swing/TableBinding.java
@@ -24,6 +24,7 @@ import java.awt.Component;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
@@ -35,7 +36,6 @@ import javax.swing.table.TableColumnModel;
 import javax.swing.table.TableModel;
 
 import org.apache.cayenne.util.Util;
-import org.apache.commons.collections.map.SingletonMap;
 
 /**
  * A binding for a JTable.
@@ -152,7 +152,7 @@ public class TableBinding extends BindingBase {
 
         // this map is used as "flyweight", providing on the spot context for Ognl
         // expression evaluation
-        Map listContext = new SingletonMap(ITEM_VAR, null);
+        Map<String, Object> listContext = Collections.singletonMap(ITEM_VAR, null);
 
         public int getColumnCount() {
             return headers.length;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/modeler/cayenne-wocompat/pom.xml
----------------------------------------------------------------------
diff --git a/modeler/cayenne-wocompat/pom.xml b/modeler/cayenne-wocompat/pom.xml
index 3ad0344..fccfedd 100644
--- a/modeler/cayenne-wocompat/pom.xml
+++ b/modeler/cayenne-wocompat/pom.xml
@@ -64,6 +64,18 @@
 
     </dependencies>
 
+	<build>
+		<plugins>
+			<plugin>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<configuration>
+					<source>1.8</source>
+					<target>1.8</target>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+
     <profiles>
         <profile>
             <id>code-quality</id>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOObjEntity.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOObjEntity.java b/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOObjEntity.java
index ed264a3..c050865 100644
--- a/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOObjEntity.java
+++ b/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOObjEntity.java
@@ -26,7 +26,6 @@ import org.apache.cayenne.exp.ExpressionFactory;
 import org.apache.cayenne.map.Entity;
 import org.apache.cayenne.map.ObjEntity;
 import org.apache.cayenne.map.Relationship;
-import org.apache.commons.collections.Transformer;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -35,6 +34,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.StringTokenizer;
+import java.util.function.Function;
 
 /**
  * An extension of ObjEntity used to accomodate extra EOModel entity properties.
@@ -154,9 +154,9 @@ public class EOObjEntity extends ObjEntity {
                 : qualifiedQueryName;
     }
 
-    final class DBPathConverter implements Transformer {
+    final class DBPathConverter implements Function<Object, Object> {
 
-        public Object transform(Object input) {
+        public Object apply(Object input) {
 
             if (!(input instanceof Expression)) {
                 return input;


[6/9] cayenne git commit: Remove java7 support from travis

Posted by nt...@apache.org.
Remove java7 support from travis


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/4e623e32
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/4e623e32
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/4e623e32

Branch: refs/heads/master
Commit: 4e623e32eed2142ac332a7aca449896e1f3c13f3
Parents: e70c5a5
Author: Nikita Timofeev <st...@gmail.com>
Authored: Thu Aug 10 14:35:39 2017 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Thu Aug 17 12:41:57 2017 +0300

----------------------------------------------------------------------
 .travis.yml | 2 --
 1 file changed, 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/4e623e32/.travis.yml
----------------------------------------------------------------------
diff --git a/.travis.yml b/.travis.yml
index 4101ebd..2f67e1f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -18,7 +18,6 @@
 # How to fix: Change build setting or fix code.
 # https://docs.travis-ci.com/user/ci-environment/#Virtualization-environments
 sudo: required
-group: deprecated-2017Q2
 
 services:
   - docker
@@ -34,7 +33,6 @@ env:
 
 jdk:
   - oraclejdk8
-  - oraclejdk7
 
 script:
   - mvn verify -q -DcayenneTestConnection=$DB_PROFILE -DcayenneLogLevel=ERROR


[3/9] cayenne git commit: CAY-2351 Remove commons-collections usage completely enable java 8 by default replace commons-collections with plain java

Posted by nt...@apache.org.
CAY-2351 Remove commons-collections usage completely
  enable java 8 by default
  replace commons-collections with plain java


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/fddb229d
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/fddb229d
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/fddb229d

Branch: refs/heads/master
Commit: fddb229d616d9cc29ea46da2a4b1994c73528755
Parents: 50801e6
Author: Nikita Timofeev <st...@gmail.com>
Authored: Thu Aug 3 18:33:53 2017 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Thu Aug 17 12:41:56 2017 +0300

----------------------------------------------------------------------
 .../org/apache/cayenne/gen/DataMapUtils.java    |  5 +-
 cayenne-client/pom.xml                          |  5 --
 cayenne-lifecycle/pom.xml                       |  7 +++
 .../ObjectIdPropagatedValueFactory.java         |  8 ++-
 cayenne-server/pom.xml                          |  8 ++-
 .../cayenne/access/DataDomainSyncBucket.java    |  6 +-
 .../access/DataNodeSyncQualifierDescriptor.java | 49 +++++----------
 .../access/jdbc/RowDescriptorBuilder.java       | 24 +++----
 .../cayenne/access/jdbc/SQLTemplateAction.java  | 18 +++---
 .../access/translator/select/JoinStack.java     |  7 +--
 .../translator/select/QualifierTranslator.java  | 10 +--
 .../cayenne/ashwood/AshwoodEntitySorter.java    |  5 +-
 .../ashwood/WeightedAshwoodEntitySorter.java    |  5 +-
 .../org/apache/cayenne/cache/MapQueryCache.java |  5 +-
 .../dba/oracle/OracleQualifierTranslator.java   |  6 +-
 .../java/org/apache/cayenne/exp/Expression.java | 16 ++---
 .../org/apache/cayenne/exp/parser/ASTIn.java    |  5 +-
 .../org/apache/cayenne/exp/parser/ASTNotIn.java |  5 +-
 .../exp/parser/AggregateConditionNode.java      |  5 +-
 .../java/org/apache/cayenne/map/DbEntity.java   |  6 +-
 .../org/apache/cayenne/map/DbRelationship.java  | 24 +------
 .../org/apache/cayenne/map/ObjAttribute.java    | 12 ++--
 .../java/org/apache/cayenne/map/ObjEntity.java  |  6 +-
 .../org/apache/cayenne/query/BatchQueryRow.java |  6 +-
 .../apache/cayenne/query/InsertBatchQuery.java  |  2 +-
 .../java/org/apache/cayenne/query/Ordering.java | 10 ++-
 .../org/apache/cayenne/query/SQLTemplate.java   | 17 +++--
 .../java/org/apache/cayenne/ObjectIdTest.java   | 10 +--
 docs/doc/pom.xml                                |  5 --
 modeler/cayenne-modeler/pom.xml                 | 12 ++++
 .../org/apache/cayenne/modeler/Application.java | 17 +----
 .../modeler/action/ImportEOModelAction.java     | 66 +++++++++-----------
 .../InferRelationshipsControllerBase.java       | 11 ++--
 .../InferRelationshipsTabController.java        | 11 +---
 .../dialog/codegen/ClassesTabController.java    |  8 +--
 .../dialog/codegen/ClientModeController.java    | 21 +------
 .../dialog/codegen/CodeGeneratorController.java |  7 +--
 .../codegen/CodeGeneratorControllerBase.java    | 28 ++++-----
 .../dialog/codegen/GeneratorController.java     | 48 +++++---------
 .../dialog/pref/DataSourcePreferences.java      | 17 +----
 .../cayenne/modeler/editor/ObjEntityTab.java    | 27 +++-----
 .../cayenne/pref/UpgradeCayennePreference.java  | 46 ++++++--------
 .../org/apache/cayenne/swing/TableBinding.java  |  4 +-
 modeler/cayenne-wocompat/pom.xml                | 12 ++++
 .../apache/cayenne/wocompat/EOObjEntity.java    |  6 +-
 45 files changed, 265 insertions(+), 373 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/cayenne-cgen/src/main/java/org/apache/cayenne/gen/DataMapUtils.java
----------------------------------------------------------------------
diff --git a/cayenne-cgen/src/main/java/org/apache/cayenne/gen/DataMapUtils.java b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/DataMapUtils.java
index f0f8f69..490c040 100644
--- a/cayenne-cgen/src/main/java/org/apache/cayenne/gen/DataMapUtils.java
+++ b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/DataMapUtils.java
@@ -34,12 +34,12 @@ import org.apache.cayenne.map.SelectQueryDescriptor;
 import org.apache.cayenne.query.Ordering;
 import org.apache.cayenne.util.CayenneMapEntry;
 import org.apache.cayenne.util.Util;
-import org.apache.commons.collections.set.ListOrderedSet;
 
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -131,8 +131,7 @@ public class DataMapUtils {
 	 * @return List of parameter names.
 	 */
 	private Set parseQualifier(String qualifierString) {
-		@SuppressWarnings("unchecked")
-		Set<String> result = (Set<String>)new ListOrderedSet();
+		Set<String> result = new LinkedHashSet<>();
 		Pattern pattern = Pattern.compile("\\$[\\w]+");
 		Matcher matcher = pattern.matcher(qualifierString);
 		while (matcher.find()) {

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/cayenne-client/pom.xml
----------------------------------------------------------------------
diff --git a/cayenne-client/pom.xml b/cayenne-client/pom.xml
index b591bd9..2821d94 100644
--- a/cayenne-client/pom.xml
+++ b/cayenne-client/pom.xml
@@ -40,11 +40,6 @@
 			<scope>compile</scope>
 		</dependency>
 		<dependency>
-			<groupId>commons-collections</groupId>
-			<artifactId>commons-collections</artifactId>
-			<scope>compile</scope>
-		</dependency>
-		<dependency>
 			<groupId>com.caucho</groupId>
             <artifactId>hessian</artifactId>
 			<scope>compile</scope>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/cayenne-lifecycle/pom.xml
----------------------------------------------------------------------
diff --git a/cayenne-lifecycle/pom.xml b/cayenne-lifecycle/pom.xml
index a9c6283..f112584 100644
--- a/cayenne-lifecycle/pom.xml
+++ b/cayenne-lifecycle/pom.xml
@@ -79,6 +79,13 @@
                     </execution>
                 </executions>
             </plugin>
+			<plugin>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<configuration>
+					<source>1.8</source>
+					<target>1.8</target>
+				</configuration>
+			</plugin>
 		</plugins>
 	</build>
 	<profiles>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/cayenne-lifecycle/src/main/java/org/apache/cayenne/lifecycle/relationship/ObjectIdPropagatedValueFactory.java
----------------------------------------------------------------------
diff --git a/cayenne-lifecycle/src/main/java/org/apache/cayenne/lifecycle/relationship/ObjectIdPropagatedValueFactory.java b/cayenne-lifecycle/src/main/java/org/apache/cayenne/lifecycle/relationship/ObjectIdPropagatedValueFactory.java
index 23fa7a8..0e0f219 100644
--- a/cayenne-lifecycle/src/main/java/org/apache/cayenne/lifecycle/relationship/ObjectIdPropagatedValueFactory.java
+++ b/cayenne-lifecycle/src/main/java/org/apache/cayenne/lifecycle/relationship/ObjectIdPropagatedValueFactory.java
@@ -18,14 +18,15 @@
  ****************************************************************/
 package org.apache.cayenne.lifecycle.relationship;
 
+import java.util.function.Supplier;
+
 import org.apache.cayenne.Persistent;
 import org.apache.cayenne.lifecycle.id.IdCoder;
-import org.apache.commons.collections.Factory;
 
 /**
  * @since 3.1
  */
-class ObjectIdPropagatedValueFactory implements Factory {
+class ObjectIdPropagatedValueFactory implements Supplier {
 
     private IdCoder referenceableHandler;
     private Persistent to;
@@ -35,7 +36,8 @@ class ObjectIdPropagatedValueFactory implements Factory {
         this.to = to;
     }
 
-    public Object create() {
+    @Override
+    public String get() {
         return referenceableHandler.getStringId(to);
     }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/cayenne-server/pom.xml
----------------------------------------------------------------------
diff --git a/cayenne-server/pom.xml b/cayenne-server/pom.xml
index 4414f43..3644697 100644
--- a/cayenne-server/pom.xml
+++ b/cayenne-server/pom.xml
@@ -49,7 +49,6 @@
 			<artifactId>commons-collections</artifactId>
 			<scope>compile</scope>
 		</dependency>
-
 		<!-- Optional dependencies... things that might have been placed in submodules... -->
 		<dependency>
 			<groupId>com.caucho</groupId>
@@ -151,6 +150,13 @@
                 </executions>
             </plugin>
 			<plugin>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<configuration>
+					<source>1.8</source>
+					<target>1.8</target>
+				</configuration>
+			</plugin>
+			<plugin>
 				<groupId>org.codehaus.mojo</groupId>
 				<artifactId>javacc-maven-plugin</artifactId>
 				<version>2.6</version>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainSyncBucket.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainSyncBucket.java b/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainSyncBucket.java
index 3bb8141..7c25ab5 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainSyncBucket.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainSyncBucket.java
@@ -35,7 +35,6 @@ import org.apache.cayenne.reflect.AttributeProperty;
 import org.apache.cayenne.reflect.ClassDescriptor;
 import org.apache.cayenne.reflect.PropertyException;
 import org.apache.cayenne.reflect.ToManyMapProperty;
-import org.apache.commons.collections.Factory;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -43,6 +42,7 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.function.Supplier;
 
 /**
  * A superclass of batch query wrappers.
@@ -274,7 +274,7 @@ abstract class DataDomainSyncBucket {
     }
 
     // a factory for extracting PKs generated on commit.
-    final static class PropagatedValueFactory implements Factory {
+    final static class PropagatedValueFactory implements Supplier {
 
         ObjectId masterID;
         String masterKey;
@@ -284,7 +284,7 @@ abstract class DataDomainSyncBucket {
             this.masterKey = masterKey;
         }
 
-        public Object create() {
+        public Object get() {
             Object value = masterID.getIdSnapshot().get(masterKey);
             if (value == null) {
                 throw new CayenneRuntimeException("Can't extract a master key. "

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/cayenne-server/src/main/java/org/apache/cayenne/access/DataNodeSyncQualifierDescriptor.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/DataNodeSyncQualifierDescriptor.java b/cayenne-server/src/main/java/org/apache/cayenne/access/DataNodeSyncQualifierDescriptor.java
index 6e48a59..e5cd484 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/DataNodeSyncQualifierDescriptor.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/DataNodeSyncQualifierDescriptor.java
@@ -23,6 +23,7 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.function.Function;
 
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.ObjectId;
@@ -32,7 +33,6 @@ import org.apache.cayenne.map.DbRelationship;
 import org.apache.cayenne.map.ObjAttribute;
 import org.apache.cayenne.map.ObjEntity;
 import org.apache.cayenne.map.ObjRelationship;
-import org.apache.commons.collections.Transformer;
 
 /**
  * Builds update qualifier snapshots, including optimistic locking.
@@ -42,7 +42,7 @@ import org.apache.commons.collections.Transformer;
 class DataNodeSyncQualifierDescriptor {
 
 	private List<DbAttribute> attributes;
-	private List<Transformer> valueTransformers;
+	private List<Function<ObjectDiff, Object>> valueTransformers;
 	private boolean usingOptimisticLocking;
 
 	public boolean isUsingOptimisticLocking() {
@@ -60,8 +60,7 @@ class DataNodeSyncQualifierDescriptor {
 		for (int i = 0; i < len; i++) {
 			DbAttribute attribute = attributes.get(i);
 			if (!map.containsKey(attribute.getName())) {
-
-				Object value = valueTransformers.get(i).transform(diff);
+				Object value = valueTransformers.get(i).apply(diff);
 				map.put(attribute.getName(), value);
 			}
 		}
@@ -79,13 +78,10 @@ class DataNodeSyncQualifierDescriptor {
 		if (descriptor.isMaster()) {
 			for (final DbAttribute attribute : descriptor.getDbEntity().getPrimaryKeys()) {
 				attributes.add(attribute);
-				valueTransformers.add(new Transformer() {
-
-					public Object transform(Object input) {
-						ObjectId id = (ObjectId) ((ObjectDiff) input).getNodeId();
-						return id.getIdSnapshot().get(attribute.getName());
-					}
-				});
+				valueTransformers.add(input -> {
+                    ObjectId id = (ObjectId) input.getNodeId();
+                    return id.getIdSnapshot().get(attribute.getName());
+                });
 			}
 		} else {
 
@@ -104,13 +100,10 @@ class DataNodeSyncQualifierDescriptor {
 					if (!attributes.contains(dbAttribute)) {
 
 						attributes.add(dbAttribute);
-						valueTransformers.add(new Transformer() {
-
-							public Object transform(Object input) {
-								ObjectId id = (ObjectId) ((ObjectDiff) input).getNodeId();
-								return id.getIdSnapshot().get(dbAttrPair.getSourceName());
-							}
-						});
+						valueTransformers.add(input -> {
+                            ObjectId id = (ObjectId) input.getNodeId();
+                            return id.getIdSnapshot().get(dbAttrPair.getSourceName());
+                        });
 					}
 				}
 			}
@@ -127,13 +120,7 @@ class DataNodeSyncQualifierDescriptor {
 					// only use qualifier if dbEntities match
 					if (dbAttribute.getEntity().equals(descriptor.getDbEntity()) && !attributes.contains(dbAttribute)) {
 						attributes.add(dbAttribute);
-
-						valueTransformers.add(new Transformer() {
-
-							public Object transform(Object input) {
-								return ((ObjectDiff) input).getSnapshotValue(attribute.getName());
-							}
-						});
+						valueTransformers.add(input -> input.getSnapshotValue(attribute.getName()));
 					}
 				}
 			}
@@ -154,14 +141,10 @@ class DataNodeSyncQualifierDescriptor {
 							continue;
 						}
 
-						Transformer transformer = new Transformer() {
-
-							public Object transform(Object input) {
-								ObjectId targetId = ((ObjectDiff) input).getArcSnapshotValue(relationship.getName());
-								return targetId != null ? targetId.getIdSnapshot().get(dbAttrPair.getTargetName())
-										: null;
-							}
-						};
+						Function<ObjectDiff, Object> transformer = input -> {
+                            ObjectId targetId = input.getArcSnapshotValue(relationship.getName());
+                            return targetId != null ? targetId.getIdSnapshot().get(dbAttrPair.getTargetName()) : null;
+                        };
 
 						if (index < 0) {
 							attributes.add(dbAttribute);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/RowDescriptorBuilder.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/RowDescriptorBuilder.java b/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/RowDescriptorBuilder.java
index ab100af..39d39cf 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/RowDescriptorBuilder.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/RowDescriptorBuilder.java
@@ -27,12 +27,12 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.function.Function;
 
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.access.types.ExtendedType;
 import org.apache.cayenne.access.types.ExtendedTypeMap;
 import org.apache.cayenne.util.Util;
-import org.apache.commons.collections.Transformer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -46,24 +46,16 @@ public class RowDescriptorBuilder {
 
     private static final Logger logger = LoggerFactory.getLogger(RowDescriptorBuilder.class);
 
-    private static final Transformer UPPERCASE_TRANSFORMER = new Transformer() {
+    private static final Function<String, String> UPPERCASE_TRANSFORMER = input ->
+            input != null ? input.toUpperCase() : null;
 
-        public Object transform(Object input) {
-            return input != null ? input.toString().toUpperCase() : null;
-        }
-    };
-
-    private static final Transformer LOWERCASE_TRANSFORMER = new Transformer() {
-
-        public Object transform(Object input) {
-            return input != null ? input.toString().toLowerCase() : null;
-        }
-    };
+    private static final Function<String, String> LOWERCASE_TRANSFORMER = input ->
+            input != null ? input.toLowerCase() : null;
 
     protected ColumnDescriptor[] columns;
     protected ResultSetMetaData resultSetMetadata;
 
-    protected Transformer caseTransformer;
+    protected Function<String, String> caseTransformer;
     protected Map<String, String> typeOverrides;
 
     protected boolean validateDuplicateColumnNames;
@@ -204,8 +196,8 @@ public class RowDescriptorBuilder {
 
         if (caseTransformer != null) {
             for (ColumnDescriptor aColumnArray : columnArray) {
-                aColumnArray.setDataRowKey((String) caseTransformer.transform(aColumnArray.getDataRowKey()));
-                aColumnArray.setName((String) caseTransformer.transform(aColumnArray.getName()));
+                aColumnArray.setDataRowKey(caseTransformer.apply(aColumnArray.getDataRowKey()));
+                aColumnArray.setName(caseTransformer.apply(aColumnArray.getName()));
             }
         }
         if (typeOverrides != null) {

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/SQLTemplateAction.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/SQLTemplateAction.java b/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/SQLTemplateAction.java
index 8d9cf65..f5d8900 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/SQLTemplateAction.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/SQLTemplateAction.java
@@ -25,7 +25,6 @@ import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Iterator;
@@ -51,7 +50,6 @@ import org.apache.cayenne.query.QueryMetadata;
 import org.apache.cayenne.query.SQLAction;
 import org.apache.cayenne.query.SQLTemplate;
 import org.apache.cayenne.util.Util;
-import org.apache.commons.collections.IteratorUtils;
 
 /**
  * Implements a strategy for execution of SQLTemplates.
@@ -138,8 +136,9 @@ public class SQLTemplateAction implements SQLAction {
 		execute(connection, callback, compiled, counts);
 	}
 
+	@SuppressWarnings("unchecked")
 	private void runWithNamedParametersBatch(Connection connection, OperationObserver callback, String template,
-			Collection<Number> counts, boolean loggable) throws Exception {
+											 Collection<Number> counts, boolean loggable) throws Exception {
 
 		int size = query.parametersSize();
 
@@ -148,14 +147,17 @@ public class SQLTemplateAction implements SQLAction {
 		int batchSize = (size > 0) ? size : 1;
 
 		// for now supporting deprecated batch parameters...
-		@SuppressWarnings("unchecked")
-		Iterator<Map<String, ?>> it = (size > 0) ? query.parametersIterator()
-				: IteratorUtils.singletonIterator(Collections.emptyMap());
+		Iterator<Map<String, ?>> it;
+		if(size == 0) {
+			Iterator empty = Collections.singleton(Collections.emptyMap()).iterator();
+			it = empty;
+		} else {
+			it = query.parametersIterator();
+		}
+
 		for (int i = 0; i < batchSize; i++) {
 			Map<String, ?> nextParameters = it.next();
-
 			SQLStatement compiled = dataNode.getSqlTemplateProcessor().processTemplate(template, nextParameters);
-
 			if (loggable) {
 				dataNode.getJdbcEventLogger().logQuery(compiled.getSql(), compiled.getBindings());
 			}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/JoinStack.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/JoinStack.java b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/JoinStack.java
index 5b11a3c..937b818 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/JoinStack.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/JoinStack.java
@@ -19,6 +19,7 @@
 package org.apache.cayenne.access.translator.select;
 
 import java.util.List;
+import java.util.function.Function;
 
 import org.apache.cayenne.dba.DbAdapter;
 import org.apache.cayenne.dba.QuotingStrategy;
@@ -26,14 +27,12 @@ import org.apache.cayenne.exp.Expression;
 import org.apache.cayenne.exp.parser.ASTDbPath;
 import org.apache.cayenne.exp.parser.ASTObjPath;
 import org.apache.cayenne.exp.parser.SimpleNode;
-import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.DbJoin;
 import org.apache.cayenne.map.DbRelationship;
 import org.apache.cayenne.map.Entity;
 import org.apache.cayenne.map.JoinType;
 import org.apache.cayenne.map.ObjEntity;
-import org.apache.commons.collections.Transformer;
 
 /**
  * Encapsulates join reuse/split logic used in SelectQuery processing. All
@@ -187,7 +186,7 @@ public class JoinStack {
 	 * to concatenated Db-paths to root entity and rejecting all original
 	 * Db-paths
 	 */
-	class JoinedDbEntityQualifierTransformer implements Transformer {
+	class JoinedDbEntityQualifierTransformer implements Function<Object, Object> {
 
 		StringBuilder pathToRoot;
 
@@ -211,7 +210,7 @@ public class JoinStack {
 			}
 		}
 
-		public Object transform(Object input) {
+		public Object apply(Object input) {
 			if (input instanceof ASTObjPath) {
 				return new ASTDbPath(pathToRoot.toString() + ((SimpleNode) input).getOperand(0));
 			}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/QualifierTranslator.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/QualifierTranslator.java b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/QualifierTranslator.java
index 51ebf52..81ec0ee 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/QualifierTranslator.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/QualifierTranslator.java
@@ -20,8 +20,10 @@
 package org.apache.cayenne.access.translator.select;
 
 import java.io.IOException;
+import java.util.Arrays;
 import java.util.Iterator;
 import java.util.List;
+import java.util.function.Function;
 
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.ObjectId;
@@ -42,8 +44,6 @@ import org.apache.cayenne.map.ObjEntity;
 import org.apache.cayenne.query.Query;
 import org.apache.cayenne.query.SelectQuery;
 import org.apache.cayenne.reflect.ClassDescriptor;
-import org.apache.commons.collections.IteratorUtils;
-import org.apache.commons.collections.Transformer;
 
 /**
  * Translates query qualifier to SQL. Used as a helper class by query
@@ -572,7 +572,7 @@ public class QualifierTranslator extends QueryAssemblerHelper implements Travers
 		if (list instanceof List) {
 			it = ((List<?>) list).iterator();
 		} else if (list instanceof Object[]) {
-			it = IteratorUtils.arrayIterator((Object[]) list);
+			it = Arrays.asList((Object[]) list).iterator();
 		} else {
 			String className = (list != null) ? list.getClass().getName() : "<null>";
 			throw new IllegalArgumentException("Unsupported type for the list expressions: " + className);
@@ -676,9 +676,9 @@ public class QualifierTranslator extends QueryAssemblerHelper implements Travers
 	 * qualifiers annotation This is done by changing all Obj-paths to Db-paths
 	 * and rejecting all original Db-paths
 	 */
-	class DbEntityQualifierTransformer implements Transformer {
+	class DbEntityQualifierTransformer implements Function<Object, Object> {
 
-		public Object transform(Object input) {
+		public Object apply(Object input) {
 			if (input instanceof ASTObjPath) {
 				return new ASTDbPath(((SimpleNode) input).getOperand(0));
 			}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/cayenne-server/src/main/java/org/apache/cayenne/ashwood/AshwoodEntitySorter.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/ashwood/AshwoodEntitySorter.java b/cayenne-server/src/main/java/org/apache/cayenne/ashwood/AshwoodEntitySorter.java
index d299f28..13214a9 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/ashwood/AshwoodEntitySorter.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/ashwood/AshwoodEntitySorter.java
@@ -39,7 +39,6 @@ import org.apache.cayenne.map.ObjEntity;
 import org.apache.cayenne.map.ObjRelationship;
 import org.apache.cayenne.query.ObjectIdQuery;
 import org.apache.cayenne.reflect.ClassDescriptor;
-import org.apache.commons.collections.comparators.ReverseComparator;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -320,7 +319,7 @@ public class AshwoodEntitySorter implements EntitySorter {
 	protected Comparator<DbEntity> getDbEntityComparator(boolean dependantFirst) {
 		Comparator<DbEntity> c = dbEntityComparator;
 		if (dependantFirst) {
-			c = new ReverseComparator(c);
+			c = c.reversed();
 		}
 		return c;
 	}
@@ -328,7 +327,7 @@ public class AshwoodEntitySorter implements EntitySorter {
 	protected Comparator<ObjEntity> getObjEntityComparator(boolean dependantFirst) {
 		Comparator<ObjEntity> c = objEntityComparator;
 		if (dependantFirst) {
-			c = new ReverseComparator(c);
+			c = c.reversed();
 		}
 		return c;
 	}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/cayenne-server/src/main/java/org/apache/cayenne/ashwood/WeightedAshwoodEntitySorter.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/ashwood/WeightedAshwoodEntitySorter.java b/cayenne-server/src/main/java/org/apache/cayenne/ashwood/WeightedAshwoodEntitySorter.java
index 99df6a6..97e6e87 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/ashwood/WeightedAshwoodEntitySorter.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/ashwood/WeightedAshwoodEntitySorter.java
@@ -25,7 +25,6 @@ import java.util.Map;
 
 import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.ObjEntity;
-import org.apache.commons.collections.comparators.ReverseComparator;
 
 /**
  * EntitySorter that takes into account entity "weights", and otherwise delegating to
@@ -72,7 +71,7 @@ public class WeightedAshwoodEntitySorter extends AshwoodEntitySorter {
     protected Comparator<DbEntity> getDbEntityComparator(boolean dependantFirst) {
         Comparator<DbEntity> c = weightedDbEntityComparator;
         if (dependantFirst) {
-            c = new ReverseComparator(c);
+            c = c.reversed();
         }
         return c;
     }
@@ -82,7 +81,7 @@ public class WeightedAshwoodEntitySorter extends AshwoodEntitySorter {
     protected Comparator<ObjEntity> getObjEntityComparator(boolean dependantFirst) {
         Comparator<ObjEntity> c = weightedObjEntityComparator;
         if (dependantFirst) {
-            c = new ReverseComparator(c);
+            c = c.reversed();
         }
         return c;
     }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/cayenne-server/src/main/java/org/apache/cayenne/cache/MapQueryCache.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/cache/MapQueryCache.java b/cayenne-server/src/main/java/org/apache/cayenne/cache/MapQueryCache.java
index ea48311..e2fb64d 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/cache/MapQueryCache.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/cache/MapQueryCache.java
@@ -25,7 +25,7 @@ import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.query.QueryMetadata;
-import org.apache.commons.collections.map.LRUMap;
+import org.apache.cayenne.util.concurrentlinkedhashmap.ConcurrentLinkedHashMap;
 
 /**
  * A default implementation of the {@link QueryCache} interface that stores data in a
@@ -152,7 +152,8 @@ public class MapQueryCache implements QueryCache, Serializable {
         if(map != null) {
             return map;
         }
-        map = new LRUMap(maxSize);
+
+        map = new ConcurrentLinkedHashMap.Builder<String, List<?>>().maximumWeightedCapacity(maxSize).build();
         cacheGroups.put(cacheName, map);
         return map;
     }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/OracleQualifierTranslator.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/OracleQualifierTranslator.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/OracleQualifierTranslator.java
index fadd468..078230f 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/OracleQualifierTranslator.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/OracleQualifierTranslator.java
@@ -29,10 +29,10 @@ import org.apache.cayenne.exp.parser.ASTNegate;
 import org.apache.cayenne.exp.parser.ASTNotIn;
 import org.apache.cayenne.exp.parser.ASTPath;
 import org.apache.cayenne.exp.parser.Node;
-import org.apache.commons.collections.Transformer;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.function.Function;
 
 /**
  * Oracle qualifier translator. In particular, trims INs with more than 1000
@@ -53,7 +53,7 @@ public class OracleQualifierTranslator extends TrimmingQualifierTranslator {
 		rootNode.traverse(this);
 	}
 
-	public static class INTrimmer implements Transformer {
+	public static class INTrimmer implements Function<Object, Object> {
 
 		public Expression trimmedInExpression(Expression exp, int maxInSize) {
 			Expression list = (Expression) exp.getOperand(1);
@@ -89,7 +89,7 @@ public class OracleQualifierTranslator extends TrimmingQualifierTranslator {
 			return res;
 		}
 
-		public Object transform(Object input) {
+		public Object apply(Object input) {
 			if (input instanceof ASTIn || input instanceof ASTNotIn) {
 				return trimmedInExpression((Expression) input, 1000);
 			}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/cayenne-server/src/main/java/org/apache/cayenne/exp/Expression.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/Expression.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/Expression.java
index 77a8cdf..6bfad77 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/Expression.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/Expression.java
@@ -29,6 +29,7 @@ import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.function.Function;
 
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.configuration.ConfigurationNodeVisitor;
@@ -38,7 +39,6 @@ import org.apache.cayenne.util.HashCodeBuilder;
 import org.apache.cayenne.util.Util;
 import org.apache.cayenne.util.XMLEncoder;
 import org.apache.cayenne.util.XMLSerializable;
-import org.apache.commons.collections.Transformer;
 
 /**
  * Superclass of Cayenne expressions that defines basic API for expressions use.
@@ -622,7 +622,7 @@ public abstract class Expression implements Serializable, XMLSerializable {
 	 * 
 	 * @since 1.1
 	 */
-	public Expression transform(Transformer transformer) {
+	public Expression transform(Function<Object, Object> transformer) {
 		Object transformed = transformExpression(transformer);
 
 		if (transformed == PRUNED_NODE || transformed == null) {
@@ -641,7 +641,7 @@ public abstract class Expression implements Serializable, XMLSerializable {
 	 * @return null, Expression.PRUNED_NODE or transformed expression.
 	 * @since 1.2
 	 */
-	protected Object transformExpression(Transformer transformer) {
+	protected Object transformExpression(Function<Object, Object> transformer) {
 		Expression copy = shallowCopy();
 		int count = getOperandCount();
 		for (int i = 0, j = 0; i < count; i++) {
@@ -651,7 +651,7 @@ public abstract class Expression implements Serializable, XMLSerializable {
 			if (operand instanceof Expression) {
 				transformedChild = ((Expression) operand).transformExpression(transformer);
 			} else if (transformer != null) {
-				transformedChild = transformer.transform(operand);
+				transformedChild = transformer.apply(operand);
 			} else {
 				transformedChild = operand;
 			}
@@ -672,7 +672,7 @@ public abstract class Expression implements Serializable, XMLSerializable {
 		}
 
 		// all the children are processed, only now transform this copy
-		return (transformer != null) ? (Expression) transformer.transform(copy) : copy;
+		return (transformer != null) ? (Expression) transformer.apply(copy) : copy;
 	}
 
 	/**
@@ -793,7 +793,7 @@ public abstract class Expression implements Serializable, XMLSerializable {
 		return toEJBQL(null, rootId);
 	}
 
-	final class NamedParamTransformer implements Transformer {
+	final class NamedParamTransformer implements Function<Object, Object> {
 
 		private Map<String, ?> parameters;
 		private boolean pruneMissing;
@@ -804,7 +804,7 @@ public abstract class Expression implements Serializable, XMLSerializable {
 		}
 
 		@Override
-		public Object transform(Object object) {
+		public Object apply(Object object) {
 			if (!(object instanceof ExpressionParameter)) {
 
 				// normally Object[] is an ASTList child
@@ -815,7 +815,7 @@ public abstract class Expression implements Serializable, XMLSerializable {
 					Object[] target = new Object[len];
 
 					for (int i = 0; i < len; i++) {
-						target[i] = transform(source[i]);
+						target[i] = apply(source[i]);
 					}
 
 					return target;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTIn.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTIn.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTIn.java
index e91c5a3..d1801ce 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTIn.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTIn.java
@@ -19,8 +19,9 @@
 
 package org.apache.cayenne.exp.parser;
 
+import java.util.function.Function;
+
 import org.apache.cayenne.exp.Expression;
-import org.apache.commons.collections.Transformer;
 
 /**
  * "In" expression.
@@ -91,7 +92,7 @@ public class ASTIn extends ConditionNode {
 	}
 
 	@Override
-	protected Object transformExpression(Transformer transformer) {
+	protected Object transformExpression(Function<Object, Object> transformer) {
 		Object transformed = super.transformExpression(transformer);
 
 		// transform empty ASTIn to ASTFalse

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTNotIn.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTNotIn.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTNotIn.java
index 09afa6d..4ce7d46 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTNotIn.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTNotIn.java
@@ -20,8 +20,9 @@
 
 package org.apache.cayenne.exp.parser;
 
+import java.util.function.Function;
+
 import org.apache.cayenne.exp.Expression;
-import org.apache.commons.collections.Transformer;
 
 /**
  * "Not In" expression.
@@ -83,7 +84,7 @@ public class ASTNotIn extends ConditionNode {
     }
     
     @Override
-    protected Object transformExpression(Transformer transformer) {
+    protected Object transformExpression(Function<Object, Object> transformer) {
         Object transformed = super.transformExpression(transformer);
         
         // transform empty ASTNotIn to ASTTrue

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/AggregateConditionNode.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/AggregateConditionNode.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/AggregateConditionNode.java
index 7574dfd..33d8c15 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/AggregateConditionNode.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/AggregateConditionNode.java
@@ -19,8 +19,9 @@
 
 package org.apache.cayenne.exp.parser;
 
+import java.util.function.Function;
+
 import org.apache.cayenne.exp.ExpressionException;
-import org.apache.commons.collections.Transformer;
 
 /**
  * Superclass of aggregated conditional nodes such as NOT, AND, OR. Performs
@@ -43,7 +44,7 @@ public abstract class AggregateConditionNode extends SimpleNode {
 	}
 
 	@Override
-	protected Object transformExpression(Transformer transformer) {
+	protected Object transformExpression(Function<Object, Object> transformer) {
 		Object transformed = super.transformExpression(transformer);
 
 		if (!(transformed instanceof AggregateConditionNode)) {

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/cayenne-server/src/main/java/org/apache/cayenne/map/DbEntity.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/map/DbEntity.java b/cayenne-server/src/main/java/org/apache/cayenne/map/DbEntity.java
index d3dda7e..f8071da 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/map/DbEntity.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/map/DbEntity.java
@@ -35,7 +35,6 @@ import org.apache.cayenne.map.event.MapEvent;
 import org.apache.cayenne.map.event.RelationshipEvent;
 import org.apache.cayenne.util.CayenneMapEntry;
 import org.apache.cayenne.util.XMLEncoder;
-import org.apache.commons.collections.Transformer;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -47,6 +46,7 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.SortedMap;
+import java.util.function.Function;
 
 /**
  * A DbEntity is a mapping descriptor that defines a structure of a database
@@ -636,7 +636,7 @@ public class DbEntity extends Entity implements ConfigurationNode, DbEntityListe
         return expression.transform(new RelationshipPathConverter(relationshipPath));
     }
 
-    final class RelationshipPathConverter implements Transformer {
+    final class RelationshipPathConverter implements Function<Object, Object> {
 
         String relationshipPath;
         boolean toMany;
@@ -656,7 +656,7 @@ public class DbEntity extends Entity implements ConfigurationNode, DbEntityListe
             }
         }
 
-        public Object transform(Object input) {
+        public Object apply(Object input) {
             if (!(input instanceof Expression)) {
                 return input;
             }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/cayenne-server/src/main/java/org/apache/cayenne/map/DbRelationship.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/map/DbRelationship.java b/cayenne-server/src/main/java/org/apache/cayenne/map/DbRelationship.java
index 53d4c73..e3678d5 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/map/DbRelationship.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/map/DbRelationship.java
@@ -24,8 +24,6 @@ import org.apache.cayenne.configuration.ConfigurationNode;
 import org.apache.cayenne.configuration.ConfigurationNodeVisitor;
 import org.apache.cayenne.util.Util;
 import org.apache.cayenne.util.XMLEncoder;
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.collections.Transformer;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -33,6 +31,7 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * A DbRelationship is a descriptor of a database inter-table relationship based
@@ -118,7 +117,7 @@ public class DbRelationship extends Relationship implements ConfigurationNode {
             return Collections.emptyList();
         }
 
-        return CollectionUtils.collect(joins, JoinTransformers.targetExtractor);
+        return joins.stream().map(DbJoin::getTarget).collect(Collectors.toList());
     }
 
     /**
@@ -132,7 +131,7 @@ public class DbRelationship extends Relationship implements ConfigurationNode {
             return Collections.emptyList();
         }
 
-        return CollectionUtils.collect(joins, JoinTransformers.sourceExtractor);
+        return joins.stream().map(DbJoin::getSource).collect(Collectors.toList());
     }
 
     /**
@@ -486,23 +485,6 @@ public class DbRelationship extends Relationship implements ConfigurationNode {
         return false;
     }
 
-    static final class JoinTransformers {
-
-        static final Transformer targetExtractor = new Transformer() {
-
-            public Object transform(Object input) {
-                return (input instanceof DbJoin) ? ((DbJoin) input).getTarget() : input;
-            }
-        };
-
-        static final Transformer sourceExtractor = new Transformer() {
-
-            public Object transform(Object input) {
-                return (input instanceof DbJoin) ? ((DbJoin) input).getSource() : input;
-            }
-        };
-    }
-
     // a join used for comparison
     static final class TestJoin extends DbJoin {
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/cayenne-server/src/main/java/org/apache/cayenne/map/ObjAttribute.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/map/ObjAttribute.java b/cayenne-server/src/main/java/org/apache/cayenne/map/ObjAttribute.java
index ae03d13..ebafe84 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/map/ObjAttribute.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/map/ObjAttribute.java
@@ -19,6 +19,7 @@
 
 package org.apache.cayenne.map;
 
+import java.util.Collections;
 import java.util.Iterator;
 
 import org.apache.cayenne.CayenneRuntimeException;
@@ -27,7 +28,6 @@ import org.apache.cayenne.configuration.ConfigurationNodeVisitor;
 import org.apache.cayenne.util.CayenneMapEntry;
 import org.apache.cayenne.util.Util;
 import org.apache.cayenne.util.XMLEncoder;
-import org.apache.commons.collections.IteratorUtils;
 
 /**
  * An ObjAttribute is a mapping descriptor of a Java class property.
@@ -217,25 +217,25 @@ public class ObjAttribute extends Attribute implements ConfigurationNode {
     @SuppressWarnings("unchecked")
     public Iterator<CayenneMapEntry> getDbPathIterator(ObjEntity entity) {
         if (dbAttributePath == null) {
-            return IteratorUtils.EMPTY_ITERATOR;
+            return Collections.emptyIterator();
         }
 
         if (entity == null) {
-            return IteratorUtils.EMPTY_ITERATOR;
+            return Collections.emptyIterator();
         }
 
         DbEntity dbEnt = entity.getDbEntity();
         if (dbEnt == null) {
-            return IteratorUtils.EMPTY_ITERATOR;
+            return Collections.emptyIterator();
         }
 
         int lastPartStart = dbAttributePath.lastIndexOf('.');
         if (lastPartStart < 0) {
             DbAttribute attribute = dbEnt.getAttribute(dbAttributePath);
             if (attribute == null) {
-                return IteratorUtils.EMPTY_ITERATOR;
+                return Collections.emptyIterator();
             }
-            return IteratorUtils.singletonIterator(attribute);
+            return Collections.<CayenneMapEntry>singleton(attribute).iterator();
         }
 
         return dbEnt.resolvePathComponents(dbAttributePath);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/cayenne-server/src/main/java/org/apache/cayenne/map/ObjEntity.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/map/ObjEntity.java b/cayenne-server/src/main/java/org/apache/cayenne/map/ObjEntity.java
index 311f5ed..536d2cf 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/map/ObjEntity.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/map/ObjEntity.java
@@ -32,7 +32,6 @@ import org.apache.cayenne.map.event.ObjEntityListener;
 import org.apache.cayenne.util.CayenneMapEntry;
 import org.apache.cayenne.util.Util;
 import org.apache.cayenne.util.XMLEncoder;
-import org.apache.commons.collections.Transformer;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -45,6 +44,7 @@ import java.util.Map;
 import java.util.Set;
 import java.util.SortedMap;
 import java.util.TreeMap;
+import java.util.function.Function;
 
 /**
  * ObjEntity is a mapping descriptor for a DataObject Java class. It contains
@@ -1104,7 +1104,7 @@ public class ObjEntity extends Entity implements ObjEntityListener, Configuratio
         return res;
     }
 
-    final class DBPathConverter implements Transformer {
+    final class DBPathConverter implements Function<Object, Object> {
 
         // TODO: make it a public method - resolveDBPathComponents or
         // something...
@@ -1143,7 +1143,7 @@ public class ObjEntity extends Entity implements ObjEntityListener, Configuratio
             return buf.toString();
         }
 
-        public Object transform(Object input) {
+        public Object apply(Object input) {
 
             if (!(input instanceof Expression)) {
                 return input;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/cayenne-server/src/main/java/org/apache/cayenne/query/BatchQueryRow.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/query/BatchQueryRow.java b/cayenne-server/src/main/java/org/apache/cayenne/query/BatchQueryRow.java
index 6fb2ddc..c19d0c2 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/query/BatchQueryRow.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/query/BatchQueryRow.java
@@ -19,11 +19,11 @@
 package org.apache.cayenne.query;
 
 import java.util.Map;
+import java.util.function.Supplier;
 
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.ObjectId;
 import org.apache.cayenne.map.DbAttribute;
-import org.apache.commons.collections.Factory;
 
 /**
  * Represents a single row of values in a BatchQuery.
@@ -60,8 +60,8 @@ public abstract class BatchQueryRow {
 
         // if a value is a Factory, resolve it here...
         // slight chance that a normal value will implement Factory interface???
-        if (value instanceof Factory) {
-            value = ((Factory) value).create();
+        if (value instanceof Supplier) {
+            value = ((Supplier) value).get();
             valueMap.put(attribute.getName(), value);
 
             // update replacement id

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/cayenne-server/src/main/java/org/apache/cayenne/query/InsertBatchQuery.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/query/InsertBatchQuery.java b/cayenne-server/src/main/java/org/apache/cayenne/query/InsertBatchQuery.java
index 84b76ca..1aebb5f 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/query/InsertBatchQuery.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/query/InsertBatchQuery.java
@@ -50,7 +50,7 @@ public class InsertBatchQuery extends BatchQuery {
     /**
      * Adds a snapshot to batch. Optionally stores the object id for the
      * snapshot. Note that snapshot can hold either the real values or the
-     * instances of org.apache.commons.collections.Factory that will be resolved
+     * instances of java.util.Supplier that will be resolved
      * to the actual value on the spot, thus allowing deferred propagated keys
      * resolution.
      * 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/cayenne-server/src/main/java/org/apache/cayenne/query/Ordering.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/query/Ordering.java b/cayenne-server/src/main/java/org/apache/cayenne/query/Ordering.java
index 5bd24bc..08417c4 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/query/Ordering.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/query/Ordering.java
@@ -38,7 +38,6 @@ import org.apache.cayenne.util.ConversionUtil;
 import org.apache.cayenne.util.Util;
 import org.apache.cayenne.util.XMLEncoder;
 import org.apache.cayenne.util.XMLSerializable;
-import org.apache.commons.collections.ComparatorUtils;
 
 /**
  * Defines object sorting criteria, used either for in-memory sorting of object
@@ -67,7 +66,14 @@ public class Ordering implements Comparator<Object>, Serializable, XMLSerializab
 	 */
 	@SuppressWarnings("unchecked")
 	public static void orderList(List<?> objects, List<? extends Ordering> orderings) {
-		Collections.sort(objects, ComparatorUtils.chainedComparator(orderings));
+		if(objects == null || orderings == null || orderings.isEmpty()) {
+			return;
+		}
+		Comparator<Object> comparator = orderings.get(0);
+		for(int i=1; i<orderings.size(); i++) {
+			comparator = comparator.thenComparing(orderings.get(i));
+		}
+		objects.sort(comparator);
 	}
 
 	/**

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/cayenne-server/src/main/java/org/apache/cayenne/query/SQLTemplate.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/query/SQLTemplate.java b/cayenne-server/src/main/java/org/apache/cayenne/query/SQLTemplate.java
index 554bb8b..eed51c1 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/query/SQLTemplate.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/query/SQLTemplate.java
@@ -30,8 +30,6 @@ import org.apache.cayenne.map.QueryDescriptor;
 import org.apache.cayenne.map.SQLResult;
 import org.apache.cayenne.util.XMLEncoder;
 import org.apache.cayenne.util.XMLSerializable;
-import org.apache.commons.collections.IteratorUtils;
-import org.apache.commons.collections.Transformer;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -42,6 +40,8 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.TreeSet;
+import java.util.function.Function;
+import java.util.stream.Stream;
 
 /**
  * A query that executes unchanged (except for template preprocessing) "raw" SQL
@@ -76,12 +76,8 @@ public class SQLTemplate extends AbstractQuery implements ParameterizedQuery {
 
 	public static final String COLUMN_NAME_CAPITALIZATION_PROPERTY = "cayenne.SQLTemplate.columnNameCapitalization";
 
-	private static final Transformer nullMapTransformer = new Transformer() {
-
-		public Object transform(Object input) {
-			return (input != null) ? input : Collections.EMPTY_MAP;
-		}
-	};
+	private static final Function<Map<String, ?>, Map<String, ?>> nullMapTransformer = input ->
+			(input != null) ? input : Collections.emptyMap();
 
 	protected String defaultTemplate;
 	protected Map<String, String> templates;
@@ -222,8 +218,9 @@ public class SQLTemplate extends AbstractQuery implements ParameterizedQuery {
 	 */
 	@SuppressWarnings("unchecked")
 	public Iterator<Map<String, ?>> parametersIterator() {
-		return (parameters == null || parameters.length == 0) ? IteratorUtils.emptyIterator() : IteratorUtils
-				.transformedIterator(IteratorUtils.arrayIterator(parameters), nullMapTransformer);
+		return (parameters == null || parameters.length == 0)
+				? Collections.emptyIterator()
+				: Stream.of(parameters).map(nullMapTransformer).iterator();
 	}
 
 	/**

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/cayenne-server/src/test/java/org/apache/cayenne/ObjectIdTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/ObjectIdTest.java b/cayenne-server/src/test/java/org/apache/cayenne/ObjectIdTest.java
index 0dc4907..2ed72ad 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/ObjectIdTest.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/ObjectIdTest.java
@@ -20,11 +20,11 @@
 package org.apache.cayenne;
 
 import org.apache.cayenne.util.Util;
-import org.apache.commons.collections.map.LinkedMap;
 import org.junit.Test;
 
 import java.math.BigDecimal;
 import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.Map;
 
 import static org.junit.Assert.assertEquals;
@@ -168,12 +168,12 @@ public class ObjectIdTest {
         // create maps with guaranteed iteration order
 
         @SuppressWarnings("unchecked")
-        Map<String, Object> hm1 = new LinkedMap();
+        Map<String, Object> hm1 = new LinkedHashMap<>();
         hm1.put("KEY1", 1);
         hm1.put("KEY2", 2);
 
         @SuppressWarnings("unchecked")
-        Map<String, Object> hm2 = new LinkedMap();
+        Map<String, Object> hm2 = new LinkedHashMap();
         // put same keys but in different order
         hm2.put("KEY2", 2);
         hm2.put("KEY1", 1);
@@ -256,12 +256,12 @@ public class ObjectIdTest {
         // create maps with guaranteed iteration order
 
         @SuppressWarnings("unchecked")
-        Map<String, Object> hm1 = new LinkedMap();
+        Map<String, Object> hm1 = new LinkedHashMap();
         hm1.put("KEY1", 1);
         hm1.put("KEY2", 2);
 
         @SuppressWarnings("unchecked")
-        Map<String, Object> hm2 = new LinkedMap();
+        Map<String, Object> hm2 = new LinkedHashMap();
         // put same keys but in different order
         hm2.put("KEY2", new BigDecimal(2.00));
         hm2.put("KEY1", 1L);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/docs/doc/pom.xml
----------------------------------------------------------------------
diff --git a/docs/doc/pom.xml b/docs/doc/pom.xml
index d3daa0a..8daefb9 100644
--- a/docs/doc/pom.xml
+++ b/docs/doc/pom.xml
@@ -48,11 +48,6 @@
 		</dependency>
 
 		<dependency>
-			<groupId>commons-collections</groupId>
-			<artifactId>commons-collections</artifactId>
-		</dependency>
-
-		<dependency>
 			<groupId>com.caucho</groupId>
             <artifactId>hessian</artifactId>
 		</dependency>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/modeler/cayenne-modeler/pom.xml
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/pom.xml b/modeler/cayenne-modeler/pom.xml
index bbc4645..d505bdb 100644
--- a/modeler/cayenne-modeler/pom.xml
+++ b/modeler/cayenne-modeler/pom.xml
@@ -103,6 +103,18 @@
 		</dependency>
 	</dependencies>
 
+	<build>
+		<plugins>
+			<plugin>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<configuration>
+					<source>1.8</source>
+					<target>1.8</target>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+
     <profiles>
         <profile>
             <id>code-quality</id>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/Application.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/Application.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/Application.java
index 3625df2..8bd18b4 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/Application.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/Application.java
@@ -34,8 +34,6 @@ import org.apache.cayenne.pref.CayenneProjectPreferences;
 import org.apache.cayenne.project.Project;
 import org.apache.cayenne.swing.BindingFactory;
 import org.apache.cayenne.util.IDUtil;
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.collections.Transformer;
 
 import javax.swing.*;
 import java.io.File;
@@ -43,6 +41,7 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.prefs.BackingStoreException;
 import java.util.prefs.Preferences;
+import java.util.stream.Collectors;
 
 /**
  * A main modeler application class that provides a number of services to the Modeler
@@ -241,7 +240,7 @@ public class Application {
                 ClasspathPreferences.class,
                 "");
 
-        Collection details = new ArrayList<>();
+        Collection<String> details = new ArrayList<>();
         String[] keys;
         ArrayList<String> values = new ArrayList<>();
 
@@ -256,17 +255,7 @@ public class Application {
         details.addAll(values);
 
         if (details.size() > 0) {
-
-            // transform preference to file...
-            Transformer transformer = new Transformer() {
-
-                public Object transform(Object object) {
-                    String pref = (String) object;
-                    return new File(pref);
-                }
-            };
-
-            classLoader.setPathFiles(CollectionUtils.collect(details, transformer));
+            classLoader.setPathFiles(details.stream().map(File::new).collect(Collectors.toList()));
         }
 
         this.modelerClassLoader = classLoader;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/ImportEOModelAction.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/ImportEOModelAction.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/ImportEOModelAction.java
index 369a8ed..9733f83 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/ImportEOModelAction.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/ImportEOModelAction.java
@@ -30,7 +30,8 @@ import org.apache.cayenne.conn.DataSourceInfo;
 import org.apache.cayenne.dba.DbAdapter;
 import org.apache.cayenne.dbsync.naming.NameBuilder;
 import org.apache.cayenne.map.DataMap;
-import org.apache.cayenne.map.Entity;
+import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.map.ObjEntity;
 import org.apache.cayenne.map.QueryDescriptor;
 import org.apache.cayenne.map.event.EntityEvent;
 import org.apache.cayenne.map.event.MapEvent;
@@ -44,7 +45,6 @@ import org.apache.cayenne.modeler.util.AdapterMapping;
 import org.apache.cayenne.modeler.util.CayenneAction;
 import org.apache.cayenne.modeler.util.FileFilters;
 import org.apache.cayenne.wocompat.EOModelProcessor;
-import org.apache.commons.collections.CollectionUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -213,75 +213,67 @@ public class ImportEOModelAction extends CayenneAction {
             // merge with existing map... have to memorize map state before and after
             // to do the right events
 
-            Collection originalOE = new ArrayList(currentMap.getObjEntities());
-            Collection originalDE = new ArrayList(currentMap.getDbEntities());
-            Collection originalQueries = new ArrayList(currentMap.getQueryDescriptors());
+            Collection<ObjEntity> originalOE = new ArrayList<>(currentMap.getObjEntities());
+            Collection<DbEntity> originalDE = new ArrayList<>(currentMap.getDbEntities());
+            Collection<QueryDescriptor> originalQueries = new ArrayList<>(currentMap.getQueryDescriptors());
 
             currentMap.mergeWithDataMap(map);
             map = currentMap;
 
             // postprocess changes
-            Collection newOE = new ArrayList(currentMap.getObjEntities());
-            Collection newDE = new ArrayList(currentMap.getDbEntities());
-            Collection newQueries = new ArrayList(currentMap.getQueryDescriptors());
+            Collection<ObjEntity> newOE = new ArrayList<>(currentMap.getObjEntities());
+            Collection<DbEntity> newDE = new ArrayList<>(currentMap.getDbEntities());
+            Collection<QueryDescriptor> newQueries = new ArrayList<>(currentMap.getQueryDescriptors());
 
             EntityEvent entityEvent = new EntityEvent(Application.getFrame(), null);
             QueryEvent queryEvent = new QueryEvent(Application.getFrame(), null);
 
-            Collection addedOE = CollectionUtils.subtract(newOE, originalOE);
-            Iterator it = addedOE.iterator();
-            while (it.hasNext()) {
-                Entity e = (Entity) it.next();
+            // 1. ObjEntities
+            Collection<ObjEntity> addedOE = new ArrayList<>(newOE);
+            addedOE.removeAll(originalOE);
+            for (ObjEntity e : addedOE) {
                 entityEvent.setEntity(e);
                 entityEvent.setId(MapEvent.ADD);
                 mediator.fireObjEntityEvent(entityEvent);
             }
 
-            Collection removedOE = CollectionUtils.subtract(originalOE, newOE);
-            it = removedOE.iterator();
-            while (it.hasNext()) {
-                Entity e = (Entity) it.next();
+            Collection<ObjEntity> removedOE = new ArrayList<>(originalOE);
+            removedOE.removeAll(newOE);
+            for (ObjEntity e : removedOE) {
                 entityEvent.setEntity(e);
                 entityEvent.setId(MapEvent.REMOVE);
                 mediator.fireObjEntityEvent(entityEvent);
             }
 
-            Collection addedDE = CollectionUtils.subtract(newDE, originalDE);
-            it = addedDE.iterator();
-            while (it.hasNext()) {
-                Entity e = (Entity) it.next();
+            // 2. DbEntities
+            Collection<DbEntity> addedDE = new ArrayList<>(newDE);
+            addedDE.removeAll(originalDE);
+            for(DbEntity e: addedDE) {
                 entityEvent.setEntity(e);
                 entityEvent.setId(MapEvent.ADD);
                 mediator.fireDbEntityEvent(entityEvent);
             }
 
-            Collection removedDE = CollectionUtils.subtract(originalDE, newDE);
-            it = removedDE.iterator();
-            while (it.hasNext()) {
-                Entity e = (Entity) it.next();
+            Collection<DbEntity> removedDE = new ArrayList<>(originalDE);
+            removedDE.removeAll(newDE);
+            for(DbEntity e: removedDE) {
                 entityEvent.setEntity(e);
                 entityEvent.setId(MapEvent.REMOVE);
                 mediator.fireDbEntityEvent(entityEvent);
             }
 
-            // queries
-            Collection addedQueries = CollectionUtils.subtract(
-                    newQueries,
-                    originalQueries);
-            it = addedQueries.iterator();
-            while (it.hasNext()) {
-                QueryDescriptor q = (QueryDescriptor) it.next();
+            // 3. queries
+            Collection<QueryDescriptor> addedQueries = new ArrayList<>(newQueries);
+            addedQueries.removeAll(originalQueries);
+            for(QueryDescriptor q: addedQueries) {
                 queryEvent.setQuery(q);
                 queryEvent.setId(MapEvent.ADD);
                 mediator.fireQueryEvent(queryEvent);
             }
 
-            Collection removedQueries = CollectionUtils.subtract(
-                    originalQueries,
-                    newQueries);
-            it = removedQueries.iterator();
-            while (it.hasNext()) {
-                QueryDescriptor q = (QueryDescriptor) it.next();
+            Collection<QueryDescriptor> removedQueries = new ArrayList<>(originalQueries);
+            removedQueries.removeAll(newQueries);
+            for(QueryDescriptor q: removedQueries) {
                 queryEvent.setQuery(q);
                 queryEvent.setId(MapEvent.REMOVE);
                 mediator.fireQueryEvent(queryEvent);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsControllerBase.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsControllerBase.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsControllerBase.java
index fd7f59b..4a41b32 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsControllerBase.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsControllerBase.java
@@ -25,7 +25,6 @@ import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.DbJoin;
 import org.apache.cayenne.map.DbRelationship;
 import org.apache.cayenne.modeler.util.CayenneController;
-import org.apache.commons.collections.Predicate;
 
 import java.awt.*;
 import java.util.ArrayList;
@@ -33,6 +32,7 @@ import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
+import java.util.function.Predicate;
 
 public class InferRelationshipsControllerBase extends CayenneController {
 
@@ -233,18 +233,17 @@ public class InferRelationshipsControllerBase extends CayenneController {
         return selected;
     }
 
-    public boolean updateSelection(Predicate predicate) {
+    public boolean updateSelection(Predicate<InferredRelationship> predicate) {
         boolean modified = false;
 
         for (InferredRelationship entity : inferredRelationships) {
-            boolean select = predicate.evaluate(entity);
+            boolean select = predicate.test(entity);
 
             if (select) {
                 if (selectedEntities.add(entity)) {
                     modified = true;
                 }
-            }
-            else {
+            } else {
                 if (selectedEntities.remove(entity)) {
                     modified = true;
                 }
@@ -259,7 +258,7 @@ public class InferRelationshipsControllerBase extends CayenneController {
     }
 
     public boolean isSelected() {
-        return currentEntity != null ? selectedEntities.contains(currentEntity) : false;
+        return currentEntity != null && selectedEntities.contains(currentEntity);
     }
 
     public void setSelected(boolean selectedFlag) {

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsTabController.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsTabController.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsTabController.java
index 5637b0c..a01bd9c 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsTabController.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsTabController.java
@@ -24,8 +24,6 @@ import org.apache.cayenne.modeler.util.CayenneController;
 import org.apache.cayenne.swing.BindingBuilder;
 import org.apache.cayenne.swing.ObjectBinding;
 import org.apache.cayenne.swing.TableBindingBuilder;
-import org.apache.commons.collections.Predicate;
-import org.apache.commons.collections.PredicateUtils;
 
 public class InferRelationshipsTabController extends CayenneController {
 
@@ -115,8 +113,7 @@ public class InferRelationshipsTabController extends CayenneController {
 
         if (selectedCount == 0) {
             view.getCheckAll().setSelected(false);
-        }
-        else if (selectedCount == getParentController().getEntities().size()) {
+        } else if (selectedCount == getParentController().getEntities().size()) {
             view.getCheckAll().setSelected(true);
         }
     }
@@ -126,11 +123,7 @@ public class InferRelationshipsTabController extends CayenneController {
      * change.
      */
     public void checkAllAction() {
-
-        Predicate predicate = view.getCheckAll().isSelected() ? PredicateUtils
-                .truePredicate() : PredicateUtils.falsePredicate();
-
-        if (getParentController().updateSelection(predicate)) {
+        if (getParentController().updateSelection(view.getCheckAll().isSelected() ? o -> true : o -> false)) {
             tableBinding.updateView();
         }
     }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/codegen/ClassesTabController.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/codegen/ClassesTabController.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/codegen/ClassesTabController.java
index a4611a2..a5b2e6a 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/codegen/ClassesTabController.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/codegen/ClassesTabController.java
@@ -28,8 +28,6 @@ import org.apache.cayenne.swing.BindingBuilder;
 import org.apache.cayenne.swing.ImageRendererColumn;
 import org.apache.cayenne.swing.ObjectBinding;
 import org.apache.cayenne.swing.TableBindingBuilder;
-import org.apache.commons.collections.Predicate;
-import org.apache.commons.collections.PredicateUtils;
 
 public class ClassesTabController extends CayenneController {
 
@@ -115,11 +113,7 @@ public class ClassesTabController extends CayenneController {
      * change.
      */
     public void checkAllAction() {
-
-        Predicate predicate = view.getCheckAll().isSelected() ? PredicateUtils
-                .truePredicate() : PredicateUtils.falsePredicate();
-
-        if (getParentController().updateSelection(predicate)) {
+        if (getParentController().updateSelection(view.getCheckAll().isSelected() ? o -> true : o -> false)) {
             tableBinding.updateView();
         }
     }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/codegen/ClientModeController.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/codegen/ClientModeController.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/codegen/ClientModeController.java
index 248b4b2..079d70c 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/codegen/ClientModeController.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/codegen/ClientModeController.java
@@ -27,32 +27,17 @@ import org.apache.cayenne.modeler.pref.DataMapDefaults;
 import org.apache.cayenne.swing.BindingBuilder;
 import org.apache.cayenne.validation.BeanValidationFailure;
 import org.apache.cayenne.validation.ValidationResult;
-import org.apache.commons.collections.Predicate;
 
 import java.util.ArrayList;
 import java.util.Map.Entry;
 import java.util.Set;
 import java.util.TreeMap;
+import java.util.function.Predicate;
 
 public class ClientModeController extends StandardModeController {
 
-    protected Predicate checkPredicate;
-
     public ClientModeController(CodeGeneratorControllerBase parent) {
         super(parent);
-
-        this.checkPredicate = new Predicate() {
-
-            public boolean evaluate(Object object) {
-                if (object instanceof ObjEntity) {
-                    ObjEntity entity = (ObjEntity) object;
-                    return entity.isClientAllowed()
-                            && getParentController().getProblem(entity.getName()) == null;
-                }
-
-                return false;
-            }
-        };
     }
 
     public void validateEntity(ValidationResult validationBuffer, ObjEntity entity) {
@@ -117,8 +102,4 @@ public class ClientModeController extends StandardModeController {
     protected ClassGenerationAction newGenerator() {
         return new ClientClassGenerationAction();
     }
-
-    public Predicate getDefaultEntityFilter() {
-        return checkPredicate;
-    }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/codegen/CodeGeneratorController.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/codegen/CodeGeneratorController.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/codegen/CodeGeneratorController.java
index 731cc61..d471682 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/codegen/CodeGeneratorController.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/codegen/CodeGeneratorController.java
@@ -24,14 +24,13 @@ import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.modeler.dialog.ErrorDebugDialog;
 import org.apache.cayenne.modeler.util.CayenneController;
 import org.apache.cayenne.swing.BindingBuilder;
-import org.apache.commons.collections.Predicate;
-import org.apache.commons.collections.PredicateUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.swing.JOptionPane;
 import java.awt.Component;
 import java.util.Collection;
+import java.util.function.Predicate;
 
 /**
  * A controller for the class generator dialog.
@@ -91,9 +90,9 @@ public class CodeGeneratorController extends CodeGeneratorControllerBase {
         GeneratorController controller = generatorSelector.getGeneratorController();
         validate(controller);
 
-        Predicate predicate = controller != null
+        Predicate<Object> predicate = controller != null
                 ? controller.getDefaultClassFilter()
-                : PredicateUtils.falsePredicate();
+                : o -> false;
 
         updateSelection(predicate);
         classesSelector.classSelectedAction();

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/codegen/CodeGeneratorControllerBase.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/codegen/CodeGeneratorControllerBase.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/codegen/CodeGeneratorControllerBase.java
index ad8c306..563de6a 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/codegen/CodeGeneratorControllerBase.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/codegen/CodeGeneratorControllerBase.java
@@ -26,7 +26,6 @@ import org.apache.cayenne.modeler.util.CayenneController;
 import org.apache.cayenne.modeler.util.CellRenderers;
 import org.apache.cayenne.validation.ValidationFailure;
 import org.apache.cayenne.validation.ValidationResult;
-import org.apache.commons.collections.Predicate;
 
 import javax.swing.Icon;
 import javax.swing.JLabel;
@@ -36,6 +35,7 @@ import java.util.Collection;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.function.Predicate;
 
 /**
  * A base superclass of a top controller for the code generator. Defines all common model
@@ -52,8 +52,8 @@ public abstract class CodeGeneratorControllerBase extends CayenneController {
 
     protected List<Object> classes;
 
-    protected Set selectedEntities;
-    protected Set selectedEmbeddables;
+    protected Set<String> selectedEntities;
+    protected Set<String> selectedEmbeddables;
 
     protected transient Object currentClass;
 
@@ -61,14 +61,14 @@ public abstract class CodeGeneratorControllerBase extends CayenneController {
         super(parent);
 
         this.dataMaps = dataMaps;
-        this.classes = new ArrayList();
+        this.classes = new ArrayList<>();
 
         for(DataMap dataMap:dataMaps){
-            this.classes.addAll(new ArrayList(dataMap.getObjEntities()));
-            this.classes.addAll(new ArrayList(dataMap.getEmbeddables()));
+            this.classes.addAll(new ArrayList<>(dataMap.getObjEntities()));
+            this.classes.addAll(new ArrayList<>(dataMap.getEmbeddables()));
         }
-        this.selectedEntities = new HashSet();
-        this.selectedEmbeddables = new HashSet();
+        this.selectedEntities = new HashSet<>();
+        this.selectedEmbeddables = new HashSet<>();
     }
 
     public List<Object> getClasses() {
@@ -99,12 +99,12 @@ public abstract class CodeGeneratorControllerBase extends CayenneController {
         this.validation = validationBuffer;
     }
 
-    public boolean updateSelection(Predicate predicate) {
+    public boolean updateSelection(Predicate<Object> predicate) {
 
         boolean modified = false;
 
         for (Object classObj : classes) {
-            boolean select = predicate.evaluate(classObj);
+            boolean select = predicate.test(classObj);
             if (classObj instanceof ObjEntity) {
 
                 if (select) {
@@ -205,12 +205,12 @@ public abstract class CodeGeneratorControllerBase extends CayenneController {
 
     public boolean isSelected() {
         if (currentClass instanceof ObjEntity) {
-            return currentClass != null ? selectedEntities
-                    .contains(((ObjEntity) currentClass).getName()) : false;
+            return selectedEntities
+                    .contains(((ObjEntity) currentClass).getName());
         }
         if (currentClass instanceof Embeddable) {
-            return currentClass != null ? selectedEmbeddables
-                    .contains(((Embeddable) currentClass).getClassName()) : false;
+            return selectedEmbeddables
+                    .contains(((Embeddable) currentClass).getClassName());
         }
         return false;
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/codegen/GeneratorController.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/codegen/GeneratorController.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/codegen/GeneratorController.java
index 962601d..e105445 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/codegen/GeneratorController.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/codegen/GeneratorController.java
@@ -41,7 +41,6 @@ import org.apache.cayenne.validation.BeanValidationFailure;
 import org.apache.cayenne.validation.SimpleValidationFailure;
 import org.apache.cayenne.validation.ValidationFailure;
 import org.apache.cayenne.validation.ValidationResult;
-import org.apache.commons.collections.Predicate;
 
 import javax.swing.JButton;
 import javax.swing.JFileChooser;
@@ -54,6 +53,7 @@ import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.Map;
 import java.util.Set;
+import java.util.function.Predicate;
 import java.util.prefs.Preferences;
 
 /**
@@ -479,44 +479,26 @@ public abstract class GeneratorController extends CayenneController {
         final Embeddable selectedEmbeddable = Application.getInstance().getFrameController().getProjectController()
                 .getCurrentEmbeddable();
 
-        // select a single entity
         if (selectedEntity != null) {
+            // select a single entity
             final boolean hasProblem = getParentController().getProblem(selectedEntity.getName()) != null;
-
-            return new Predicate() {
-
-                public boolean evaluate(Object object) {
-                    return !hasProblem && object == selectedEntity;
-                }
-            };
-        }
-        // select a single embeddable
-        else if (selectedEmbeddable != null) {
+            return object -> !hasProblem && object == selectedEntity;
+        } else if (selectedEmbeddable != null) {
+            // select a single embeddable
             final boolean hasProblem = getParentController().getProblem(selectedEmbeddable.getClassName()) != null;
-
-            return new Predicate() {
-
-                public boolean evaluate(Object object) {
-                    return !hasProblem && object == selectedEmbeddable;
+            return object -> !hasProblem && object == selectedEmbeddable;
+        } else {
+            // select all entities
+            return object -> {
+                if (object instanceof ObjEntity) {
+                    return getParentController().getProblem(((ObjEntity) object).getName()) == null;
                 }
-            };
-        }
-        // select all entities
-        else {
-
-            return new Predicate() {
-
-                public boolean evaluate(Object object) {
-                    if (object instanceof ObjEntity) {
-                        return getParentController().getProblem(((ObjEntity) object).getName()) == null;
-                    }
-
-                    if (object instanceof Embeddable) {
-                        return getParentController().getProblem(((Embeddable) object).getClassName()) == null;
-                    }
 
-                    return false;
+                if (object instanceof Embeddable) {
+                    return getParentController().getProblem(((Embeddable) object).getClassName()) == null;
                 }
+
+                return false;
             };
         }
     }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/pref/DataSourcePreferences.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/pref/DataSourcePreferences.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/pref/DataSourcePreferences.java
index 151d56c..149fb8d 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/pref/DataSourcePreferences.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/pref/DataSourcePreferences.java
@@ -27,11 +27,11 @@ import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.StringTokenizer;
 import java.util.prefs.Preferences;
+import java.util.stream.Collectors;
 
 import javax.swing.DefaultComboBoxModel;
 import javax.swing.JOptionPane;
@@ -39,7 +39,6 @@ import javax.swing.JOptionPane;
 import org.apache.cayenne.datasource.DriverDataSource;
 import org.apache.cayenne.map.event.MapEvent;
 import org.apache.cayenne.modeler.FileClassLoadingService;
-import org.apache.cayenne.modeler.ProjectController;
 import org.apache.cayenne.modeler.event.DataSourceModificationEvent;
 import org.apache.cayenne.modeler.pref.DBConnectionInfo;
 import org.apache.cayenne.modeler.util.CayenneController;
@@ -48,8 +47,6 @@ import org.apache.cayenne.pref.ChildrenMapPreference;
 import org.apache.cayenne.pref.PreferenceEditor;
 import org.apache.cayenne.swing.BindingBuilder;
 import org.apache.cayenne.util.Util;
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.collections.Transformer;
 
 /**
  * Editor for the local DataSources configured in preferences.
@@ -260,17 +257,7 @@ public class DataSourcePreferences extends CayenneController {
 			}
 
 			if (details.size() > 0) {
-
-				// transform preference to file...
-				Transformer transformer = new Transformer() {
-
-					public Object transform(Object object) {
-						String pref = (String) object;
-						return new File(pref);
-					}
-				};
-
-				classLoader.setPathFiles(CollectionUtils.collect(details, transformer));
+				classLoader.setPathFiles(details.stream().map(File::new).collect(Collectors.toList()));
 			}
 
 			Class<Driver> driverClass = classLoader.loadClass(Driver.class, currentDataSource.getJdbcDriver());

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fddb229d/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjEntityTab.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjEntityTab.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjEntityTab.java
index 1b2b18c..8c6272f 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjEntityTab.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjEntityTab.java
@@ -31,6 +31,8 @@ import java.util.Collection;
 import java.util.EventObject;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
 
 import javax.swing.BorderFactory;
 import javax.swing.DefaultComboBoxModel;
@@ -74,8 +76,6 @@ import org.apache.cayenne.project.extension.info.ObjectInfo;
 import org.apache.cayenne.util.CayenneMapEntry;
 import org.apache.cayenne.util.Util;
 import org.apache.cayenne.validation.ValidationException;
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.collections.Predicate;
 
 import com.jgoodies.forms.builder.DefaultFormBuilder;
 import com.jgoodies.forms.layout.FormLayout;
@@ -424,23 +424,14 @@ public class ObjEntityTab extends JPanel implements ObjEntityDisplayListener, Ex
         toggleClientFieldsVisible(map.isClientSupported());
         toggleEnabled(entity.getSuperEntityName() == null, !entity.isServerOnly());
 
-        // init ObjEntities for inheritance
-        Predicate inheritanceFilter = new Predicate() {
-            public boolean evaluate(Object object) {
-                // do not show this entity or any of the subentities
-                return entity != object && !((ObjEntity) object).isSubentityOf(entity);
-            }
-        };
-
-        @SuppressWarnings("unchecked")
-        ObjEntity[] objEntities = ((Collection<ObjEntity>)CollectionUtils.select(map.getObjEntities(), inheritanceFilter))
-                .toArray(new ObjEntity[0]);
-        Arrays.sort(objEntities, Comparators.getDataMapChildrenComparator());
-        ObjEntity[] finalObjEntities = new ObjEntity[objEntities.length + 1];
-        finalObjEntities[0] = NO_INHERITANCE;
-        System.arraycopy(objEntities, 0, finalObjEntities, 1, objEntities.length);
+        // do not show this entity or any of the subentities
+        List<ObjEntity> objEntities = map.getObjEntities().stream()
+                .filter(object -> entity != object && !object.isSubentityOf(entity))
+                .sorted(Comparators.getDataMapChildrenComparator())
+                .collect(Collectors.toList());
+        objEntities.add(0, NO_INHERITANCE);
 
-        DefaultComboBoxModel<ObjEntity> superEntityModel = new DefaultComboBoxModel<>(finalObjEntities);
+        DefaultComboBoxModel<ObjEntity> superEntityModel = new DefaultComboBoxModel<>(objEntities.toArray(new ObjEntity[0]));
         superEntityModel.setSelectedItem(entity.getSuperEntity());
         superEntityCombo.setRenderer(CellRenderers.entityListRendererWithIcons(map));
         superEntityCombo.setModel(superEntityModel);


[7/9] cayenne git commit: CAY-2351 Remove dependency on commons-collection performance optimizations of Weak- and SoftValueMap

Posted by nt...@apache.org.
CAY-2351 Remove dependency on commons-collection
  performance optimizations of Weak- and SoftValueMap


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/7f7aca81
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/7f7aca81
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/7f7aca81

Branch: refs/heads/master
Commit: 7f7aca813d3eba5eedb9c75567d7f42320a1529b
Parents: bc7399a
Author: Nikita Timofeev <st...@gmail.com>
Authored: Mon Aug 14 17:41:41 2017 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Thu Aug 17 12:41:58 2017 +0300

----------------------------------------------------------------------
 .../org/apache/cayenne/util/ReferenceMap.java   | 38 ++++++++++----------
 1 file changed, 20 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/7f7aca81/cayenne-server/src/main/java/org/apache/cayenne/util/ReferenceMap.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/util/ReferenceMap.java b/cayenne-server/src/main/java/org/apache/cayenne/util/ReferenceMap.java
index 530ea30..8e177f1 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/util/ReferenceMap.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/util/ReferenceMap.java
@@ -30,6 +30,7 @@ import java.util.AbstractSet;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
@@ -76,11 +77,6 @@ abstract class ReferenceMap<K, V, R extends Reference<V>> extends AbstractMap<K,
      */
     protected transient Map<K, R> map;
 
-    /**
-     * This is aux storage to faster remove cleared references
-     */
-    protected transient Map<R, K> reverseMap;
-
     protected transient ReferenceQueue<V> referenceQueue;
 
     /**
@@ -90,13 +86,11 @@ abstract class ReferenceMap<K, V, R extends Reference<V>> extends AbstractMap<K,
 
     public ReferenceMap() {
         map = new HashMap<>();
-        reverseMap = new HashMap<>();
         referenceQueue = new ReferenceQueue<>();
     }
 
     public ReferenceMap(int initialCapacity) {
         map = new HashMap<>(initialCapacity);
-        reverseMap = new HashMap<>(initialCapacity);
         referenceQueue = new ReferenceQueue<>();
     }
 
@@ -154,7 +148,6 @@ abstract class ReferenceMap<K, V, R extends Reference<V>> extends AbstractMap<K,
         checkReferenceQueue();
         R refValue = newReference(value);
         R oldValue = map.put(key, refValue);
-        reverseMap.put(refValue, key);
         if(oldValue == null) {
             return null;
         }
@@ -168,7 +161,6 @@ abstract class ReferenceMap<K, V, R extends Reference<V>> extends AbstractMap<K,
         if(oldValue == null) {
             return null;
         }
-        reverseMap.remove(oldValue);
         return oldValue.get();
     }
 
@@ -178,14 +170,12 @@ abstract class ReferenceMap<K, V, R extends Reference<V>> extends AbstractMap<K,
         for(Map.Entry<? extends K, ? extends V> entry : m.entrySet()) {
             R value = newReference(entry.getValue());
             map.put(entry.getKey(), value);
-            reverseMap.put(value, entry.getKey());
         }
     }
 
     @Override
     public void clear() {
         map.clear();
-        reverseMap.clear();
         resetReferenceQueue();
     }
 
@@ -224,13 +214,28 @@ abstract class ReferenceMap<K, V, R extends Reference<V>> extends AbstractMap<K,
      * Cleanup all references collected by GC so far
      */
     protected void checkReferenceQueue() {
+        Collection<Reference<? extends V>> valuesToRemove = null;
         Reference<? extends V> reference;
-
         while((reference = referenceQueue.poll()) != null) {
-            K keyToRemove = reverseMap.remove(reference);
-            if(keyToRemove != null) {
-                map.remove(keyToRemove);
+            if(valuesToRemove == null) {
+                valuesToRemove = new HashSet<>();
             }
+            valuesToRemove.add(reference);
+        }
+
+        if(valuesToRemove == null) {
+            return;
+        }
+
+        Collection<K> keysToRemove = new ArrayList<>(valuesToRemove.size());
+        for(Map.Entry<K, R> entry : map.entrySet()) {
+            if(valuesToRemove.contains(entry.getValue())) {
+                keysToRemove.add(entry.getKey());
+            }
+        }
+
+        for(K keyToRemove : keysToRemove) {
+            map.remove(keyToRemove);
         }
     }
 
@@ -271,10 +276,8 @@ abstract class ReferenceMap<K, V, R extends Reference<V>> extends AbstractMap<K,
         @SuppressWarnings("unchecked")
         Map<K, V> replacement = (Map<K, V>) in.readObject();
         map = new HashMap<>(replacement.size());
-        reverseMap = new HashMap<>(replacement.size());
         referenceQueue = new ReferenceQueue<>();
         putAll(replacement);
-        map.forEach((k, v) -> reverseMap.put(v, k));
     }
 
     /**
@@ -333,7 +336,6 @@ abstract class ReferenceMap<K, V, R extends Reference<V>> extends AbstractMap<K,
         public V setValue(V value) {
             R newRef = newReference(value);
             R oldRef = refEntry.setValue(newRef);
-            reverseMap.put(newRef, reverseMap.remove(oldRef));
             if(oldRef != null) {
                 return oldRef.get();
             }