You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2010/05/26 02:40:52 UTC

svn commit: r948278 - in /tapestry/tapestry5/trunk: tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/func/ ...

Author: hlship
Date: Wed May 26 00:40:51 2010
New Revision: 948278

URL: http://svn.apache.org/viewvc?rev=948278&view=rev
Log:
Add new methods to Predicate and introduce AbstractPredicate

Added:
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/func/AbstractPredicate.java   (with props)
Modified:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ApplicationStateWorker.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/OnEventWorker.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PageLifecycleAnnotationWorker.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PageResetAnnotationWorker.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ParameterWorker.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorker.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/func/AbstractWorker.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/func/F.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/func/Predicate.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/func/Worker.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/InternalUtilsTest.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/util/func/FuncTest.java

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java?rev=948278&r1=948277&r2=948278&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java Wed May 26 00:40:51 2010
@@ -40,6 +40,7 @@ import org.apache.tapestry5.ioc.services
 import org.apache.tapestry5.ioc.services.FieldValueConduit;
 import org.apache.tapestry5.ioc.services.MethodSignature;
 import org.apache.tapestry5.ioc.util.BodyBuilder;
+import org.apache.tapestry5.ioc.util.func.AbstractPredicate;
 import org.apache.tapestry5.ioc.util.func.Predicate;
 import org.apache.tapestry5.model.ComponentModel;
 import org.apache.tapestry5.model.MutableComponentModel;
@@ -1471,7 +1472,7 @@ public final class InternalClassTransfor
 
         failIfFrozen();
 
