abdera-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jmsn...@apache.org
Subject svn commit: r1173209 [16/49] - in /abdera/abdera2: ./ .settings/ activities/ activities/src/ activities/src/main/ activities/src/main/java/ activities/src/main/java/org/ activities/src/main/java/org/apache/ activities/src/main/java/org/apache/abdera2/ ...
Date Tue, 20 Sep 2011 15:57:20 GMT
Added: 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=1173209&view=auto
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/TemplateProvider.java (added)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/templates/TemplateProvider.java Tue Sep 20 15:56:46 2011
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.common.templates;
+
+public interface TemplateProvider {
+
+  String getTemplate();
+  
+}

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

Added: 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=1173209&view=auto
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/CharUtils.java (added)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/CharUtils.java Tue Sep 20 15:56:46 2011
@@ -0,0 +1,673 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.common.text;
+
+import org.apache.abdera2.common.xml.XMLVersion;
+
+/**
+ * General utilities for dealing with Unicode characters
+ */
+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);
+            }
+        });
+        
+        private final Filter filter;
+
+        Profile(Filter filter) {
+            this.filter = filter;
+        }
+
+        public Filter filter() {
+            return filter;
+        }
+
+        public boolean filter(int codepoint) {
+            return filter.filter(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);
+        }
+    }
+
+    /**
+     * 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;
+      int n = 0, e = st.length();
+      if (st.charAt(0) == x) n++;
+      if (st.charAt(e-1) == y) e--;
+      return st.substring(n,e);
+    }
+    
+    public static String unquote(String s) {
+      if (s == null || s.length() == 0)
+        return s;
+      int n = 0, e = s.length();
+      if (s.charAt(0) == '"') n++;
+      if (s.charAt(e-1) == '"' && s.charAt(e-2) != '\\') e--;
+      return s.substring(n,e);
+    }
+
+    public static String[] splitAndTrim(
+        String value) {
+          if (value == null || value.length() == 0)
+            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);
+    }
+
+    public static String quoted(String val, boolean wrap) {
+      StringBuilder buf = new StringBuilder();
+      if (wrap) buf.append('"');
+      int l = val.length();
+      for (int n = 0; n < l; n++) {
+        char c = val.charAt(n);
+        if (c == '"')
+          buf.append('\\');
+        buf.append(c);
+      }
+      if (wrap) buf.append('"');
+      return buf.toString();
+    }
+
+    public static int scanFor(char c, String text, int s, boolean errifnotws) {
+      return scanFor(c,text,s,errifnotws,',');
+    }
+    
+    public static int scanFor(char c, String text, int s, boolean errifnotws, char breakat) {
+      boolean inquoted = false;
+      int l = text.length();
+      for (int n = s; n < l; n++) {
+        char ch = text.charAt(n);
+          if (ch == '"') inquoted = !inquoted;
+          if (ch == breakat && !inquoted) return n;
+          if (ch == c) return n;
+          if (errifnotws && Character.isWhitespace(ch))
+            throw new InvalidCharacterException(ch);
+      }
+      return -1;
+    }
+    
+}

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

Added: 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=1173209&view=auto
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/Codec.java (added)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/Codec.java Tue Sep 20 15:56:46 2011
@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.common.text;
+
+import java.io.ByteArrayInputStream;
+
+import org.apache.commons.codec.DecoderException;
+import org.apache.commons.codec.EncoderException;
+import org.apache.commons.codec.StringDecoder;
+import org.apache.commons.codec.StringEncoder;
+import org.apache.commons.codec.net.BCodec;
+import org.apache.commons.codec.net.QCodec;
+
+public enum Codec {
+    B, 
+    Q,
+    STAR;
+    
+    private String _encode(String value) {
+      return _encode(value, DEFAULT_CHARSET);
+    }
+    
+    private String _encode(String value, String charset) {
+      if (value == null)
+          return null;
+      try {
+          StringEncoder e = null;
+          switch (this) {
+              case Q: e = new QCodec(charset); break;
+              case B: e = new BCodec(charset); break;
+              case STAR: e = new StarCodec(charset); break;
+          }
+          return e.encode(value);
+      } catch (Exception e) {
+          return value;
+      }
+    }
+    
+    public static final String DEFAULT_CHARSET = "UTF-8";
+
+    public static String encode(String value, String charset, Codec codec) {
+      return codec._encode(value, charset);
+    }
+    
+    public static String encode(String value, Codec codec) {
+      return codec._encode(value);
+    }
+    
+    public static String encode(String value) {
+      return STAR._encode(value);
+    }
+    
+    public static String encode(String value, String charset) {
+      return STAR._encode(value, charset);
+    }
+    
+    public static String decode(String value) {
+        if (value == null)
+          return null;
+        Class<?>[] _classes = 
+          {StarCodec.class,BCodec.class,QCodec.class};
+        for (Class<?> _class : _classes) {
+          try {
+            StringDecoder dec = 
+              (StringDecoder) _class.newInstance();
+            return dec.decode(value);
+          } catch (DecoderException de) {
+            // try next
+          } catch (Exception e) {
+            break;
+          }
+        }
+        return value;
+    }
+
+    public static class StarCodec 
+      implements StringEncoder, 
+                 StringDecoder {
+      
+      public final String charset;
+      
+      public StarCodec() {
+        this("UTF-8");
+      }
+      
+      public StarCodec(String charset) {
+        this.charset = charset;
+      }
+
+      public Object encode(Object object) throws EncoderException {
+        if (object == null)
+          return null;
+        if (object instanceof String)
+          return encode((String)object);
+        throw new EncoderException();
+      }
+
+      public Object decode(Object object) throws DecoderException {
+        if (object == null)
+          return null;
+        if (object instanceof String)
+          return decode((String)object);
+        throw new DecoderException();
+      }
+
+      public String decode(String string) throws DecoderException {
+        try {
+          String[] parts = string.split("'",3);
+          if (parts.length != 3) 
+            throw new DecoderException();
+          return UrlEncoding.decode(parts[2], parts[0]);
+        } catch (Throwable t) {
+          throw new DecoderException(t.getMessage(),t);
+        }
+      }
+
+      public String encode(String string) throws EncoderException {
+        if (!needs(string)) return string;
+        StringBuilder buf = new StringBuilder();
+        buf.append(charset).append("''"); // we're not encoding language data
+        if (!charset.equalsIgnoreCase("UTF-8")) {
+          try {
+            ByteArrayInputStream in = 
+              new ByteArrayInputStream(string.getBytes(charset));
+            buf.append(UrlEncoding.encode(in, charset, CharUtils.Profile.RFC5987));
+          } catch (Throwable t) {
+            throw new EncoderException(t.getMessage());
+          }
+        } else   
+          buf.append(UrlEncoding.encode(string, CharUtils.Profile.RFC5987));
+        return buf.toString();
+      }
+      
+      private boolean needs(String string) {
+        for (char c : string.toCharArray())
+          if (!CharUtils.isToken(c) && c != 0x20)
+            return true;
+        return false;
+      }
+    }
+}
\ No newline at end of file

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

Added: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/CodepointIterator.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/CodepointIterator.java?rev=1173209&view=auto
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/CodepointIterator.java (added)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/CodepointIterator.java Tue Sep 20 15:56:46 2011
@@ -0,0 +1,238 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.common.text;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.Reader;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.channels.Channels;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.channels.WritableByteChannel;
+import java.nio.charset.Charset;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+
+import com.ibm.icu.text.UCharacterIterator;
+
+public abstract class CodepointIterator 
+  implements Iterator<Integer> {
+  
+  /**
+   * Get a CodepointIterator for the specified char array
+   */
+  public static CodepointIterator getInstance(char[] array) {
+      return new CharArrayCodepointIterator(array);
+  }
+
+  /**
+   * Get a CodepointIterator for the specified CharSequence
+   */
+  public static CodepointIterator getInstance(CharSequence seq) {
+      return new CharSequenceCodepointIterator(seq);
+  }
+
+  /**
+   * Get a CodepointIterator for the specified byte array, using the default charset
+   */
+  public static CodepointIterator getInstance(byte[] array) {
+      return new ByteArrayCodepointIterator(array);
+  }
+
+  /**
+   * Get a CodepointIterator for the specified byte array, using the specified charset
+   */
+  public static CodepointIterator getInstance(byte[] array, String charset) {
+      return new ByteArrayCodepointIterator(array, charset);
+  }
+
+  /**
+   * Get a CodepointIterator for the specified CharBuffer
+   */
+  public static CodepointIterator getInstance(CharBuffer buffer) {
+      return new CharBufferCodepointIterator(buffer);
+  }
+
+  /**
+   * Get a CodepointIterator for the specified ReadableByteChannel
+   */
+  public static CodepointIterator getInstance(ReadableByteChannel channel) {
+      return new ReadableByteChannelCodepointIterator(channel);
+  }
+
+  /**
+   * Get a CodepointIterator for the specified ReadableByteChannel
+   */
+  public static CodepointIterator getInstance(ReadableByteChannel channel, String charset) {
+      return new ReadableByteChannelCodepointIterator(channel, charset);
+  }
+
+  /**
+   * Get a CodepointIterator for the specified InputStream
+   */
+  public static CodepointIterator getInstance(InputStream in) {
+      return new ReadableByteChannelCodepointIterator(Channels.newChannel(in));
+  }
+
+  /**
+   * Get a CodepointIterator for the specified InputStream using the specified charset
+   */
+  public static CodepointIterator getInstance(InputStream in, String charset) {
+      return new ReadableByteChannelCodepointIterator(Channels.newChannel(in), charset);
+  }
+
+  /**
+   * Get a CodepointIterator for the specified Reader
+   */
+  public static CodepointIterator getInstance(Reader in) {
+      return new ReaderCodepointIterator(in);
+  }
+
+  /**
+   * Get the next codepoint
+   */
+  protected abstract int get();
+
+
+  /**
+   * True if there are codepoints remaining
+   */
+  public abstract boolean hasNext();
+
+  /**
+   * Return the next codepoint
+   */
+  public Integer next() throws InvalidCharacterException {
+      return get();
+  }
+
+  public void remove() {
+      throw new UnsupportedOperationException();
+  }
+
+
+  static class ByteArrayCodepointIterator extends CharArrayCodepointIterator {
+      public ByteArrayCodepointIterator(byte[] bytes) {
+          this(bytes, Charset.defaultCharset());
+      }
+
+      public ByteArrayCodepointIterator(byte[] bytes, String charset) {
+          this(bytes, Charset.forName(charset));
+      }
+
+      public ByteArrayCodepointIterator(byte[] bytes, Charset charset) {
+          super(charset.decode(ByteBuffer.wrap(bytes)).array());
+      }
+  }
+
+  static class CharArrayCodepointIterator extends CodepointIterator {      
+      protected final UCharacterIterator i;
+      protected int current;
+      public CharArrayCodepointIterator(char[] buffer) {
+          this.i = UCharacterIterator.getInstance(buffer);
+          current = i.next();
+      }
+      public CharArrayCodepointIterator(char[] buffer, int n, int e) {
+          this.i = UCharacterIterator.getInstance(buffer, n, e);
+          current = i.next();
+      }
+      protected int get() {
+        if (current != UCharacterIterator.DONE) {
+          int v = current;
+          current = i.nextCodePoint();
+          return v;
+        } else throw new NoSuchElementException();
+      }
+      public boolean hasNext() {
+        return current != UCharacterIterator.DONE;
+      }
+
+  }
+
+  static class CharBufferCodepointIterator extends CharArrayCodepointIterator {
+      public CharBufferCodepointIterator(CharBuffer cb) {
+          super(cb.array());
+      }
+  }
+
+  static class CharSequenceCodepointIterator extends CharArrayCodepointIterator {
+      public CharSequenceCodepointIterator(CharSequence buffer) {
+          this(buffer, 0, buffer.length());
+      }
+      public CharSequenceCodepointIterator(CharSequence buffer, int n, int e) {
+          super(toCharArray(buffer,n,e));
+      }
+      private static char[] toCharArray(CharSequence seq, int n, int e) {
+        char[] ret = new char[seq.length()];
+        for (int i = n; i < e; i++)
+          ret[i] = seq.charAt(i);
+        return ret;
+      }
+  }
+
+  static class ReadableByteChannelCodepointIterator extends CharArrayCodepointIterator {
+      public ReadableByteChannelCodepointIterator(ReadableByteChannel channel) {
+          this(channel, Charset.defaultCharset());
+      }
+      public ReadableByteChannelCodepointIterator(ReadableByteChannel channel, String charset) {
+          this(channel, Charset.forName(charset));
+      }
+      public ReadableByteChannelCodepointIterator(ReadableByteChannel channel, Charset charset) {
+          super(toCharArray(channel, charset));
+      }
+      private static char[] toCharArray(ReadableByteChannel channel, Charset charset) {
+        try {
+          ByteBuffer buf = ByteBuffer.allocate(1024);
+          ByteArrayOutputStream out = new ByteArrayOutputStream();
+          WritableByteChannel outc = Channels.newChannel(out);
+          while (channel.read(buf) > 0) {
+              buf.flip();
+              outc.write(buf);
+          }
+          CharBuffer cb = charset.decode(ByteBuffer.wrap(out.toByteArray()));
+          return cb.array();
+        } catch (Throwable t) {
+          throw new RuntimeException(t);
+        }
+      }
+  }
+
+  static class ReaderCodepointIterator extends CharArrayCodepointIterator {
+      public ReaderCodepointIterator(Reader reader) {
+          super(toCharArray(reader));
+      }
+      private static char[] toCharArray(Reader reader) {
+        try {
+          StringBuilder sb = new StringBuilder();
+          char[] buf = new char[1024];
+          int n = -1;
+          while ((n = reader.read(buf)) > -1) {
+              sb.append(buf, 0, n);
+          }
+          char[] ret = new char[sb.length()];
+          sb.getChars(0, sb.length(), ret, 0);
+          return ret;
+        } catch (Throwable t) {
+          throw new RuntimeException(t);
+        }
+      }
+  }
+
+}

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

