CAY-2345 Own template renderer as a replacement for Velocity
  - move Velocity to separate module
  - remove dependencies on commons-lang


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

Branch: refs/heads/master
Commit: f734851f4f7ef71eb95d78c8432c94035f1d9e20
Parents: 54feb97
Author: Nikita Timofeev <stari...@gmail.com>
Authored: Wed Aug 9 16:42:09 2017 +0300
Committer: Nikita Timofeev <stari...@gmail.com>
Committed: Wed Aug 16 18:30:02 2017 +0300

----------------------------------------------------------------------
 cayenne-ant/pom.xml                             |  14 -
 .../org/apache/cayenne/gen/StringUtils.java     |  14 +-
 .../dbsync/reverse/dbload/ExportedKey.java      |   2 +-
 .../merge/builders/DbAttributeBuilder.java      |   5 +-
 .../dbsync/merge/builders/DbEntityBuilder.java  |   4 +-
 .../dbsync/merge/builders/DefaultBuilder.java   |   6 +-
 .../dbsync/merge/builders/ObjEntityBuilder.java |   4 +-
 cayenne-server/pom.xml                          |   5 -
 .../access/jdbc/RowDescriptorBuilder.java       |   4 +-
 .../configuration/server/ServerModule.java      |   2 -
 .../template/SQLTemplateRenderingUtils.java     |  37 +
 .../apache/cayenne/util/CompareToBuilder.java   | 717 +++++++++++++++++++
 .../main/java/org/apache/cayenne/util/Util.java |  26 +
 .../ConcurrentLinkedHashMap.java                |  86 +--
 .../apache/cayenne/velocity/BindDirective.java  | 158 ----
 .../cayenne/velocity/BindEqualDirective.java    |  57 --
 .../cayenne/velocity/BindNotEqualDirective.java |  56 --
 .../velocity/BindObjectEqualDirective.java      | 164 -----
 .../velocity/BindObjectNotEqualDirective.java   |  70 --
 .../apache/cayenne/velocity/ChainDirective.java | 112 ---
 .../apache/cayenne/velocity/ChunkDirective.java |  75 --
 .../cayenne/velocity/ResultDirective.java       | 202 ------
 .../velocity/SQLTemplateRenderingUtils.java     |  37 -
 .../velocity/SQLTemplateResourceManager.java    | 106 ---
 .../velocity/VelocitySQLTemplateProcessor.java  | 208 ------
 .../template/directive/BindDirectiveIT.java     | 239 +++++++
 .../template/directive/ResultDirectiveIT.java   | 112 +++
 .../cayenne/velocity/BindDirectiveIT.java       | 239 -------
 .../cayenne/velocity/ResultDirectiveIT.java     | 112 ---
 .../SQLTemplateResourceManagerTest.java         |  77 --
 .../VelocitySQLTemplateProcessorTest.java       | 234 ------
 .../VelocitySQLTemplateProcessor_ChainTest.java | 184 -----
 ...VelocitySQLTemplateProcessor_SelectTest.java | 109 ---
 cayenne-velocity/pom.xml                        |  87 +++
 .../apache/cayenne/velocity/BindDirective.java  | 158 ++++
 .../cayenne/velocity/BindEqualDirective.java    |  57 ++
 .../cayenne/velocity/BindNotEqualDirective.java |  56 ++
 .../velocity/BindObjectEqualDirective.java      | 164 +++++
 .../velocity/BindObjectNotEqualDirective.java   |  70 ++
 .../apache/cayenne/velocity/ChainDirective.java | 112 +++
 .../apache/cayenne/velocity/ChunkDirective.java |  75 ++
 .../cayenne/velocity/ResultDirective.java       | 202 ++++++
 .../velocity/SQLTemplateResourceManager.java    | 106 +++
 .../apache/cayenne/velocity/VelocityModule.java |  35 +
 .../velocity/VelocitySQLTemplateProcessor.java  | 209 ++++++
 .../velocity/VelocityServerModuleProvider.java  |  50 ++
 ...iguration.server.CayenneServerModuleProvider |  20 +
 .../SQLTemplateResourceManagerTest.java         |  77 ++
 .../VelocitySQLTemplateProcessorTest.java       | 234 ++++++
 .../VelocitySQLTemplateProcessor_ChainTest.java | 184 +++++
 ...VelocitySQLTemplateProcessor_SelectTest.java | 109 +++
 docs/doc/pom.xml                                |   5 -
 modeler/cayenne-modeler/pom.xml                 |  25 +-
 modeler/cayenne-wocompat/pom.xml                |  32 +-
 pom.xml                                         |   7 +-
 55 files changed, 3202 insertions(+), 2349 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/f734851f/cayenne-ant/pom.xml
----------------------------------------------------------------------
diff --git a/cayenne-ant/pom.xml b/cayenne-ant/pom.xml
index 9b12f4e..6773efb 100644
--- a/cayenne-ant/pom.xml
+++ b/cayenne-ant/pom.xml
@@ -39,34 +39,20 @@
         <dependency>
             <groupId>org.apache.ant</groupId>
             <artifactId>ant</artifactId>
-            <scope>compile</scope>
         </dependency>
                <dependency>
-                       <groupId>commons-collections</groupId>
-                       <artifactId>commons-collections</artifactId>
-            <scope>compile</scope>
-               </dependency>
-               <dependency>
-                       <groupId>org.apache.velocity</groupId>
-                       <artifactId>velocity</artifactId>
-            <scope>compile</scope>
-               </dependency>
-               <dependency>
                        <groupId>org.apache.cayenne</groupId>
                        <artifactId>cayenne-cgen</artifactId>
                        <version>${project.version}</version>
-            <scope>compile</scope>
                </dependency>
         <dependency>
             <groupId>org.apache.cayenne</groupId>
             <artifactId>cayenne-dbsync</artifactId>
             <version>${project.version}</version>
-            <scope>compile</scope>
         </dependency>
                <dependency>
                        <groupId>foundrylogic.vpp</groupId>
                        <artifactId>vpp</artifactId>
-            <scope>compile</scope>
                </dependency>
 
         <!-- Test Dependencies -->

