You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@abdera.apache.org by jm...@apache.org on 2011/11/08 20:12:18 UTC

svn commit: r1199390 [1/2] - in /abdera/abdera2: activities/src/main/java/org/apache/abdera2/activities/extra/ common/src/main/java/org/apache/abdera2/common/date/ common/src/main/java/org/apache/abdera2/common/lang/ common/src/main/java/org/apache/abd...

Author: jmsnell
Date: Tue Nov  8 19:12:16 2011
New Revision: 1199390

URL: http://svn.apache.org/viewvc?rev=1199390&view=rev
Log:
additional code improvements...

Added:
    abdera/abdera2/common/src/main/java/org/apache/abdera2/common/selector/Selectors.java   (with props)
Removed:
    abdera/abdera2/common/src/main/java/org/apache/abdera2/common/selector/InvertedSelector.java
    abdera/abdera2/common/src/main/java/org/apache/abdera2/common/selector/MultiSelector.java
    abdera/abdera2/common/src/main/java/org/apache/abdera2/common/selector/TransformSelector.java
Modified:
    abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/ASContext.java
    abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/Extra.java
    abdera/abdera2/common/src/main/java/org/apache/abdera2/common/date/DateTimes.java
    abdera/abdera2/common/src/main/java/org/apache/abdera2/common/lang/Lang.java
    abdera/abdera2/common/src/main/java/org/apache/abdera2/common/misc/MoreFunctions.java
    abdera/abdera2/common/src/main/java/org/apache/abdera2/common/misc/Pair.java
    abdera/abdera2/common/src/main/java/org/apache/abdera2/common/protocol/RouteManager.java
    abdera/abdera2/common/src/main/java/org/apache/abdera2/common/protocol/TemplateManagerTargetBuilder.java
    abdera/abdera2/common/src/main/java/org/apache/abdera2/common/selector/AbstractSelector.java
    abdera/abdera2/common/src/main/java/org/apache/abdera2/common/selector/Selector.java
    abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/AbstractContext.java
    abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/CachingContext.java
    abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/Context.java
    abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/DelegatingContext.java
    abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/Expression.java
    abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/MapContext.java
    abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/MultiContext.java
    abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/ObjectContext.java
    abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/Operation.java
    abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/QueryContext.java
    abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/Template.java
    abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/TemplateManager.java
    abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/Codec.java
    abdera/abdera2/core/src/main/java/org/apache/abdera2/factory/AbstractExtensionFactory.java
    abdera/abdera2/core/src/main/java/org/apache/abdera2/factory/ExtensionFactoryMap.java
    abdera/abdera2/core/src/main/java/org/apache/abdera2/factory/StreamBuilder.java
    abdera/abdera2/core/src/main/java/org/apache/abdera2/model/ElementList.java
    abdera/abdera2/core/src/main/java/org/apache/abdera2/model/selector/CategorySchemeSelector.java
    abdera/abdera2/core/src/main/java/org/apache/abdera2/model/selector/CollectionAcceptSelector.java
    abdera/abdera2/core/src/main/java/org/apache/abdera2/model/selector/LinkHrefLangSelector.java
    abdera/abdera2/core/src/main/java/org/apache/abdera2/model/selector/LinkRelSelector.java
    abdera/abdera2/core/src/main/java/org/apache/abdera2/model/selector/Selectors.java
    abdera/abdera2/core/src/main/java/org/apache/abdera2/model/selector/XPathSelector.java
    abdera/abdera2/core/src/main/java/org/apache/abdera2/parser/axiom/FOMElement.java
    abdera/abdera2/core/src/main/java/org/apache/abdera2/parser/axiom/FOMWorkspace.java
    abdera/abdera2/core/src/main/java/org/apache/abdera2/writer/AbstractStreamWriter.java
    abdera/abdera2/examples/src/main/java/org/apache/abdera2/examples/uritemplates/URITemplates.java
    abdera/abdera2/ext/src/main/java/org/apache/abdera2/ext/activities/FeedToActivityConverter.java
    abdera/abdera2/ext/src/main/java/org/apache/abdera2/ext/features/FeaturesHelper.java
    abdera/abdera2/test/src/main/java/org/apache/abdera2/test/ext/features/FeatureTest.java
    abdera/abdera2/test/src/main/java/org/apache/abdera2/test/selector/SelectorTest.java

Modified: abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/ASContext.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/ASContext.java?rev=1199390&r1=1199389&r2=1199390&view=diff
==============================================================================
--- abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/ASContext.java (original)
+++ abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/ASContext.java Tue Nov  8 19:12:16 2011
@@ -23,6 +23,12 @@ public final class ASContext 
   private final ASBase base;
   
   public ASContext(ASBase base) {
+    super(false);
+    this.base = base;
+  }
+  
+  public ASContext(ASBase base, boolean isiri) {
+    super(isiri);
     this.base = base;
   }
   

Modified: abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/Extra.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/Extra.java?rev=1199390&r1=1199389&r2=1199390&view=diff
==============================================================================
--- abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/Extra.java (original)
+++ abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/Extra.java Tue Nov  8 19:12:16 2011
@@ -18,7 +18,7 @@ import org.apache.abdera2.common.date.Da
 import org.apache.abdera2.common.selector.AbstractSelector;
 import org.apache.abdera2.common.selector.PropertySelector;
 import org.apache.abdera2.common.selector.Selector;
-import org.apache.abdera2.common.selector.MultiSelector;
+import org.apache.abdera2.common.selector.Selectors;
 import org.joda.time.DateTime;
 
 import com.google.common.base.CaseFormat;
