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/10/20 00:33:52 UTC

svn commit: r1186541 [4/8] - in /abdera/abdera2: ./ .settings/ activities/ activities/.settings/ activities/src/main/java/org/apache/abdera2/activities/client/ activities/src/main/java/org/apache/abdera2/activities/extra/ activities/src/main/java/org/a...

Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/DefaultingContext.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/DefaultingContext.java?rev=1186541&r1=1186540&r2=1186541&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/DefaultingContext.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/DefaultingContext.java Wed Oct 19 22:33:04 2011
@@ -16,7 +16,7 @@
  * directory of this distribution.
  */
 package org.apache.abdera2.common.templates;
-
+import static com.google.common.base.Preconditions.*;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Set;
@@ -30,8 +30,7 @@ public class DefaultingContext 
   
   public DefaultingContext(Context main, Context defaults) {
     super(main);
-    if (defaults == null)
-      throw new IllegalArgumentException();
+    checkNotNull(defaults);
     this.defaults = defaults;
   }
 
@@ -61,4 +60,30 @@ public class DefaultingContext 
     buf.append("Default Context: " + defaults);
     return buf.toString();
   }
+
+  @Override
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((defaults == null) ? 0 : defaults.hashCode());
+    return result;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    DefaultingContext other = (DefaultingContext) obj;
+    if (defaults == null) {
+      if (other.defaults != null)
+        return false;
+    } else if (!defaults.equals(other.defaults))
+      return false;
+    return true;
+  }
+  
 }

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=1186541&r1=1186540&r2=1186541&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 Wed Oct 19 22:33:04 2011
@@ -18,7 +18,7 @@
 package org.apache.abdera2.common.templates;
 
 import java.util.Iterator;