-        List<TransformField> fields = matchFields(new Predicate<TransformField>()
+        List<TransformField> fields = matchFields(new AbstractPredicate<TransformField>()
         {
             public boolean accept(TransformField object)
             {
@@ -1491,7 +1492,7 @@ public final class InternalClassTransfor
 
     public List<TransformField> matchFieldsWithAnnotation(final Class<? extends Annotation> annotationClass)
     {
-        return matchFields(new Predicate<TransformField>()
+        return matchFields(new AbstractPredicate<TransformField>()
         {
             public boolean accept(TransformField field)
             {
@@ -1502,7 +1503,7 @@ public final class InternalClassTransfor
 
     public List<TransformMethodSignature> findMethodsWithAnnotation(final Class<? extends Annotation> annotationClass)
     {
-        List<TransformMethod> methods = matchMethods(new Predicate<TransformMethod>()
+        List<TransformMethod> methods = matchMethods(new AbstractPredicate<TransformMethod>()
         {
             public boolean accept(TransformMethod method)
             {
@@ -1517,7 +1518,7 @@ public final class InternalClassTransfor
     {
         Defense.notNull(filter, "filter");
 
-        List<TransformMethod> methods = matchMethods(new Predicate<TransformMethod>()
+        List<TransformMethod> methods = matchMethods(new AbstractPredicate<TransformMethod>()
         {
             public boolean accept(TransformMethod object)
             {
@@ -1537,7 +1538,7 @@ public final class InternalClassTransfor
 
     public List<TransformMethod> matchMethodsWithAnnotation(final Class<? extends Annotation> annotationType)
     {
-        return matchMethods(new Predicate<TransformMethod>()
+        return matchMethods(new AbstractPredicate<TransformMethod>()
         {
             public boolean accept(TransformMethod method)
             {
@@ -1579,7 +1580,7 @@ public final class InternalClassTransfor
 
     public List<TransformField> matchUnclaimedFields()
     {
-        return matchFields(new Predicate<TransformField>()
+        return matchFields(new AbstractPredicate<TransformField>()
         {
             public boolean accept(TransformField object)
             {

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ApplicationStateWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ApplicationStateWorker.java?rev=948278&r1=948277&r2=948278&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ApplicationStateWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ApplicationStateWorker.java Wed May 26 00:40:51 2010
@@ -22,7 +22,7 @@ import org.apache.tapestry5.annotations.
 import org.apache.tapestry5.annotations.SessionState;
 import org.apache.tapestry5.internal.services.ComponentClassCache;
 import org.apache.tapestry5.ioc.services.FieldValueConduit;
-import org.apache.tapestry5.ioc.util.func.Predicate;
+import org.apache.tapestry5.ioc.util.func.AbstractPredicate;
 import org.apache.tapestry5.model.MutableComponentModel;
 import org.apache.tapestry5.services.ApplicationStateManager;
 import org.apache.tapestry5.services.ClassTransformation;
@@ -50,8 +50,7 @@ public class ApplicationStateWorker impl
     {
         Map<TransformField, Boolean> fields = new TreeMap<TransformField, Boolean>();
 
-        for (TransformField field : transformation
-                .matchFieldsWithAnnotation(ApplicationState.class))
+        for (TransformField field : transformation.matchFieldsWithAnnotation(ApplicationState.class))
         {
             ApplicationState annotation = field.getAnnotation(ApplicationState.class);
 
@@ -76,8 +75,7 @@ public class ApplicationStateWorker impl
     }
 
     @SuppressWarnings("unchecked")
-    private void transform(ClassTransformation transformation, TransformField field,
-            final boolean create)
+    private void transform(ClassTransformation transformation, TransformField field, final boolean create)
     {
         final Class fieldClass = componentClassCache.forName(field.getType());
 
@@ -97,12 +95,11 @@ public class ApplicationStateWorker impl
 
         final String expectedName = field.getName() + "Exists";
 
-        List<TransformField> fields = transformation.matchFields(new Predicate<TransformField>()
+        List<TransformField> fields = transformation.matchFields(new AbstractPredicate<TransformField>()
         {
             public boolean accept(TransformField field)
             {
-                return field.getType().equals("boolean")
-                        && field.getName().equalsIgnoreCase(expectedName);
+                return field.getType().equals("boolean") && field.getName().equalsIgnoreCase(expectedName);
             }
         });
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/OnEventWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/OnEventWorker.java?rev=948278&r1=948277&r2=948278&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/OnEventWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/OnEventWorker.java Wed May 26 00:40:51 2010
@@ -25,7 +25,7 @@ import org.apache.tapestry5.annotations.
 import org.apache.tapestry5.internal.services.ComponentClassCache;
 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
 import org.apache.tapestry5.ioc.internal.util.InternalUtils;
-import org.apache.tapestry5.ioc.util.func.Predicate;
+import org.apache.tapestry5.ioc.util.func.AbstractPredicate;
 import org.apache.tapestry5.model.MutableComponentModel;
 import org.apache.tapestry5.runtime.ComponentEvent;
 import org.apache.tapestry5.services.ClassTransformation;
@@ -177,7 +177,7 @@ public class OnEventWorker implements Co
 
     private List<TransformMethod> matchEventHandlerMethods(ClassTransformation transformation)
     {
-        return transformation.matchMethods(new Predicate<TransformMethod>()
+        return transformation.matchMethods(new AbstractPredicate<TransformMethod>()
         {
             public boolean accept(TransformMethod method)
             {

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PageLifecycleAnnotationWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PageLifecycleAnnotationWorker.java?rev=948278&r1=948277&r2=948278&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PageLifecycleAnnotationWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PageLifecycleAnnotationWorker.java Wed May 26 00:40:51 2010
@@ -17,7 +17,7 @@ package org.apache.tapestry5.internal.tr
 import java.lang.annotation.Annotation;
 import java.util.List;
 
-import org.apache.tapestry5.ioc.util.func.Predicate;
+import org.apache.tapestry5.ioc.util.func.AbstractPredicate;
 import org.apache.tapestry5.model.MutableComponentModel;
 import org.apache.tapestry5.services.ClassTransformation;
 import org.apache.tapestry5.services.ComponentClassTransformWorker;
@@ -97,7 +97,7 @@ public class PageLifecycleAnnotationWork
 
     private List<TransformMethod> matchLifecycleMethods(final ClassTransformation transformation)
     {
-        return transformation.matchMethods(new Predicate<TransformMethod>()
+        return transformation.matchMethods(new AbstractPredicate<TransformMethod>()
         {
 
             public boolean accept(TransformMethod method)

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PageResetAnnotationWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PageResetAnnotationWorker.java?rev=948278&r1=948277&r2=948278&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PageResetAnnotationWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PageResetAnnotationWorker.java Wed May 26 00:40:51 2010
@@ -20,7 +20,7 @@ import org.apache.tapestry5.annotations.
 import org.apache.tapestry5.internal.InternalComponentResources;
 import org.apache.tapestry5.internal.structure.PageResetListener;
 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
-import org.apache.tapestry5.ioc.util.func.Predicate;
+import org.apache.tapestry5.ioc.util.func.AbstractPredicate;
 import org.apache.tapestry5.model.MutableComponentModel;
 import org.apache.tapestry5.services.ClassTransformation;
 import org.apache.tapestry5.services.ComponentClassTransformWorker;
@@ -132,9 +132,8 @@ public class PageResetAnnotationWorker i
 
     private List<TransformMethod> matchPageResetMethods(final ClassTransformation transformation)
     {
-        return transformation.matchMethods(new Predicate<TransformMethod>()
+        return transformation.matchMethods(new AbstractPredicate<TransformMethod>()
         {
-
             public boolean accept(TransformMethod method)
             {
                 return method.getName().equalsIgnoreCase("pageReset") || method.getAnnotation(PageReset.class) != null;

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ParameterWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ParameterWorker.java?rev=948278&r1=948277&r2=948278&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ParameterWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ParameterWorker.java Wed May 26 00:40:51 2010
@@ -25,6 +25,7 @@ import org.apache.tapestry5.internal.ser
 import org.apache.tapestry5.ioc.internal.util.InternalUtils;
 import org.apache.tapestry5.ioc.internal.util.TapestryException;
 import org.apache.tapestry5.ioc.services.TypeCoercer;
+import org.apache.tapestry5.ioc.util.func.AbstractPredicate;
 import org.apache.tapestry5.ioc.util.func.Predicate;
 import org.apache.tapestry5.model.MutableComponentModel;
 import org.apache.tapestry5.services.*;
@@ -133,7 +134,7 @@ public class ParameterWorker implements 
 
     private List<TransformField> matchParameterFields(ClassTransformation transformation, final boolean principal)
     {
-        Predicate<TransformField> predicate = new Predicate<TransformField>()
+        Predicate<TransformField> predicate = new AbstractPredicate<TransformField>()
         {
             public boolean accept(TransformField field)
             {
@@ -437,7 +438,7 @@ public class ParameterWorker implements 
     {
         final String methodName = "default" + parameterName;
 
-        Predicate<TransformMethod> predicate = new Predicate<TransformMethod>()
+        Predicate<TransformMethod> predicate = new AbstractPredicate<TransformMethod>()
         {
             public boolean accept(TransformMethod method)
             {

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorker.java?rev=948278&r1=948277&r2=948278&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorker.java Wed May 26 00:40:51 2010
@@ -32,7 +32,7 @@ import org.apache.tapestry5.annotations.
 import org.apache.tapestry5.annotations.SetupRender;
 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
 import org.apache.tapestry5.ioc.internal.util.InternalUtils;
-import org.apache.tapestry5.ioc.util.func.Predicate;
+import org.apache.tapestry5.ioc.util.func.AbstractPredicate;
 import org.apache.tapestry5.model.MutableComponentModel;
 import org.apache.tapestry5.runtime.Event;
 import org.apache.tapestry5.services.ClassTransformation;
@@ -263,7 +263,7 @@ public class RenderPhaseMethodWorker imp
 
     private List<TransformMethod> matchAllMethodsNotOverriddenFromBaseClass(final ClassTransformation transformation)
     {
-        return transformation.matchMethods(new Predicate<TransformMethod>()
+        return transformation.matchMethods(new AbstractPredicate<TransformMethod>()
         {
             public boolean accept(TransformMethod method)
             {

Added: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/func/AbstractPredicate.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/func/AbstractPredicate.java?rev=948278&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/func/AbstractPredicate.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/func/AbstractPredicate.java Wed May 26 00:40:51 2010
@@ -0,0 +1,64 @@
+// Copyright 2010 The Apache Software Foundation
+//
+// Licensed 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.tapestry5.ioc.util.func;
+
+import org.apache.tapestry5.ioc.internal.util.Defense;
+
+public abstract class AbstractPredicate<T> implements Predicate<T>
+{
+    public Predicate<T> and(final Predicate<? super T> other)
+    {
+        Defense.notNull(other, "other");
+
+        final Predicate<T> left = this;
+
+        return new AbstractPredicate<T>()
+        {
+            public boolean accept(T object)
+            {
+                return left.accept(object) && other.accept(object);
+            };
+        };
+    }
+
+    public Predicate<T> or(final Predicate<? super T> other)
+    {
+        Defense.notNull(other, "other");
+
+        final Predicate<T> left = this;
+
+        return new AbstractPredicate<T>()
+        {
+            public boolean accept(T object)
+            {
+                return left.accept(object) || other.accept(object);
+            };
+        };
+    }
+
+    public Predicate<T> invert()
+    {
+        final Predicate<T> normal = this;
+
+        return new AbstractPredicate<T>()
+        {
+            public boolean accept(T object)
+            {
+                return !normal.accept(object);
+            };
+        };
+    }
+
+}

Propchange: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/func/AbstractPredicate.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/func/AbstractWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/func/AbstractWorker.java?rev=948278&r1=948277&r2=948278&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/func/AbstractWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/func/AbstractWorker.java Wed May 26 00:40:51 2010
@@ -16,7 +16,7 @@ package org.apache.tapestry5.ioc.util.fu
 
 public abstract class AbstractWorker<T> implements Worker<T>
 {
-    public Worker<T> combine(final Worker<T> other)
+    public Worker<T> combine(final Worker<? super T> other)
     {
         final Worker<T> first = this;
 

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/func/F.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/func/F.java?rev=948278&r1=948277&r2=948278&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/func/F.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/func/F.java Wed May 26 00:40:51 2010
@@ -119,60 +119,20 @@ public class F
         return result;
     }
 
-    /** Inverts a predicate, returning a new predicate. */
-    public static <T> Predicate<T> invert(final Predicate<T> predicate)
-    {
-        Defense.notNull(predicate, "predicate");
-
-        return new Predicate<T>()
-        {
-            public boolean accept(T value)
-            {
-                return !predicate.accept(value);
-            }
-        };
-    }
-
     /**
      * Returns a new list containing only those values of the source list for which the predicate
      * evaluates to false.
      */
     public static <T> List<T> remove(Predicate<? super T> predicate, List<T> source)
     {
-        return filter(invert(predicate), source);
-    }
-
-    public static <T> Predicate<T> and(final Predicate<? super T> left, final Predicate<? super T> right)
-    {
-        Defense.notNull(left, "left");
-        Defense.notNull(right, "right");
-
-        return new Predicate<T>()
-        {
-            public boolean accept(T object)
-            {
-                return left.accept(object) && right.accept(object);
-            };
-        };
-    }
-
-    public static <T> Predicate<T> or(final Predicate<? super T> left, final Predicate<? super T> right)
-    {
-        Defense.notNull(left, "left");
-        Defense.notNull(right, "right");
+        Defense.notNull(predicate, "predicate");
 
-        return new Predicate<T>()
-        {
-            public boolean accept(T object)
-            {
-                return left.accept(object) || right.accept(object);
-            };
-        };
+        return filter(predicate.invert(), source);
     }
 
     public static Predicate<Number> eq(final long value)
     {
-        return new Predicate<Number>()
+        return new AbstractPredicate<Number>()
         {
             public boolean accept(Number object)
             {
@@ -183,12 +143,12 @@ public class F
 
     public static Predicate<Number> neq(long value)
     {
-        return invert(eq(value));
+        return eq(value).invert();
     }
 
     public static Predicate<Number> gt(final long value)
     {
-        return new Predicate<Number>()
+        return new AbstractPredicate<Number>()
         {
             public boolean accept(Number object)
             {
@@ -199,22 +159,22 @@ public class F
 
     public static Predicate<Number> gteq(long value)
     {
-        return or(eq(value), gt(value));
+        return eq(value).or(gt(value));
     }
 
     public static Predicate<Number> lt(long value)
     {
-        return invert(gteq(value));
+        return gteq(value).invert();
     }
 
     public static Predicate<Number> lteq(long value)
     {
-        return invert(gt(value));
+        return gt(value).invert();
     }
 
     public static <T> Predicate<T> isNull()
     {
-        return new Predicate<T>()
+        return new AbstractPredicate<T>()
         {
             public boolean accept(T object)
             {
@@ -227,7 +187,7 @@ public class F
     {
         Predicate<T> isNull = isNull();
 
-        return invert(isNull);
+        return isNull.invert();
     }
 
     public static <S, T> Mapper<S, T> always(final T fixedResult)
@@ -298,7 +258,7 @@ public class F
     /** Allows Coercion to boolean to be used as a Predicate. */
     public static <S> Predicate<S> toPredicate(final Mapper<S, Boolean> mapper)
     {
-        return new Predicate<S>()
+        return new AbstractPredicate<S>()
         {
             public boolean accept(S object)
             {

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/func/Predicate.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/func/Predicate.java?rev=948278&r1=948277&r2=948278&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/func/Predicate.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/func/Predicate.java Wed May 26 00:40:51 2010
@@ -28,4 +28,10 @@ public interface Predicate<T>
      * @return true to accept, false to reject
      */
     boolean accept(T object);
+
+    Predicate<T> invert();
+
+    Predicate<T> and(Predicate<? super T> right);
+
+    Predicate<T> or(Predicate<? super T> right);
 }

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/func/Worker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/func/Worker.java?rev=948278&r1=948277&r2=948278&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/func/Worker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/func/Worker.java Wed May 26 00:40:51 2010
@@ -31,5 +31,5 @@ public interface Worker<T>
      * Combines this worker with the other worker, forming a new composite worker. In the composite,
      * the value passed first to this worker, then to the other worker.
      */
-    Worker<T> combine(Worker<T> other);
+    Worker<T> combine(Worker<? super T> other);
 }

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/InternalUtilsTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/InternalUtilsTest.java?rev=948278&r1=948277&r2=948278&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/InternalUtilsTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/InternalUtilsTest.java Wed May 26 00:40:51 2010
@@ -14,30 +14,46 @@
 
 package org.apache.tapestry5.ioc.internal.util;
 
-import org.apache.tapestry5.ioc.*;
+import static org.apache.tapestry5.ioc.internal.util.CollectionFactory.newMap;
+import static org.apache.tapestry5.ioc.internal.util.InternalUtils.toList;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.isA;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.tapestry5.ioc.AnnotationProvider;
+import org.apache.tapestry5.ioc.Locatable;
+import org.apache.tapestry5.ioc.Location;
+import org.apache.tapestry5.ioc.ObjectCreator;
+import org.apache.tapestry5.ioc.ObjectLocator;
+import org.apache.tapestry5.ioc.OperationTracker;
+import org.apache.tapestry5.ioc.ScopeConstants;
+import org.apache.tapestry5.ioc.ServiceBuilderResources;
 import org.apache.tapestry5.ioc.annotations.Inject;
 import org.apache.tapestry5.ioc.def.ServiceDef;
 import org.apache.tapestry5.ioc.def.ServiceDef2;
 import org.apache.tapestry5.ioc.internal.QuietOperationTracker;
-import static org.apache.tapestry5.ioc.internal.util.CollectionFactory.newMap;
-import static org.apache.tapestry5.ioc.internal.util.InternalUtils.toList;
 import org.apache.tapestry5.ioc.services.Builtin;
 import org.apache.tapestry5.ioc.services.SymbolSource;
 import org.apache.tapestry5.ioc.test.IOCTestCase;
-import org.apache.tapestry5.ioc.util.func.Predicate;
+import org.apache.tapestry5.ioc.util.func.AbstractPredicate;
 import org.easymock.EasyMock;
-import static org.easymock.EasyMock.eq;
-import static org.easymock.EasyMock.isA;
 import org.easymock.IAnswer;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
-import java.io.Closeable;
-import java.io.IOException;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.util.*;
-
 public class InternalUtilsTest extends IOCTestCase
 {
     private final OperationTracker tracker = new QuietOperationTracker();
@@ -648,7 +664,7 @@ public class InternalUtilsTest extends I
     {
         List<String> input = CollectionFactory.newList("Fred", "Barney", "..", ".hidden", "Wilma");
 
-        List<String> output = InternalUtils.matchAndSort(input, new Predicate<String>()
+        List<String> output = InternalUtils.matchAndSort(input, new AbstractPredicate<String>()
         {
             public boolean accept(String object)
             {

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/util/func/FuncTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/util/func/FuncTest.java?rev=948278&r1=948277&r2=948278&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/util/func/FuncTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/util/func/FuncTest.java Wed May 26 00:40:51 2010
@@ -40,7 +40,7 @@ public class FuncTest extends TestBase
         }
     };
 
-    private Predicate<Number> evenp = new Predicate<Number>()
+    private Predicate<Number> evenp = new AbstractPredicate<Number>()
     {
         public boolean accept(Number object)
         {
@@ -180,7 +180,7 @@ public class FuncTest extends TestBase
     {
         List<Integer> input = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
 
-        List<Integer> output = F.filter(F.and(evenp, F.gt(3)), input);
+        List<Integer> output = F.filter(evenp.and(F.gt(3)), input);
 
         assertListsEquals(output, 4, 6);
     }
@@ -213,4 +213,17 @@ public class FuncTest extends TestBase
 
         assertListsEquals(filtered, "Mary", "little", "lamb");
     }
+
+    @Test
+    public void null_and_not_null()
+    {
+        Predicate<String> isNull = F.isNull();
+        Predicate<String> isNotNull = F.notNull();
+
+        assertEquals(isNull.accept(null), true);
+        assertEquals(isNotNull.accept(null), false);
+
+        assertEquals(isNull.accept("foo"), false);
+        assertEquals(isNotNull.accept("bar"), true);
+    }
 }