Added: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/InvalidCharacterException.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/InvalidCharacterException.java?rev=1173209&view=auto
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/InvalidCharacterException.java (added)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/InvalidCharacterException.java Tue Sep 20 15:56:46 2011
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.common.text;
+
+public class InvalidCharacterException extends RuntimeException {
+
+    private static final long serialVersionUID = -7150645484748059676L;
+    private int input;
+
+    public InvalidCharacterException(int input) {
+        this.input = input;
+    }
+
+    @Override
+    public String getMessage() {     
+      return String.format(
+        "Invalid Character 0x%s (%c)", 
+        Integer.toHexString(input), 
+        (char)input);
+    }
+
+}

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

Added: 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=1173209&view=auto
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/NormalizationForm.java (added)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/NormalizationForm.java Tue Sep 20 15:56:46 2011
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.common.text;
+
+import com.ibm.icu.text.Normalizer2;
+import com.ibm.icu.text.Normalizer2.Mode;
+
+public enum NormalizationForm {
+    D(Mode.DECOMPOSE,  "nfc"), 
+    C(Mode.COMPOSE,    "nfc"), 
+    KD(Mode.DECOMPOSE, "nfkc"), 
+    KC(Mode.COMPOSE,   "nfkc");
+    
+    private final Normalizer2.Mode mode;
+    private final String name;
+    
+    NormalizationForm(
+        Normalizer2.Mode mode, 
+        String name) {
+      this.mode = mode;
+      this.name = name;
+    }
+    
+    public String normalize(CharSequence s) {
+      return Normalizer2.getInstance(null, name, mode).normalize(s);
+    }
+}
\ No newline at end of file

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