-
+import static com.google.common.base.Preconditions.*;
 @SuppressWarnings("unchecked")
 public abstract class DelegatingContext extends AbstractContext {
 
@@ -26,6 +26,7 @@ public abstract class DelegatingContext 
     protected final Context subcontext;
 
     protected DelegatingContext(Context subcontext) {
+        checkNotNull(subcontext);
         this.subcontext = subcontext;
     }
 

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=1186541&r1=1186540&r2=1186541&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 Wed Oct 19 22:33:04 2011
@@ -28,6 +28,9 @@ import org.apache.abdera2.common.templat
 import org.apache.abdera2.common.templates.Expression;
 import org.apache.abdera2.common.templates.Operation;
 
+import static com.google.common.base.Preconditions.*;
+import static org.apache.abdera2.common.misc.MorePreconditions.*;
+
 public class Expression 
   implements Iterable<Expression.VarSpec>, Serializable {
   
@@ -101,12 +104,10 @@ public class Expression 
 
   private void parse() {
     Matcher mt = EXPRESSION.matcher(EXP);
-    if (mt.find()) {
+    if (checkArgument(mt.find(),"Invalid Expression")) {
       this.op = Operation.get(mt.group(1)); // grab the operation
       String varlist = mt.group(2);
-      if (varlist == null)
-          throw new IllegalArgumentException(
-              "Invalid Expression: No variables");
+      checkNotNull(varlist, "No variables");
       String[] vars = 
         varlist.split("\\s*,\\s*");
       for (String var : vars) {
@@ -114,13 +115,8 @@ public class Expression 
         if (vt.find()) {
           VarSpec spec = new VarSpec(vt.group(1),vt.group(2));
           varspecs.add(spec);
-        } else {
-          //throw new IllegalArgumentException(
-          //  "Invalid Expression: Invalid variable spec");
         }
       }
-    } else {
-      throw new IllegalArgumentException("Invalid Expression");
     }
   }
   

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=1186541&r1=1186540&r2=1186541&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 Wed Oct 19 22:33:04 2011
@@ -24,6 +24,9 @@ import java.util.Map;
 import org.apache.abdera2.common.templates.Context;
 import org.apache.abdera2.common.templates.MapContext;
 
+import com.google.common.collect.Multimap;
+import static com.google.common.base.Preconditions.*;
+
 /**
  * Context implementation based on a HashMap
  */
@@ -51,6 +54,7 @@ public class MapContext extends HashMap<
     }
     
     public MapContext(Context context) {
+      checkNotNull(context);
       for (String name : context)
         put(name, context.resolve(name));
     }
@@ -96,4 +100,11 @@ public class MapContext extends HashMap<
     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;
+    }
 }

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=1186541&r1=1186540&r2=1186541&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 Wed Oct 19 22:33:04 2011
@@ -22,6 +22,7 @@ import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
+import static com.google.common.base.Preconditions.*;
 
 public class MultiContext 
   extends CachingContext {
@@ -36,24 +37,26 @@ public class MultiContext 
   }
   
   public MultiContext(Iterable<Context> contexts) {
+    checkNotNull(contexts);
     for (Context context : contexts)
       this.contexts.add(context);
   }
   
   public MultiContext(Collection<Context> contexts) {
+    checkNotNull(contexts);
     if (contexts == null)
       throw new IllegalArgumentException();
     this.contexts.addAll(contexts);
   }
   
   public void add(Context context) {
-    if (context == null)
-      throw new IllegalArgumentException();
+    checkNotNull(context);
     this.contexts.add(context);
   }
   
   @SuppressWarnings("unchecked")
   public void add(Object object) {
+    checkNotNull(object);
     this.contexts.add(
       object instanceof Context ? 
         (Context)object :

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=1186541&r1=1186540&r2=1186541&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 Wed Oct 19 22:33:04 2011
@@ -26,6 +26,8 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 
+import static com.google.common.base.Preconditions.*;
+import static org.apache.abdera2.common.misc.MorePreconditions.*;
 import org.apache.abdera2.common.templates.CachingContext;
 import org.apache.abdera2.common.templates.ObjectContext;
 import org.apache.abdera2.common.anno.Name;
@@ -35,24 +37,26 @@ public final class ObjectContext extends
 
     private static final long serialVersionUID = -1387599933658718221L;
     private final Object target;
-    private final Map<String, AccessibleObject> accessors = new HashMap<String, AccessibleObject>();
+    private final Map<String, AccessibleObject> accessors = 
+      new HashMap<String, AccessibleObject>();
 
     public ObjectContext(Object object) {
         this(object, false);
     }
 
     public ObjectContext(Object object, boolean isiri) {
-        if (object == null)
-            throw new IllegalArgumentException();
+        checkNotNull(object);
         this.target = object;
         setIri(isiri);
         initMethods();
     }
-
+    
     private void initMethods() {
         Class<?> _class = target.getClass();
-        if (_class.isAnnotation() || _class.isArray() || _class.isEnum() || _class.isPrimitive())
-            throw new IllegalArgumentException();
+        checkArguments(!_class.isAnnotation(),
+                       !_class.isArray(),
+                       !_class.isEnum(),
+                       !_class.isPrimitive());
         if (!_class.isInterface()) {
             Field[] fields = _class.getFields();
             for (Field field : fields) {

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=1186541&r1=1186540&r2=1186541&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 Wed Oct 19 22:33:04 2011
@@ -21,12 +21,17 @@ 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;
 import org.apache.abdera2.common.templates.Context;
 import org.apache.abdera2.common.templates.Expression;
 import org.apache.abdera2.common.templates.Operation;
@@ -34,7 +39,12 @@ import org.apache.abdera2.common.templat
 import org.apache.abdera2.common.text.CharUtils;
 import org.apache.abdera2.common.text.UrlEncoding;
 
+import com.google.common.base.Optional;
+import com.google.common.base.Supplier;
+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.*;
 
 @SuppressWarnings("unchecked")
 public abstract class Operation implements Serializable {
@@ -66,19 +76,14 @@ public abstract class Operation implemen
      * any template expansion occurs.
      */
     public static void register(String key, Operation operation) {
-        if ("+#./;?&".contains(key))
-          throw new IllegalArgumentException(
-            "Cannot override reserved operators");
-        operations.put(key, operation);
+      checkArgument("+#./;?&".contains(key), "Cannot override reserved operators");
+      operations.put(key, operation);
     }
 
     public static Operation get(String name) {
-        if (name == null)
-            name = "";
-        Operation op = operations.get(name);
-        if (op != null)
-            return op;
-        throw new UnsupportedOperationException(name);
+      Operation op = operations.get(name!=null?name:"");
+      if (op != null) return op;
+      throw new UnsupportedOperationException(name);
     }
 
     protected static String eval(
@@ -87,6 +92,8 @@ public abstract class Operation implemen
         boolean reserved, 
         String explodeDelim, 
         String explodePfx) {
+        checkNotNull(varspec);
+        checkNotNull(context);
         String name = varspec.getName();
         Object rep = context.resolve(name);
         String val = toString(
@@ -321,6 +328,33 @@ public abstract class Operation implemen
                  .append(_val);
             }
             return buf.toString();
+        } else if (val instanceof Supplier) {
+          return toString(((Supplier<?>)val).get(), context, reserved, explode, explodeDelim, explodePfx, len);
+        } else if (val instanceof Optional) {
+          Optional<?> o = (Optional<?>) val;
+          return toString(o.orNull(), context, reserved, explode, explodeDelim, explodePfx, len);
+        } else if (val instanceof Multimap) {
+          Multimap<?,?> mm = (Multimap<?,?>)val;
+          return toString(mm.asMap(), context, reserved, explode, explodeDelim, explodePfx, len);
+        } else if (val instanceof Callable) {
+          Callable<Object> callable = (Callable<Object>) val;
+          try {
+            return toString(callable.call(), context, reserved, explode, explodeDelim, explodePfx, len);
+          } catch (Exception e) {
+            throw ExceptionHelper.propogate(e);
+          }
+        } else if (val instanceof Reference) {
+          Reference<Object> ref = (Reference<Object>) val;
+          return toString(ref.get(), context, reserved, explode, explodeDelim, explodePfx, len);
+        } else if (val instanceof Future) {
+          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) {
+            throw ExceptionHelper.propogate(e);
+          }
         } else {
             if (val != null)
               val = normalize(val.toString());

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=1186541&r1=1186540&r2=1186541&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 Wed Oct 19 22:33:04 2011
@@ -24,6 +24,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.abdera2.common.iri.IRI;
+import static com.google.common.base.Preconditions.*;
 
 /**
  * Constructs a mutable Template Context based on an existing IRI/URI 
@@ -79,6 +80,7 @@ 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();
@@ -109,6 +111,7 @@ public class QueryContext extends MapCon
   }
   
   public static Template templateFromContext(Context context, boolean fragment) {
+    checkNotNull(context);
     StringBuilder buf = new StringBuilder();
     buf.append('{').append(fragment?'&':'?');
     boolean first = true;
@@ -127,14 +130,17 @@ public class QueryContext extends MapCon
   }
   
   public static Template templateFromIri(IRI iri) {
+    checkNotNull(iri);
     return templateFromQuery(iri.toString(), false, null);
   }
   
   public static Template templateFromIri(IRI iri, Context additionalParams) {
+    checkNotNull(iri);
     return templateFromQuery(iri.toString(), false, additionalParams);
   }
   
   public static Template templateFromQuery(String query, boolean fragment, Context additionalParams) {
+    checkNotNull(query);
     Context context = new QueryContext(query);
     if (additionalParams != null)
       context = new DefaultingContext(context,additionalParams);
@@ -144,21 +150,29 @@ public class QueryContext extends MapCon
   }
   
   public static String baseFromQuery(String query) {
+    checkNotNull(query);
     IRI iri = new IRI(query);
     String s = iri.resolve(iri.getPath()).toString();
-    //return s.equals(query) ? "" : s;
     return s;
   }
   
   public static String expandQuery(String query, Context context) {
+    checkNotNull(query);
+    checkNotNull(context);
     return expandQuery(query,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));
   }
   
   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);
     Template temp = QueryContext.templateFromQuery(query, false, qc);

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=1186541&r1=1186540&r2=1186541&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 Wed Oct 19 22:33:04 2011
@@ -33,6 +33,9 @@ import org.apache.abdera2.common.templat
 import org.apache.abdera2.common.templates.Template;
 import org.apache.abdera2.common.templates.Expression.VarSpec;
 
+import com.google.common.base.Supplier;
+import static com.google.common.base.Preconditions.*;
+
 @SuppressWarnings("unchecked")
 public final class Template implements Iterable<Expression>, Serializable {
 
@@ -50,10 +53,9 @@ public final class Template implements I
      * @param pattern A URI Template
      */
     public Template(String pattern) {
-        if (pattern == null)
-          throw new IllegalArgumentException("Template pattern must not be null");
-        this.pattern = pattern;
-        initExpressions();
+      checkNotNull(pattern, "Template pattern must not be null");
+      this.pattern = pattern;
+      initExpressions();
     }
     
     public Template(Object object) {
@@ -73,10 +75,9 @@ public final class Template implements I
         uriTemplate != null ?
            uriTemplate.value() :
            object instanceof TemplateProvider ? 
-             ((TemplateProvider)object).getTemplate() : 
+             ((TemplateProvider)object).get() : 
              null;
-      if (pattern == null)
-        throw new IllegalArgumentException();
+      checkNotNull(pattern);
       return pattern;
     }
 
@@ -177,8 +178,8 @@ public final class Template implements I
     }
 
     public static String expand(String pattern, Context context) {
-        if (context == null || pattern == null)
-            throw new IllegalArgumentException();
+        checkNotNull(context);
+        checkNotNull(pattern);
         return new Template(pattern).expand(context);
     }
 
@@ -187,8 +188,8 @@ public final class Template implements I
     }
 
     public static String expand(String pattern, Object object, boolean isiri) {
-        if (object == null || pattern == null)
-            throw new IllegalArgumentException();
+        checkNotNull(pattern);
+        checkNotNull(object);
         return new Template(pattern).expand(object, isiri);
     }
 
@@ -198,6 +199,7 @@ public final class Template implements I
     
     @SuppressWarnings("rawtypes")
     private static Context asContext(Object obj, boolean isiri) {
+      checkNotNull(obj);
       return 
         obj instanceof Context ? 
           (Context)obj : 
@@ -210,8 +212,7 @@ public final class Template implements I
      * Use an Object annotated with the URITemplate annotation to expand a template
      */
     public static String expandAnnotated(Object object, Object additional) {
-        if (object == null)
-            throw new IllegalArgumentException();
+        checkNotNull(object);
         Object contextObject = null;
         Class<?> _class = null;
         if (object instanceof Class<?>) {
@@ -225,20 +226,16 @@ public final class Template implements I
           }
         }
         URITemplate uritemplate = (URITemplate)_class.getAnnotation(URITemplate.class);
-        if (uritemplate != null) {
-            if (additional != null) {
-              Context add = asContext(additional, uritemplate.isiri());
-              Context main = asContext(contextObject, uritemplate.isiri());
-              contextObject = new DefaultingContext(add,main);
-            }
-            return expand(
-              uritemplate.value(), 
-              contextObject, 
-              uritemplate.isiri());
-        } else {
-            throw new IllegalArgumentException("No URI Template provided");
+        checkNotNull(uritemplate, "No URI Template Provided");
+        if (additional != null) {
+          Context add = asContext(additional, uritemplate.isiri());
+          Context main = asContext(contextObject, uritemplate.isiri());
+          contextObject = new DefaultingContext(add,main);
         }
-
+        return expand(
+          uritemplate.value(), 
+          contextObject, 
+          uritemplate.isiri());
     }
     
     public static Context getAnnotatedContext(Object object) {
@@ -261,4 +258,20 @@ public final class Template implements I
         buf.append(template);
       return new Template(buf.toString());
     }
+    
+    public Supplier<String> supplierFor(Object context) {
+      return new TSupplier(this,context);
+    }
+    
+    private static class TSupplier implements Supplier<String> {
+      private final Template template;
+      private final Object context;
+      TSupplier(Template template, Object context) {
+        this.template = template;
+        this.context = context;
+      }
+      public String get() {
+        return template.expand(context);
+      }
+    }
 }

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=1186541&r1=1186540&r2=1186541&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 Wed Oct 19 22:33:04 2011
@@ -16,121 +16,147 @@
  * directory of this distribution.
  */
 package org.apache.abdera2.common.templates;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 
 import org.apache.abdera2.common.iri.IRI;
 
-
+import com.google.common.base.Supplier;
+import static com.google.common.base.Preconditions.*;
+import static org.apache.abdera2.common.misc.MorePreconditions.*;
+@SuppressWarnings("unchecked")
 public class TemplateManager<T>
   implements Iterable<T> { 
 
+  public static <M>Builder<M> make() {
+    return new Builder<M>();
+  }
+  
+  public static class Builder<T> {
+    
+    protected final Map<T,Template> templates = 
+      new HashMap<T,Template>();
+    protected boolean isiri;
+    protected IRI base;
+    protected final MultiContext contextDefaults = 
+      new MultiContext();
+       
+    public Builder() {}
+    
+    public <M extends Builder<T>>M add(T key, Template template) {
+      checkNotNull(key);
+      checkNotNull(template);
+      this.templates.put(key,template);
+      return (M)this;
+    }
+    
+    public <M extends Builder<T>>M add(T key, String template) {
+      checkNotNull(key);
+      checkNotNull(template);
+      return (M)add(key, new Template(template));
+    }
+    
+    public <M extends Builder<T>>M add(T key, Object template) {
+      checkNotNull(template);
+      checkNotNull(key);
+      checkArgumentTypes(template,Map.class,Collection.class);
+      if (template instanceof Supplier)
+        return add(key,((Supplier<?>)template).get());
+      Template temp = 
+        template instanceof Template ?
+          (Template)template :
+        new Template(template);
+      return (M)add(key, temp);
+    }
+    
+    public <M extends Builder<T>>M add(Map<T,Object> templates) {
+      checkNotNull(templates);
+      for (Map.Entry<T,Object> entry : templates.entrySet())
+        add(entry.getKey(),entry.getValue());
+      return (M)this;
+    }
+    
+    public <M extends Builder<T>>M asIri() {
+      this.isiri = true;
+      return (M)this;
+    }
+    
+    public <M extends Builder<T>>M withDefaults(Context context) {
+      checkNotNull(context);
+      this.contextDefaults.add(context);
+      return (M)this;
+    }
+    
+    public <M extends Builder<T>>M withDefaults(MapContext context) {
+      checkNotNull(context);
+      this.contextDefaults.add(context);
+      return (M)this;
+    }
+    
+    public <M extends Builder<T>>M withDefaults(Map<String,Object> map) {
+      checkNotNull(map);
+      this.contextDefaults.add(new MapContext(map));
+      return (M)this;
+    }
+    
+    public <M extends Builder<T>>M withDefaults(Object context) {
+      checkNotNull(context);
+      this.contextDefaults.add(new ObjectContext(context));
+      return (M)this;
+    }
+    
+    public <M extends Builder<T>>M withBase(IRI iri) {
+      checkNotNull(iri);
+      this.base = iri;
+      return (M)this;
+    }
+    
+    public <M extends Builder<T>>M withBase(String iri) {
+      checkNotNull(iri);
+      return (M)withBase(new IRI(iri));
+    }
+    
+    public TemplateManager<T> get() {
+      return new TemplateManager<T>(
+        templates,isiri,base,contextDefaults);
+    }
+  }
+  
   private final Map<T,Template> templates = 
     new HashMap<T,Template>();
   private final boolean isiri;
   private final IRI base;
   private final Context contextDefaults;
 
-  public TemplateManager(String base) {
-    this(new IRI(base));
-  }
-  
-  public TemplateManager(IRI base) {
-    this.isiri = true;
-    this.base = base;
-    this.contextDefaults = null;
-  }
-  
-  public TemplateManager() {
-    this.isiri = true;
-    this.base = null;
-    this.contextDefaults = null;
-  }
-  
-  public TemplateManager(String base, boolean iri) {
-    this(new IRI(base),iri);
+  protected TemplateManager(
+    Map<T,Template> templates, 
+    boolean isiri, 
+    IRI base, 
+    Context contextDefaults) {
+      this.templates.putAll(templates);
+      this.isiri = isiri;
+      this.base = base;
+      this.contextDefaults = contextDefaults;
   }
-  
-  public TemplateManager(IRI base, boolean iri) {
-    this.isiri = iri;
-    this.base = base;
-    this.contextDefaults = null;
-  }
-  
-  public TemplateManager(boolean iri) {
-    this.isiri = iri;
-    this.base = null;
-    this.contextDefaults = null;
-  }
-
-  public TemplateManager(String base, Context defaults) {
-    this(new IRI(base),defaults);
-  }
-  
-  public TemplateManager(IRI base, Context defaults) {
-    if (defaults == null)
-      throw new IllegalArgumentException();
-    this.isiri = defaults.isIri();
-    this.contextDefaults = defaults;
-    this.base = base;
-  }
-  
-  public TemplateManager(Context defaults) {
-    this((IRI)null,defaults);
-  }
-  
-  public TemplateManager(String base, Object defaults) {
-    this(new IRI(base),defaults);
-  }
-  
-  public TemplateManager(IRI base, Object defaults) {
-    this(base,defaults,true);
-  }
- 
-  public TemplateManager(Object defaults) {
-    this((IRI)null,defaults,true);
-  }
-  
-  public TemplateManager(Object defaults, boolean isiri) {
-    this(_innerContext(defaults,isiri));
-  }
-  
-  public TemplateManager(String base, Object defaults, boolean isiri) {
-    this(new IRI(base),defaults,isiri);
-  }
-  
-  public TemplateManager(IRI base, Object defaults, boolean isiri) {
-    this(base,_innerContext(defaults,isiri));
-  }
-  
+    
   public Context getDefaultContext() {
     return this.contextDefaults;
   }
   
-  public void add(T key, Template template) {
-    this.templates.put(key,template);
-  }
-  
-  public void add(T key, String template) {
-    add(key, new Template(template));
-  }
-  
-  public void add(T key, Object template) {
-    add(key, new Template(template));
-  }
-  
-  public void add(Map<T,Object> templates) {
-    TemplateManager<T> tm = fromMap(templates);
-    this.templates.putAll(tm.templates);
-  }
-  
   public String expandAndResolve(T key, Object object, String base) {
+    checkNotNull(key);
+    checkNotNull(object);
+    checkNotNull(base);
     IRI iri = expandAndResolve(key,object,new IRI(base));
     return iri != null ? iri.toString() : null;
   }
   
   public IRI expandAndResolve(T key, Object object, IRI base) {
+    checkNotNull(key);
+    checkNotNull(object);
+    checkNotNull(base);
     String ex = expand(key,object);
     return ex != null ? 
         base == null ? 
@@ -162,6 +188,8 @@ public class TemplateManager<T>
   }
   
   public String expand(T key, Object object) {
+    checkNotNull(key);
+    checkNotNull(object);
     if (!templates.containsKey(key))
       return null;
     Template template = templates.get(key);
@@ -169,19 +197,20 @@ public class TemplateManager<T>
   }
   
   public String expand(T key) {
-    if (contextDefaults == null)
-      throw new IllegalArgumentException();
+    checkNotNull(key);
+    checkNotNull(contextDefaults);
     return expand(key,contextDefaults);
   }
   
   public String expand(T key, Context context) {
+    checkNotNull(key);
+    checkNotNull(context);
     if (!templates.containsKey(key))
       return null;
     Template template = templates.get(key);
     return template.expand(_wrap(context,contextDefaults));
   }
   
-  @SuppressWarnings("unchecked")
   private static Context _innerContext(Object object, boolean isiri) {
     return object instanceof Context ? (Context)object : object instanceof Map
         ? new MapContext((Map<String,Object>)object, isiri) : new ObjectContext(object, isiri);
@@ -232,11 +261,38 @@ public class TemplateManager<T>
     return true;
   }
  
-  public static <T>TemplateManager<T> fromMap(Map<T,Object> map) {
-    TemplateManager<T> tm = new TemplateManager<T>();
-    for (Map.Entry<T, Object> entry : map.entrySet()) {
-      tm.add(entry.getKey(),entry.getValue());
+  public Supplier<String> supplierFor(T key, Object context) {
+    checkNotNull(key);
+    checkNotNull(context);
+    return new TMSupplier<T>(this,key,context);
+  }
+  
+  public Supplier<String> supplierFor(T key) {
+    checkNotNull(key);
+    return new TMSupplier<T>(this,key,null);
+  }
+  
+  private static class TMSupplier<T>
+    implements Supplier<String> {
+    private final T key;
+    private final TemplateManager<T> tm;
+    private final Object context;
+    TMSupplier(TemplateManager<T> tm, T key, Object context) {
+      this.key = key;
+      this.tm = tm;
+      this.context = context;
+    }
+    public String get() {
+      return context != null ?
+        tm.expand(key,context) : 
+        tm.expand(key);
     }
-    return tm;
+  }
+  
+  public static <T>TemplateManager<T> fromMap(Map<T,Object> map) {
+    checkNotNull(map);
+    Builder<T> b = make();
+    b.add(map);
+    return b.get();
   }
 }

Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/TemplateProvider.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/TemplateProvider.java?rev=1186541&r1=1186540&r2=1186541&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/TemplateProvider.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/TemplateProvider.java Wed Oct 19 22:33:04 2011
@@ -17,8 +17,8 @@
  */
 package org.apache.abdera2.common.templates;
 
-public interface TemplateProvider {
+import com.google.common.base.Supplier;
 
-  String getTemplate();
+public interface TemplateProvider extends Supplier<String> {
   
 }

Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/CharUtils.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/CharUtils.java?rev=1186541&r1=1186540&r2=1186541&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/CharUtils.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/CharUtils.java Wed Oct 19 22:33:04 2011
@@ -26,556 +26,87 @@ public final class CharUtils {
 
     private CharUtils() {
     }
-
-    private static boolean inRange(int codepoint, int low, int high) {
-        return codepoint >= low && codepoint <= high;
-    }
-
-    /**
-     * True if the codepoint is a valid hex digit
-     */
-    private static boolean isHex (int codepoint){
-        return isDigit(codepoint) || 
-               CharUtils.inRange(codepoint, 'a', 'f') || 
-               CharUtils.inRange(codepoint, 'A', 'F');
-    }
-    
-    private interface Filter {
-      /**
-       * Return true if the codepoint should be rejected, false if it 
-       * should be accepted
-       */
-      boolean filter(int c);
-
-      public static final Filter NONOPFILTER = new Filter() {
-          public boolean filter(int c) {
-              return true;
-          }
-      };
-  }
-
-
+   
     public static enum Profile {
-        NONE(new Filter() {
-            public boolean filter(int codepoint) {
-                return true;
-            }
-        }), NONOP(Filter.NONOPFILTER)
-          , ALPHA(new Filter() {
-            public boolean filter(int codepoint) {
-                return !isAlpha(codepoint);
-            }
-        }), ALPHANUM(new Filter() {
-            public boolean filter(int codepoint) {
-                return !isAlphaDigit(codepoint);
-            }
-        }), FRAGMENT(new Filter() {
-            public boolean filter(int codepoint) {
-                return !isFragment(codepoint);
-            }
-        }), IFRAGMENT(new Filter() {
-            public boolean filter(int codepoint) {
-                return !is_ifragment(codepoint);
-            }
-        }), PATH(new Filter() {
-            public boolean filter(int codepoint) {
-                return !isPath(codepoint);
-            }
-        }), IPATH(new Filter() {
-            public boolean filter(int codepoint) {
-                return !is_ipath(codepoint);
-            }
-        }), IUSERINFO(new Filter() {
-            public boolean filter(int codepoint) {
-                return !is_iuserinfo(codepoint);
-            }
-        }), USERINFO(new Filter() {
-            public boolean filter(int codepoint) {
-                return !isUserInfo(codepoint);
-            }
-        }), QUERY(new Filter() {
-            public boolean filter(int codepoint) {
-                return !isQuery(codepoint);
-            }
-        }), IQUERY(new Filter() {
-            public boolean filter(int codepoint) {
-                return !is_iquery(codepoint);
-            }
-        }), SCHEME(new Filter() {
-            public boolean filter(int codepoint) {
-                return !isScheme(codepoint);
-            }
-        }), PATHNODELIMS(new Filter() {
-            public boolean filter(int codepoint) {
-                return !isPathNoDelims(codepoint);
-            }
-        }), IPATHNODELIMS(new Filter() {
-            public boolean filter(int codepoint) {
-                return !is_ipathnodelims(codepoint);
-            }
-        }), IPATHNODELIMS_SEG(new Filter() {
-            public boolean filter(int codepoint) {
-                return !is_ipathnodelims(codepoint) && codepoint != '@' && codepoint != ':';
-            }
-        }), IREGNAME(new Filter() {
-            public boolean filter(int codepoint) {
-                return !is_iregname(codepoint);
-            }
-        }), IHOST (new Filter(){
-            public boolean filter(int codepoint){
-                return !is_ihost(codepoint);
-            }
-        }), IPRIVATE(new Filter() {
-            public boolean filter(int codepoint) {
-                return !is_iprivate(codepoint);
-            }
-        }), RESERVED(new Filter() {
-            public boolean filter(int codepoint) {
-                return !isReserved(codepoint);
-            }
-        }), IUNRESERVED(new Filter() {
-            public boolean filter(int codepoint) {
-                return !is_iunreserved(codepoint);
-            }
-        }), UNRESERVED(new Filter() {
-            public boolean filter(int codepoint) {
-                return !isUnreserved(codepoint);
-            }            
-
-    }), RESERVEDANDUNRESERVED(new Filter() {
-        public boolean filter(int codepoint) {
-          return !isUnreserved(codepoint) && 
-                 !isReserved(codepoint);
-        }
-    }), RESERVEDANDIUNRESERVED(new Filter() {
-        public boolean filter(int codepoint) {
-          return !is_iunreserved(codepoint) && 
-                 !isReserved(codepoint);
-        }
-        
-    }), XML1RESTRICTED(new Filter() {
-        public boolean filter(int codepoint) {
-          return restricted(XMLVersion.XML10, codepoint);
-        }
-    }), XML11RESTRICTED(new Filter() {
-      public boolean filter(int codepoint) {
-        return restricted(XMLVersion.XML11, codepoint);
-      }
-    }), RFC5987(new Filter() {
-      public boolean filter(int codepoint) {
-        return !is5987(codepoint);
-      }
-    }), TOKEN(new Filter() {
-      public boolean filter(int codepoint) {
-        return !isToken(codepoint);
-      }
-        }), SCHEMESPECIFICPART(new Filter() {
-            public boolean filter(int codepoint) {
-                return !is_iunreserved(codepoint) && !isReserved(codepoint)
-                    && !is_iprivate(codepoint)
-                    && !isPctEnc(codepoint)
-                    && codepoint != '#';
-            }
-        }), AUTHORITY(new Filter() {
-            public boolean filter(int codepoint) {
-                return !is_regname(codepoint) && !isUserInfo(codepoint) && !isGenDelim(codepoint);
-            }
-        });
+        NONE(CodepointMatcher.MATCH_NONE), 
+        NONOP(CodepointMatcher.MATCH_ALL), 
+        ALPHA(CodepointMatchers.isAlpha().negate()), 
+        ALPHANUM(CodepointMatchers.isAlphaNum().negate()), 
+        FRAGMENT(CodepointMatchers.isFragment().negate()), 
+        IFRAGMENT(CodepointMatchers.isIFragment().negate()), 
+        PATH(CodepointMatchers.isPath().negate()), 
+        IPATH(CodepointMatchers.isIPath().negate()), 
+        IUSERINFO(CodepointMatchers.isIUserInfo().negate()), 
+        USERINFO(CodepointMatchers.isUserInfo().negate()), 
+        QUERY(CodepointMatchers.isQuery().negate()), 
+        IQUERY(CodepointMatchers.isIQuery().negate()), 
+        SCHEME(CodepointMatchers.isScheme().negate()), 
+        PATHNODELIMS(CodepointMatchers.isPathNoDelims().negate()), 
+        IPATHNODELIMS(CodepointMatchers.isIPathNoDelims().negate()), 
+        IPATHNODELIMS_SEG(
+            CodepointMatcher.and(
+              CodepointMatchers.isIPathNoDelims().negate(),
+              CodepointMatcher.is('@',':').negate())),
+        IREGNAME(CodepointMatchers.isRegName().negate()), 
+        IHOST (CodepointMatchers.isIHost().negate()), 
+        IPRIVATE(CodepointMatchers.isIPrivate().negate()), 
+        RESERVED(CodepointMatchers.isReserved().negate()), 
+        IUNRESERVED(CodepointMatchers.isIUnreserved().negate()), 
+        UNRESERVED(CodepointMatchers.isUnreserved().negate()), 
+        RESERVEDANDUNRESERVED(
+          CodepointMatcher.and(
+            CodepointMatchers.isUnreserved().negate(),
+            CodepointMatchers.isReserved().negate()
+          )), 
+        RESERVEDANDIUNRESERVED(
+          CodepointMatcher.and(
+            CodepointMatchers.isIUnreserved().negate(),
+            CodepointMatchers.isReserved().negate()
+          )),
+        XML1RESTRICTED(
+          CodepointMatchers.isRestricted(XMLVersion.XML10)), 
+        XML11RESTRICTED(
+          CodepointMatchers.isRestricted(XMLVersion.XML11)), 
+        RFC5987(CodepointMatchers.is5987().negate()), 
+        TOKEN(CodepointMatchers.isToken().negate()), 
+        SCHEMESPECIFICPART(
+          CodepointMatcher.and(
+            CodepointMatchers.isIUnreserved().negate(),
+            CodepointMatchers.isReserved().negate(),
+            CodepointMatchers.isIPrivate().negate(),
+            CodepointMatchers.isPct().negate(),
+            CodepointMatcher.is('#').negate())
+            ), 
+         AUTHORITY(
+           CodepointMatcher.and(
+             CodepointMatchers.isRegName().negate(),
+             CodepointMatchers.isUserInfo().negate(),
+             CodepointMatchers.isGenDelim().negate()));
         
-        private final Filter filter;
+        private final CodepointMatcher matcher;
 
-        Profile(Filter filter) {
-            this.filter = filter;
+        Profile(CodepointMatcher matcher) {
+            this.matcher = matcher;
         }
 
-        public Filter filter() {
-            return filter;
+        public CodepointMatcher matcher() {
+            return matcher;
         }
 
-        public boolean filter(int codepoint) {
-            return filter.filter(codepoint);
+        public boolean apply(int codepoint) {
+            return matcher.apply(codepoint);
         }
-    }
-
-    public static boolean is5987(int codepoint) {
-      return isAlphaDigit(codepoint) || 
-             codepoint == '!' || 
-             codepoint == '#' ||
-             codepoint == '$' || 
-             codepoint == '&' || 
-             codepoint == '+' || 
-             codepoint == '-' || 
-             codepoint == '.' ||
-             codepoint == '^' || 
-             codepoint == '_' || 
-             codepoint == '`' || 
-             codepoint == '|' || 
-             codepoint == '~';
-    }
-    
-    public static boolean isPctEnc(int codepoint) {
-        return codepoint == '%' || isDigit(codepoint)
-            || CharUtils.inRange(codepoint, 'A', 'F')
-            || CharUtils.inRange(codepoint, 'a', 'f');
-    }
-
-    public static boolean isMark(int codepoint) {
-        return codepoint == '-' || codepoint == '_'
-            || codepoint == '.'
-            || codepoint == '!'
-            || codepoint == '~'
-            || codepoint == '*'
-            || codepoint == '\\'
-            || codepoint == '\''
-            || codepoint == '('
-            || codepoint == ')'
-            || codepoint == '`'; // JIRA: https://issues.apache.org/jira/browse/ABDERA-238
-    }
-
-    public static boolean isUnreserved(int codepoint) {
-        return isAlphaDigit(codepoint) || 
-               codepoint == '-' || 
-               codepoint == '.' || 
-               codepoint == '_' || 
-               codepoint == '~' || 
-               codepoint == '`';
-    }
-
-    public static boolean isReserved(int codepoint) {
-        return isGenDelim(codepoint) || isSubDelim(codepoint);
-    }
-
-    public static boolean isGenDelim(int codepoint) {
-        return codepoint == ':' 
-            || codepoint == '/'
-            || codepoint == '?'
-            || codepoint == '#'
-            || codepoint == '['
-            || codepoint == ']'
-            || codepoint == '@';
-    }
-
-    public static boolean isSubDelim(int codepoint) {
-        return codepoint == '!' 
-            || codepoint == '$'
-            || codepoint == '&'
-            || codepoint == '\''
-            || codepoint == '('
-            || codepoint == ')'
-            || codepoint == '*'
-            || codepoint == '+'
-            || codepoint == ','
-            || codepoint == ';'
-            || codepoint == '='
-            || codepoint == '\\';
-    }
-
-    public static boolean isPchar(int codepoint) {
-        return isUnreserved(codepoint) || codepoint == ':'
-            || codepoint == '@'
-            || codepoint == '&'
-            || codepoint == '='
-            || codepoint == '+'
-            || codepoint == '$'
-            || codepoint == ',';
-    }
-
-    public static boolean isPath(int codepoint) {
-        return isPchar(codepoint) || codepoint == ';' || codepoint == '/' || codepoint == '%' || codepoint == ',';
-    }
-
-    public static boolean isPathNoDelims(int codepoint) {
-        return isPath(codepoint) && !isGenDelim(codepoint);
-    }
-
-    public static boolean isScheme(int codepoint) {
-        return isAlphaDigit(codepoint) || codepoint == '+' || codepoint == '-' || codepoint == '.';
-    }
-
-    public static boolean isUserInfo(int codepoint) {
-        return isUnreserved(codepoint) || isSubDelim(codepoint) || isPctEnc(codepoint);
-    }
-
-    public static boolean isQuery(int codepoint) {
-        return isPchar(codepoint) || codepoint == ';' || codepoint == '/' || codepoint == '?' || codepoint == '%';
-    }
-
-    public static boolean isFragment(int codepoint) {
-        return isPchar(codepoint) || codepoint == '/' || codepoint == '?' || codepoint == '%';
-    }
-
-    public static boolean is_ucschar(int codepoint) {
-        return CharUtils.inRange(codepoint, '\u00A0', '\uD7FF') 
-            || CharUtils.inRange(codepoint, '\uF900', '\uFDCF')
-            || CharUtils.inRange(codepoint, '\uFDF0', '\uFFEF')
-            || CharUtils.inRange(codepoint, 0x10000, 0x1FFFD)
-            || CharUtils.inRange(codepoint, 0x20000, 0x2FFFD)
-            || CharUtils.inRange(codepoint, 0x30000, 0x3FFFD)
-            || CharUtils.inRange(codepoint, 0x40000, 0x4FFFD)
-            || CharUtils.inRange(codepoint, 0x50000, 0x5FFFD)
-            || CharUtils.inRange(codepoint, 0x60000, 0x6FFFD)
-            || CharUtils.inRange(codepoint, 0x70000, 0x7FFFD)
-            || CharUtils.inRange(codepoint, 0x80000, 0x8FFFD)
-            || CharUtils.inRange(codepoint, 0x90000, 0x9FFFD)
-            || CharUtils.inRange(codepoint, 0xA0000, 0xAFFFD)
-            || CharUtils.inRange(codepoint, 0xB0000, 0xBFFFD)
-            || CharUtils.inRange(codepoint, 0xC0000, 0xCFFFD)
-            || CharUtils.inRange(codepoint, 0xD0000, 0xDFFFD)
-            || CharUtils.inRange(codepoint, 0xE1000, 0xEFFFD);
-    }
-
-    public static boolean is_iprivate(int codepoint) {
-        return CharUtils.inRange(codepoint, '\uE000', '\uF8FF') 
-            || CharUtils.inRange(codepoint, 0xF0000, 0xFFFFD)
-            || CharUtils.inRange(codepoint, 0x100000, 0x10FFFD);
-    }
-
-    public static boolean is_iunreserved(int codepoint) {
-        return isAlphaDigit(codepoint) 
-            || isMark(codepoint) 
-            || is_ucschar(codepoint);
-    }
-
-    public static boolean is_ipchar(int codepoint) {
-        return is_iunreserved(codepoint) || isSubDelim(codepoint)
-            || codepoint == ':'
-            || codepoint == '@'
-            || codepoint == '&'
-            || codepoint == '='
-            || codepoint == '+'
-            || codepoint == '$';
-    }
-
-    public static boolean is_ipath(int codepoint) {
-        return is_ipchar(codepoint) 
-            || codepoint == ';' 
-            || codepoint == '/' 
-            || codepoint == '%' 
-            || codepoint == ',';
-    }
-
-    public static boolean is_ipathnodelims(int codepoint) {
-        return is_ipath(codepoint) && !isGenDelim(codepoint);
-    }
-
-    public static boolean is_iquery(int codepoint) {
-        return is_ipchar(codepoint) || is_iprivate(codepoint)
-            || codepoint == ';'
-            || codepoint == '/'
-            || codepoint == '?'
-            || codepoint == '%';
-    }
-
-    public static boolean is_ifragment(int codepoint) {
-        return is_ipchar(codepoint) || is_iprivate(codepoint)
-            || codepoint == '/'
-            || codepoint == '?'
-            || codepoint == '%';
-    }
-
-    public static boolean is_iregname(int codepoint) {
-        return is_iunreserved(codepoint) || codepoint == '!'
-            || codepoint == '$'
-            || codepoint == '&'
-            || codepoint == '\''
-            || codepoint == '('
-            || codepoint == ')'
-            || codepoint == '*'
-            || codepoint == '+'
-            || codepoint == ','
-            || codepoint == ';'
-            || codepoint == '='
-            || codepoint == '"';
-    }
-    
-    public static boolean is_ipliteral (int codepoint){
-        return isHex(codepoint) || codepoint==':' 
-            || codepoint =='[' 
-            || codepoint==']';
-    }
-    
-    public static boolean is_ihost (int codepoint){
-        return is_iregname(codepoint) || is_ipliteral(codepoint);
-    }
-
-    public static boolean is_regname(int codepoint) {
-        return isUnreserved(codepoint) || codepoint == '!'
-            || codepoint == '$'
-            || codepoint == '&'
-            || codepoint == '\''
-            || codepoint == '('
-            || codepoint == ')'
-            || codepoint == '*'
-            || codepoint == '+'
-            || codepoint == ','
-            || codepoint == ';'
-            || codepoint == '='
-            || codepoint == '"';
-    }
-
-    public static boolean is_iuserinfo(int codepoint) {
-        return is_iunreserved(codepoint) || codepoint == ';'
-            || codepoint == ':'
-            || codepoint == '&'
-            || codepoint == '='
-            || codepoint == '+'
-            || codepoint == '$'
-            || codepoint == ',';
-    }
-
-    public static boolean is_iserver(int codepoint) {
-        return is_iuserinfo(codepoint) || is_iregname(codepoint)
-            || isAlphaDigit(codepoint)
-            || codepoint == '.'
-            || codepoint == ':'
-            || codepoint == '@'
-            || codepoint == '['
-            || codepoint == ']'
-            || codepoint == '%'
-            || codepoint == '-';
-    }
-
-    private static boolean check(int cp, Filter filter, boolean invert) {
-      boolean answer = !filter.filter(cp);
-      return (!invert) ? !answer : answer;
-  }
-    
-    /**
-     * Verifies a sequence of codepoints using the specified filter
-     */
-    public static void verify(CodepointIterator ci, Filter filter) throws InvalidCharacterException {
-        while (ci.hasNext()) {
-            int cp = ci.next();
-            if (check(cp,filter,false))
-              throw new InvalidCharacterException(cp);
+        
+        public void verify(CharSequence seq) {
+          if (seq == null) return;
+          matcher.verifyNot(CodepointIterator.getInstance(seq));
+        }
+        public boolean check(CharSequence seq) {
+          if (seq == null) return false;
+          return matcher.all(seq);
         }
     }
 
-    /**
-     * Verifies a sequence of codepoints using the specified filter
-     */
-    public static void verify(CodepointIterator ci, Profile profile) throws InvalidCharacterException {
-        verify(ci, profile.filter());
-    }
-
-    /**
-     * Verifies a sequence of codepoints using the specified profile
-     */
-    public static void verify(char[] s, Profile profile) throws InvalidCharacterException {
-        if (s == null)
-            return;
-        verify(CodepointIterator.getInstance(s), profile);
-    }
-
-    /**
-     * Verifies a sequence of codepoints using the specified profile
-     */
-    public static void verify(String s, Profile profile) throws InvalidCharacterException {
-        if (s == null)
-            return;
-        verify(CodepointIterator.getInstance(s), profile);
-    }
-
-    /**
-     * Verifies a sequence of codepoints using the specified filter
-     */
-    public static void verifyNot(CodepointIterator ci, Filter filter) throws InvalidCharacterException {
-      while (ci.hasNext()) {
-        int cp = ci.next();
-        if (check(cp,filter,true))
-          throw new InvalidCharacterException(cp);
-      }
-    }
-
-    /**
-     * Verifies a sequence of codepoints using the specified profile
-     */
-    public static void verifyNot(String s, Profile profile) throws InvalidCharacterException {
-        if (s == null)
-            return;
-        verifyNot(CodepointIterator.getInstance(s), profile);
-    }
-    
-    /**
-     * Verifies a sequence of codepoints using the specified profile
-     */
-    public static void verifyNot(CodepointIterator ci, Profile profile) throws InvalidCharacterException {
-        verifyNot(ci,profile.filter());
-    }
-
-    /**
-     * Verifies a sequence of codepoints using the specified profile
-     */
-    public static void verifyNot(char[] array, Profile profile) throws InvalidCharacterException {
-      if (array == null)
-        return;
-      verifyNot(CodepointIterator.getInstance(array), profile);
-    }
-    
-    /**
-     * True if the codepoint is a digit
-     */
-    public static boolean isDigit(int codepoint) {
-        return CharUtils.inRange(codepoint, '0', '9');
-    }
-
-    /**
-     * True if the codepoint is part of the ASCII alphabet (a-z, A-Z)
-     */
-    public static boolean isAlpha(int codepoint) {
-        return CharUtils.inRange(codepoint, 'A', 'Z') || CharUtils.inRange(codepoint, 'a', 'z');
-    }
-
-    /**
-     * True if isAlpha and isDigit both return true
-     */
-    public static boolean isAlphaDigit(int codepoint) {
-        return isAlpha(codepoint) || isDigit(codepoint);
-    }
-    
-    public static boolean isToken(int codepoint) {
-      return isAscii(codepoint) && !isCtl(codepoint) && !isSep(codepoint);
-    }
-    
-    public static boolean isToken(String token) {
-      if (token == null) return false;
-      int l = token.length();
-      for (int n = 0; n < l; n++)
-        if (!isToken(token.charAt(n)))
-          return false;
-      return true;
-    }
-    
-    public static boolean isAscii(int codepoint) {
-      return codepoint >= 0 && codepoint <= 127;
-    }
-    
-    public static boolean isCtl(int codepoint) {
-      return (codepoint >= 0 && codepoint <= 31) || codepoint == 127;
-    }
-    
-    public static boolean isSep(int codepoint) {
-      return codepoint == '(' ||
-             codepoint == ')' ||
-             codepoint == '<' ||
-             codepoint == '>' ||
-             codepoint == '@' ||
-             codepoint == ',' || 
-             codepoint == ';' ||
-             codepoint == ':' ||
-             codepoint == '\\' ||
-             codepoint == '"' ||
-             codepoint == '/' ||
-             codepoint == '[' ||
-             codepoint == ']' ||
-             codepoint == '?' ||
-             codepoint == '=' ||
-             codepoint == '{' ||
-             codepoint == '}' ||
-             codepoint == 32 ||
-             codepoint == 9;
-    }
-
     public static String unwrap(String st, char x, char y) {
       if (st == null || st.length() == 0)
         return st;
@@ -600,42 +131,9 @@ public final class CharUtils {
             return new String[0];
           return unquote(value).split("\\s*,\\s*");
     }
-
-    /**
-     * Treats the specified int array as an Inversion Set and returns true if the value is located within the set. This
-     * will only work correctly if the values in the int array are monotonically increasing
-     */
-    public static boolean invset_contains(int[] set, int value) {
-        int s = 0, e = set.length;
-        while (e - s > 8) {
-            int i = (e + s) >> 1;
-            s = set[i] <= value ? i : s;
-            e = set[i] > value ? i : e;
-        }
-        while (s < e) {
-            if (value < set[s])
-                break;
-            s++;
-        }
-        return ((s - 1) & 1) == 0;
-    }
-    
-    // inversion set
-    private static int[] RESTRICTED_SET_v1 = {0, 9, 11, 13, 14, 32, 55296, 57344, 65534, 65536};
-
-    // inversion set
-    private static int[] RESTRICTED_SET_v11 = {11, 13, 14, 32, 127, 160, 55296, 57344, 65534, 65536};
-
-    public static boolean restricted(XMLVersion version, char c) {
-        return restricted(version, (int)c);
-    }
-
-    public static boolean restricted(XMLVersion version, int c) {
-        return CharUtils.invset_contains(version == XMLVersion.XML10 ? RESTRICTED_SET_v1 : RESTRICTED_SET_v11, c);
-    }
     
     public static String quotedIfNotToken(String value) {
-      return isToken(value)?value:quoted(value,true);
+      return CodepointMatchers.isToken().all(value)?value:quoted(value,true);
     }
 
     public static String quoted(String val, boolean wrap) {

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=1186541&r1=1186540&r2=1186541&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 Wed Oct 19 22:33:04 2011
@@ -145,10 +145,15 @@ public enum Codec {
           buf.append(UrlEncoding.encode(string, CharUtils.Profile.RFC5987));
         return buf.toString();
       }
+ 
+      private static final CodepointMatcher CHECKER =
+          CodepointMatcher.and(
+            CodepointMatchers.isToken().negate(),
+            CodepointMatcher.isNot(0x20));
       
       private boolean needs(String string) {
         for (char c : string.toCharArray())
-          if (!CharUtils.isToken(c) && c != 0x20)
+          if (CHECKER.apply(c)) 
             return true;
         return false;
       }

Added: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/CodepointMatcher.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/CodepointMatcher.java?rev=1186541&view=auto
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/CodepointMatcher.java (added)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/CodepointMatcher.java Wed Oct 19 22:33:04 2011
@@ -0,0 +1,225 @@
+package org.apache.abdera2.common.text;
+
+import java.util.Arrays;
+
+import org.apache.abdera2.common.text.CodepointIterator;
+
+import com.google.common.base.Predicate;
+
+public abstract class CodepointMatcher 
+  implements Predicate<Integer> {
+    
+  public static final CodepointMatcher MATCH_ALL = matchAll();
+  public static final CodepointMatcher MATCH_NONE = matchNone();
+  
+  public void verify(CodepointIterator iterator) {
+    while(iterator.hasNext()) {
+      int cp = iterator.next();
+      if (!apply(cp))
+        throw new InvalidCharacterException(cp);
+    }
+  }
+  
+  public void verifyNot(CodepointIterator iterator) {
+    while(iterator.hasNext()) {
+      int cp = iterator.next();
+      if (apply(cp))
+        throw new InvalidCharacterException(cp);
+    }
+  }
+  
+  public boolean all(CharSequence seq) {
+    return all(CodepointIterator.getInstance(seq));
+  }
+  
+  public boolean any(CharSequence seq) {
+    return any(CodepointIterator.getInstance(seq));
+  }
+  
+  public boolean all(CodepointIterator iterator) {
+    while (iterator.hasNext())
+      if (!apply(iterator.next()))
+        return false;
+    return true;
+  }
+  
+  public boolean any(CodepointIterator iterator) {
+    while (iterator.hasNext())
+      if (apply(iterator.next()))
+        return true;
+    return false;    
+  }
+  
+  public boolean matches(int codepoint) {
+    return apply(codepoint);
+  }
+  
+  public boolean apply(int codepoint) {
+    return this.apply(Integer.valueOf(codepoint));
+  }
+  
+  public CodepointMatcher negate() {
+    return new NegatingCodepointMatcher(this);
+  }
+  
+  public static CodepointMatcher negate(CodepointMatcher matcher) {
+    return matcher.negate();
+  }
+
+  public CodepointMatcher or(CodepointMatcher that) {
+    return new OrCodepointMatcher(this,that);
+  }
+  
+  public static CodepointMatcher or(CodepointMatcher... matchers) {
+    return new OrCodepointMatcher(matchers);
+  }
+  
+  public CodepointMatcher and(CodepointMatcher that) {
+    return new AndCodepointMatcher(this,that);
+  }
+  
+  public static CodepointMatcher and(CodepointMatcher... matchers) {
+    return new AndCodepointMatcher(matchers);
+  }
+  
+  public static CodepointMatcher inRange(int low, int high) {
+    return new RangeCodepointMatcher(low,high);
+  }
+  
+  public static CodepointMatcher notInRange(int low, int high) {
+    return new NegatingCodepointMatcher(inRange(low,high));
+  }
+  
+  public static CodepointMatcher is(int... cp) {
+    return new IsCodepointMatcher(cp);
+  }
+  
+  public static CodepointMatcher isNot(int cp) {
+    return new NegatingCodepointMatcher(is(cp));
+  }
+  
+  public static CodepointMatcher inInversionSet(int[] set) {
+    return new InversionSetCodepointMatcher(set);
+  }
+  
+  public static CodepointMatcher notInInversionSet(int[] set) {
+    return new NegatingCodepointMatcher(inInversionSet(set));
+  }
+  
+  public static CodepointMatcher matchAll() {
+    return new MatchAllCodepointMatcher();
+  }
+  
+  public static CodepointMatcher matchNone() {
+    return new MatchNoneCodepointMatcher();
+  }
+    
+  public static class MatchAllCodepointMatcher extends CodepointMatcher {
+    public boolean apply(Integer codepoint) {
+      return true;
+    }    
+  }
+  
+  public static class MatchNoneCodepointMatcher extends CodepointMatcher {
+    public boolean apply(Integer codepoint) {
+      return false;
+    }
+  }
+  
+  public static abstract class CodepointMatcherWrapper extends CodepointMatcher {
+    protected final CodepointMatcher internal;
+    public CodepointMatcherWrapper(CodepointMatcher internal) {
+      this.internal = internal;
+    }
+  }
+  
+  public static class IsCodepointMatcher extends CodepointMatcher {
+    private final int[] cp;
+    public IsCodepointMatcher(int... cp) {
+      this.cp = cp;
+      Arrays.sort(this.cp);
+    }
+    public boolean apply(Integer codepoint) {
+      return Arrays.binarySearch(cp, codepoint) > -1;
+    }
+  }
+  
+  public static class RangeCodepointMatcher extends CodepointMatcher {
+    private final int low,high;
+    public RangeCodepointMatcher(int low, int high) {
+      this.low = low;
+      this.high = high;
+    }
+    public boolean apply(Integer codepoint) {
+      return low <= codepoint && high >= codepoint;
+    }
+  }
+  
+  /**
+   * CodepointMatcher that matches all of the specified internal matchers
+   */
+  public static class AndCodepointMatcher extends CodepointMatcher {
+    private final CodepointMatcher[] internal;
+    public AndCodepointMatcher(CodepointMatcher... internal) {
+      this.internal = internal;
+    }
+    public boolean apply(Integer codepoint) {
+      for (CodepointMatcher matcher : internal)
+        if (!matcher.apply(codepoint))
+          return false;
+      return true;
+    }
+  }
+  
+  public static class OrCodepointMatcher extends CodepointMatcher {
+    private final CodepointMatcher[] internal;
+    public OrCodepointMatcher(CodepointMatcher... internal) {
+      this.internal = internal;
+    }
+    public boolean apply(Integer codepoint) {
+      for (CodepointMatcher matcher : internal)
+        if (matcher.apply(codepoint))
+          return true;
+      return false;
+    }
+  }
+  
+  public static class NegatingCodepointMatcher extends CodepointMatcherWrapper {
+    public NegatingCodepointMatcher(CodepointMatcher internal) {
+      super(internal);
+    }
+    public boolean apply(Integer codepoint) {
+      return !internal.apply(codepoint);
+    } 
+  }
+  
+  /**
+   * Matches codepoints that are contained within the specified inversion set
+   */
+  public static class InversionSetCodepointMatcher extends CodepointMatcher {
+    private final int[] set;
+    public InversionSetCodepointMatcher(int[] set) {
+      this.set = set;
+    }
+    public boolean apply(Integer codepoint) {
+      return invset_contains(set,codepoint);
+    }
+  }
+  
+  private static boolean invset_contains(int[] set, int value) {
+      int s = 0, e = set.length;
+      while (e - s > 8) {
+          int i = (e + s) >> 1;
+          s = set[i] <= value ? i : s;
+          e = set[i] > value ? i : e;
+      }
+      while (s < e) {
+          if (value < set[s])
+              break;
+          s++;
+      }
+      return ((s - 1) & 1) == 0;
+  }
+  
+}
+  

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

Added: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/CodepointMatchers.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/CodepointMatchers.java?rev=1186541&view=auto
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/CodepointMatchers.java (added)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/CodepointMatchers.java Wed Oct 19 22:33:04 2011
@@ -0,0 +1,253 @@
+package org.apache.abdera2.common.text;
+
+import static org.apache.abdera2.common.text.CodepointMatcher.*;
+
+import org.apache.abdera2.common.xml.XMLVersion;
+
+public class CodepointMatchers {
+
+  public static CodepointMatcher isAlpha() {
+    return new OrCodepointMatcher(
+      inRange('A','Z'),
+      inRange('a','z')
+    );
+  }
+  
+  public static CodepointMatcher isDigit() {
+    return inRange('0','9');
+  }
+  
+  public static CodepointMatcher isAlphaNum() {
+    return new OrCodepointMatcher(
+      inRange('A','Z'),
+      inRange('a','z'),
+      inRange('0','9'));
+  }
+  
+  public static CodepointMatcher isHex() {
+    return new OrCodepointMatcher(
+      inRange('0','9'),
+      inRange('a','f'),
+      inRange('A','F'));
+  }
+  
+  public static CodepointMatcher isPct() {
+    return new OrCodepointMatcher(
+      is('%'),
+      isHex());
+  }
+  
+  public static CodepointMatcher is5987() {
+    return new OrCodepointMatcher(
+      isAlphaNum(),
+      is('!','#','$','&','+','-','.','^','_','`','|','~')
+    );
+  }
+  
+  public static CodepointMatcher isMark() {
+    return is('-','_','.','!','~','*','\\','\'','(',')','`');
+  }
+
+  public static CodepointMatcher isUnreserved() {
+    return or(
+      isAlphaNum(),
+      is('-','.','_','~','`'));
+  }
+
+  public static CodepointMatcher isGenDelim() {
+    return is(':','/','?','#','[',']','@');
+  }
+
+  public static CodepointMatcher isSubDelim() {
+    return is('!','$','&','\'','(',')','*','+',',',';','=','\\');
+  }
+
+  public static CodepointMatcher isReserved() {
+    return or(isGenDelim(),isSubDelim());
+  }
+
+  public static CodepointMatcher isPchar() {
+    return or(
+      isUnreserved(),
+      is(':','@','&','=','+','$',','));
+  }
+
+  public static CodepointMatcher isPath() {
+    return or(
+      isPchar(),
+      is(';','/','%',','));
+  }
+
+  public static CodepointMatcher isPathNoDelims() {
+    return and(
+      isPath(),
+      isGenDelim().negate());
+  }
+  
+  public static CodepointMatcher isScheme() {
+    return or(
+      isAlphaNum(),
+      is('+','-','.'));
+  }
+
+  public static CodepointMatcher isUserInfo() {
+    return or(
+      isUnreserved(),
+      isSubDelim(),
+      isPct());
+  }
+
+  public static CodepointMatcher isQuery() {
+    return or(
+      isPchar(),
+      is(';','/','?','%'));
+  }
+
+  public static CodepointMatcher isFragment() {
+    return or(
+      isPchar(),
+      is('/','?','%'));
+  }
+
+  // TODO: Would inv_set be better here?
+  public static CodepointMatcher isUcsChar() {
+    return or(
+        inRange('\u00A0', '\uD7FF'),
+        inRange('\uF900', '\uFDCF'),
+        inRange('\uFDF0', '\uFFEF'),
+        inRange(0x10000, 0x1FFFD),
+        inRange(0x20000, 0x2FFFD),
+        inRange(0x30000, 0x3FFFD),
+        inRange(0x40000, 0x4FFFD),
+        inRange(0x50000, 0x5FFFD),
+        inRange(0x60000, 0x6FFFD),
+        inRange(0x70000, 0x7FFFD),
+        inRange(0x80000, 0x8FFFD),
+        inRange(0x90000, 0x9FFFD),
+        inRange(0xA0000, 0xAFFFD),
+        inRange(0xB0000, 0xBFFFD),
+        inRange(0xC0000, 0xCFFFD),
+        inRange(0xD0000, 0xDFFFD),
+        inRange(0xE1000, 0xEFFFD)
+      );
+  }
+
+  public static CodepointMatcher isIPrivate() {
+    return or(
+      inRange('\uE000','\uF8FF'),
+      inRange(0xF0000,0xFFFFD),
+      inRange(0x100000,0x10FFFD));
+  }
+
+  public static CodepointMatcher isIUnreserved() {
+    return or(
+      isAlphaNum(),
+      isMark(),
+      isUcsChar());
+  }
+
+  public static CodepointMatcher isIPchar() {
+    return or(
+      isIUnreserved(),
+      isSubDelim(),
+      is(':','@','&','=','+','$')
+    );
+  }
+
+  public static CodepointMatcher isIPath() {
+    return or(
+      isIPchar(),
+      is(';','/','%',','));
+  }
+  
+  public static CodepointMatcher isIPathNoDelims() {
+    return and(
+      isIPath(),
+      isGenDelim().negate());
+  }
+
+  public static CodepointMatcher isIQuery() {
+    return or(
+      isIPchar(),
+      isIPrivate(),
+      is(';','/','?','%'));
+  }
+  
+  public static CodepointMatcher isIFragment() {
+    return or(
+      isIPchar(),
+      isIPrivate(),
+      is('/','?','%'));
+  }
+  
+  public static CodepointMatcher isIRegName() {
+    return or(
+      isIUnreserved(),
+      is('!','$','&','\'','(',')','*','+',',',';','=','"'));
+  }
+  
+  public static CodepointMatcher isIpLiteral() {
+    return or(
+      isHex(),
+      is(':','[',']'));
+  }
+
+  public static CodepointMatcher isIHost() {
+    return or(
+      isIRegName(),
+      isIpLiteral());
+  }
+
+  public static CodepointMatcher isRegName() {
+    return or(
+        isUnreserved(),
+        is('!','$','&','\'','(',')','*','+',',',';','=','"'));
+  }
+
+  public static CodepointMatcher isIUserInfo() {
+    return or(
+      isIUnreserved(),
+      is(';',':','&','=','+','$',','));
+  }
+  
+  public static CodepointMatcher isIServer() {
+    return or(
+      isIUserInfo(),
+      isIRegName(),
+      isAlphaNum(),
+      is('.',':','@','[',']','%','-'));
+  }
+  
+  public static CodepointMatcher isToken() {
+    return and(
+      isAscii(),
+      isCtl().negate(),
+      isSep().negate());
+  }
+  
+  public static CodepointMatcher isAscii() {
+    return inRange(0,127);
+  }
+  
+  public static CodepointMatcher isCtl() {
+    return or(inRange(0,31),is(127));
+  }
+  
+  public static CodepointMatcher isSep() {
+    return is(
+      '(',')','<','>','@',',',';',':','\\',
+      '"','/','[',']','?','=','{','}',32,9);
+  }
+  
+  // Inversion set
+  private static int[] RESTRICTED_SET_v1 = {0, 9, 11, 13, 14, 32, 55296, 57344, 65534, 65536};
+  private static int[] RESTRICTED_SET_v11 = {11, 13, 14, 32, 127, 160, 55296, 57344, 65534, 65536};
+  
+  public static CodepointMatcher isRestricted(XMLVersion version) {
+    return CodepointMatcher.inInversionSet(
+      version == XMLVersion.XML10 ? 
+        RESTRICTED_SET_v1 : 
+        RESTRICTED_SET_v11);
+  }
+
+}

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

Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/NormalizationForm.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/NormalizationForm.java?rev=1186541&r1=1186540&r2=1186541&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/NormalizationForm.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/NormalizationForm.java Wed Oct 19 22:33:04 2011
@@ -17,6 +17,8 @@
  */
 package org.apache.abdera2.common.text;
 
+import com.google.common.base.Equivalence;
+import com.google.common.base.Equivalences;
 import com.ibm.icu.text.Normalizer2;
 import com.ibm.icu.text.Normalizer2.Mode;
 
@@ -28,15 +30,54 @@ public enum NormalizationForm {
     
     private final Normalizer2.Mode mode;
     private final String name;
+    private final NormalizedEquivalence ne;
     
     NormalizationForm(
         Normalizer2.Mode mode, 
         String name) {
       this.mode = mode;
       this.name = name;
+      this.ne = new NormalizedEquivalence(this);
     }
     
     public String normalize(CharSequence s) {
       return Normalizer2.getInstance(null, name, mode).normalize(s);
     }
+    
+    /**
+     * Returns true if the normalized form of both input sequences
+     * are equivalent to one another
+     */
+    public boolean equivalent(CharSequence s1, CharSequence s2) {
+      return ne.equivalent(s1, s2);
+    }
+    
+    public NormalizedEquivalence equivalence() {
+      return ne;
+    }
+    
+    public static class NormalizedEquivalence
+      extends Equivalence<CharSequence> {
+      private final NormalizationForm form;
+      public NormalizedEquivalence(NormalizationForm form) {
+        this.form = form;
+      }
+      protected boolean doEquivalent(
+        CharSequence a, 
+        CharSequence b) {
+          if (a == null && b != null) return false;
+          if (a != null && b == null) return false;
+          String s1 = form.normalize(a);
+          String s2 = form.normalize(b);
+          return Equivalences.equals().equivalent(s1, s2);
+      }
+
+      protected int doHash(CharSequence t) {
+        if (t == null)
+          throw new IllegalArgumentException();
+        String s1 = form.normalize(t);
+        return s1.hashCode();
+      }
+      
+    }
 }
\ No newline at end of file

Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/UrlEncoding.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/UrlEncoding.java?rev=1186541&r1=1186540&r2=1186541&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/UrlEncoding.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/UrlEncoding.java Wed Oct 19 22:33:04 2011
@@ -295,7 +295,7 @@ public final class UrlEncoding {
 
     private static boolean check(int codepoint, Profile... profiles) {
         for (Profile profile : profiles) {
-            if (profile.filter(codepoint))
+            if (profile.apply(codepoint))
                 return true;
         }
         return false;

Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/xml/XMLStreamSniffingInputStream.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/xml/XMLStreamSniffingInputStream.java?rev=1186541&r1=1186540&r2=1186541&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/xml/XMLStreamSniffingInputStream.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/xml/XMLStreamSniffingInputStream.java Wed Oct 19 22:33:04 2011
@@ -26,9 +26,9 @@ import javax.xml.stream.XMLStreamReader;
 import org.apache.abdera2.common.io.CharsetSniffingInputStream;
 import org.apache.abdera2.common.io.PeekAheadInputStream;
 
-
 /**
- * Will attempt to autodetect the character encoding from the XML Stream This will preserve the BOM if it exists.
+ * Will attempt to autodetect the character encoding from the XML Stream 
+ * This will preserve the BOM if it exists.
  */
 public class XMLStreamSniffingInputStream extends CharsetSniffingInputStream {
 
@@ -38,17 +38,20 @@ public class XMLStreamSniffingInputStrea
 
     @Override
     protected String detectEncoding() throws IOException {
-        String charset = super.detectEncoding();
-        PeekAheadInputStream pin = getInternal();
-        try {
-            byte[] p = new byte[200];
-            pin.peek(p);
-            XMLStreamReader xmlreader =
-                XMLInputFactory.newInstance().createXMLStreamReader(new java.io.ByteArrayInputStream(p));
-            String cs = xmlreader.getCharacterEncodingScheme();
-            if (cs != null)
-                charset = cs;
-        } catch (Exception e) {
+        String charset = super.detectEncoding(); // first check the bom...
+        if (charset == null) { // if the bom check failed...
+          PeekAheadInputStream pin = getInternal();
+          try {
+              byte[] p = new byte[200]; // peek into the stream a ways
+              pin.peek(p);
+              XMLStreamReader xmlreader =
+                  XMLInputFactory.newInstance().createXMLStreamReader(
+                    new java.io.ByteArrayInputStream(p));
+              String cs = xmlreader.getCharacterEncodingScheme();
+              if (cs != null)
+                  charset = cs;
+          } catch (Exception e) {
+          }
         }
         return charset;
     }

Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/xml/XMLVersion.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/xml/XMLVersion.java?rev=1186541&r1=1186540&r2=1186541&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/xml/XMLVersion.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/xml/XMLVersion.java Wed Oct 19 22:33:04 2011
@@ -41,7 +41,12 @@ public enum XMLVersion {
     }
     
     public static XMLVersion get(String version) {
-      return version == null ? XMLVersion.XML10 : version.equals("1.0") ? XMLVersion.XML10 : version.equals("1.1")
-          ? XMLVersion.XML11 : XMLVersion.XML10;
+      return version == null ? 
+        XMLVersion.XML10 : 
+        version.equals("1.0") ? 
+          XMLVersion.XML10 : 
+          version.equals("1.1") ? 
+            XMLVersion.XML11 : 
+            XMLVersion.XML10;
   }
 }
\ No newline at end of file

Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/xml/XmlRestrictedCharReader.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/xml/XmlRestrictedCharReader.java?rev=1186541&r1=1186540&r2=1186541&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/xml/XmlRestrictedCharReader.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/xml/XmlRestrictedCharReader.java Wed Oct 19 22:33:04 2011
@@ -26,9 +26,15 @@ import org.apache.abdera2.common.io.Filt
 
 
 /**
- * A reader implementation that filters out characters that are not allowed in XML 1.0 or XML 1.1 documents. The default
- * xMLVersion is to assume XML 1.0. By default, invalid characters are simply removed from the stream. Alternatively, a
+ * A reader implementation that filters out characters that are not allowed 
+ * in XML 1.0 or XML 1.1 documents. The two different versions have very 
+ * different requirements as far as restricted characters go, with the latter 
+ * version being far more permissive. The default behavior is to assume XML 1.0. 
+ * By default, invalid characters are simply removed from the stream. Alternatively, a
  * replacement character can be provided so long as it is a valid XML character itself.
+ * Using replacement characters should be done very carefully as it could 
+ * introduce other problems in the stream depending on where they end up. It's
+ * probably better to just ignore the characters when using this reader.
  */
 public class XmlRestrictedCharReader extends FilteredCharReader {
 

Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/xml/XmlVersionInputStream.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/xml/XmlVersionInputStream.java?rev=1186541&r1=1186540&r2=1186541&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/xml/XmlVersionInputStream.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/xml/XmlVersionInputStream.java Wed Oct 19 22:33:04 2011
@@ -28,7 +28,8 @@ import org.apache.abdera2.common.io.Peek
 
 
 /**
- * Will attempt to autodetect the character encoding from the stream This will preserve the BOM if it exists
+ * Will attempt to autodetect the character encoding from the stream
+ * @Deprecated @see org.apache.abdera2.common.xml.XmlVersionReader
  */
 public class XmlVersionInputStream extends FilterInputStream {
 
@@ -59,7 +60,8 @@ public class XmlVersionInputStream exten
             byte[] p = new byte[peek_ahead];
             pin.peek(p);
             XMLStreamReader xmlreader =
-                XMLInputFactory.newInstance().createXMLStreamReader(new java.io.ByteArrayInputStream(p));
+                XMLInputFactory.newInstance().createXMLStreamReader(
+                   new java.io.ByteArrayInputStream(p));
             String v = xmlreader.getVersion();
             if (v != null)
                 version = v;

Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/xml/XmlVersionReader.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/xml/XmlVersionReader.java?rev=1186541&r1=1186540&r2=1186541&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/xml/XmlVersionReader.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/xml/XmlVersionReader.java Wed Oct 19 22:33:04 2011
@@ -53,7 +53,8 @@ public class XmlVersionReader extends Pu
             char[] p = new char[peek_ahead];
             int r = read(p);
             XMLStreamReader xmlreader =
-                XMLInputFactory.newInstance().createXMLStreamReader(new java.io.CharArrayReader(p));
+                XMLInputFactory.newInstance().createXMLStreamReader(
+                  new java.io.CharArrayReader(p));
             String v = xmlreader.getVersion();
             if (v != null)
                 version = v;

Added: abdera/abdera2/core/.classpath
URL: http://svn.apache.org/viewvc/abdera/abdera2/core/.classpath?rev=1186541&view=auto
==============================================================================
--- abdera/abdera2/core/.classpath (added)
+++ abdera/abdera2/core/.classpath Wed Oct 19 22:33:04 2011
@@ -0,0 +1,18 @@
+<classpath>
+  <classpathentry kind="src" path="src/main/java" including="**/*.java"/>
+  <classpathentry kind="src" path="src/main/resources" excluding="**/*.java"/>
+  <classpathentry kind="src" path="target/maven-shared-archive-resources" excluding="**/*.java"/>
+  <classpathentry kind="output" path="target/classes"/>
+  <classpathentry kind="src" path="/abdera2-common"/>
+  <classpathentry kind="var" path="M2_REPO/org/apache/ws/commons/axiom/axiom-api/1.2.12/axiom-api-1.2.12.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/apache/ws/commons/axiom/axiom-impl/1.2.12/axiom-impl-1.2.12.jar"/>
+  <classpathentry kind="var" path="M2_REPO/commons-codec/commons-codec/1.5/commons-codec-1.5.jar"/>
+  <classpathentry kind="var" path="M2_REPO/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/apache/geronimo/specs/geronimo-activation_1.1_spec/1.1/geronimo-activation_1.1_spec-1.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/apache/geronimo/specs/geronimo-javamail_1.4_spec/1.6/geronimo-javamail_1.4_spec-1.6.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/apache/geronimo/specs/geronimo-stax-api_1.0_spec/1.0.1/geronimo-stax-api_1.0_spec-1.0.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/com/ibm/icu/icu4j/4.8.1.1/icu4j-4.8.1.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/jaxen/jaxen/1.1.1/jaxen-1.1.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/codehaus/woodstox/wstx-asl/3.2.6/wstx-asl-3.2.6.jar"/>
+  <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+</classpath>
\ No newline at end of file

Propchange: abdera/abdera2/core/.classpath
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2/core/.project
URL: http://svn.apache.org/viewvc/abdera/abdera2/core/.project?rev=1186541&view=auto
==============================================================================
--- abdera/abdera2/core/.project (added)
+++ abdera/abdera2/core/.project Wed Oct 19 22:33:04 2011
@@ -0,0 +1,15 @@
+<projectDescription>
+  <name>abdera2-core</name>
+  <comment>Atom Specification Implementation Core. NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclipse-plugin are not supported in M2Eclipse.</comment>
+  <projects>
+    <project>abdera2-common</project>
+  </projects>
+  <buildSpec>
+    <buildCommand>
+      <name>org.eclipse.jdt.core.javabuilder</name>
+    </buildCommand>
+  </buildSpec>
+  <natures>
+    <nature>org.eclipse.jdt.core.javanature</nature>
+  </natures>
+</projectDescription>
\ No newline at end of file

Propchange: abdera/abdera2/core/.project
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2/core/.settings/org.eclipse.jdt.core.prefs
URL: http://svn.apache.org/viewvc/abdera/abdera2/core/.settings/org.eclipse.jdt.core.prefs?rev=1186541&view=auto
==============================================================================
--- abdera/abdera2/core/.settings/org.eclipse.jdt.core.prefs (added)
+++ abdera/abdera2/core/.settings/org.eclipse.jdt.core.prefs Wed Oct 19 22:33:04 2011
@@ -0,0 +1,5 @@
+#Thu Sep 29 16:38:17 PDT 2011
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.source=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6

Propchange: abdera/abdera2/core/.settings/org.eclipse.jdt.core.prefs
------------------------------------------------------------------------------
    svn:mime-type = text/plain