@@ -511,43 +511,43 @@ public class Extra {
   public static <X extends ASObject>Selector<X> isMeOr(ASObject object) {
     Selector<X> s1 = sameIdentity(object);
     Selector<X> s2 = sameIdentity(ME());
-    return MultiSelector.<X>or(s1,s2);
+    return Selectors.<X>or(s1,s2);
   }
   
   public static <X extends ASObject>Selector<X> isSelfOr(ASObject object) {
     Selector<X> s1 = sameIdentity(object);
     Selector<X> s2 = sameIdentity(SELF());
-    return MultiSelector.<X>or(s1,s2);
+    return Selectors.<X>or(s1,s2);
   }
   
   public static <X extends ASObject>Selector<X> isFriendsOr(ASObject object) {
     Selector<X> s1 = sameIdentity(object);
     Selector<X> s2 = sameIdentity(FRIENDS());
-    return MultiSelector.<X>or(s1,s2);
+    return Selectors.<X>or(s1,s2);
   }
   
   public static <X extends ASObject>Selector<X> isFriendsOr(String id, ASObject object) {
     Selector<X> s1 = sameIdentity(object);
     Selector<X> s2 = sameIdentity(FRIENDS(id));
-    return MultiSelector.<X>or(s1,s2);
+    return Selectors.<X>or(s1,s2);
   }
   
   public static <X extends ASObject>Selector<X> isNetworkOr(ASObject object) {
     Selector<X> s1 = sameIdentity(object);
     Selector<X> s2 = sameIdentity(NETWORK());
-    return MultiSelector.<X>or(s1,s2);
+    return Selectors.<X>or(s1,s2);
   }
   
   public static <X extends ASObject>Selector<X> isAllOr(ASObject object) {
     Selector<X> s1 = sameIdentity(object);
     Selector<X> s2 = sameIdentity(ALL());
-    return MultiSelector.<X>or(s1,s2);
+    return Selectors.<X>or(s1,s2);
   }
   
   public static <X extends ASObject>Selector<X> isPublicOr(ASObject object) {
     Selector<X> s1 = sameIdentity(object);
     Selector<X> s2 = sameIdentity(PUBLIC());
-    return MultiSelector.<X>or(s1,s2);
+    return Selectors.<X>or(s1,s2);
   }
   
   /**

Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/date/DateTimes.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/date/DateTimes.java?rev=1199390&r1=1199389&r2=1199390&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/date/DateTimes.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/date/DateTimes.java Tue Nov  8 19:12:16 2011
@@ -6,6 +6,7 @@ import java.util.Date;
 import java.util.TimeZone;
 
 import org.apache.abdera2.common.selector.Selector;
+import org.apache.abdera2.common.selector.Selectors;
 import org.joda.time.format.DateTimeFormatter;
 import org.joda.time.format.ISODateTimeFormat;
 import org.joda.time.DateTime;
@@ -335,7 +336,7 @@ public final class DateTimes {
   }
   
   public static Selector<DateTime> selectorForRange(Range<DateTime> range) {
-    return Selector.Utils.forPredicate(range);
+    return Selectors.forPredicate(range);
   }
   
   public static Range<DateTime> all() {

Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/lang/Lang.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/lang/Lang.java?rev=1199390&r1=1199389&r2=1199390&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/lang/Lang.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/lang/Lang.java Tue Nov  8 19:12:16 2011
@@ -41,6 +41,13 @@ import com.google.common.collect.Iterabl
 public final class Lang 
   extends SubtagSet {
 
+    public static final Function<String,Lang> parser = 
+      new Function<String,Lang>() {
+        public Lang apply(String input) {
+          return new Lang(input);
+        }
+    };
+  
     private static final long serialVersionUID = -7095560018906537331L;
     private final Locale locale;
 

Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/misc/MoreFunctions.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/misc/MoreFunctions.java?rev=1199390&r1=1199389&r2=1199390&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/misc/MoreFunctions.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/misc/MoreFunctions.java Tue Nov  8 19:12:16 2011
@@ -17,11 +17,24 @@ import com.google.common.base.Function;
 import com.google.common.base.Predicate;
 import com.google.common.base.Supplier;
 import com.google.common.base.Suppliers;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 import com.google.common.util.concurrent.ListenableFutureTask;
 
 public class MoreFunctions {
   
+  public static <T,S>Set<S> immutableSetOf(T[] items, Function<T,S> transform, Class<S> _class) {
+    S[] set = each(items, transform, _class);
+    return ImmutableSet.<S>copyOf(set);
+  }
+  
+  public static <T,S>List<S> immutableListOf(T[] items, Function<T,S> transform, Class<S> _class) {
+    S[] set = each(items, transform, _class);
+    return ImmutableList.<S>copyOf(set);
+  }
+  
+  @SuppressWarnings({ "unchecked", "rawtypes" })
   private static int _hash(Object obj ) {
     if (obj != null) {
       Class<?> type = obj.getClass();

Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/misc/Pair.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/misc/Pair.java?rev=1199390&r1=1199389&r2=1199390&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/misc/Pair.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/misc/Pair.java Tue Nov  8 19:12:16 2011
@@ -1,5 +1,10 @@
 package org.apache.abdera2.common.misc;
 
+import java.util.List;
+
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+
 public class Pair<K,V> {
 
   private final K k;
@@ -22,6 +27,22 @@ public class Pair<K,V> {
     return new Pair<K,V>(k,v);
   }
   
+  public static Pair<String,String> from(String pair) {
+    String[] split = pair.split("\\s*=\\s*",2);
+    return new Pair<String,String>(split[0],split.length>1?split[1]:null);
+  }
+  
+  public static Iterable<Pair<String,String>> from(String[] pairs) {
+    List<Pair<String,String>> list = Lists.newArrayList();
+    for (String pair : pairs)
+      list.add(from(pair));
+    return Iterables.unmodifiableIterable(list);
+  }
+  
+  public static Iterable<Pair<String,String>> from(String pairs, String delim) {
+    return from(pairs.split(String.format("\\s*%s\\s*",delim)));
+  }
+  
   @Override
   public int hashCode() {
     return MoreFunctions.genHashCode(1, k,v);

Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/protocol/RouteManager.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/protocol/RouteManager.java?rev=1199390&r1=1199389&r2=1199390&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/protocol/RouteManager.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/protocol/RouteManager.java Tue Nov  8 19:12:16 2011
@@ -34,6 +34,7 @@ import org.apache.abdera2.common.templat
 
 import com.google.common.base.Function;
 import com.google.common.base.Supplier;
+import com.sun.xml.internal.xsom.impl.scd.Iterators;
 
 /**
  * This is a largely experimental implementation of a Target Resolver and Target Builder based on URL patterns similar
@@ -214,21 +215,21 @@ public class RouteManager<T,X extends Re
         return (Map<String, Object>)param;
     }
 
-    private static class EmptyContext extends CachingContext {
-        private static final long serialVersionUID = 4681906592987534451L;
-
-        public boolean contains(String var) {
-          return false;
-        }
-        
-        protected <T> T resolveActual(String var) {
-            return null;
-        }
-
-        public Iterator<String> iterator() {
-            List<String> list = Arrays.asList(new String[0]);
-            return list.iterator();
-        }
+    private static class EmptyContext 
+      extends CachingContext {
+      private static final long serialVersionUID = 4681906592987534451L;
+      public EmptyContext() {
+        super(false);
+      }
+      public boolean contains(String var) {
+        return false;
+      }  
+      protected <T> T resolveActual(String var) {
+        return null;
+      }
+      public Iterator<String> iterator() {
+        return Iterators.<String>empty();
+      }
     }
 
     public static class RouteTarget extends SimpleTarget {

Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/protocol/TemplateManagerTargetBuilder.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/protocol/TemplateManagerTargetBuilder.java?rev=1199390&r1=1199389&r2=1199390&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/protocol/TemplateManagerTargetBuilder.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/protocol/TemplateManagerTargetBuilder.java Tue Nov  8 19:12:16 2011
@@ -46,7 +46,7 @@ public class TemplateManagerTargetBuilde
   public static class Builder<T> extends TemplateManager.Builder<T> {
     public TemplateManager<T> get() {
       return new TemplateManagerTargetBuilder<T>(
-        templates,isiri,base,contextDefaults);
+        templates,isiri,base,defaultContexts.get());
     }
     public TemplateManagerTargetBuilder<T> getTargetBuilder() {
       return (TemplateManagerTargetBuilder<T>) get();

Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/selector/AbstractSelector.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/selector/AbstractSelector.java?rev=1199390&r1=1199389&r2=1199390&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/selector/AbstractSelector.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/selector/AbstractSelector.java Tue Nov  8 19:12:16 2011
@@ -19,7 +19,7 @@ public abstract class AbstractSelector<X
   }
 
   public Function<X,Boolean> asFunction() {
-    return Utils.asFunction(this);
+    return Selectors.asFunction(this);
   }
   
   public Predicate<X> asPredicate() {
@@ -30,27 +30,27 @@ public abstract class AbstractSelector<X
   }
   
   public Selector<X> limit(int limit) {
-    return (Selector<X>)and(Utils.<X>counting(limit));
+    return (Selector<X>)and(Selectors.<X>limit(limit));
   }
   
   public <Y>Selector<Y> compose(Function<Y,X> transform) {
-    return Utils.compose(this, transform);
+    return Selectors.compose(this, transform);
   }
   
   public Selector<X> negate() {
-    return Utils.negate(this);
+    return Selectors.negate(this);
   }
   
   public Selector<X> and(Selector<X> selector) {
-    return MultiSelector.<X>and(this,selector);
+    return Selectors.<X>and(this,selector);
   }
   public Selector<X> or(Selector<X> selector) {
-    return MultiSelector.<X>or(this,selector);
+    return Selectors.<X>or(this,selector);
   }
   public Selector<X> andNot(Selector<X> selector) {
-    return MultiSelector.<X>and(this, selector.negate());
+    return Selectors.<X>and(this, selector.negate());
   }
   public Selector<X> orNot(Selector<X> selector) {
-    return MultiSelector.<X>or(this, selector.negate());
+    return Selectors.<X>or(this, selector.negate());
   }
 }

Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/selector/Selector.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/selector/Selector.java?rev=1199390&r1=1199389&r2=1199390&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/selector/Selector.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/selector/Selector.java Tue Nov  8 19:12:16 2011
@@ -17,8 +17,6 @@
  */
 package org.apache.abdera2.common.selector;
 
-import java.util.concurrent.atomic.AtomicInteger;
-
 import com.google.common.base.Function;
 import com.google.common.base.Predicate;
 import com.google.common.collect.Constraint;
@@ -70,86 +68,6 @@ public interface Selector<X>
      */
     public Selector<X> orNot(Selector<X> selector);
     
-    public static class Utils {
-      
-      /**
-       * Creates a selector that will select at most the given number 
-       * of items. Once the threshold has been met, the selector will
-       * return false;
-       */
-      public static <X>Selector<X> counting(int limit) {
-        return new CountingSelector<X>(limit);
-      }
-      
-      private static class CountingSelector<X> 
-        extends AbstractSelector<X> {
-          private final AtomicInteger counter = new AtomicInteger();
-          private final int limit;
-          private boolean done = false;
-          public CountingSelector(int limit) {
-            this.limit = limit;
-          }
-          public boolean select(Object object) {
-            if (done) return false;
-            if (counter.incrementAndGet() <= limit)
-              return true;
-            else done = true;
-            return false;
-          }
-      }
-      
-      /**
-       * Creates a new Selector A using Selector B and Function C such that
-       * X = C(Y),
-       * B(X),
-       * A(Y) = B(C(Y)). 
-       * That is, for instance, supposing we have a 
-       * Selector<Long> B and Function<String,Long> C, this creates a 
-       * Selector<String> that will first pass the input string to the 
-       * Function, which returns a Long, and in turn passes that to selector
-       * B.
-       */
-      public static <X,Y>Selector<Y> compose(Selector<X> b, Function<Y,X> c) {
-        return new TransformSelector<Y,X>(b,c);
-      }
-      
-      /**
-       * Returns the Selector<X> as a Function<X,Boolean>
-       */
-      public static <X>Function<X,Boolean> asFunction(final Selector<X> selector) {
-        return new Function<X,Boolean>() {
-          public Boolean apply(X input) {
-            return selector.apply(input);
-          }
-        };
-      }
-      
-      /**
-       * Returns a Selector<X> that selects the inverse of the provided
-       * Selector<X>
-       */
-      public static <X>Selector<X> negate(Selector<X> selector) {
-        return new InvertedSelector<X>(selector);
-      }
-      
-      /**
-       * Returns a Selector<X> that wraps the specified Predicate<X>
-       */
-      public static <X>Selector<X> forPredicate(
-        Predicate<X> predicate) {
-          return new PredicateSelector<X>(predicate);
-      }
-      
-      /**
-       * Returns a Selector<X> that wraps a Constraint<X>
-       */
-      public static <X>Selector<X> forConstraint(
-        Constraint<X> constraint) {
-          return new ConstraintSelector<X>(constraint);
-      }
-      
-    }
-    
     public static class ConstraintSelector<X>
       extends AbstractSelector<X> {
       private final Constraint<X> internal;

Added: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/selector/Selectors.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/selector/Selectors.java?rev=1199390&view=auto
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/selector/Selectors.java (added)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/selector/Selectors.java Tue Nov  8 19:12:16 2011
@@ -0,0 +1,188 @@
+package org.apache.abdera2.common.selector;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Constraint;
+import com.google.common.collect.ImmutableSet;
+
+public final class Selectors {
+  
+  private Selectors() {}
+  
+  public static <X>Selector<X> alwaysTrue() {
+    return forPredicate(Predicates.<X>alwaysTrue());
+  }
+  
+  public static <X>Selector<X> alwaysFalse() {
+    return forPredicate(Predicates.<X>alwaysFalse());
+  }
+  
+  public static <X>Selector<X> oneOf(final X... items) {
+    return forPredicate(Predicates.in(ImmutableSet.<X>copyOf(items)));
+  }
+  
+  public static Selector<Object> instanceOf(final Class<?> _class) {
+    return forPredicate(Predicates.instanceOf(_class));
+  }
+  
+  /**
+   * Uses ==
+   */
+  public static <X>Selector<X> identity(final X instance) {
+    return new AbstractSelector<X>() {
+      public boolean select(Object item) {
+        return item == instance;
+      }
+    };
+  }
+  
+  /**
+   * Uses equals()
+   */
+  public static <X>Selector<X> of(final X instance) {
+    return new AbstractSelector<X>() {
+      public boolean select(Object item) {
+        return item.equals(instance);
+      }
+    };
+  }
+  
+  /**
+   * Creates a selector that will select at most the given number 
+   * of items. Once the threshold has been met, the selector will
+   * return false;
+   */
+  public static <X>Selector<X> limit(int limit) {
+    return new Selectors.CountingSelector<X>(limit);
+  }
+  
+  private static class CountingSelector<X> 
+    extends AbstractSelector<X> {
+      private final AtomicInteger counter = 
+        new AtomicInteger();
+      private final int limit;
+      private boolean done = false;
+      public CountingSelector(int limit) {
+        this.limit = limit;
+      }
+      public boolean select(Object object) {
+        if (done) return false;
+        if (counter.incrementAndGet() <= limit)
+          return true;
+        else done = true;
+        return false;
+      }
+  }
+  
+  /**
+   * Creates a new Selector A using Selector B and Function C such that
+   * X = C(Y),
+   * B(X),
+   * A(Y) = B(C(Y)). 
+   * That is, for instance, supposing we have a 
+   * Selector<Long> B and Function<String,Long> C, this creates a 
+   * Selector<String> that will first pass the input string to the 
+   * Function, which returns a Long, and in turn passes that to selector
+   * B.
+   */
+  public static <X,Y>Selector<Y> compose(Selector<X> b, Function<Y,X> c) {
+    return new TransformSelector<Y,X>(b,c);
+  }
+  
+  /**
+   * Returns the Selector<X> as a Function<X,Boolean>
+   */
+  public static <X>Function<X,Boolean> asFunction(final Selector<X> selector) {
+    return new Function<X,Boolean>() {
+      public Boolean apply(X input) {
+        return selector.apply(input);
+      }
+    };
+  }
+  
+  /**
+   * Returns a Selector<X> that selects the inverse of the provided
+   * Selector<X>
+   */
+  public static <X>Selector<X> negate(final Selector<X> selector) {
+    return new AbstractSelector<X>() {
+      public boolean select(Object item) {
+        return !selector.select(item);
+      }
+    };
+  }
+  
+  /**
+   * Returns a Selector<X> that wraps the specified Predicate<X>
+   */
+  public static <X>Selector<X> forPredicate(
+    Predicate<X> predicate) {
+      return new Selector.PredicateSelector<X>(predicate);
+  }
+  
+  /**
+   * Returns a Selector<X> that wraps a Constraint<X>
+   */
+  public static <X>Selector<X> forConstraint(
+    Constraint<X> constraint) {
+      return new Selector.ConstraintSelector<X>(constraint);
+  }
+  
+  public static <X>Selector<X> not(Selector<X>...selectors) {
+    return Selectors.negate(and(selectors));
+  }
+
+  public static <X>Selector<X> or(Selector<X>...selectors) {
+    return new MultiSelector<X>(selectors) {
+      public boolean select(Object item) {
+        for (Selector<X> selector : selectors)
+          if (selector.select(item))
+            return true;
+        return false;
+      }
+    };
+  }
+  
+  public static <X>Selector<X> and(Selector<X>...selectors) {
+    return new MultiSelector<X>(selectors) {
+      public boolean select(Object item) {
+        for (Selector<X> selector : selectors)
+          if (!selector.select(item))
+            return false;
+        return true;
+      }
+    };
+  }
+  
+  private static abstract class MultiSelector<X> 
+    extends AbstractSelector<X>
+    implements Selector<X> {
+
+    private static final long serialVersionUID = 5257601171344714824L;
+    protected final Selector<X>[] selectors;
+  
+    public MultiSelector(Selector<X>... selectors) {
+      this.selectors = selectors;
+    }
+  }
+  
+  
+  private static class TransformSelector<X,Y>
+    extends AbstractSelector<X> {  
+    private final Selector<Y> inner;
+    private final Function<X,Y> function;
+    public TransformSelector(
+      Selector<Y> selector, 
+      Function<X,Y> transform) {
+        this.inner = selector;
+        this.function = transform;
+    }
+    @SuppressWarnings("unchecked")
+    public boolean select(Object item) {
+      return inner.select((Y)function.apply((X)item));
+    }
+  }
+}
\ No newline at end of file

Propchange: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/selector/Selectors.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/AbstractContext.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/AbstractContext.java?rev=1199390&r1=1199389&r2=1199390&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/AbstractContext.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/AbstractContext.java Tue Nov  8 19:12:16 2011
@@ -24,16 +24,12 @@ import org.apache.abdera2.common.templat
  */
 public abstract class AbstractContext implements Context {
 
-    private static final long serialVersionUID = -2511167897930514261L;
-
-    protected boolean iri = false;
-
-    public boolean isIri() {
-        return iri;
-    }
-
-    public void setIri(boolean isiri) {
-        this.iri = isiri;
-    }
-
+  private static final long serialVersionUID = -2511167897930514261L;
+  private final boolean iri;
+  protected AbstractContext(boolean iri) {
+    this.iri = iri;
+  }
+  public boolean isIri() {
+      return iri;
+  }
 }

Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/CachingContext.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/CachingContext.java?rev=1199390&r1=1199389&r2=1199390&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/CachingContext.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/CachingContext.java Tue Nov  8 19:12:16 2011
@@ -26,26 +26,31 @@ import org.apache.abdera2.common.templat
  * Abstract Context implementation that caches resolved values so that do not have to be resolved again
  */
 @SuppressWarnings("unchecked")
-public abstract class CachingContext extends AbstractContext {
+public abstract class CachingContext 
+  extends AbstractContext {
 
-    private static final long serialVersionUID = 8912954163958644811L;
+  private static final long serialVersionUID = 8912954163958644811L;
     
-    private Map<String, Object> cache = 
-      new HashMap<String, Object>();
+  private Map<String, Object> cache = 
+    new HashMap<String, Object>();
 
-    public <T> T resolve(String var) {
-        T t = (T)cache.get(var);
-        if (t == null) {
-            t = (T)resolveActual(var);
-            if (t != null)
-                cache.put(var, t);
-        }
-        return t;
+  protected CachingContext(boolean iri) {
+    super(iri);
+  }
+  
+  public <T> T resolve(String var) {
+    T t = (T)cache.get(var);
+    if (t == null) {
+      t = (T)resolveActual(var);
+      if (t != null)
+          cache.put(var, t);
     }
+    return t;
+  }
 
-    protected abstract <T> T resolveActual(String var);
+  protected abstract <T> T resolveActual(String var);
 
-    public void clear() {
-        cache.clear();
-    }
+  public void clear() {
+    cache.clear();
+  }
 }

Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/Context.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/Context.java?rev=1199390&r1=1199389&r2=1199390&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/Context.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/Context.java Tue Nov  8 19:12:16 2011
@@ -34,15 +34,5 @@ public interface Context extends Seriali
      */
     boolean isIri();
 
-    /**
-     * True if IRI expansion is to be enabled
-     */
-    void setIri(boolean isiri);
-
-    /**
-     * Clear this context
-     */
-    void clear();
-
     boolean contains(String var);
 }

Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/DelegatingContext.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/DelegatingContext.java?rev=1199390&r1=1199389&r2=1199390&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/DelegatingContext.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/DelegatingContext.java Tue Nov  8 19:12:16 2011
@@ -26,8 +26,9 @@ public abstract class DelegatingContext 
     protected final Context subcontext;
 
     protected DelegatingContext(Context subcontext) {
-        checkNotNull(subcontext);
-        this.subcontext = subcontext;
+      super(subcontext.isIri());
+      checkNotNull(subcontext);
+      this.subcontext = subcontext;
     }
 
     protected <T> T resolveActual(String var) {
@@ -42,10 +43,6 @@ public abstract class DelegatingContext 
       return this.subcontext.isIri();
     }
     
-    public void setIri(boolean isiri) {
-      this.subcontext.setIri(isiri);
-    }
-    
     public boolean contains(String var) {
       return this.subcontext.contains(var);
     }
@@ -54,7 +51,4 @@ public abstract class DelegatingContext 
       return (T)this.subcontext.resolve(var);
     }
 
-    public void clear() {
-      this.subcontext.clear();
-    }
 }

Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/Expression.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/Expression.java?rev=1199390&r1=1199389&r2=1199390&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/Expression.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/Expression.java Tue Nov  8 19:12:16 2011
@@ -25,14 +25,17 @@ import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import org.apache.abdera2.common.misc.MoreFunctions;
+import org.apache.abdera2.common.misc.Pair;
 import org.apache.abdera2.common.templates.Context;
 import org.apache.abdera2.common.templates.Expression;
 import org.apache.abdera2.common.templates.Operation;
 
+import com.google.common.collect.Iterables;
+
 import static com.google.common.base.Preconditions.*;
 import static org.apache.abdera2.common.misc.MorePreconditions.*;
 
-public class Expression 
+public final class Expression 
   implements Iterable<Expression.VarSpec>, Serializable {
   
   private static final long serialVersionUID = 1457650843240079628L;
@@ -41,13 +44,14 @@ public class Expression 
   private static final Pattern LENGTH = Pattern.compile("\\:(\\d+)");
   
   private final String EXP;
-  private Operation op;
-  private List<VarSpec> varspecs = 
-    new ArrayList<VarSpec>();
+  private final Operation op;
+  private final Iterable<VarSpec> varspecs;
   
   public Expression(String exp) {
     this.EXP = exp;
-    parse();
+    Pair<Operation,Iterable<VarSpec>> parsed = parse();
+    this.op = parsed.first();
+    this.varspecs = parsed.second();
   }
   
   public String toString() {
@@ -98,31 +102,37 @@ public class Expression 
     return varspecs.iterator();
   }
 
-  private void parse() {
+  private Pair<Operation,Iterable<VarSpec>> parse() {
+    List<VarSpec> varspecs = new ArrayList<VarSpec>();
+    Operation op = null;
     Matcher mt = EXPRESSION.matcher(EXP);
     if (checkArgument(mt.find(),"Invalid Expression")) {
-      this.op = Operation.get(mt.group(1)); // grab the operation
+      op = Operation.get(mt.group(1));
       String varlist = mt.group(2);
-      checkNotNull(varlist, "No variables");
       String[] vars = 
-        varlist.split("\\s*,\\s*");
+        checkNotNull(varlist).split("\\s*,\\s*");
       for (String var : vars) {
         Matcher vt = VARSPEC.matcher(var);
-        if (vt.find()) {
-          VarSpec spec = new VarSpec(vt.group(1),vt.group(2));
-          varspecs.add(spec);
-        }
+        if (vt.find())
+          varspecs.add(
+            VarSpec.create(
+              vt.group(1),
+              vt.group(2)));
       }
     }
+    return Pair.of(op,Iterables.unmodifiableIterable(varspecs));
   }
   
   
-  public static class VarSpec {
+  public static final class VarSpec {
     private final String name;
     private final int length;
     private final boolean explode;
     private final boolean noval;
-    public VarSpec(String name, String modifier) {
+    public static VarSpec create(String name, String modifier) {
+      return new VarSpec(name, modifier);
+    }
+    VarSpec(String name, String modifier) {
       this.name = name;
       this.length = getLength(modifier);
       this.explode = isExplode(modifier);

Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/MapContext.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/MapContext.java?rev=1199390&r1=1199389&r2=1199390&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/MapContext.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/MapContext.java Tue Nov  8 19:12:16 2011
@@ -17,14 +17,18 @@
  */
 package org.apache.abdera2.common.templates;
 
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
+import java.util.Set;
 
 import org.apache.abdera2.common.misc.MoreFunctions;
 import org.apache.abdera2.common.templates.Context;
 import org.apache.abdera2.common.templates.MapContext;
 
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Multimap;
 import static com.google.common.base.Preconditions.*;
 
@@ -32,77 +36,114 @@ import static com.google.common.base.Pre
  * Context implementation based on a HashMap
  */
 @SuppressWarnings("unchecked")
-public class MapContext extends HashMap<String, Object> implements Context {
+public class MapContext 
+  extends HashMap<String, Object> 
+  implements Context {
+
+  private static final long serialVersionUID = 2206000974505975049L;
+
+  private final boolean isiri;
+
+  public MapContext() {
+    this.isiri = false;
+  }
+
+  public MapContext(boolean isiri) {
+    this.isiri = isiri;
+  }
+  
+  public MapContext(Map<String, Object> map) {
+      super(map);
+      this.isiri = false;
+  }
 
-    private static final long serialVersionUID = 2206000974505975049L;
-
-    private boolean isiri = false;
-
-    public MapContext() {
-    }
-
-    public MapContext(boolean isiri) {
+  public MapContext(Map<String, Object> map, boolean isiri) {
+      super(map);
       this.isiri = isiri;
+  }
+  
+  public MapContext(Context context) {
+    checkNotNull(context);
+    this.isiri = context.isIri();
+    for (String name : context)
+      put(name, context.resolve(name));
+  }
+
+  public <T> T resolve(String var) {
+      return (T)get(var);
+  }
+
+  public boolean isIri() {
+      return isiri;
+  }
+
+  public Iterator<String> iterator() {
+      return keySet().iterator();
+  }
+
+  @Override
+  public int hashCode() {
+    return MoreFunctions.genHashCode(super.hashCode(), isiri);
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+      if (this == obj)
+          return true;
+      if (!super.equals(obj))
+          return false;
+      if (getClass() != obj.getClass())
+          return false;
+      final MapContext other = (MapContext)obj;
+      if (isiri != other.isiri)
+          return false;
+      return true;
+  }
+
+  public boolean contains(String var) {
+    return containsKey(var);
+  }
+  
+  public static MapContext fromMultimap(
+    Multimap<String,Object> multimap) {
+      MapContext mc = new MapContext();
+      mc.putAll(multimap.asMap());
+      return mc;
+  }
+  
+  /**
+   * Returns an Immutable version of this MapContext
+   */
+  public MapContext immutable() {
+    return new ImmutableMapContext(this);
+  }
+  
+  private static final class ImmutableMapContext extends MapContext {
+    private static final long serialVersionUID = 7979187415358996598L;
+    ImmutableMapContext(MapContext context) {
+      super((Map<String,Object>)context);
+    }
+    public void clear() {
+      throw new UnsupportedOperationException();
+    }
+    public Set<java.util.Map.Entry<String, Object>> entrySet() {
+      return ImmutableSet.copyOf(super.entrySet());
+    }
+    public Set<String> keySet() {
+      return ImmutableSet.copyOf(super.keySet());
+    }
+    public Object put(String arg0, Object arg1) {
+      throw new UnsupportedOperationException();
     }
-    
-    public MapContext(Map<String, Object> map) {
-        super(map);
-    }
-
-    public MapContext(Map<String, Object> map, boolean isiri) {
-        super(map);
-        this.isiri = isiri;
-    }
-    
-    public MapContext(Context context) {
-      checkNotNull(context);
-      for (String name : context)
-        put(name, context.resolve(name));
-    }
-
-    public <T> T resolve(String var) {
-        return (T)get(var);
-    }
-
-    public boolean isIri() {
-        return isiri;
-    }
-
-    public void setIri(boolean isiri) {
-        this.isiri = isiri;
+    public void putAll(Map<? extends String, ? extends Object> arg0) {
+      throw new UnsupportedOperationException();
     }
-
-    public Iterator<String> iterator() {
-        return keySet().iterator();
+    public Object remove(Object arg0) {
+      throw new UnsupportedOperationException();
     }
-
-    @Override
-    public int hashCode() {
-      return MoreFunctions.genHashCode(super.hashCode(), isiri);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj)
-            return true;
-        if (!super.equals(obj))
-            return false;
-        if (getClass() != obj.getClass())
-            return false;
-        final MapContext other = (MapContext)obj;
-        if (isiri != other.isiri)
-            return false;
-        return true;
-    }
-
-    public boolean contains(String var) {
-      return containsKey(var);
+    public Collection<Object> values() {
+      return ImmutableList.copyOf(super.values());
     }
     
-    public static MapContext fromMultimap(
-      Multimap<String,Object> multimap) {
-        MapContext mc = new MapContext();
-        mc.putAll(multimap.asMap());
-        return mc;
-    }
+  }
 }

Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/MultiContext.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/MultiContext.java?rev=1199390&r1=1199389&r2=1199390&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/MultiContext.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/MultiContext.java Tue Nov  8 19:12:16 2011
@@ -17,62 +17,73 @@
  */
 package org.apache.abdera2.common.templates;
 
-import java.util.Collection;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.LinkedHashSet;
 import java.util.Map;
 import java.util.Set;
+
+import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableSet;
+
 import static com.google.common.base.Preconditions.*;
 
-public class MultiContext 
+public final class MultiContext 
   extends CachingContext {
 
-  private static final long serialVersionUID = 1691294411780004133L;
-  private final Set<Context> contexts = 
-    new HashSet<Context>();
-  
-  public MultiContext(Context... contexts) {
-    for (Context context : contexts)
-      this.contexts.add(context);
+  public static Builder make() {
+    return new Builder();
   }
   
-  public MultiContext(Iterable<Context> contexts) {
-    checkNotNull(contexts);
-    for (Context context : contexts)
+  public static final class Builder implements Supplier<Context> {
+
+    private final Set<Context> contexts = 
+      new LinkedHashSet<Context>();
+    private boolean isiri;
+    
+    public Builder iri() {
+      this.isiri = false;
+      return this;
+    }
+    
+    public Builder with(Context context) {
+      checkNotNull(context);
       this.contexts.add(context);
+      return this;
+    }
+    
+    @SuppressWarnings("unchecked")
+    public Builder with(Object object) {
+      checkNotNull(object);
+      this.contexts.add(
+        object instanceof Context ? 
+          (Context)object :
+          object instanceof Map ?
+            new MapContext((Map<String,Object>)object) :
+            new ObjectContext(object)
+      );
+      return this;
+    }
+    
+    public Context get() {
+      return new MultiContext(this);
+    }
+    
   }
   
-  public MultiContext(Collection<Context> contexts) {
-    checkNotNull(contexts);
-    if (contexts == null)
-      throw new IllegalArgumentException();
-    this.contexts.addAll(contexts);
-  }
-  
-  public void add(Context context) {
-    checkNotNull(context);
-    this.contexts.add(context);
-  }
-  
-  @SuppressWarnings("unchecked")
-  public void add(Object object) {
-    checkNotNull(object);
-    this.contexts.add(
-      object instanceof Context ? 
-        (Context)object :
-        object instanceof Map ?
-          new MapContext((Map<String,Object>)object) :
-          new ObjectContext(object)
-    );
-  }
+  private static final long serialVersionUID = 1691294411780004133L;
+  private final Set<Context> contexts;
   
+  MultiContext(Builder builder) {
+    super(builder.isiri);
+    this.contexts = ImmutableSet.copyOf(builder.contexts);
+  } 
   public boolean contains(String var) {
     for (Context context : contexts)
       if (context.contains(var))
         return true;
     return false;
   }
-
   public Iterator<String> iterator() {
     Set<String> names = new HashSet<String>();
     for (Context context : contexts) 
@@ -80,15 +91,10 @@ public class MultiContext 
         names.add(name);
     return names.iterator();
   }
-
-  @SuppressWarnings("unchecked")
-  @Override
   protected <T> T resolveActual(String var) {
     for (Context context : contexts)
       if (context.contains(var))
-        return (T)context.resolve(var);
+        return context.<T>resolve(var);
     return null;
   }
-
-
 }

Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/ObjectContext.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/ObjectContext.java?rev=1199390&r1=1199389&r2=1199390&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/ObjectContext.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/ObjectContext.java Tue Nov  8 19:12:16 2011
@@ -43,14 +43,14 @@ public final class ObjectContext extends
       new HashMap<String, AccessibleObject>();
 
     public ObjectContext(Object object) {
-        this(object, false);
+      this(object, false);
     }
 
     public ObjectContext(Object object, boolean isiri) {
-        checkNotNull(object);
-        this.target = object;
-        setIri(isiri);
-        initMethods();
+      super(isiri);
+      checkNotNull(object);
+      this.target = object;
+      initMethods();
     }
     
     private void initMethods() {

Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/Operation.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/Operation.java?rev=1199390&r1=1199389&r2=1199390&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/Operation.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/Operation.java Tue Nov  8 19:12:16 2011
@@ -17,18 +17,15 @@
  */
 package org.apache.abdera2.common.templates;
 
-import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.Serializable;
 import java.lang.ref.Reference;
 import java.nio.CharBuffer;
 import java.util.Enumeration;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 
 import org.apache.abdera2.common.misc.ExceptionHelper;
@@ -41,10 +38,11 @@ import org.apache.abdera2.common.text.Ur
 
 import com.google.common.base.Optional;
 import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Multimap;
 import com.ibm.icu.text.Normalizer2;
 import static com.google.common.base.Preconditions.*;
-import static org.apache.abdera2.common.misc.MorePreconditions.*;
+import static org.apache.abdera2.common.text.CharUtils.*;
 
 @SuppressWarnings("unchecked")
 public abstract class Operation implements Serializable {
@@ -52,38 +50,23 @@ public abstract class Operation implemen
     private static final long serialVersionUID = -1734350302144527120L;
     public abstract String evaluate(Expression exp, Context context);
 
-    private static Map<String, Operation> operations = getOperations();
-
-    private static Map<String, Operation> getOperations() {
-        Map<String, Operation> ops = new HashMap<String, Operation>();
-        ops.put("", new DefaultOperation());
-        ops.put("+", new ReservedExpansionOperation());
-        ops.put("#", new FragmentExpansionOperation());
-        ops.put(".", new DotExpansionOperation());
-        ops.put("/", new PathExpansionOperation());
-        ops.put(";", new PathParamExpansionOperation());
-        ops.put("?", new FormExpansionOperation());
-        ops.put("&", new QueryExpansionOperation());
-        return ops;
-    }
-
-    /**
-     * Register a new operation. The built in operations cannot be 
-     * overridden. Key should be a single character. This method
-     * is not synchronized; it is not recommended that registrations 
-     * be allowed from multiple threads or while multiple threads are
-     * expanding templates. Perform all registrations <i>before</i>
-     * any template expansion occurs.
-     */
-    public static void register(String key, Operation operation) {
-      checkArgument("+#./;?&".contains(key), "Cannot override reserved operators");
-      operations.put(key, operation);
-    }
+    private static Map<String, Operation> operations = 
+      ImmutableMap
+        .<String,Operation>builder()
+          .put("", new DefaultOperation())
+          .put("+", new ReservedExpansionOperation())
+          .put("#", new FragmentExpansionOperation())
+          .put(".", new DotExpansionOperation())
+          .put("/", new PathExpansionOperation())
+          .put(";", new PathParamExpansionOperation())
+          .put("?", new FormExpansionOperation())
+          .put("&", new QueryExpansionOperation())
+        .build();
 
     public static Operation get(String name) {
-      Operation op = operations.get(name!=null?name:"");
-      if (op != null) return op;
-      throw new UnsupportedOperationException(name);
+      name = name != null ? name : "";
+      checkArgument(operations.containsKey(name));
+      return operations.get(name);
     }
 
     protected static String eval(
@@ -92,10 +75,9 @@ public abstract class Operation implemen
         boolean reserved, 
         String explodeDelim, 
         String explodePfx) {
+        String name = checkNotNull(varspec).getName();
+        Object rep = checkNotNull(context).resolve(name);
         checkNotNull(varspec);
-        checkNotNull(context);
-        String name = varspec.getName();
-        Object rep = context.resolve(name);
         String val = toString(
             rep, 
             context, 
@@ -120,7 +102,19 @@ public abstract class Operation implemen
         Normalizer2.Mode.COMPOSE)
           .normalize(s);
     }
-
+    
+    private static <T>void appendPrim(
+      T obj, 
+      int len, 
+      StringBuilder buf, 
+      boolean explode, 
+      String exp, 
+      String explodePfx) {
+      appendif(buf.length()>0,buf,exp);
+      appendif(explode && explodePfx != null, buf, explodePfx);
+      buf.append(trim(String.valueOf(obj),len));
+    }
+    
     private static String toString(
         Object val, 
         Context context, 
@@ -131,6 +125,7 @@ public abstract class Operation implemen
         int len) {
         if (val == null)
             return null;
+        String exp = explode && explodeDelim != null ? explodeDelim : ",";
         if (val.getClass().isArray()) {
             if (val instanceof byte[]) {
                 return UrlEncoding.encode((byte[])val);
@@ -149,119 +144,79 @@ public abstract class Operation implemen
                           CharUtils.Profile.RESERVEDANDUNRESERVED);                
             } else if (val instanceof short[]) {
                 StringBuilder buf = new StringBuilder();
-                short[] array = (short[])val;
-                for (short obj : array) {
-                    if (buf.length() > 0)
-                        buf.append(explode && explodeDelim != null ? explodeDelim : ",");
-                    if (explode && explodePfx != null) 
-                      buf.append(explodePfx);
-                    buf.append(trim(String.valueOf(obj),len));
-                }
+                for (short obj : (short[])val)
+                  appendPrim(obj,len,buf,explode,exp,explodePfx);
                 return buf.toString();
             } else if (val instanceof int[]) {
                 StringBuilder buf = new StringBuilder();
-                int[] array = (int[])val;
-                for (int obj : array) {
-                    if (buf.length() > 0)
-                        buf.append(explode && explodeDelim != null ? explodeDelim : ",");
-                    if (explode && explodePfx != null) 
-                      buf.append(explodePfx);
-                    buf.append(trim(String.valueOf(obj),len));
-                }
+                for (int obj : (int[])val)
+                  appendPrim(obj,len,buf,explode,exp,explodePfx);
                 return buf.toString();
             } else if (val instanceof long[]) {
                 StringBuilder buf = new StringBuilder();
-                long[] array = (long[])val;
-                for (long obj : array) {
-                    if (buf.length() > 0)
-                        buf.append(explode && explodeDelim != null ? explodeDelim : ",");
-                    if (explode && explodePfx != null) 
-                      buf.append(explodePfx);
-                    buf.append(trim(String.valueOf(obj),len));
-                }
+                for (long obj : (long[])val)
+                  appendPrim(obj,len,buf,explode,exp,explodePfx);
                 return buf.toString();
             } else if (val instanceof double[]) {
                 StringBuilder buf = new StringBuilder();
-                double[] array = (double[])val;
-                for (double obj : array) {
-                    if (buf.length() > 0)
-                        buf.append(explode && explodeDelim != null ? explodeDelim : ",");
-                    if (explode && explodePfx != null) 
-                      buf.append(explodePfx);
-                    buf.append(trim(String.valueOf(obj),len));
-                }
+                for (double obj : (double[])val)
+                  appendPrim(obj,len,buf,explode,exp,explodePfx);
                 return buf.toString();
             } else if (val instanceof float[]) {
                 StringBuilder buf = new StringBuilder();
-                float[] array = (float[])val;
-                for (float obj : array) {
-                    if (buf.length() > 0)
-                        buf.append(explode && explodeDelim != null ? explodeDelim : ",");
-                    if (explode && explodePfx != null) 
-                      buf.append(explodePfx);
-                    buf.append(trim(String.valueOf(obj),len));
-                }
+                for (float obj : (float[])val)
+                  appendPrim(obj,len,buf,explode,exp,explodePfx);
                 return buf.toString();
             } else if (val instanceof boolean[]) {
                 StringBuilder buf = new StringBuilder();
-                boolean[] array = (boolean[])val;
-                for (boolean obj : array) {
-                    if (buf.length() > 0)
-                        buf.append(explode && explodeDelim != null ? explodeDelim : ",");
-                    if (explode && explodePfx != null) 
-                      buf.append(explodePfx);
-                    buf.append(trim(String.valueOf(obj),len));
-                }
+                for (boolean obj : (boolean[])val)
+                  appendPrim(obj,len,buf,explode,exp,explodePfx);
                 return buf.toString();
             } else {
                 StringBuilder buf = new StringBuilder();
-                Object[] array = (Object[])val;
-                for (Object obj : array) {
-                  if (buf.length() > 0)
-                    buf.append(explode && explodeDelim != null ? explodeDelim : ",");
-                  if (explode && explodePfx != null) 
-                    buf.append(explodePfx);
+                for (Object obj : (Object[])val) {
+                  appendif(buf.length()>0,buf,exp);
+                  appendif(explode && explodePfx != null, buf, explodePfx);
                   buf.append(toString(obj, context, reserved, false, null, null, len));
                 }
                 return buf.toString();
             }
         } else if (val instanceof InputStream) {
             try {
-                if (len > -1) {
-                  byte[] buf = new byte[len];
-                  int r = ((InputStream)val).read(buf);
-                  byte[] dat = new byte[r];
-                  System.arraycopy(buf, 0, dat, 0, r);
-                  val = new ByteArrayInputStream(dat);
-                }
+              if (len > -1) {
+                byte[] buf = new byte[len];
+                int r = ((InputStream)val).read(buf);
+                return r > 0 ?
+                  UrlEncoding.encode(buf,0,r) : "";
+              } else
                 return UrlEncoding.encode((InputStream)val);
             } catch (IOException e) {
-                throw new RuntimeException(e);
+              throw ExceptionHelper.propogate(e);
             }
         } else if (val instanceof Readable) {
             try { 
-                if (len > -1) {
-                  CharBuffer buf = CharBuffer.allocate(len);
-                  int r = ((Readable)val).read(buf);
-                  buf.limit(r);
-                  buf.position(0);
-                  val = buf;
-                }
-                return !reserved ?
-                    UrlEncoding.encode(
-                      (Readable)val, 
-                      "UTF-8", 
-                      context.isIri() ? 
-                          CharUtils.Profile.IUNRESERVED : 
-                          CharUtils.Profile.UNRESERVED) :
+              if (len > -1) {
+                CharBuffer buf = CharBuffer.allocate(len);
+                int r = ((Readable)val).read(buf);
+                buf.limit(r);
+                buf.position(0);
+                val = buf;
+              }
+              return !reserved ?
+                UrlEncoding.encode(
+                  (Readable)val, 
+                  "UTF-8", 
+                  context.isIri() ? 
+                    CharUtils.Profile.IUNRESERVED : 
+                    CharUtils.Profile.UNRESERVED) :
                     UrlEncoding.encode(
                       (Readable)val,
                       "UTF-8",
                       context.isIri() ?
-                          CharUtils.Profile.RESERVEDANDIUNRESERVED :
-                          CharUtils.Profile.RESERVEDANDUNRESERVED);
+                        CharUtils.Profile.RESERVEDANDIUNRESERVED :
+                        CharUtils.Profile.RESERVEDANDUNRESERVED);
             } catch (IOException e) {
-                throw new RuntimeException(e);
+              throw new RuntimeException(e);
             }
         } else if (val instanceof CharSequence) {
             val = trim(normalize((CharSequence)val),len);
@@ -273,8 +228,7 @@ public abstract class Operation implemen
           Context ctx = (Context) val;
           for (String name : ctx) {
             String _val = toString(ctx.resolve(name), context, reserved, false, null, null, len);
-            if (buf.length() > 0)
-              buf.append(explode && explodeDelim != null ? explodeDelim : ",");
+            appendif(buf.length()>0,buf,exp);
             buf.append(name)
                .append(explode ? '=' : ',')
                .append(_val);
@@ -282,13 +236,10 @@ public abstract class Operation implemen
           return buf.toString();
         } else if (val instanceof Iterable) {
             StringBuilder buf = new StringBuilder();
-            Iterable<Object> i = (Iterable<Object>)val;
-            for (Object obj : i) {
-                if (buf.length() > 0)
-                  buf.append(explode && explodeDelim != null ? explodeDelim : ",");
-                if (explode && explodePfx != null) 
-                  buf.append(explodePfx);
-                buf.append(toString(obj, context, reserved, false, null, null, len));
+            for (Object obj : (Iterable<Object>)val) {
+              appendif(buf.length()>0,buf,exp);
+              appendif(explode && explodePfx != null,buf,explodePfx);
+              buf.append(toString(obj, context, reserved, false, null, null, len));
             }
             return buf.toString();
         } else if (val instanceof Iterator) {
@@ -296,10 +247,8 @@ public abstract class Operation implemen
           Iterator<Object> i = (Iterator<Object>)val;
           while (i.hasNext()) {
               Object obj = i.next();
-              if (buf.length() > 0)
-                buf.append(explode && explodeDelim != null ? explodeDelim : ",");
-              if (explode && explodePfx != null) 
-                buf.append(explodePfx);
+              appendif(buf.length()>0,buf,exp);
+              appendif(explode && explodePfx != null,buf,explodePfx);
               buf.append(toString(obj, context, reserved, false, null, null, len));
           }
           return buf.toString();
@@ -308,10 +257,8 @@ public abstract class Operation implemen
           Enumeration<Object> i = (Enumeration<Object>)val;
           while (i.hasMoreElements()) {
               Object obj = i.nextElement();
-              if (buf.length() > 0)
-                buf.append(explode && explodeDelim != null ? explodeDelim : ",");
-              if (explode && explodePfx != null) 
-                buf.append(explodePfx);
+              appendif(buf.length()>0,buf,exp);
+              appendif(explode && explodePfx != null,buf,explodePfx);
               buf.append(toString(obj, context, reserved, false, null, null, len));
           }
           return buf.toString();
@@ -321,8 +268,7 @@ public abstract class Operation implemen
             for (Map.Entry<Object, Object> entry : map.entrySet()) {
               String _key = toString(entry.getKey(), context, reserved, false, null, null, len);
               String _val = toString(entry.getValue(), context, reserved, false, null, null, len);
-              if (buf.length() > 0)
-                buf.append(explode && explodeDelim != null ? explodeDelim : ",");
+              appendif(buf.length()>0,buf,exp);
               buf.append(_key)
                  .append(explode ? '=' : ',')
                  .append(_val);
@@ -350,9 +296,7 @@ public abstract class Operation implemen
           try {
             Future<Object> future = (Future<Object>) val;
             return toString(future.get(), context, reserved, explode, explodeDelim, explodePfx, len);
-          } catch (InterruptedException e) {
-            throw ExceptionHelper.propogate(e);
-          } catch (ExecutionException e) {
+          } catch (Throwable e) {
             throw ExceptionHelper.propogate(e);
           }
         } else {
@@ -378,7 +322,7 @@ public abstract class Operation implemen
     /**
      * Simple String Expansion ({VAR})
      */
-    private static final class DefaultOperation extends Operation {
+    static final class DefaultOperation extends Operation {
       private static final long serialVersionUID = 8676696520810767327L;
         public String evaluate(Expression exp, Context context) {
             StringBuilder buf = new StringBuilder();
@@ -396,7 +340,7 @@ public abstract class Operation implemen
     /**
      * Reserved Expansion Operation ({+VAR})
      */
-    private static final class ReservedExpansionOperation extends Operation {
+    static final class ReservedExpansionOperation extends Operation {
         private static final long serialVersionUID = 1736980072492867748L;
         public String evaluate(Expression exp, Context context) {
             StringBuilder buf = new StringBuilder();
@@ -414,7 +358,7 @@ public abstract class Operation implemen
     /**
      * Fragment Expansion Operation ({#VAR})
      */
-    private static final class FragmentExpansionOperation extends Operation {
+    static final class FragmentExpansionOperation extends Operation {
         private static final long serialVersionUID = -2207953454022197435L;
         public String evaluate(Expression exp, Context context) {
             StringBuilder buf = new StringBuilder();
@@ -434,7 +378,7 @@ public abstract class Operation implemen
     /**
      * Dot Expansion Operation ({.VAR})
      */
-    private static final class DotExpansionOperation extends Operation {
+    static final class DotExpansionOperation extends Operation {
         private static final long serialVersionUID = -4357734926260213270L;
         public String evaluate(Expression exp, Context context) {
             StringBuilder buf = new StringBuilder();
@@ -452,7 +396,7 @@ public abstract class Operation implemen
     /**
      * Path Expansion Operation ({/VAR})
      */
-    private static final class PathExpansionOperation extends Operation {
+    static final class PathExpansionOperation extends Operation {
         private static final long serialVersionUID = 5578346646541533713L;
         public String evaluate(Expression exp, Context context) {
             StringBuilder buf = new StringBuilder();
@@ -469,7 +413,7 @@ public abstract class Operation implemen
     /**
      * Path Param Expansion Operation ({;VAR})
      */
-    private static final class PathParamExpansionOperation extends Operation {
+    static final class PathParamExpansionOperation extends Operation {
         private static final long serialVersionUID = 4556090632293646419L;
         public String evaluate(Expression exp, Context context) {
             StringBuilder buf = new StringBuilder();
@@ -492,14 +436,13 @@ public abstract class Operation implemen
     /**
      * Form Expansion Operation ({?VAR})
      */
-    private static final class FormExpansionOperation extends Operation {  
+    static final class FormExpansionOperation extends Operation {  
         private static final long serialVersionUID = -2166695868296435715L;
         public String evaluate(Expression exp, Context context) {
             StringBuilder buf = new StringBuilder();
             boolean first = true;
             buf.append("?");
             for (VarSpec varspec : exp) {
-              //String val = eval(varspec, context, false, "&", varspec.getName() + "=");
               String val = eval(varspec, context, false, "&", ""); // Per Draft Seven (http://tools.ietf.org/html/draft-gregorio-uritemplate-07)
               if (context.contains(varspec.getName())) {
                 if (!first) buf.append('&');
@@ -520,12 +463,11 @@ public abstract class Operation implemen
     /**
      * Query Expansion Operation ({&VAR})
      */
-    private static final class QueryExpansionOperation extends Operation {
+    static final class QueryExpansionOperation extends Operation {
         private static final long serialVersionUID = 4029538625501399067L;
         public String evaluate(Expression exp, Context context) {
             StringBuilder buf = new StringBuilder();
             for (VarSpec varspec : exp) {
-              //String val = eval(varspec, context, false, "&", varspec.getName() + "=");
               String val = eval(varspec, context, false, "&", ""); // Per Draft Seven (http://tools.ietf.org/html/draft-gregorio-uritemplate-07)
               if (context.contains(varspec.getName())) {
                 if (varspec.isExplode()) buf.append('&');

Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/QueryContext.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/QueryContext.java?rev=1199390&r1=1199389&r2=1199390&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/QueryContext.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/QueryContext.java Tue Nov  8 19:12:16 2011
@@ -17,13 +17,18 @@
  */
 package org.apache.abdera2.common.templates;
 
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
 import org.apache.abdera2.common.iri.IRI;
+import org.apache.abdera2.common.misc.Pair;
+
+import static java.util.Collections.addAll;
+import static org.apache.abdera2.common.text.CharUtils.*;
+import static com.google.common.collect.Lists.newArrayList;
+
 import static com.google.common.base.Preconditions.*;
 
 /**
@@ -80,33 +85,22 @@ public class QueryContext extends MapCon
   }
   
   private static Map<String,Object> parse(IRI iri) {
-    checkNotNull(iri);
     Map<String,Object> map = new HashMap<String,Object>();
-    if (iri != null) {
-      String query = iri.getQuery();
-      if (query != null) {
-        String[] params = query.split("\\s*&\\s*");
-        for (String param : params) {
-          String[] pair = param.split("\\s*=\\s*",2);
-          setval(map,pair[0],pair.length==1?null:pair[1]);
-        }
-      }
-    }
+    String query = checkNotNull(iri).getQuery();
+    if (query != null)
+      for (Pair<String,String> pair : Pair.from(query,"&"))
+        setval(map,pair.first(),pair.second());
     return map;
   }
   
   @SuppressWarnings({ "rawtypes", "unchecked" })
   private static void setval(Map<String,Object> map, String key, String val) {
-    if (map.containsKey(key)) {
+    if (checkNotNull(map).containsKey(key)) {
       Object value = map.get(key);
-      if (value instanceof Collection) {
-        ((Collection)value).add(val);
-      } else {
-        List<Object> l = new ArrayList<Object>();
-        l.add(value);
-        l.add(val);
-        map.put(key, l);
-      }
+      if (value instanceof Collection)
+        addAll((Collection)value, val);
+      else
+        map.put(key, newArrayList(value,val));
     } else map.put(key,val);
   }
   
@@ -116,32 +110,26 @@ public class QueryContext extends MapCon
     buf.append('{').append(fragment?'&':'?');
     boolean first = true;
     for (String name : context) {
-      if (!first) buf.append(',');
-      else first = false;
+      first = appendcomma(first,buf);
       buf.append(name);
       Object val = context.resolve(name);
-      if (val == null)
-        buf.append('^');
-      else if (val instanceof List)
-        buf.append('*');
+      appendif(val == null, buf, "^");
+      appendif(val instanceof List, buf, "*");
     }
     buf.append('}');
     return new Template(buf.toString());
   }
   
   public static Template templateFromIri(IRI iri) {
-    checkNotNull(iri);
-    return templateFromQuery(iri.toString(), false, null);
+    return templateFromQuery(checkNotNull(iri).toString(), false, null);
   }
   
   public static Template templateFromIri(IRI iri, Context additionalParams) {
-    checkNotNull(iri);
-    return templateFromQuery(iri.toString(), false, additionalParams);
+    return templateFromQuery(checkNotNull(iri).toString(), false, additionalParams);
   }
   
   public static Template templateFromQuery(String query, boolean fragment, Context additionalParams) {
-    checkNotNull(query);
-    Context context = new QueryContext(query);
+    Context context = new QueryContext(checkNotNull(query));
     if (additionalParams != null)
       context = new DefaultingContext(context,additionalParams);
     StringBuilder buf = new StringBuilder(baseFromQuery(query));
@@ -150,34 +138,29 @@ public class QueryContext extends MapCon
   }
   
   public static String baseFromQuery(String query) {
-    checkNotNull(query);
-    IRI iri = new IRI(query);
+    IRI iri = new IRI(checkNotNull(query));
     String s = iri.resolve(iri.getPath()).toString();
     return s;
   }
   
   public static String expandQuery(String query, Context context) {
-    checkNotNull(query);
-    checkNotNull(context);
-    return expandQuery(query,context,(Template)null);
+    return expandQuery(
+      checkNotNull(query),
+      checkNotNull(context),
+      (Template)null);
   }
   
   public static String expandQuery(String query, Context context, String extender) {
-    checkNotNull(query);
-    checkNotNull(context);
-    checkNotNull(extender);
-    return expandQuery(query,context,new Template(extender));
+    return expandQuery(
+      checkNotNull(query),
+      checkNotNull(context),
+      new Template(checkNotNull(extender)));
   }
   
   public static String expandQuery(String query, Context context, Template extender) {
-    checkNotNull(query);
-    checkNotNull(context);
-    checkNotNull(extender);
-    QueryContext qc = new QueryContext(query);
-    DefaultingContext dc = new DefaultingContext(context,qc);
+    QueryContext qc = new QueryContext(checkNotNull(query));
+    DefaultingContext dc = new DefaultingContext(checkNotNull(context),qc);
     Template temp = QueryContext.templateFromQuery(query, false, qc);
-    if (extender != null)
-      temp = temp.extend(extender);
-    return temp.expand(dc);  
+    return temp.extend(checkNotNull(extender)).expand(dc);
   }
 }

Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/Template.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/Template.java?rev=1199390&r1=1199389&r2=1199390&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/Template.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/Template.java Tue Nov  8 19:12:16 2011
@@ -18,10 +18,10 @@
 package org.apache.abdera2.common.templates;
 
 import java.io.Serializable;
-import java.util.HashSet;
+import java.util.ArrayList;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
-import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -36,10 +36,15 @@ import org.apache.abdera2.common.templat
 
 import com.google.common.base.Function;
 import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+
 import static com.google.common.base.Preconditions.*;
 
 @SuppressWarnings("unchecked")
-public final class Template implements Iterable<Expression>, Serializable {
+public final class Template 
+  implements Iterable<Expression>, 
+             Serializable {
 
     private static final long serialVersionUID = -613907262632631896L;
 
@@ -48,8 +53,8 @@ public final class Template implements I
     private static final String EXP_STOP = "\\}";
 
     private final String pattern;
-    private final Set<Expression> expressions = new HashSet<Expression>();
-    private final Set<String> variables = new HashSet<String>();
+    private final Iterable<Expression> expressions;
+    private final Iterable<String> variables;
 
     /**
      * @param pattern A URI Template
@@ -57,7 +62,17 @@ public final class Template implements I
     public Template(String pattern) {
       checkNotNull(pattern, "Template pattern must not be null");
       this.pattern = pattern;
-      initExpressions();
+      this.expressions = initExpressions();
+      this.variables = initVariables(expressions);
+    }
+    
+    private static Iterable<String> initVariables(Iterable<Expression> expressions) {
+      ImmutableSet.Builder<String> builder = 
+        ImmutableSet.builder();
+      for (Expression exp : expressions)
+        for (VarSpec spec : exp)
+          builder.add(spec.getName());
+      return builder.build();
     }
     
     public Template(Object object) {
@@ -93,16 +108,16 @@ public final class Template implements I
     /**
      * Return the array of template variables
      */
-    private void initExpressions() {
-        Matcher matcher = EXPRESSION.matcher(pattern);
-        while (matcher.find()) {
-            String token = matcher.group();
-            token = token.substring(1, token.length() - 1);
-            Expression exp = new Expression(token);
-            for (VarSpec varspec : exp)
-              variables.add(varspec.getName());
-            expressions.add(exp);
-        }
+    private Iterable<Expression> initExpressions() {
+      List<Expression> expressions = new ArrayList<Expression>();
+      Matcher matcher = EXPRESSION.matcher(pattern);
+      while (matcher.find()) {
+        String token = matcher.group();
+        token = token.substring(1, token.length() - 1);
+        Expression exp = new Expression(token);
+        expressions.add(exp);
+      }
+      return Iterables.unmodifiableIterable(expressions);
     }
 
     /**

Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/TemplateManager.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/TemplateManager.java?rev=1199390&r1=1199389&r2=1199390&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/TemplateManager.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/TemplateManager.java Tue Nov  8 19:12:16 2011
@@ -41,8 +41,8 @@ public class TemplateManager<T>
       new HashMap<T,Template>();
     protected boolean isiri;
     protected IRI base;
-    protected final MultiContext contextDefaults = 
-      new MultiContext();
+    protected final MultiContext.Builder defaultContexts = 
+      MultiContext.make();
        
     public Builder() {}
     
@@ -86,25 +86,25 @@ public class TemplateManager<T>
     
     public <M extends Builder<T>>M withDefaults(Context context) {
       checkNotNull(context);
-      this.contextDefaults.add(context);
+      this.defaultContexts.with(context);
       return (M)this;
     }
     
     public <M extends Builder<T>>M withDefaults(MapContext context) {
       checkNotNull(context);
-      this.contextDefaults.add(context);
+      this.defaultContexts.with(context);
       return (M)this;
     }
     
     public <M extends Builder<T>>M withDefaults(Map<String,Object> map) {
       checkNotNull(map);
-      this.contextDefaults.add(new MapContext(map));
+      this.defaultContexts.with(new MapContext(map));
       return (M)this;
     }
     
     public <M extends Builder<T>>M withDefaults(Object context) {
       checkNotNull(context);
-      this.contextDefaults.add(new ObjectContext(context));
+      this.defaultContexts.with(new ObjectContext(context));
       return (M)this;
     }
     
@@ -121,7 +121,7 @@ public class TemplateManager<T>
     
     public TemplateManager<T> get() {
       return new TemplateManager<T>(
-        templates,isiri,base,contextDefaults);
+        templates,isiri,base,defaultContexts.get());
     }
   }
   

Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/Codec.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/Codec.java?rev=1199390&r1=1199389&r2=1199390&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/Codec.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/Codec.java Tue Nov  8 19:12:16 2011
@@ -18,6 +18,7 @@
 package org.apache.abdera2.common.text;
 
 import java.io.ByteArrayInputStream;
+import java.util.Set;
 
 import org.apache.commons.codec.DecoderException;
 import org.apache.commons.codec.EncoderException;
@@ -27,6 +28,7 @@ import org.apache.commons.codec.net.BCod
 import org.apache.commons.codec.net.QCodec;
 
 import com.google.common.base.Function;
+import com.google.common.collect.ImmutableSet;
 
 public enum Codec {
     B, 
@@ -71,18 +73,19 @@ public enum Codec {
       return STAR._encode(value, charset);
     }
     
+    private static final Set<StringDecoder> codecs =
+      ImmutableSet.<StringDecoder>of(
+        new StarCodec(),
+        new BCodec(),
+        new QCodec());
+    
     public static String decode(String value) {
         if (value == null)
           return null;
-        Class<?>[] _classes = 
-          {StarCodec.class,BCodec.class,QCodec.class};
-        for (Class<?> _class : _classes) {
+        for (StringDecoder dec : codecs) {
           try {
-            StringDecoder dec = 
-              (StringDecoder) _class.newInstance();
             return dec.decode(value);
           } catch (DecoderException de) {
-            // try next
           } catch (Exception e) {
             break;
           }

Modified: abdera/abdera2/core/src/main/java/org/apache/abdera2/factory/AbstractExtensionFactory.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/core/src/main/java/org/apache/abdera2/factory/AbstractExtensionFactory.java?rev=1199390&r1=1199389&r2=1199390&view=diff
==============================================================================
--- abdera/abdera2/core/src/main/java/org/apache/abdera2/factory/AbstractExtensionFactory.java (original)
+++ abdera/abdera2/core/src/main/java/org/apache/abdera2/factory/AbstractExtensionFactory.java Tue Nov  8 19:12:16 2011
@@ -39,6 +39,8 @@ import org.apache.abdera2.model.ElementW
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
+import static com.google.common.base.Preconditions.*;
+
 /**
  * <p>
  * Provides a base implementation for ExtensionFactory instances. By extending this, specific extension factories need
@@ -136,10 +138,8 @@ public abstract class AbstractExtensionF
      * with an IllegalArgumentException.
      */
     protected AbstractExtensionFactory addImpl(Class<? extends ElementWrapper> impl) {
-      QName qname = AnnoUtil.getQName(impl);
-      if (qname == null)
-        throw new IllegalArgumentException();
-      addImpl(qname,impl);
+      QName qname = AnnoUtil.getQName(checkNotNull(impl));
+      addImpl(checkNotNull(qname),impl);
       return this;
     }
     
@@ -148,15 +148,12 @@ public abstract class AbstractExtensionF
      * method ignores the QName annotation and uses the provided qname
      */
     protected AbstractExtensionFactory addImpl(QName qname, Class<? extends ElementWrapper> impl) {
-        if (qname == null || impl == null)
-          throw new IllegalArgumentException();
+        checkNotNull(qname);
+        checkNotNull(impl);
         log.debug(String.format("Adding implementation for [%s] : %s",qname.toString(),impl));
-        Constructor<? extends ElementWrapper> con = constructor(impl);
-        if (con == null) {
-          log.debug("An appropriate ElementWrapper constructor could not be found");
-          throw new IllegalArgumentException("Missing Element Wrapper Constructor.");
-        }
-        impls.put(qname, con);
+        impls.put(qname, 
+          checkNotNull(constructor(impl), 
+            "Missing Element Wrapper Constructor"));
         return this;
     }
    

Modified: abdera/abdera2/core/src/main/java/org/apache/abdera2/factory/ExtensionFactoryMap.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/core/src/main/java/org/apache/abdera2/factory/ExtensionFactoryMap.java?rev=1199390&r1=1199389&r2=1199390&view=diff
==============================================================================
--- abdera/abdera2/core/src/main/java/org/apache/abdera2/factory/ExtensionFactoryMap.java (original)
+++ abdera/abdera2/core/src/main/java/org/apache/abdera2/factory/ExtensionFactoryMap.java Tue Nov  8 19:12:16 2011
@@ -41,9 +41,8 @@ public class ExtensionFactoryMap 
       new HashSet<String>();
     
     public ExtensionFactoryMap(Iterable<ExtensionFactory> factories) {
-      for (ExtensionFactory factory : factories) {
+      for (ExtensionFactory factory : factories)
         addFactory(factory);
-      }
     }
 
     @SuppressWarnings("unchecked")
@@ -81,10 +80,9 @@ public class ExtensionFactoryMap 
     public <T extends Base> String getMimeType(T base) {
         Element element = base instanceof Element ? (Element)base : ((Document<?>)base).getRoot();
         String namespace = element.getQName().getNamespaceURI();
-        for (ExtensionFactory factory : factories) {
+        for (ExtensionFactory factory : factories)
             if (factory.handlesNamespace(namespace))
                 return factory.getMimeType(base);
-        }
         return null;
     }