Added: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/Slug.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/Slug.java?rev=1173209&view=auto
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/Slug.java (added)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/Slug.java Tue Sep 20 15:56:46 2011
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.common.text;
+
+import org.apache.abdera2.common.text.CharUtils.Profile;
+
+public class Slug {
+
+    public static final String SANITIZE_PATTERN = "[^A-Za-z0-9\\%!$&\\\\'()*+,;=_]+";
+
+    public static Slug create(
+        String slug) {
+        return create(slug, "", true, NormalizationForm.D, SANITIZE_PATTERN);
+    }
+
+    public static Slug create(
+        String slug, 
+        String filler) {
+        return create(slug, filler, true, NormalizationForm.D, SANITIZE_PATTERN);
+    }
+
+    public static Slug create(
+        String slug, 
+        String filler, 
+        boolean lower) {
+        return create(slug, filler, lower, NormalizationForm.D, SANITIZE_PATTERN);
+    }
+
+    public static Slug create(
+        String slug, 
+        String filler, 
+        String pattern) {
+        return create(slug, filler, true, NormalizationForm.D, pattern);
+    }
+
+    public static Slug create(
+        String slug, 
+        String filler, 
+        boolean lower, 
+        String pattern) {
+        return create(slug, filler, lower, NormalizationForm.D, pattern);
+    }
+
+    public static Slug create(
+        String slug, 
+        String filler, 
+        boolean lower, 
+        NormalizationForm form) {
+        return create(slug, filler, lower, form, SANITIZE_PATTERN);
+    }
+
+    /**
+     * Used to sanitize a string. Optionally performs Unicode normalization on the string to break extended
+     * characters down, then replaces non alphanumeric characters with a specified filler replacement.
+     * 
+     * @param slug The source string
+     * @param filler The replacement string
+     * @param lower True if the result should be lowercase
+     * @param form Unicode Normalization form to use (or null)
+     */
+    public static Slug create(
+        String slug, 
+        String filler, 
+        boolean lower, 
+        NormalizationForm form, 
+        String pattern) {
+        if (slug == null)
+            return null;
+        if (lower)
+            slug = slug.toLowerCase();
+        if (form != null) {
+            slug = form.normalize(slug);
+        }
+        slug = slug.replaceAll("\\s+", "_");
+        if (filler != null) {
+            slug = slug.replaceAll(pattern, filler);
+        } else {
+            slug = UrlEncoding.encode(slug, Profile.PATHNODELIMS);
+        }
+        return new Slug(slug);
+    }
+    
+    private final String slug;
+    
+    private Slug(String slug) {
+      this.slug = slug;
+    }
+    
+    public String toString() {
+      return slug;
+    }
+
+    @Override
+    public int hashCode() {
+      final int prime = 31;
+      int result = 1;
+      result = prime * result + ((slug == null) ? 0 : slug.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;
+      Slug other = (Slug) obj;
+      if (slug == null) {
+        if (other.slug != null)
+          return false;
+      } else if (!slug.equals(other.slug))
+        return false;
+      return true;
+    }
+    
+}

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

Added: 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=1173209&view=auto
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/UrlEncoding.java (added)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/UrlEncoding.java Tue Sep 20 15:56:46 2011
@@ -0,0 +1,550 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.common.text;
+
+import java.io.ByteArrayInputStream;
+import java.io.FilterInputStream;
+import java.io.FilterOutputStream;
+import java.io.FilterReader;
+import java.io.FilterWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.nio.CharBuffer;
+
+import org.apache.abdera2.common.text.CharUtils.Profile;
+
+/**
+ * Performs URL Percent Encoding
+ */
+public final class UrlEncoding {
+
+    private static final String DEFAULT_ENCODING = "UTF-8";
+    public final static char[] HEX = 
+      {'0', '1', '2', '3', '4', '5', '6', '7', 
+       '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
+
+    private UrlEncoding() {
+    }
+
+    private static void encode(Appendable sb, byte... bytes) {
+        encode(sb, 0, bytes.length, bytes);
+    }
+
+    private static void encodeByte(Appendable sb, byte c) throws IOException {
+      sb.append(HEX[(c >> 4) & 0x0f])
+        .append(HEX[(c >> 0) & 0x0f]);
+    }
+    
+    public static void hex(Appendable sb, int offset, int length, byte... bytes) {
+      try {
+        int lim = Math.min(bytes.length, offset+length);
+        while(lim-offset>0)
+          encodeByte(sb,bytes[offset++]);
+      } catch (IOException e) {
+          throw new RuntimeException(e);
+      }
+    }
+    
+    private static void encode(Appendable sb, int offset, int length, byte... bytes) {
+        try {
+            int lim = Math.min(bytes.length, offset+length);
+            while(lim-offset>0) {
+                sb.append("%");
+                encodeByte(sb,bytes[offset++]);
+            }
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static String encode(char... chars) {
+        return encode(chars, 0, chars.length, DEFAULT_ENCODING, new Profile[0]);
+    }
+
+    public static String encode(char[] chars, Profile profile) {
+        return encode(chars, 0, chars.length, DEFAULT_ENCODING, new Profile[] {profile});
+    }
+
+    public static String encode(char[] chars, Profile... profiles) {
+        return encode(chars, 0, chars.length, DEFAULT_ENCODING, profiles);
+    }
+
+    public static String encode(char[] chars, String enc) {
+        return encode(chars, 0, chars.length, enc, new Profile[0]);
+    }
+
+    public static String encode(char[] chars, String enc, Profile profile) {
+        return encode(chars, 0, chars.length, enc, new Profile[] {profile});
+    }
+
+    public static String encode(char[] chars, String enc, Profile... profiles) {
+        return encode(chars, 0, chars.length, enc, profiles);
+    }
+
+    public static String encode(char[] chars, int offset, int length) {
+        return encode(chars, offset, length, DEFAULT_ENCODING, new Profile[0]);
+    }
+
+    public static String encode(char[] chars, int offset, int length, String enc) {
+        return encode(chars, offset, length, enc, new Profile[0]);
+    }
+
+    public static String encode(char[] chars, int offset, int length, Profile profile) {
+        return encode(chars, offset, length, DEFAULT_ENCODING, new Profile[] {profile});
+    }
+
+    public static String encode(char[] chars, int offset, int length, Profile... profiles) {
+        return encode(chars, offset, length, DEFAULT_ENCODING, profiles);
+    }
+
+    public static String encode(char[] chars, int offset, int length, String enc, Profile profile) {
+        return encode(chars, offset, length, enc, new Profile[] {profile});
+    }
+
+    public static String encode(char[] chars, int offset, int length, String enc, Profile... profiles) {
+        try {
+            return encode((CharSequence)CharBuffer.wrap(chars, offset, length), enc, profiles);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static String encode(InputStream in) throws IOException {
+        StringBuilder buf = new StringBuilder();
+        byte[] chunk = new byte[1024];
+        int r = -1;
+        while ((r = in.read(chunk)) > -1)
+            encode(buf, 0, r, chunk);
+        return buf.toString();
+    }
+
+    public static String encode(InputStream in, String charset) throws IOException {
+        return encode(in, charset, DEFAULT_ENCODING, new Profile[0]);
+    }
+
+    public static String encode(InputStream in, String charset, Profile profile) throws IOException {
+        return encode(in, charset, DEFAULT_ENCODING, new Profile[] {profile});
+    }
+
+    public static String encode(InputStream in, String charset, String enc) throws IOException {
+        return encode(in, charset, enc, new Profile[0]);
+    }
+
+    public static String encode(InputStream in, String charset, String enc, Profile profile) throws IOException {
+        return encode(in, charset, enc, new Profile[] {profile});
+    }
+
+    public static String encode(InputStream in, String charset, String enc, Profile... profiles) throws IOException {
+        return encode(new InputStreamReader(in, charset), enc, profiles);
+    }
+
+    public static String encode(InputStream in, String charset, Profile... profiles) throws IOException {
+        return encode(new InputStreamReader(in, charset), DEFAULT_ENCODING, profiles);
+    }
+
+    public static String encode(Reader reader) throws IOException {
+        return encode(reader, DEFAULT_ENCODING, new Profile[0]);
+    }
+
+    public static String encode(Readable readable) throws IOException {
+        return encode(readable, DEFAULT_ENCODING, new Profile[0]);
+    }
+
+    public static String encode(Reader reader, String enc) throws IOException {
+        return encode(reader, enc, new Profile[0]);
+    }
+
+    public static String encode(Readable readable, String enc) throws IOException {
+        return encode(readable, enc, new Profile[0]);
+    }
+
+    public static String encode(Reader reader, String enc, Profile profile) throws IOException {
+        return encode(reader, enc, new Profile[] {profile});
+    }
+
+    public static String encode(Reader reader, Profile profile) throws IOException {
+        return encode(reader, DEFAULT_ENCODING, new Profile[] {profile});
+    }
+
+    public static String encode(Reader reader, Profile... profiles) throws IOException {
+        return encode(reader, DEFAULT_ENCODING, profiles);
+    }
+
+    public static String encode(Readable readable, String enc, Profile profile) throws IOException {
+        return encode(readable, enc, new Profile[] {profile});
+    }
+
+    public static String encode(Readable readable, Profile profile) throws IOException {
+        return encode(readable, DEFAULT_ENCODING, new Profile[] {profile});
+    }
+
+    public static String encode(Readable readable, Profile... profiles) throws IOException {
+        return encode(readable, DEFAULT_ENCODING, profiles);
+    }
+
+    private static void processChars(StringBuilder sb, CharBuffer chars, String enc, Profile... profiles)
+        throws IOException {
+        for (int n = 0; n < chars.length(); n++) {
+            char c = chars.charAt(n);
+            if (!Character.isHighSurrogate(c) && check(c, profiles)) {
+                encode(sb, String.valueOf(c).getBytes(enc));
+            } else if (Character.isHighSurrogate(c)) {
+                if (check(c, profiles)) {
+                    StringBuilder buf = new StringBuilder();
+                    buf.append(c)
+                       .append(chars.charAt(++n));
+                    byte[] b = buf.toString().getBytes(enc);
+                    encode(sb, b);
+                } else {
+                    sb.append(c)
+                      .append(chars.charAt(++n));
+                }
+            } else {
+                sb.append(c);
+            }
+        }
+    }
+
+    public static String encode(Readable readable, String enc, Profile... profiles) throws IOException {
+        StringBuilder sb = new StringBuilder();
+        CharBuffer chars = CharBuffer.allocate(1024);
+        while (readable.read(chars) > -1) {
+            chars.flip();
+            processChars(sb, chars, enc, profiles);
+        }
+        return sb.toString();
+    }
+
+    public static String encode(Reader reader, String enc, Profile... profiles) throws IOException {
+        StringBuilder sb = new StringBuilder();
+        char[] chunk = new char[1024];
+        int r = -1;
+        while ((r = reader.read(chunk)) > -1)
+            processChars(sb, CharBuffer.wrap(chunk, 0, r), enc, profiles);
+        return sb.toString();
+    }
+
+    public static String encode(byte... bytes) {
+        StringBuilder buf = new StringBuilder();
+        encode(buf, bytes);
+        return buf.toString();
+    }
+
+    public static String encode(byte[] bytes, int off, int len) {
+        StringBuilder buf = new StringBuilder();
+        encode(buf, off, len, bytes);
+        return buf.toString();
+    }
+
+    public static String encode(CharSequence s) {
+        return encode(s, Profile.NONOP);
+    }
+
+    public static String encode(CharSequence s, Profile profile) {
+        return encode(s, new Profile[] {profile});
+    }
+
+    public static String encode(CharSequence s, Profile... profiles) {
+        try {
+            if (s == null)
+                return null;
+            return encode(s, "utf-8", profiles);
+        } catch (UnsupportedEncodingException e) {
+            return null; // shouldn't happen
+        }
+    }
+
+    public static String encode(CharSequence s, int offset, int length) {
+        return encode(s, offset, length, Profile.NONOP);
+    }
+
+    public static String encode(CharSequence s, int offset, int length, Profile profile) {
+        return encode(s, offset, length, new Profile[] {profile});
+    }
+
+    public static String encode(CharSequence s, int offset, int length, Profile... profiles) {
+        try {
+            if (s == null)
+                return null;
+            return encode(s, offset, length, "utf-8", profiles);
+        } catch (UnsupportedEncodingException e) {
+            return null; // shouldn't happen
+        }
+    }
+
+    private static boolean check(int codepoint, Profile... profiles) {
+        for (Profile profile : profiles) {
+            if (profile.filter(codepoint))
+                return true;
+        }
+        return false;
+    }
+
+    public static String encode(CharSequence s, int offset, int length, String enc, Profile... profiles)
+        throws UnsupportedEncodingException {
+        int end = Math.min(s.length(), offset + length);
+        CharSequence seq = s.subSequence(offset, end);
+        return encode(seq, enc, profiles);
+    }
+
+    public static String encode(CharSequence s, String enc, Profile... profiles) throws UnsupportedEncodingException {
+        if (s == null)
+            return null;
+        StringBuilder sb = new StringBuilder();
+
+        for (int n = 0; n < s.length(); n++) {
+            char c = s.charAt(n);
+            if (!Character.isHighSurrogate(c) && check(c, profiles)) {
+                encode(sb, String.valueOf(c).getBytes(enc));
+            } else if (Character.isHighSurrogate(c)) {
+                if (check(c, profiles)) {
+                    StringBuilder buf = new StringBuilder();
+                    buf.append(c)
+                       .append(s.charAt(++n));
+                    byte[] b = buf.toString().getBytes(enc);
+                    encode(sb, b);
+                } else {
+                    sb.append(c)
+                      .append(s.charAt(++n));
+                }
+            } else {
+                sb.append(c);
+            }
+        }
+        return sb.toString();
+    }
+
+    public static String decode(String e, String enc) throws UnsupportedEncodingException {
+      try {
+        DecodingInputStream r = new DecodingInputStream(e.getBytes(enc));
+        StringBuilder builder = new StringBuilder();
+        byte[] buf = new byte[100];
+        int i = -1;
+        while ((i = r.read(buf)) != -1)
+          builder.append(new String(buf,0,i,enc));
+        return builder.toString();
+      } catch (IOException i) {
+        throw new RuntimeException(i);
+      }
+    }
+
+    public static String decode(String e) {
+        try {
+            return decode(e, "utf-8");
+        } catch (Exception ex) {
+            return e;
+        }
+    }
+
+    public static class EncodingOutputStream extends FilterOutputStream {
+
+        public EncodingOutputStream(OutputStream out) {
+            super(out);
+        }
+
+        @Override
+        public void write(byte[] b, int off, int len) throws IOException {
+            String enc = encode(b, off, len);
+            out.write(enc.getBytes(DEFAULT_ENCODING));
+        }
+
+        @Override
+        public void write(byte[] b) throws IOException {
+            String enc = encode(b);
+            out.write(enc.getBytes(DEFAULT_ENCODING));
+        }
+
+        @Override
+        public void write(int b) throws IOException {
+            String enc = encode((byte)b);
+            out.write(enc.getBytes(DEFAULT_ENCODING));
+        }
+    }
+
+    public static class EncodingWriter extends FilterWriter {
+        private final Profile[] profiles;
+
+        public EncodingWriter(OutputStream out) {
+            this(new OutputStreamWriter(out));
+        }
+
+        public EncodingWriter(OutputStream out, Profile profile) {
+            this(new OutputStreamWriter(out), profile);
+        }
+
+        public EncodingWriter(OutputStream out, Profile... profiles) {
+            this(new OutputStreamWriter(out), profiles);
+        }
+
+        public EncodingWriter(Writer out) {
+            this(out, new Profile[0]);
+        }
+
+        public EncodingWriter(Writer out, Profile profile) {
+            this(out, new Profile[] {profile});
+        }
+
+        public EncodingWriter(Writer out, Profile... profiles) {
+            super(out);
+            this.profiles = profiles;
+        }
+
+        @Override
+        public void write(char[] b, int off, int len) throws IOException {
+            String enc = encode(b, off, len, profiles);
+            out.write(enc.toCharArray());
+        }
+
+        @Override
+        public void write(char[] b) throws IOException {
+            String enc = encode(b, profiles);
+            out.write(enc.toCharArray());
+        }
+
+        @Override
+        public void write(int b) throws IOException {
+            String enc = encode(new char[] {(char)b}, profiles);
+            out.write(enc.toCharArray());
+        }
+
+        @Override
+        public void write(String str, int off, int len) throws IOException {
+            String enc = encode(str, off, len, profiles);
+            out.write(enc.toCharArray());
+        }
+    }
+
+    public static class DecodingInputStream extends FilterInputStream {
+        public DecodingInputStream(InputStream in) {
+            super(in);
+        }
+
+        public DecodingInputStream(byte[] in) {
+            super(new ByteArrayInputStream(in));
+        }
+
+        public int read() throws IOException {
+            int c = super.read();
+            if (c == '%') {
+                return decode(
+                  (char)super.read(), 
+                  (char)super.read());
+            } else {
+                return c;
+            }
+        }
+
+        @Override
+        public synchronized int read(byte[] b, int off, int len) throws IOException {
+            int n = off;
+            int i = -1;
+            while ((i = read()) != -1 && n < off + len) {
+                b[n++] = (byte)i;
+            }
+            int r = n - off;
+            return r==0?-1:n - off;
+        }
+
+        @Override
+        public int read(byte[] b) throws IOException {
+            return read(b, 0, b.length);
+        }
+
+        @Override
+        public long skip(long n) throws IOException {
+            long i = 0;
+            for (; i < n; i++)
+                read();
+            return i;
+        }
+
+    }
+
+    public static class DecodingReader extends FilterReader {
+        public DecodingReader(byte[] buf) throws UnsupportedEncodingException {
+            this(new ByteArrayInputStream(buf));
+        }
+
+        public DecodingReader(byte[] buf, String enc) throws UnsupportedEncodingException {
+            this(new ByteArrayInputStream(buf), enc);
+        }
+
+        public DecodingReader(InputStream in) throws UnsupportedEncodingException {
+            this(in, DEFAULT_ENCODING);
+        }
+
+        public DecodingReader(InputStream in, String enc) throws UnsupportedEncodingException {
+            this(new InputStreamReader(in, enc));
+        }
+
+        public DecodingReader(Reader in) {
+            super(in);
+        }
+
+        public int read() throws IOException {
+            int c = super.read();
+            if (c == '%') {
+                int c1 = super.read();
+                int c2 = super.read();
+                return decode((char)c1, (char)c2);
+            } else {
+                return c;
+            }
+        }
+
+        @Override
+        public synchronized int read(char[] b, int off, int len) throws IOException {
+            int n = off;
+            int i = -1;
+            while ((i = read()) != -1 && n < off + len) {
+                b[n++] = (char)i;
+            }
+            int r = n - off;
+            return r==0?-1:r;
+        }
+
+        @Override
+        public int read(char[] b) throws IOException {
+            return read(b, 0, b.length);
+        }
+
+        @Override
+        public long skip(long n) throws IOException {
+            long i = 0;
+            for (; i < n; i++)
+                read();
+            return i;
+        }
+    }
+
+    private static byte decode(char c, int shift) {
+        return (byte)((((c >= '0' && c <= '9') ? c - '0' : (c >= 'A' && c <= 'F') ? c - 'A' + 10
+            : (c >= 'a' && c <= 'f') ? c - 'a' + 10 : -1) & 0xf) << shift);
+    }
+
+    private static byte decode(char c1, char c2) {
+        return (byte)(decode(c1, 4) | decode(c2, 0));
+    }
+
+}

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

Added: 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=1173209&view=auto
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/xml/XMLStreamSniffingInputStream.java (added)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/xml/XMLStreamSniffingInputStream.java Tue Sep 20 15:56:46 2011
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.common.xml;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.xml.stream.XMLInputFactory;
+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.
+ */
+public class XMLStreamSniffingInputStream extends CharsetSniffingInputStream {
+
+    public XMLStreamSniffingInputStream(InputStream in) {
+        super(in);
+    }
+
+    @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) {
+        }
+        return charset;
+    }
+
+}

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

Added: 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=1173209&view=auto
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/xml/XMLVersion.java (added)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/xml/XMLVersion.java Tue Sep 20 15:56:46 2011
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.common.xml;
+
+import org.apache.abdera2.common.text.CharUtils;
+import org.apache.abdera2.common.text.CharUtils.Profile;
+
+public enum XMLVersion {
+    XML10("1.0",CharUtils.Profile.XML1RESTRICTED), 
+    XML11("1.1",CharUtils.Profile.XML11RESTRICTED);
+    
+    private final Profile profile;
+    private final String label;
+    
+    XMLVersion(String label, Profile profile) {
+      this.profile = profile;
+      this.label = label;
+    }
+    
+    public Profile profile() {
+      return profile;
+    }
+    
+    public String label() {
+      return label;
+    }
+    
+    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;
+  }
+}
\ No newline at end of file

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

Added: 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=1173209&view=auto
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/xml/XmlRestrictedCharReader.java (added)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/xml/XmlRestrictedCharReader.java Tue Sep 20 15:56:46 2011
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.common.xml;
+
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+
+import org.apache.abdera2.common.io.FilteredCharReader;
+
+
+/**
+ * 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
+ * replacement character can be provided so long as it is a valid XML character itself.
+ */
+public class XmlRestrictedCharReader extends FilteredCharReader {
+
+    /**
+     * The XMLVersion determines which set of restrictions to apply depending on the XML version being parsed
+     */
+    public XmlRestrictedCharReader(InputStream in) {
+        this(new InputStreamReader(in));
+    }
+
+    public XmlRestrictedCharReader(InputStream in, String charset) throws UnsupportedEncodingException {
+        this(new InputStreamReader(in, charset));
+    }
+
+    public XmlRestrictedCharReader(InputStream in, XMLVersion version) {
+        this(new InputStreamReader(in), version);
+    }
+
+    public XmlRestrictedCharReader(InputStream in, String charset, XMLVersion version)
+        throws UnsupportedEncodingException {
+        this(new InputStreamReader(in, charset), version);
+    }
+
+    public XmlRestrictedCharReader(InputStream in, char replacement) {
+        this(new InputStreamReader(in), replacement);
+    }
+
+    public XmlRestrictedCharReader(InputStream in, String charset, char replacement)
+        throws UnsupportedEncodingException {
+        this(new InputStreamReader(in, charset), replacement);
+    }
+
+    public XmlRestrictedCharReader(InputStream in, XMLVersion version, char replacement) {
+        this(new InputStreamReader(in), version, replacement);
+    }
+
+    public XmlRestrictedCharReader(InputStream in, String charset, XMLVersion version, char replacement)
+        throws UnsupportedEncodingException {
+        this(new InputStreamReader(in, charset), version, replacement);
+    }
+
+    public XmlRestrictedCharReader(Reader in) {
+        this(in, XMLVersion.XML10, (char)0);
+    }
+
+    public XmlRestrictedCharReader(Reader in, XMLVersion version) {
+        this(in, version, (char)0);
+    }
+
+    public XmlRestrictedCharReader(Reader in, char replacement) {
+        this(in, XMLVersion.XML10, replacement);
+    }
+
+    public XmlRestrictedCharReader(Reader in, XMLVersion version, char replacement) {
+        super(in, version.profile(), replacement);
+    }
+
+}

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

Added: 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=1173209&view=auto
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/xml/XmlVersionInputStream.java (added)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/xml/XmlVersionInputStream.java Tue Sep 20 15:56:46 2011
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.common.xml;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.abdera2.common.io.PeekAheadInputStream;
+
+
+/**
+ * Will attempt to autodetect the character encoding from the stream This will preserve the BOM if it exists
+ */
+public class XmlVersionInputStream extends FilterInputStream {
+
+    private XMLVersion version = null;
+    private final int peek_ahead;
+    private static final int DEFAULT_PEEK_AHEAD = 200;
+
+    public XmlVersionInputStream(InputStream in, int peek_ahead) {
+      super(new PeekAheadInputStream(in, peek_ahead));
+      this.peek_ahead = peek_ahead;
+      try {
+        version = detectVersion();
+      } catch (IOException e) {}
+    }
+    
+    public XmlVersionInputStream(InputStream in) {
+        this(in,DEFAULT_PEEK_AHEAD);
+    }
+
+    public XMLVersion getVersion() {
+        return version;
+    }
+
+    private XMLVersion detectVersion() throws IOException {
+        String version = "1.0";
+        PeekAheadInputStream pin = (PeekAheadInputStream)this.in;
+        try {
+            byte[] p = new byte[peek_ahead];
+            pin.peek(p);
+            XMLStreamReader xmlreader =
+                XMLInputFactory.newInstance().createXMLStreamReader(new java.io.ByteArrayInputStream(p));
+            String v = xmlreader.getVersion();
+            if (v != null)
+                version = v;
+        } catch (Exception e) {
+        }
+        return XMLVersion.get(version);
+    }
+
+}

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

Added: 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=1173209&view=auto
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/xml/XmlVersionReader.java (added)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/xml/XmlVersionReader.java Tue Sep 20 15:56:46 2011
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.common.xml;
+
+import java.io.IOException;
+import java.io.PushbackReader;
+import java.io.Reader;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamReader;
+
+public class XmlVersionReader extends PushbackReader {
+
+  private XMLVersion version = null;
+  private final int peek_ahead;
+  private static final int DEFAULT_PEEK_AHEAD = 200;
+  
+    public XmlVersionReader(Reader in, int peek_ahead) {
+      super(in, peek_ahead);
+      this.peek_ahead = peek_ahead;
+      try {
+        version = detectVersion();
+      } catch (IOException e) {
+      }
+    }
+  
+    public XmlVersionReader(Reader in) {
+        this(in,DEFAULT_PEEK_AHEAD);
+    }
+
+    public XMLVersion getVersion() {
+        return version;
+    }
+
+    private XMLVersion detectVersion() throws IOException {
+        String version = "1.0";
+        try {
+            char[] p = new char[peek_ahead];
+            int r = read(p);
+            XMLStreamReader xmlreader =
+                XMLInputFactory.newInstance().createXMLStreamReader(new java.io.CharArrayReader(p));
+            String v = xmlreader.getVersion();
+            if (v != null)
+                version = v;
+            unread(p, 0, r);
+        } catch (Exception e) {
+        }
+        return XMLVersion.get(version);
+    }
+}

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

Added: abdera/abdera2/core/log4j.properties
URL: http://svn.apache.org/viewvc/abdera/abdera2/core/log4j.properties?rev=1173209&view=auto
==============================================================================
--- abdera/abdera2/core/log4j.properties (added)
+++ abdera/abdera2/core/log4j.properties Tue Sep 20 15:56:46 2011
@@ -0,0 +1,20 @@
+#   Licensed to the Apache Software Foundation (ASF) under one or more
+#   contributor license agreements.  See the NOTICE file distributed with
+#   this work for additional information regarding copyright ownership.
+#   The ASF licenses this file to You under the Apache License, Version 2.0
+#   (the "License"); you may not use this file except in compliance with
+#   the License.  You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.err
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%c{1}.%M: %m%n
+log4j.rootLogger=warn, stdout
\ No newline at end of file

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



Mime
View raw message