http://git-wip-us.apache.org/repos/asf/cayenne/blob/f734851f/cayenne-cgen/src/main/java/org/apache/cayenne/gen/StringUtils.java
----------------------------------------------------------------------
diff --git a/cayenne-cgen/src/main/java/org/apache/cayenne/gen/StringUtils.java 
b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/StringUtils.java
index 778a09b..85e328e 100644
--- a/cayenne-cgen/src/main/java/org/apache/cayenne/gen/StringUtils.java
+++ b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/StringUtils.java
@@ -82,11 +82,7 @@ public class StringUtils {
      * @since 1.1
      */
     public String capitalized(String name) {
-        if (name == null || name.length() == 0)
-            return name;
-
-        char c = Character.toUpperCase(name.charAt(0));
-        return (name.length() == 1) ? Character.toString(c) : c + 
name.substring(1);
+        return Util.capitalized(name);
     }
 
     /**
@@ -94,12 +90,8 @@ public class StringUtils {
      * 
      * @since 1.2
      */
-    public static String uncapitalized(String aString) {
-        if (aString == null || aString.length() == 0)
-            return aString;
-
-        char c = Character.toLowerCase(aString.charAt(0));
-        return (aString.length() == 1) ? Character.toString(c) : c + 
aString.substring(1);
+    public String uncapitalized(String aString) {
+        return Util.uncapitalized(aString);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/cayenne/blob/f734851f/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbload/ExportedKey.java
----------------------------------------------------------------------
diff --git 
a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbload/ExportedKey.java
 
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbload/ExportedKey.java
index 5443dfc..6d5f25c 100644
--- 
a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbload/ExportedKey.java
+++ 
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbload/ExportedKey.java
@@ -21,7 +21,7 @@ package org.apache.cayenne.dbsync.reverse.dbload;
 
 import org.apache.cayenne.util.EqualsBuilder;
 import org.apache.cayenne.util.HashCodeBuilder;
-import org.apache.commons.lang.builder.CompareToBuilder;
+import org.apache.cayenne.util.CompareToBuilder;
 
 import java.sql.ResultSet;
 import java.sql.SQLException;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/f734851f/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/DbAttributeBuilder.java
----------------------------------------------------------------------
diff --git 
a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/DbAttributeBuilder.java
 
b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/DbAttributeBuilder.java
index 99739da..094a904 100644
--- 
a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/DbAttributeBuilder.java
+++ 
b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/DbAttributeBuilder.java
@@ -22,8 +22,7 @@ import org.apache.cayenne.datafactory.DictionaryValueProvider;
 import org.apache.cayenne.datafactory.ValueProvider;
 import org.apache.cayenne.dba.TypesMapping;
 import org.apache.cayenne.map.DbAttribute;
-
-import static org.apache.commons.lang.StringUtils.isEmpty;
+import org.apache.cayenne.util.Util;
 
 /**
  * @since 4.0.
@@ -101,7 +100,7 @@ public class DbAttributeBuilder extends 
DefaultBuilder<DbAttribute> {
 
     @Override
     public DbAttribute build() {
-        if (isEmpty(obj.getName())) {
+        if (Util.isEmptyString(obj.getName())) {
             name();
         }
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/f734851f/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/DbEntityBuilder.java
----------------------------------------------------------------------
diff --git 
a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/DbEntityBuilder.java
 
b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/DbEntityBuilder.java
index 03f0738..5afeedf 100644
--- 
a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/DbEntityBuilder.java
+++ 
b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/DbEntityBuilder.java
@@ -20,7 +20,7 @@ package org.apache.cayenne.dbsync.merge.builders;
 
 import org.apache.cayenne.map.DbAttribute;
 import org.apache.cayenne.map.DbEntity;
-import org.apache.commons.lang.StringUtils;
+import org.apache.cayenne.util.Util;
 
 /**
  * @since 4.0.
@@ -73,7 +73,7 @@ public class DbEntityBuilder extends DefaultBuilder<DbEntity> 
{
     @Override
     public DbEntity build() {
         if (obj.getName() == null) {
-            obj.setName(StringUtils.capitalize(getRandomJavaName()));
+            obj.setName(Util.capitalized(getRandomJavaName()));
         }
 
         return obj;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/f734851f/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/DefaultBuilder.java
----------------------------------------------------------------------
diff --git 
a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/DefaultBuilder.java
 
b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/DefaultBuilder.java
index 559347b..e44ef38 100644
--- 
a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/DefaultBuilder.java
+++ 
b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/DefaultBuilder.java
@@ -19,7 +19,7 @@
 package org.apache.cayenne.dbsync.merge.builders;
 
 import org.apache.cayenne.datafactory.DataFactory;
-import org.apache.commons.lang.StringUtils;
+import org.apache.cayenne.util.Util;
 
 /**
  * @since 4.0.
@@ -39,10 +39,10 @@ public abstract class DefaultBuilder<T> implements 
Builder<T> {
         int count = dataFactory.getNumberBetween(1, 5);
         StringBuilder res = new StringBuilder();
         for (int i = 0; i < count; i++) {
-            res.append(StringUtils.capitalize(dataFactory.getRandomWord()));
+            res.append(Util.capitalized(dataFactory.getRandomWord()));
         }
 
-        return StringUtils.uncapitalize(res.toString());
+        return Util.uncapitalized(res.toString());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/cayenne/blob/f734851f/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/ObjEntityBuilder.java
----------------------------------------------------------------------
diff --git 
a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/ObjEntityBuilder.java
 
b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/ObjEntityBuilder.java
index f2f701c..df52e0e 100644
--- 
a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/ObjEntityBuilder.java
+++ 
b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/ObjEntityBuilder.java
@@ -20,7 +20,7 @@ package org.apache.cayenne.dbsync.merge.builders;
 
 import org.apache.cayenne.map.ObjAttribute;
 import org.apache.cayenne.map.ObjEntity;
-import org.apache.commons.lang.StringUtils;
+import org.apache.cayenne.util.Util;
 
 /**
  * @since 4.0.
@@ -69,7 +69,7 @@ public class ObjEntityBuilder extends 
DefaultBuilder<ObjEntity> {
     @Override
     public ObjEntity build() {
         if (obj.getName() == null) {
-            obj.setName(StringUtils.capitalize(getRandomJavaName()));
+            obj.setName(Util.capitalized(getRandomJavaName()));
         }
 
         return obj;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/f734851f/cayenne-server/pom.xml
----------------------------------------------------------------------
diff --git a/cayenne-server/pom.xml b/cayenne-server/pom.xml
index d5d604d..4414f43 100644
--- a/cayenne-server/pom.xml
+++ b/cayenne-server/pom.xml
@@ -49,11 +49,6 @@
                        <artifactId>commons-collections</artifactId>
                        <scope>compile</scope>
                </dependency>
-               <dependency>
-                       <groupId>org.apache.velocity</groupId>
-                       <artifactId>velocity</artifactId>
-                       <scope>compile</scope>
-               </dependency>
 
                <!-- Optional dependencies... things that might have been 
placed in submodules... -->
                <dependency>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/f734851f/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 90151c0..ab100af 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
@@ -31,8 +31,8 @@ import java.util.Set;
 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.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -143,7 +143,7 @@ public class RowDescriptorBuilder {
         }
 
         if(validateDuplicateColumnNames && !duplicates.isEmpty()) {
-            logger.warn("Found duplicated columns '" + 
StringUtils.join(duplicates, "', '") + "' in row descriptor. " +
+            logger.warn("Found duplicated columns '" + Util.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/f734851f/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java
index e951c49..49018ef 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java
@@ -117,7 +117,6 @@ import org.apache.cayenne.tx.DefaultTransactionManager;
 import org.apache.cayenne.tx.TransactionFactory;
 import org.apache.cayenne.tx.TransactionFilter;
 import org.apache.cayenne.tx.TransactionManager;
-import org.apache.cayenne.velocity.VelocitySQLTemplateProcessor;
 import org.xml.sax.XMLReader;
 
 import java.util.Calendar;
@@ -409,7 +408,6 @@ public class ServerModule implements Module {
         
binder.bind(TransactionManager.class).to(DefaultTransactionManager.class);
         binder.bind(RowReaderFactory.class).to(DefaultRowReaderFactory.class);
 
-//        
binder.bind(SQLTemplateProcessor.class).to(VelocitySQLTemplateProcessor.class);
         
binder.bind(SQLTemplateProcessor.class).to(CayenneSQLTemplateProcessor.class);
 
         binder.bind(HandlerFactory.class).to(DefaultHandlerFactory.class);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/f734851f/cayenne-server/src/main/java/org/apache/cayenne/template/SQLTemplateRenderingUtils.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/template/SQLTemplateRenderingUtils.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/template/SQLTemplateRenderingUtils.java
new file mode 100644
index 0000000..f468a9e
--- /dev/null
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/template/SQLTemplateRenderingUtils.java
@@ -0,0 +1,37 @@
+/*****************************************************************
+ *   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.template;
+
+import org.apache.cayenne.exp.ExpressionFactory;
+
+/**
+ * Implements utility methods used inside Velocity templates when rendering
+ * SQLTemplates.
+ * 
+ * @since 1.1
+ */
+public class SQLTemplateRenderingUtils {
+       /**
+        * Returns the result of evaluation of expression with object.
+        */
+       public Object cayenneExp(Object object, String expression) {
+               return ExpressionFactory.exp(expression).evaluate(object);
+       }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/f734851f/cayenne-server/src/main/java/org/apache/cayenne/util/CompareToBuilder.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/util/CompareToBuilder.java 
b/cayenne-server/src/main/java/org/apache/cayenne/util/CompareToBuilder.java
new file mode 100644
index 0000000..0235910
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/util/CompareToBuilder.java
@@ -0,0 +1,717 @@
+/*****************************************************************
+ *   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.Comparator;
+
+/**
+ * Assists in implementing {@link java.lang.Comparable#compareTo(Object)} 
methods.
+ *
+ * This code is based on CompareToBuilder from commons-lang v2.6
+ *
+ * @since 4.1
+ */
+public class CompareToBuilder {
+    /**
+     * Current state of the comparison as appended fields are checked.
+     */
+    private int comparison;
+
+    /**
+     * <p>Constructor for CompareToBuilder.</p>
+     *
+     * <p>Starts off assuming that the objects are equal. Multiple calls are
+     * then made to the various append methods, followed by a call to
+     * {@link #toComparison} to get the result.</p>
+     */
+    public CompareToBuilder() {
+        super();
+        comparison = 0;
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Appends to the <code>builder</code> the 
<code>compareTo(Object)</code>
+     * result of the superclass.</p>
+     *
+     * @param superCompareTo  result of calling 
<code>super.compareTo(Object)</code>
+     * @return this - used to chain append calls
+     */
+    public CompareToBuilder appendSuper(int superCompareTo) {
+        if (comparison != 0) {
+            return this;
+        }
+        comparison = superCompareTo;
+        return this;
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Appends to the <code>builder</code> the comparison of
+     * two <code>Object</code>s.</p>
+     *
+     * <ol>
+     * <li>Check if <code>lhs == rhs</code></li>
+     * <li>Check if either <code>lhs</code> or <code>rhs</code> is 
<code>null</code>,
+     *     a <code>null</code> object is less than a non-<code>null</code> 
object</li>
+     * <li>Check the object contents</li>
+     * </ol>
+     *
+     * <p><code>lhs</code> must either be an array or implement {@link 
Comparable}.</p>
+     *
+     * @param lhs  left-hand object
+     * @param rhs  right-hand object
+     * @return this - used to chain append calls
+     * @throws ClassCastException  if <code>rhs</code> is not 
assignment-compatible
+     *  with <code>lhs</code>
+     */
+    public CompareToBuilder append(Object lhs, Object rhs) {
+        return append(lhs, rhs, null);
+    }
+
+    /**
+     * <p>Appends to the <code>builder</code> the comparison of
+     * two <code>Object</code>s.</p>
+     *
+     * <ol>
+     * <li>Check if <code>lhs == rhs</code></li>
+     * <li>Check if either <code>lhs</code> or <code>rhs</code> is 
<code>null</code>,
+     *     a <code>null</code> object is less than a non-<code>null</code> 
object</li>
+     * <li>Check the object contents</li>
+     * </ol>
+     *
+     * <p>If <code>lhs</code> is an array, array comparison methods will be 
used.
+     * Otherwise <code>comparator</code> will be used to compare the objects.
+     * If <code>comparator</code> is <code>null</code>, <code>lhs</code> must
+     * implement {@link Comparable} instead.</p>
+     *
+     * @param lhs  left-hand object
+     * @param rhs  right-hand object
+     * @param comparator  <code>Comparator</code> used to compare the objects,
+     *  <code>null</code> means treat lhs as <code>Comparable</code>
+     * @return this - used to chain append calls
+     * @throws ClassCastException  if <code>rhs</code> is not 
assignment-compatible
+     *  with <code>lhs</code>
+     * @since 2.0
+     */
+    public CompareToBuilder append(Object lhs, Object rhs, Comparator 
comparator) {
+        if (comparison != 0) {
+            return this;
+        }
+        if (lhs == rhs) {
+            return this;
+        }
+        if (lhs == null) {
+            comparison = -1;
+            return this;
+        }
+        if (rhs == null) {
+            comparison = +1;
+            return this;
+        }
+        if (lhs.getClass().isArray()) {
+            // switch on type of array, to dispatch to the correct handler
+            // handles multi dimensional arrays
+            // throws a ClassCastException if rhs is not the correct array type
+            if (lhs instanceof long[]) {
+                append((long[]) lhs, (long[]) rhs);
+            } else if (lhs instanceof int[]) {
+                append((int[]) lhs, (int[]) rhs);
+            } else if (lhs instanceof short[]) {
+                append((short[]) lhs, (short[]) rhs);
+            } else if (lhs instanceof char[]) {
+                append((char[]) lhs, (char[]) rhs);
+            } else if (lhs instanceof byte[]) {
+                append((byte[]) lhs, (byte[]) rhs);
+            } else if (lhs instanceof double[]) {
+                append((double[]) lhs, (double[]) rhs);
+            } else if (lhs instanceof float[]) {
+                append((float[]) lhs, (float[]) rhs);
+            } else if (lhs instanceof boolean[]) {
+                append((boolean[]) lhs, (boolean[]) rhs);
+            } else {
+                // not an array of primitives
+                // throws a ClassCastException if rhs is not an array
+                append((Object[]) lhs, (Object[]) rhs, comparator);
+            }
+        } else {
+            // the simple case, not an array, just test the element
+            if (comparator == null) {
+                comparison = ((Comparable) lhs).compareTo(rhs);
+            } else {
+                comparison = comparator.compare(lhs, rhs);
+            }
+        }
+        return this;
+    }
+
+    //-------------------------------------------------------------------------
+    /**
+     * Appends to the <code>builder</code> the comparison of
+     * two <code>long</code>s.
+     *
+     * @param lhs  left-hand value
+     * @param rhs  right-hand value
+     * @return this - used to chain append calls
+     */
+    public CompareToBuilder append(long lhs, long rhs) {
+        if (comparison != 0) {
+            return this;
+        }
+        comparison = Long.compare(lhs, rhs);
+        return this;
+    }
+
+    /**
+     * Appends to the <code>builder</code> the comparison of
+     * two <code>int</code>s.
+     *
+     * @param lhs  left-hand value
+     * @param rhs  right-hand value
+     * @return this - used to chain append calls
+     */
+    public CompareToBuilder append(int lhs, int rhs) {
+        if (comparison != 0) {
+            return this;
+        }
+        comparison = Integer.compare(lhs, rhs);
+        return this;
+    }
+
+    /**
+     * Appends to the <code>builder</code> the comparison of
+     * two <code>short</code>s.
+     *
+     * @param lhs  left-hand value
+     * @param rhs  right-hand value
+     * @return this - used to chain append calls
+     */
+    public CompareToBuilder append(short lhs, short rhs) {
+        if (comparison != 0) {
+            return this;
+        }
+        comparison = Short.compare(lhs, rhs);
+        return this;
+    }
+
+    /**
+     * Appends to the <code>builder</code> the comparison of
+     * two <code>char</code>s.
+     *
+     * @param lhs  left-hand value
+     * @param rhs  right-hand value
+     * @return this - used to chain append calls
+     */
+    public CompareToBuilder append(char lhs, char rhs) {
+        if (comparison != 0) {
+            return this;
+        }
+        comparison = Character.compare(lhs, rhs);
+        return this;
+    }
+
+    /**
+     * Appends to the <code>builder</code> the comparison of
+     * two <code>byte</code>s.
+     *
+     * @param lhs  left-hand value
+     * @param rhs  right-hand value
+     * @return this - used to chain append calls
+     */
+    public CompareToBuilder append(byte lhs, byte rhs) {
+        if (comparison != 0) {
+            return this;
+        }
+        comparison = Byte.compare(lhs, rhs);
+        return this;
+    }
+
+    /**
+     * <p>Appends to the <code>builder</code> the comparison of
+     * two <code>double</code>s.</p>
+     *
+     * <p>This handles NaNs, Infinities, and <code>-0.0</code>.</p>
+     *
+     * <p>It is compatible with the hash code generated by
+     * <code>HashCodeBuilder</code>.</p>
+     *
+     * @param lhs  left-hand value
+     * @param rhs  right-hand value
+     * @return this - used to chain append calls
+     */
+    public CompareToBuilder append(double lhs, double rhs) {
+        if (comparison != 0) {
+            return this;
+        }
+        comparison = Double.compare(lhs, rhs);
+        return this;
+    }
+
+    /**
+     * <p>Appends to the <code>builder</code> the comparison of
+     * two <code>float</code>s.</p>
+     *
+     * <p>This handles NaNs, Infinities, and <code>-0.0</code>.</p>
+     *
+     * <p>It is compatible with the hash code generated by
+     * <code>HashCodeBuilder</code>.</p>
+     *
+     * @param lhs  left-hand value
+     * @param rhs  right-hand value
+     * @return this - used to chain append calls
+     */
+    public CompareToBuilder append(float lhs, float rhs) {
+        if (comparison != 0) {
+            return this;
+        }
+        comparison = Float.compare(lhs, rhs);
+        return this;
+    }
+
+    /**
+     * Appends to the <code>builder</code> the comparison of
+     * two <code>booleans</code>s.
+     *
+     * @param lhs  left-hand value
+     * @param rhs  right-hand value
+     * @return this - used to chain append calls
+     */
+    public CompareToBuilder append(boolean lhs, boolean rhs) {
+        if (comparison != 0) {
+            return this;
+        }
+        if (lhs == rhs) {
+            return this;
+        }
+        if (!lhs) {
+            comparison = -1;
+        } else {
+            comparison = +1;
+        }
+        return this;
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Appends to the <code>builder</code> the deep comparison of
+     * two <code>Object</code> arrays.</p>
+     *
+     * <ol>
+     *  <li>Check if arrays are the same using <code>==</code></li>
+     *  <li>Check if for <code>null</code>, <code>null</code> is less than 
non-<code>null</code></li>
+     *  <li>Check array length, a short length array is less than a long 
length array</li>
+     *  <li>Check array contents element by element using {@link 
#append(Object, Object, Comparator)}</li>
+     * </ol>
+     *
+     * <p>This method will also will be called for the top level of 
multi-dimensional,
+     * ragged, and multi-typed arrays.</p>
+     *
+     * @param lhs  left-hand array
+     * @param rhs  right-hand array
+     * @return this - used to chain append calls
+     * @throws ClassCastException  if <code>rhs</code> is not 
assignment-compatible
+     *  with <code>lhs</code>
+     */
+    public CompareToBuilder append(Object[] lhs, Object[] rhs) {
+        return append(lhs, rhs, null);
+    }
+
+    /**
+     * <p>Appends to the <code>builder</code> the deep comparison of
+     * two <code>Object</code> arrays.</p>
+     *
+     * <ol>
+     *  <li>Check if arrays are the same using <code>==</code></li>
+     *  <li>Check if for <code>null</code>, <code>null</code> is less than 
non-<code>null</code></li>
+     *  <li>Check array length, a short length array is less than a long 
length array</li>
+     *  <li>Check array contents element by element using {@link 
#append(Object, Object, Comparator)}</li>
+     * </ol>
+     *
+     * <p>This method will also will be called for the top level of 
multi-dimensional,
+     * ragged, and multi-typed arrays.</p>
+     *
+     * @param lhs  left-hand array
+     * @param rhs  right-hand array
+     * @param comparator  <code>Comparator</code> to use to compare the array 
elements,
+     *  <code>null</code> means to treat <code>lhs</code> elements as 
<code>Comparable</code>.
+     * @return this - used to chain append calls
+     * @throws ClassCastException  if <code>rhs</code> is not 
assignment-compatible
+     *  with <code>lhs</code>
+     * @since 2.0
+     */
+    public CompareToBuilder append(Object[] lhs, Object[] rhs, Comparator 
comparator) {
+        if (comparison != 0) {
+            return this;
+        }
+        if (lhs == rhs) {
+            return this;
+        }
+        if (lhs == null) {
+            comparison = -1;
+            return this;
+        }
+        if (rhs == null) {
+            comparison = +1;
+            return this;
+        }
+        if (lhs.length != rhs.length) {
+            comparison = (lhs.length < rhs.length) ? -1 : +1;
+            return this;
+        }
+        for (int i = 0; i < lhs.length && comparison == 0; i++) {
+            append(lhs[i], rhs[i], comparator);
+        }
+        return this;
+    }
+
+    /**
+     * <p>Appends to the <code>builder</code> the deep comparison of
+     * two <code>long</code> arrays.</p>
+     *
+     * <ol>
+     *  <li>Check if arrays are the same using <code>==</code></li>
+     *  <li>Check if for <code>null</code>, <code>null</code> is less than 
non-<code>null</code></li>
+     *  <li>Check array length, a shorter length array is less than a longer 
length array</li>
+     *  <li>Check array contents element by element using {@link #append(long, 
long)}</li>
+     * </ol>
+     *
+     * @param lhs  left-hand array
+     * @param rhs  right-hand array
+     * @return this - used to chain append calls
+     */
+    public CompareToBuilder append(long[] lhs, long[] rhs) {
+        if (comparison != 0) {
+            return this;
+        }
+        if (lhs == rhs) {
+            return this;
+        }
+        if (lhs == null) {
+            comparison = -1;
+            return this;
+        }
+        if (rhs == null) {
+            comparison = +1;
+            return this;
+        }
+        if (lhs.length != rhs.length) {
+            comparison = (lhs.length < rhs.length) ? -1 : +1;
+            return this;
+        }
+        for (int i = 0; i < lhs.length && comparison == 0; i++) {
+            append(lhs[i], rhs[i]);
+        }
+        return this;
+    }
+
+    /**
+     * <p>Appends to the <code>builder</code> the deep comparison of
+     * two <code>int</code> arrays.</p>
+     *
+     * <ol>
+     *  <li>Check if arrays are the same using <code>==</code></li>
+     *  <li>Check if for <code>null</code>, <code>null</code> is less than 
non-<code>null</code></li>
+     *  <li>Check array length, a shorter length array is less than a longer 
length array</li>
+     *  <li>Check array contents element by element using {@link #append(int, 
int)}</li>
+     * </ol>
+     *
+     * @param lhs  left-hand array
+     * @param rhs  right-hand array
+     * @return this - used to chain append calls
+     */
+    public CompareToBuilder append(int[] lhs, int[] rhs) {
+        if (comparison != 0) {
+            return this;
+        }
+        if (lhs == rhs) {
+            return this;
+        }
+        if (lhs == null) {
+            comparison = -1;
+            return this;
+        }
+        if (rhs == null) {
+            comparison = +1;
+            return this;
+        }
+        if (lhs.length != rhs.length) {
+            comparison = (lhs.length < rhs.length) ? -1 : +1;
+            return this;
+        }
+        for (int i = 0; i < lhs.length && comparison == 0; i++) {
+            append(lhs[i], rhs[i]);
+        }
+        return this;
+    }
+
+    /**
+     * <p>Appends to the <code>builder</code> the deep comparison of
+     * two <code>short</code> arrays.</p>
+     *
+     * <ol>
+     *  <li>Check if arrays are the same using <code>==</code></li>
+     *  <li>Check if for <code>null</code>, <code>null</code> is less than 
non-<code>null</code></li>
+     *  <li>Check array length, a shorter length array is less than a longer 
length array</li>
+     *  <li>Check array contents element by element using {@link 
#append(short, short)}</li>
+     * </ol>
+     *
+     * @param lhs  left-hand array
+     * @param rhs  right-hand array
+     * @return this - used to chain append calls
+     */
+    public CompareToBuilder append(short[] lhs, short[] rhs) {
+        if (comparison != 0) {
+            return this;
+        }
+        if (lhs == rhs) {
+            return this;
+        }
+        if (lhs == null) {
+            comparison = -1;
+            return this;
+        }
+        if (rhs == null) {
+            comparison = +1;
+            return this;
+        }
+        if (lhs.length != rhs.length) {
+            comparison = (lhs.length < rhs.length) ? -1 : +1;
+            return this;
+        }
+        for (int i = 0; i < lhs.length && comparison == 0; i++) {
+            append(lhs[i], rhs[i]);
+        }
+        return this;
+    }
+
+    /**
+     * <p>Appends to the <code>builder</code> the deep comparison of
+     * two <code>char</code> arrays.</p>
+     *
+     * <ol>
+     *  <li>Check if arrays are the same using <code>==</code></li>
+     *  <li>Check if for <code>null</code>, <code>null</code> is less than 
non-<code>null</code></li>
+     *  <li>Check array length, a shorter length array is less than a longer 
length array</li>
+     *  <li>Check array contents element by element using {@link #append(char, 
char)}</li>
+     * </ol>
+     *
+     * @param lhs  left-hand array
+     * @param rhs  right-hand array
+     * @return this - used to chain append calls
+     */
+    public CompareToBuilder append(char[] lhs, char[] rhs) {
+        if (comparison != 0) {
+            return this;
+        }
+        if (lhs == rhs) {
+            return this;
+        }
+        if (lhs == null) {
+            comparison = -1;
+            return this;
+        }
+        if (rhs == null) {
+            comparison = +1;
+            return this;
+        }
+        if (lhs.length != rhs.length) {
+            comparison = (lhs.length < rhs.length) ? -1 : +1;
+            return this;
+        }
+        for (int i = 0; i < lhs.length && comparison == 0; i++) {
+            append(lhs[i], rhs[i]);
+        }
+        return this;
+    }
+
+    /**
+     * <p>Appends to the <code>builder</code> the deep comparison of
+     * two <code>byte</code> arrays.</p>
+     *
+     * <ol>
+     *  <li>Check if arrays are the same using <code>==</code></li>
+     *  <li>Check if for <code>null</code>, <code>null</code> is less than 
non-<code>null</code></li>
+     *  <li>Check array length, a shorter length array is less than a longer 
length array</li>
+     *  <li>Check array contents element by element using {@link #append(byte, 
byte)}</li>
+     * </ol>
+     *
+     * @param lhs  left-hand array
+     * @param rhs  right-hand array
+     * @return this - used to chain append calls
+     */
+    public CompareToBuilder append(byte[] lhs, byte[] rhs) {
+        if (comparison != 0) {
+            return this;
+        }
+        if (lhs == rhs) {
+            return this;
+        }
+        if (lhs == null) {
+            comparison = -1;
+            return this;
+        }
+        if (rhs == null) {
+            comparison = +1;
+            return this;
+        }
+        if (lhs.length != rhs.length) {
+            comparison = (lhs.length < rhs.length) ? -1 : +1;
+            return this;
+        }
+        for (int i = 0; i < lhs.length && comparison == 0; i++) {
+            append(lhs[i], rhs[i]);
+        }
+        return this;
+    }
+
+    /**
+     * <p>Appends to the <code>builder</code> the deep comparison of
+     * two <code>double</code> arrays.</p>
+     *
+     * <ol>
+     *  <li>Check if arrays are the same using <code>==</code></li>
+     *  <li>Check if for <code>null</code>, <code>null</code> is less than 
non-<code>null</code></li>
+     *  <li>Check array length, a shorter length array is less than a longer 
length array</li>
+     *  <li>Check array contents element by element using {@link 
#append(double, double)}</li>
+     * </ol>
+     *
+     * @param lhs  left-hand array
+     * @param rhs  right-hand array
+     * @return this - used to chain append calls
+     */
+    public CompareToBuilder append(double[] lhs, double[] rhs) {
+        if (comparison != 0) {
+            return this;
+        }
+        if (lhs == rhs) {
+            return this;
+        }
+        if (lhs == null) {
+            comparison = -1;
+            return this;
+        }
+        if (rhs == null) {
+            comparison = +1;
+            return this;
+        }
+        if (lhs.length != rhs.length) {
+            comparison = (lhs.length < rhs.length) ? -1 : +1;
+            return this;
+        }
+        for (int i = 0; i < lhs.length && comparison == 0; i++) {
+            append(lhs[i], rhs[i]);
+        }
+        return this;
+    }
+
+    /**
+     * <p>Appends to the <code>builder</code> the deep comparison of
+     * two <code>float</code> arrays.</p>
+     *
+     * <ol>
+     *  <li>Check if arrays are the same using <code>==</code></li>
+     *  <li>Check if for <code>null</code>, <code>null</code> is less than 
non-<code>null</code></li>
+     *  <li>Check array length, a shorter length array is less than a longer 
length array</li>
+     *  <li>Check array contents element by element using {@link 
#append(float, float)}</li>
+     * </ol>
+     *
+     * @param lhs  left-hand array
+     * @param rhs  right-hand array
+     * @return this - used to chain append calls
+     */
+    public CompareToBuilder append(float[] lhs, float[] rhs) {
+        if (comparison != 0) {
+            return this;
+        }
+        if (lhs == rhs) {
+            return this;
+        }
+        if (lhs == null) {
+            comparison = -1;
+            return this;
+        }
+        if (rhs == null) {
+            comparison = +1;
+            return this;
+        }
+        if (lhs.length != rhs.length) {
+            comparison = (lhs.length < rhs.length) ? -1 : +1;
+            return this;
+        }
+        for (int i = 0; i < lhs.length && comparison == 0; i++) {
+            append(lhs[i], rhs[i]);
+        }
+        return this;
+    }
+
+    /**
+     * <p>Appends to the <code>builder</code> the deep comparison of
+     * two <code>boolean</code> arrays.</p>
+     *
+     * <ol>
+     *  <li>Check if arrays are the same using <code>==</code></li>
+     *  <li>Check if for <code>null</code>, <code>null</code> is less than 
non-<code>null</code></li>
+     *  <li>Check array length, a shorter length array is less than a longer 
length array</li>
+     *  <li>Check array contents element by element using {@link 
#append(boolean, boolean)}</li>
+     * </ol>
+     *
+     * @param lhs  left-hand array
+     * @param rhs  right-hand array
+     * @return this - used to chain append calls
+     */
+    public CompareToBuilder append(boolean[] lhs, boolean[] rhs) {
+        if (comparison != 0) {
+            return this;
+        }
+        if (lhs == rhs) {
+            return this;
+        }
+        if (lhs == null) {
+            comparison = -1;
+            return this;
+        }
+        if (rhs == null) {
+            comparison = +1;
+            return this;
+        }
+        if (lhs.length != rhs.length) {
+            comparison = (lhs.length < rhs.length) ? -1 : +1;
+            return this;
+        }
+        for (int i = 0; i < lhs.length && comparison == 0; i++) {
+            append(lhs[i], rhs[i]);
+        }
+        return this;
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Returns a negative integer, a positive integer, or zero as
+     * the <code>builder</code> has judged the "left-hand" side
+     * as less than, greater than, or equal to the "right-hand"
+     * side.
+     *
+     * @return final comparison result
+     */
+    public int toComparison() {
+        return comparison;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/f734851f/cayenne-server/src/main/java/org/apache/cayenne/util/Util.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/util/Util.java 
b/cayenne-server/src/main/java/org/apache/cayenne/util/Util.java
index ff477ff..e2575d9 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/util/Util.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/util/Util.java
@@ -238,6 +238,32 @@ public class Util {
        }
 
        /**
+        * Capitalizes the first letter of the property name.
+        *
+        * @since 4.1
+        */
+       public static String capitalized(String name) {
+               if (name == null || name.length() == 0)
+                       return name;
+
+               char c = Character.toUpperCase(name.charAt(0));
+               return (name.length() == 1) ? Character.toString(c) : c + 
name.substring(1);
+       }
+
+       /**
+        * Returns string with lowercased first letter
+        *
+        * @since 4.2
+        */
+       public static String uncapitalized(String aString) {
+               if (aString == null || aString.length() == 0)
+                       return aString;
+
+               char c = Character.toLowerCase(aString.charAt(0));
+               return (aString.length() == 1) ? Character.toString(c) : c + 
aString.substring(1);
+       }
+
+       /**
         * Creates Serializable object copy using serialization/deserialization.
         */
        @SuppressWarnings("unchecked")

http://git-wip-us.apache.org/repos/asf/cayenne/blob/f734851f/cayenne-server/src/main/java/org/apache/cayenne/util/concurrentlinkedhashmap/ConcurrentLinkedHashMap.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/util/concurrentlinkedhashmap/ConcurrentLinkedHashMap.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/util/concurrentlinkedhashmap/ConcurrentLinkedHashMap.java
index a2f6e51..91f15f2 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/util/concurrentlinkedhashmap/ConcurrentLinkedHashMap.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/util/concurrentlinkedhashmap/ConcurrentLinkedHashMap.java
@@ -169,7 +169,7 @@ public class ConcurrentLinkedHashMap<K, V> extends 
AbstractMap<K, V> implements
         BUFFER_MASK = buffers - 1;
     }
 
-    static final int ceilingNextPowerOfTwo(int x) {
+    static int ceilingNextPowerOfTwo(int x) {
         // From Hacker's Delight, Chapter 3, Harry S. Warren Jr.
         return 1 << (Integer.SIZE - Integer.numberOfLeadingZeros(x - 1));
     }
@@ -228,7 +228,7 @@ public class ConcurrentLinkedHashMap<K, V> extends 
AbstractMap<K, V> implements
         // The data store and its maximum capacity
         concurrencyLevel = builder.concurrencyLevel;
         capacity = Math.min(builder.capacity, MAXIMUM_CAPACITY);
-        data = new ConcurrentHashMap<K, Node>(
+        data = new ConcurrentHashMap<>(
                 builder.initialCapacity,
                 0.75f,
                 concurrencyLevel);
@@ -239,13 +239,13 @@ public class ConcurrentLinkedHashMap<K, V> extends 
AbstractMap<K, V> implements
         nextOrder = Integer.MIN_VALUE;
         drainedOrder = Integer.MIN_VALUE;
         evictionLock = new ReentrantLock();
-        evictionDeque = new LinkedDeque<Node>();
-        drainStatus = new AtomicReference<DrainStatus>(DrainStatus.IDLE);
+        evictionDeque = new LinkedDeque<>();
+        drainStatus = new AtomicReference<>(DrainStatus.IDLE);
 
         buffers = (Queue<Task>[]) new Queue[NUMBER_OF_BUFFERS];
         bufferLengths = new AtomicIntegerArray(NUMBER_OF_BUFFERS);
         for (int i = 0; i < NUMBER_OF_BUFFERS; i++) {
-            buffers[i] = new ConcurrentLinkedQueue<Task>();
+            buffers[i] = new ConcurrentLinkedQueue<>();
         }
 
         // The notification queue and listener
@@ -755,7 +755,7 @@ public class ConcurrentLinkedHashMap<K, V> extends 
AbstractMap<K, V> implements
         checkNotNull(value);
 
         final int weight = weigher.weightOf(value);
-        final WeightedValue<V> weightedValue = new WeightedValue<V>(value, 
weight);
+        final WeightedValue<V> weightedValue = new WeightedValue<>(value, 
weight);
         final Node node = new Node(key, weightedValue);
 
         for (;;) {
@@ -831,7 +831,7 @@ public class ConcurrentLinkedHashMap<K, V> extends 
AbstractMap<K, V> implements
         checkNotNull(value);
 
         final int weight = weigher.weightOf(value);
-        final WeightedValue<V> weightedValue = new WeightedValue<V>(value, 
weight);
+        final WeightedValue<V> weightedValue = new WeightedValue<>(value, 
weight);
 
         final Node node = data.get(key);
         if (node == null) {
@@ -858,7 +858,7 @@ public class ConcurrentLinkedHashMap<K, V> extends 
AbstractMap<K, V> implements
         checkNotNull(newValue);
 
         final int weight = weigher.weightOf(newValue);
-        final WeightedValue<V> newWeightedValue = new 
WeightedValue<V>(newValue, weight);
+        final WeightedValue<V> newWeightedValue = new 
WeightedValue<>(newValue, weight);
 
         final Node node = data.get(key);
         if (node == null) {
@@ -965,7 +965,7 @@ public class ConcurrentLinkedHashMap<K, V> extends 
AbstractMap<K, V> implements
             int initialCapacity = (weigher == Weighers.singleton()) ? Math.min(
                     limit,
                     weightedSize()) : 16;
-            Set<K> keys = new LinkedHashSet<K>(initialCapacity);
+            Set<K> keys = new LinkedHashSet<>(initialCapacity);
             Iterator<Node> iterator = ascending
                     ? evictionDeque.iterator()
                     : evictionDeque.descendingIterator();
@@ -1070,7 +1070,7 @@ public class ConcurrentLinkedHashMap<K, V> extends 
AbstractMap<K, V> implements
             int initialCapacity = (weigher == Weighers.singleton()) ? Math.min(
                     limit,
                     weightedSize()) : 16;
-            Map<K, V> map = new LinkedHashMap<K, V>(initialCapacity);
+            Map<K, V> map = new LinkedHashMap<>(initialCapacity);
             Iterator<Node> iterator = ascending
                     ? evictionDeque.iterator()
                     : evictionDeque.descendingIterator();
@@ -1171,7 +1171,7 @@ public class ConcurrentLinkedHashMap<K, V> extends 
AbstractMap<K, V> implements
          */
         boolean tryToRetire(WeightedValue<V> expect) {
             if (expect.isAlive()) {
-                WeightedValue<V> retired = new WeightedValue<V>(
+                WeightedValue<V> retired = new WeightedValue<>(
                         expect.value,
                         -expect.weight);
                 return compareAndSet(expect, retired);
@@ -1189,7 +1189,7 @@ public class ConcurrentLinkedHashMap<K, V> extends 
AbstractMap<K, V> implements
                 if (!current.isAlive()) {
                     return;
                 }
-                WeightedValue<V> retired = new WeightedValue<V>(
+                WeightedValue<V> retired = new WeightedValue<>(
                         current.value,
                         -current.weight);
                 if (compareAndSet(current, retired)) {
@@ -1205,7 +1205,7 @@ public class ConcurrentLinkedHashMap<K, V> extends 
AbstractMap<K, V> implements
         void makeDead() {
             for (;;) {
                 WeightedValue<V> current = get();
-                WeightedValue<V> dead = new WeightedValue<V>(current.value, 0);
+                WeightedValue<V> dead = new WeightedValue<>(current.value, 0);
                 if (compareAndSet(current, dead)) {
                     weightedSize -= Math.abs(current.weight);
                     return;
@@ -1397,7 +1397,7 @@ public class ConcurrentLinkedHashMap<K, V> extends 
AbstractMap<K, V> implements
     }
 
     /** An entry that allows updates to write through to the map. */
-    final class WriteThroughEntry extends SimpleEntry<K, V> {
+    final class WriteThroughEntry extends AbstractMap.SimpleEntry<K, V> {
 
         static final long serialVersionUID = 1;
 
@@ -1412,7 +1412,7 @@ public class ConcurrentLinkedHashMap<K, V> extends 
AbstractMap<K, V> implements
         }
 
         Object writeReplace() {
-            return new SimpleEntry<K, V>(this);
+            return new AbstractMap.SimpleEntry<>(this);
         }
     }
 
@@ -1574,7 +1574,7 @@ public class ConcurrentLinkedHashMap<K, V> extends 
AbstractMap<K, V> implements
     static final long serialVersionUID = 1;
 
     Object writeReplace() {
-        return new SerializationProxy<K, V>(this);
+        return new SerializationProxy<>(this);
     }
 
     private void readObject(ObjectInputStream stream) throws 
InvalidObjectException {
@@ -1771,7 +1771,7 @@ public class ConcurrentLinkedHashMap<K, V> extends 
AbstractMap<K, V> implements
         public Builder<K, V> weigher(Weigher<? super V> weigher) {
             this.weigher = (weigher == Weighers.singleton())
                     ? Weighers.<V> singleton()
-                    : new BoundedWeigher<V>(weigher);
+                    : new BoundedWeigher<>(weigher);
             return this;
         }
 
@@ -1820,7 +1820,7 @@ public class ConcurrentLinkedHashMap<K, V> extends 
AbstractMap<K, V> implements
             if (capacity < 0) {
                 throw new IllegalStateException();
             }
-            ConcurrentLinkedHashMap<K, V> map = new ConcurrentLinkedHashMap<K, 
V>(this);
+            ConcurrentLinkedHashMap<K, V> map = new 
ConcurrentLinkedHashMap<>(this);
             if (executor != DEFAULT_EXECUTOR) {
                 ScheduledExecutorService es = (ScheduledExecutorService) 
executor;
                 es.scheduleWithFixedDelay(new CatchUpTask(map), delay, delay, 
unit);
@@ -1828,54 +1828,4 @@ public class ConcurrentLinkedHashMap<K, V> extends 
AbstractMap<K, V> implements
             return map;
         }
     }
-
-    // a class similar to AbstractMap.SimpleEntry. Needed for JDK 5 
compatibility. Java 6
-    // exposes it to external users.
-    static class SimpleEntry<K, V> implements Entry<K, V> {
-
-        K key;
-        V value;
-
-        public SimpleEntry(K key, V value) {
-            this.key = key;
-            this.value = value;
-        }
-
-        public SimpleEntry(Entry<K, V> e) {
-            this.key = e.getKey();
-            this.value = e.getValue();
-        }
-
-        public K getKey() {
-            return key;
-        }
-
-        public V getValue() {
-            return value;
-        }
-
-        public V setValue(V value) {
-            V oldValue = this.value;
-            this.value = value;
-            return oldValue;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (!(o instanceof Entry))
-                return false;
-            Entry e = (Entry) o;
-            return eq(key, e.getKey()) && eq(value, e.getValue());
-        }
-
-        @Override
-        public int hashCode() {
-            return ((key == null) ? 0 : key.hashCode())
-                    ^ ((value == null) ? 0 : value.hashCode());
-        }
-
-        private static boolean eq(Object o1, Object o2) {
-            return (o1 == null ? o2 == null : o1.equals(o2));
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/f734851f/cayenne-server/src/main/java/org/apache/cayenne/velocity/BindDirective.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/velocity/BindDirective.java 
b/cayenne-server/src/main/java/org/apache/cayenne/velocity/BindDirective.java
deleted file mode 100644
index 94080d6..0000000
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/velocity/BindDirective.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*****************************************************************
- *   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.velocity;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Collection;
-import java.util.Iterator;
-
-import org.apache.cayenne.access.translator.ParameterBinding;
-import org.apache.cayenne.dba.TypesMapping;
-import org.apache.cayenne.util.ConversionUtil;
-import org.apache.velocity.context.InternalContextAdapter;
-import org.apache.velocity.exception.MethodInvocationException;
-import org.apache.velocity.exception.ParseErrorException;
-import org.apache.velocity.exception.ResourceNotFoundException;
-import org.apache.velocity.runtime.directive.Directive;
-import org.apache.velocity.runtime.parser.node.Node;
-
-/**
- * A custom Velocity directive to create a PreparedStatement parameter text.
- * There are the following possible invocation formats inside the template:
- * 
- * <pre>
- * #bind(value) - e.g. #bind($xyz)
- * #bind(value jdbc_type_name) - e.g. #bind($xyz 'VARCHAR'). This is the most 
common and useful form.
- * #bind(value jdbc_type_name, scale) - e.g. #bind($xyz 'VARCHAR' 2)
- * </pre>
- * <p>
- * Other examples:
- * </p>
- * <p>
- * <strong>Binding literal parameter value:</strong>
- * </p>
- * <p>
- * <code>"WHERE SOME_COLUMN &gt; #bind($xyz)"</code> produces
- * <code>"WHERE SOME_COLUMN &gt; ?"</code> and also places the value of the
- * "xyz" parameter in the context "bindings" collection.
- * </p>
- * <p>
- * <strong>Binding ID column of a DataObject value:</strong>
- * </p>
- * <p>
- * <code>"WHERE ID_COL1 = #bind($helper.cayenneExp($xyz, 'db:ID_COL2')) 
- * AND ID_COL2 = #bind($helper.cayenneExp($xyz, 'db:ID_COL2'))"</code> produces
- * <code>"WHERE ID_COL1 = ? AND ID_COL2 = ?"</code> and also places the values
- * of id columns of the DataObject parameter "xyz" in the context "bindings"
- * collection.
- * </p>
- * 
- * @since 1.1
- */
-public class BindDirective extends Directive {
-
-       @Override
-       public String getName() {
-               return "bind";
-       }
-
-       @Override
-       public int getType() {
-               return LINE;
-       }
-
-       /**
-        * Extracts the value of the object property to render and passes 
control to
-        * {@link #render(InternalContextAdapter, Writer, ParameterBinding)} to 
do
-        * the actual rendering.
-        */
-       @Override
-       public boolean render(InternalContextAdapter context, Writer writer, 
Node node) throws IOException,
-                       ResourceNotFoundException, ParseErrorException, 
MethodInvocationException {
-
-               Object value = getChild(context, node, 0);
-               Object type = getChild(context, node, 1);
-               int scale = ConversionUtil.toInt(getChild(context, node, 2), 
-1);
-               String typeString = type != null ? type.toString() : null;
-
-               if (value instanceof Collection) {
-                       Iterator<?> it = ((Collection) value).iterator();
-                       while (it.hasNext()) {
-                               render(context, writer, node, it.next(), 
typeString, scale);
-
-                               if (it.hasNext()) {
-                                       writer.write(',');
-                               }
-                       }
-               } else {
-                       render(context, writer, node, value, typeString, scale);
-               }
-
-               return true;
-       }
-
-       /**
-        * @since 3.0
-        */
-       protected void render(InternalContextAdapter context, Writer writer, 
Node node, Object value, String typeString,
-                       int scale) throws IOException, ParseErrorException {
-
-               int jdbcType = TypesMapping.NOT_DEFINED;
-               if (typeString != null) {
-                       jdbcType = TypesMapping.getSqlTypeByName(typeString);
-               } else if (value != null) {
-                       jdbcType = 
TypesMapping.getSqlTypeByJava(value.getClass());
-               } else {
-                       // value is null, set JDBC type to NULL
-                       jdbcType = 
TypesMapping.getSqlTypeByName(TypesMapping.SQL_NULL);
-               }
-
-               if (jdbcType == TypesMapping.NOT_DEFINED) {
-                       throw new ParseErrorException("Can't determine JDBC 
type of binding (" + value + ", " + typeString
-                                       + ") at line " + node.getLine() + ", 
column " + node.getColumn());
-               }
-
-               render(context, writer, new ParameterBinding(value, jdbcType, 
scale));
-       }
-
-       protected void render(InternalContextAdapter context, Writer writer, 
ParameterBinding binding) throws IOException {
-
-               bind(context, binding);
-               writer.write('?');
-       }
-
-       protected Object getChild(InternalContextAdapter context, Node node, 
int i) throws MethodInvocationException {
-               return (i >= 0 && i < node.jjtGetNumChildren()) ? 
node.jjtGetChild(i).value(context) : null;
-       }
-
-       /**
-        * Adds value to the list of bindings in the context.
-        */
-       protected void bind(InternalContextAdapter context, ParameterBinding 
binding) {
-
-               Collection bindings = (Collection) 
context.getInternalUserContext().get(
-                               VelocitySQLTemplateProcessor.BINDINGS_LIST_KEY);
-
-               if (bindings != null) {
-                       bindings.add(binding);
-               }
-       }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/f734851f/cayenne-server/src/main/java/org/apache/cayenne/velocity/BindEqualDirective.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/velocity/BindEqualDirective.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/velocity/BindEqualDirective.java
deleted file mode 100644
index bf9c820..0000000
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/velocity/BindEqualDirective.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*****************************************************************
- *   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.velocity;
-
-import java.io.IOException;
-import java.io.Writer;
-
-import org.apache.cayenne.access.translator.ParameterBinding;
-import org.apache.velocity.context.InternalContextAdapter;
-
-/**
- * A custom Velocity directive to create a PreparedStatement parameter text
- * for "= ?". If null value is encountered, generated text will look like "IS 
NULL".
- * Usage in Velocity template is "WHERE SOME_COLUMN #bindEqual($xyz)".
- * 
- * @since 1.1
- */
-public class BindEqualDirective extends BindDirective {
-
-    @Override
-    public String getName() {
-        return "bindEqual";
-    }
-
-    @Override
-    protected void render(
-        InternalContextAdapter context,
-        Writer writer,
-        ParameterBinding binding)
-        throws IOException {
-
-        if (binding.getValue() != null) {
-            bind(context, binding);
-            writer.write("= ?");
-        }
-        else {
-            writer.write("IS NULL");
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/f734851f/cayenne-server/src/main/java/org/apache/cayenne/velocity/BindNotEqualDirective.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/velocity/BindNotEqualDirective.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/velocity/BindNotEqualDirective.java
deleted file mode 100644
index af548da..0000000
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/velocity/BindNotEqualDirective.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*****************************************************************
- *   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.velocity;
-
-import java.io.IOException;
-import java.io.Writer;
-
-import org.apache.cayenne.access.translator.ParameterBinding;
-import org.apache.velocity.context.InternalContextAdapter;
-
-/**
- * A custom Velocity directive to create a PreparedStatement parameter text 
for "&lt;&gt;?".
- * If null value is encountered, generated text will look like "IS NOT NULL". 
Usage in
- * Velocity template is "WHERE SOME_COLUMN #bindNotEqual($xyz)".
- * 
- * @since 1.1
- */
-public class BindNotEqualDirective extends BindDirective {
-
-    @Override
-    public String getName() {
-        return "bindNotEqual";
-    }
-
-    @Override
-    protected void render(
-            InternalContextAdapter context,
-            Writer writer,
-            ParameterBinding binding) throws IOException {
-
-        if (binding.getValue() != null) {
-            bind(context, binding);
-            writer.write("<> ?");
-        }
-        else {
-            writer.write("IS NOT NULL");
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/f734851f/cayenne-server/src/main/java/org/apache/cayenne/velocity/BindObjectEqualDirective.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/velocity/BindObjectEqualDirective.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/velocity/BindObjectEqualDirective.java
deleted file mode 100644
index 8394673..0000000
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/velocity/BindObjectEqualDirective.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*****************************************************************
- *   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.velocity;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.sql.Types;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Map;
-
-import org.apache.cayenne.ObjectId;
-import org.apache.cayenne.Persistent;
-import org.apache.cayenne.access.translator.ParameterBinding;
-import org.apache.cayenne.dba.TypesMapping;
-import org.apache.velocity.context.InternalContextAdapter;
-import org.apache.velocity.exception.MethodInvocationException;
-import org.apache.velocity.exception.ParseErrorException;
-import org.apache.velocity.exception.ResourceNotFoundException;
-import org.apache.velocity.runtime.parser.node.Node;
-
-/**
- * A custom Velocity directive to create a set of SQL conditions to match an 
ObjectId of
- * an object. Usage in Velocity template is "WHERE #bindObjectEqual($object)" 
or "WHERE
- * #bindObjectEqual($object $columns $idValues)".
- * 
- * @since 3.0
- */
-public class BindObjectEqualDirective extends BindDirective {
-
-    @Override
-    public String getName() {
-        return "bindObjectEqual";
-    }
-
-    @Override
-    public boolean render(InternalContextAdapter context, Writer writer, Node 
node)
-            throws IOException, ResourceNotFoundException, ParseErrorException,
-            MethodInvocationException {
-
-        Object object = getChild(context, node, 0);
-        Map idMap = toIdMap(object);
-
-        Object sqlColumns = getChild(context, node, 1);
-        Object idColumns = getChild(context, node, 2);
-
-        if (idMap == null) {
-            // assume null object, and bind all null values
-
-            if (sqlColumns == null || idColumns == null) {
-                throw new ParseErrorException("Invalid parameters. "
-                        + "Either object has to be set "
-                        + "or sqlColumns and idColumns or both.");
-            }
-
-            idMap = Collections.EMPTY_MAP;
-        }
-        else if (sqlColumns == null || idColumns == null) {
-            // infer SQL columns from ID columns
-            sqlColumns = idMap.keySet().toArray();
-            idColumns = sqlColumns;
-        }
-
-        Object[] sqlColumnsArray = toArray(sqlColumns);
-        Object[] idColumnsArray = toArray(idColumns);
-
-        if (sqlColumnsArray.length != idColumnsArray.length) {
-            throw new ParseErrorException(
-                    "SQL columns and ID columns arrays have different sizes.");
-        }
-
-        for (int i = 0; i < sqlColumnsArray.length; i++) {
-
-            Object value = idMap.get(idColumnsArray[i]);
-
-            int jdbcType = (value != null) ? 
TypesMapping.getSqlTypeByJava(value
-                    .getClass()) : Types.INTEGER;
-
-            renderColumn(context, writer, sqlColumnsArray[i], i);
-            writer.write(' ');
-            render(context, writer, new ParameterBinding(value, jdbcType, -1));
-        }
-
-        return true;
-    }
-
-    protected Object[] toArray(Object columns) {
-        if (columns instanceof Collection) {
-            return ((Collection) columns).toArray();
-        }
-        else if (columns.getClass().isArray()) {
-            return (Object[]) columns;
-        }
-        else {
-            return new Object[] {
-                columns
-            };
-        }
-    }
-
-    protected Map toIdMap(Object object) throws ParseErrorException {
-        if (object instanceof Persistent) {
-            return ((Persistent) object).getObjectId().getIdSnapshot();
-        }
-        else if (object instanceof ObjectId) {
-            return ((ObjectId) object).getIdSnapshot();
-        }
-        else if(object instanceof Map) {
-            return (Map) object;
-        }
-        else if (object != null) {
-            throw new ParseErrorException(
-                    "Invalid object parameter, expected Persistent or ObjectId 
or null: "
-                            + object);
-        }
-        else {
-            return null;
-        }
-    }
-
-    protected void renderColumn(
-            InternalContextAdapter context,
-            Writer writer,
-            Object columnName,
-            int columnIndex) throws IOException {
-
-        if (columnIndex > 0) {
-            writer.write(" AND ");
-        }
-
-        writer.write(columnName.toString());
-    }
-
-    @Override
-    protected void render(
-            InternalContextAdapter context,
-            Writer writer,
-            ParameterBinding binding) throws IOException {
-
-        if (binding.getValue() != null) {
-            bind(context, binding);
-            writer.write("= ?");
-        }
-        else {
-            writer.write("IS NULL");
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/f734851f/cayenne-server/src/main/java/org/apache/cayenne/velocity/BindObjectNotEqualDirective.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/velocity/BindObjectNotEqualDirective.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/velocity/BindObjectNotEqualDirective.java
deleted file mode 100644
index 6c95852..0000000
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/velocity/BindObjectNotEqualDirective.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*****************************************************************
- *   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.velocity;
-
-import java.io.IOException;
-import java.io.Writer;
-
-import org.apache.cayenne.access.translator.ParameterBinding;
-import org.apache.velocity.context.InternalContextAdapter;
-
-/**
- * A custom Velocity directive to create a set of SQL conditions to check 
unequality of an
- * ObjectId of an object. Usage in Velocity template is "WHERE
- * #bindObjectNotEqual($object)" or "WHERE #bindObjectNotEqual($object $columns
- * $idValues)".
- * 
- * @since 3.0
- */
-public class BindObjectNotEqualDirective extends BindObjectEqualDirective {
-
-    @Override
-    public String getName() {
-        return "bindObjectNotEqual";
-    }
-
-    @Override
-    protected void renderColumn(
-            InternalContextAdapter context,
-            Writer writer,
-            Object columnName,
-            int columnIndex) throws IOException {
-
-        if (columnIndex > 0) {
-            writer.write(" OR ");
-        }
-
-        writer.write(columnName.toString());
-    }
-
-    @Override
-    protected void render(
-            InternalContextAdapter context,
-            Writer writer,
-            ParameterBinding binding) throws IOException {
-
-        if (binding.getValue() != null) {
-            bind(context, binding);
-            writer.write("<> ?");
-        }
-        else {
-            writer.write("IS NOT NULL");
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/f734851f/cayenne-server/src/main/java/org/apache/cayenne/velocity/ChainDirective.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/velocity/ChainDirective.java 
b/cayenne-server/src/main/java/org/apache/cayenne/velocity/ChainDirective.java
deleted file mode 100644
index acd0f8c..0000000
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/velocity/ChainDirective.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*****************************************************************
- *   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.velocity;
-
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.Writer;
-
-import org.apache.velocity.context.InternalContextAdapter;
-import org.apache.velocity.exception.MethodInvocationException;
-import org.apache.velocity.exception.ParseErrorException;
-import org.apache.velocity.exception.ResourceNotFoundException;
-import org.apache.velocity.runtime.directive.Directive;
-import org.apache.velocity.runtime.parser.node.ASTDirective;
-import org.apache.velocity.runtime.parser.node.Node;
-
-/**
- * A custom Velocity directive to conditionally join a number of {@link 
ChunkDirective chunks}.
- * Usage of chain is the following:
- * 
- * <pre>
- * #chain(operator) - e.g. #chain(' AND ')
- * #chain(operator prefix) - e.g. #chain(' AND ' 'WHERE ')</pre>
- * 
- * <p><code>operator</code> (e.g. AND, OR, etc.) is used to join chunks that 
are included
- * in a chain. <code>prefix</code> is inserted if a chain contains at least 
one chunk.
- * </p>
- * 
- * @since 1.1
- */
-public class ChainDirective extends Directive {
-
-    @Override
-    public String getName() {
-        return "chain";
-    }
-
-    @Override
-    public int getType() {
-        return BLOCK;
-    }
-
-    @Override
-    public boolean render(InternalContextAdapter context, Writer writer, Node 
node)
-        throws
-            IOException,
-            ResourceNotFoundException,
-            ParseErrorException,
-            MethodInvocationException {
-
-        int size = node.jjtGetNumChildren();
-        if (size == 0) {
-            return true;
-        }
-
-        // BLOCK is the last child
-        Node block = node.jjtGetChild(node.jjtGetNumChildren() - 1);
-        String join = (size > 1) ? (String) node.jjtGetChild(0).value(context) 
: "";
-        String prefix = (size > 2) ? (String) 
node.jjtGetChild(1).value(context) : "";
-
-        // if there is a conditional prefix, use a separate buffer for children
-        StringWriter childWriter = new StringWriter(30);
-
-        int len = block.jjtGetNumChildren();
-        int includedChunks = 0;
-        for (int i = 0; i < len; i++) {
-            Node child = block.jjtGetChild(i);
-
-            // if this is a "chunk", evaluate its expression and prepend join 
if included...
-            if (child instanceof ASTDirective
-                && "chunk".equals(((ASTDirective) child).getDirectiveName())) {
-
-                if (child.jjtGetNumChildren() < 2
-                    || child.jjtGetChild(0).value(context) != null) {
-
-                    if (includedChunks > 0) {
-                        childWriter.write(join);
-                    }
-
-                    includedChunks++;
-                }
-            }
-
-            child.render(context, childWriter);
-        }
-
-        if (includedChunks > 0) {
-            childWriter.flush();
-            writer.write(prefix);
-            writer.write(childWriter.toString());
-        }
-
-        return true;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/f734851f/cayenne-server/src/main/java/org/apache/cayenne/velocity/ChunkDirective.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/velocity/ChunkDirective.java 
b/cayenne-server/src/main/java/org/apache/cayenne/velocity/ChunkDirective.java
deleted file mode 100644
index 5ff0a5e..0000000
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/velocity/ChunkDirective.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*****************************************************************
- *   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.velocity;
-
-import java.io.IOException;
-import java.io.Writer;
-
-import org.apache.velocity.context.InternalContextAdapter;
-import org.apache.velocity.exception.MethodInvocationException;
-import org.apache.velocity.exception.ParseErrorException;
-import org.apache.velocity.exception.ResourceNotFoundException;
-import org.apache.velocity.runtime.directive.Directive;
-import org.apache.velocity.runtime.parser.node.Node;
-
-/**
- * A custom Velocity directive to describe a conditional chunk of a {@link 
ChainDirective chain}.
- * Usage of chunk is the following:
- * 
- * <pre>
- * #chunk()...#end - e.g. #chunk()A = 5#end
- * #chunk($paramKey)...#end - e.g. #chunk($a)A = $a#end
- * </pre>
- * <p>
- * If context contains paramKey and it's value isn't null, chunk is included 
in the
- * chain, and if it is not the first chunk, it is prefixed with chain join 
(OR/AND).
- * If context doesn't contain paramKey or it's value is null, chunk is skipped.
- * @since 1.1
- */
-public class ChunkDirective extends Directive {
-
-    @Override
-    public String getName() {
-        return "chunk";
-    }
-
-    @Override
-    public int getType() {
-        return BLOCK;
-    }
-
-    @Override
-    public boolean render(InternalContextAdapter context, Writer writer, Node 
node)
-            throws IOException, ResourceNotFoundException, ParseErrorException,
-            MethodInvocationException {
-
-        // first child is an expression, second is BLOCK
-        if (node.jjtGetNumChildren() > 1 && node.jjtGetChild(0).value(context) 
== null) {
-            // skip this chunk
-            return false;
-        }
-
-        // BLOCK is the last child
-        Node block = node.jjtGetChild(node.jjtGetNumChildren() - 1);
-        block.render(context, writer);
-        return true;
-    }
-
-}

Reply via email to