abdera-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jmsn...@apache.org
Subject svn commit: r600056 - in /incubator/abdera/java/trunk/dependencies/i18n/src: main/java/org/apache/abdera/i18n/io/ main/java/org/apache/abdera/i18n/iri/ main/java/org/apache/abdera/i18n/templates/ main/java/org/apache/abdera/i18n/unicode/ test/java/org/...
Date Sat, 01 Dec 2007 08:11:40 GMT
Author: jmsnell
Date: Sat Dec  1 00:11:39 2007
New Revision: 600056

URL: http://svn.apache.org/viewvc?rev=600056&view=rev
Log:
Variety of improvements including support for proper rendering of IRI Templates that contain
bidi characters, better handling of escaped characters, additional escaping options, etc

Modified:
    incubator/abdera/java/trunk/dependencies/i18n/src/main/java/org/apache/abdera/i18n/io/CharUtils.java
    incubator/abdera/java/trunk/dependencies/i18n/src/main/java/org/apache/abdera/i18n/iri/Escaping.java
    incubator/abdera/java/trunk/dependencies/i18n/src/main/java/org/apache/abdera/i18n/templates/HashMapContext.java
    incubator/abdera/java/trunk/dependencies/i18n/src/main/java/org/apache/abdera/i18n/templates/Operation.java
    incubator/abdera/java/trunk/dependencies/i18n/src/main/java/org/apache/abdera/i18n/templates/Template.java
    incubator/abdera/java/trunk/dependencies/i18n/src/main/java/org/apache/abdera/i18n/unicode/Normalizer.java
    incubator/abdera/java/trunk/dependencies/i18n/src/test/java/org/apache/abdera/i18n/test/iri/TestTemplate.java

Modified: incubator/abdera/java/trunk/dependencies/i18n/src/main/java/org/apache/abdera/i18n/io/CharUtils.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/dependencies/i18n/src/main/java/org/apache/abdera/i18n/io/CharUtils.java?rev=600056&r1=600055&r2=600056&view=diff
==============================================================================
--- incubator/abdera/java/trunk/dependencies/i18n/src/main/java/org/apache/abdera/i18n/io/CharUtils.java
(original)
+++ incubator/abdera/java/trunk/dependencies/i18n/src/main/java/org/apache/abdera/i18n/io/CharUtils.java
Sat Dec  1 00:11:39 2007
@@ -281,6 +281,10 @@
       s = s.substring(0,s.length()-1);
     return s;
   }
+    
+  public static String stripBidiInternal(String s) {
+    return s.replaceAll("[\u202A\u202B\u202D\u202E\u200E\u200F\u202C]", "");
+  }
   
   /**
    * Returns true if the character is a bidi control 

Modified: incubator/abdera/java/trunk/dependencies/i18n/src/main/java/org/apache/abdera/i18n/iri/Escaping.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/dependencies/i18n/src/main/java/org/apache/abdera/i18n/iri/Escaping.java?rev=600056&r1=600055&r2=600056&view=diff
==============================================================================
--- incubator/abdera/java/trunk/dependencies/i18n/src/main/java/org/apache/abdera/i18n/iri/Escaping.java
(original)
+++ incubator/abdera/java/trunk/dependencies/i18n/src/main/java/org/apache/abdera/i18n/iri/Escaping.java
Sat Dec  1 00:11:39 2007
@@ -18,9 +18,19 @@
 package org.apache.abdera.i18n.iri;
 
 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.abdera.i18n.io.CharUtils;
 import org.apache.abdera.i18n.io.CharUtils.Profile;
@@ -39,8 +49,13 @@
   private Escaping() {}
   
   private static void encode(Appendable sb, byte... bytes) {
+    encode(sb,0,bytes.length,bytes);
+  }
+  
+  private static void encode(Appendable sb, int offset, int length, byte... bytes) {
     try {
-      for (byte c : bytes) {
+      for (int n = offset, i = 0; n < bytes.length && i < length; n++, i++)
{
+        byte c = bytes[n];
         sb.append("%");
         sb.append(HEX[(c >> 4) & 0x0f]);
         sb.append(HEX[(c >> 0) & 0x0f]);
@@ -50,15 +65,261 @@
     }
   }
   
-  public static String encode(String s) {
+  public static String encode(char... chars) {
+    return encode(chars,0,chars.length,"UTF-8",new Profile[0]);
+  }
+  
+  public static String encode(char[] chars, Profile profile) {
+    return encode(chars,0,chars.length,"UTF-8",new Profile[] {profile});
+  }
+  
+  public static String encode(char[] chars, Profile... profiles) {
+    return encode(chars,0,chars.length,"UTF-8",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,"UTF-8",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,"UTF-8",new Profile[] {profile});
+  }
+  
+  public static String encode(char[] chars, int offset, int length, Profile... profiles)
{
+    return encode(chars,offset,length,"UTF-8",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,"UTF-8",new Profile[0]);
+  }
+
+  public static String encode(
+    InputStream in, 
+    String charset,
+    Profile profile) 
+      throws IOException {
+    return encode(in,charset,"UTF-8",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),"UTF-8",profiles);
+  }
+  
+  public static String encode(
+    Reader reader) 
+      throws IOException {
+    return encode(reader,"UTF-8", new Profile[0]);
+  }
+
+  public static String encode(
+    Readable readable) 
+      throws IOException {
+    return encode(readable,"UTF-8", 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,"UTF-8",new Profile[] {profile});
+  }
+
+  public static String encode(
+    Reader reader,  
+    Profile... profiles)
+      throws IOException {
+    return encode(reader,"UTF-8",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,"UTF-8",new Profile[] {profile});
+  }
+
+  public static String encode(
+    Readable readable,  
+    Profile... profiles)
+      throws IOException {
+    return encode(readable,"UTF-8",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 (!CharUtils.isHighSurrogate(c) && check(c,profiles)) {
+        encode(sb,String.valueOf(c).getBytes(enc));
+      } else if (CharUtils.isHighSurrogate(c)) {
+        if (check(c,profiles)) {
+          StringBuilder buf = new StringBuilder();
+          buf.append(c);
+          buf.append(chars.charAt(++n));
+          byte[] b = buf.toString().getBytes(enc);
+          encode(sb,b);
+        } else {
+          sb.append(c);
+          sb.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.NONE);
   }
   
-  public static String encode(String s, Profile profile) {
+  public static String encode(CharSequence s, Profile profile) {
     return encode(s, new Profile[] {profile});
   }
   
-  public static String encode(String s, Profile... profiles) {
+  public static String encode(CharSequence s, Profile... profiles) {
     try {
       if (s == null) return null;
       return encode(s,"utf-8",profiles);
@@ -67,35 +328,64 @@
     }
   }
   
+  public static String encode(CharSequence s, int offset, int length) {
+    return encode(s,offset,length,Profile.NONE);
+  }
+  
+  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.check(codepoint)) return false;
     }
     return true;
   }
+
+  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(
-    String s, 
+    CharSequence s, 
     String enc, 
     Profile... profiles) 
       throws UnsupportedEncodingException {
-    if (s == null) return s;
+    if (s == null) return s.toString();
     StringBuilder sb = new StringBuilder();
-    char[] chars = s.toCharArray();
-    for (int n = 0; n < chars.length; n++) {
-      char c = (char) chars[n];
+
+    for (int n = 0; n < s.length(); n++) {
+        char c = s.charAt(n);
       if (!CharUtils.isHighSurrogate(c) && check(c,profiles)) {
         encode(sb,String.valueOf(c).getBytes(enc));
       } else if (CharUtils.isHighSurrogate(c)) {
         if (check(c,profiles)) {
           StringBuilder buf = new StringBuilder();
           buf.append(c);
-          buf.append(chars[++n]);
+          buf.append(s.charAt(++n));
           byte[] b = buf.toString().getBytes(enc);
           encode(sb,b);
         } else {
           sb.append(c);
-          sb.append(chars[++n]);
+          sb.append(s.charAt(++n));
         }
       } else {
         sb.append(c);
@@ -123,13 +413,86 @@
     }
   }
   
-  public static class DecodingInputStream 
-    extends ByteArrayInputStream {
+  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("UTF-8"));
+    }
+    @Override 
+    public void write(byte[] b) throws IOException {
+      String enc = encode(b);
+      out.write(enc.getBytes("UTF-8"));
+    }
+    @Override 
+    public void write(int b) throws IOException {
+      String enc = encode((byte)b);
+      out.write(enc.getBytes("UTF-8"));
+    }
+  }
+
+  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());
+    }
+  }
 
-    DecodingInputStream(byte[] buf) {
-      super(buf);
+  public static class DecodingInputStream 
+    extends FilterInputStream {
+    public DecodingInputStream(InputStream in) {
+      super(in);
+    }
+    public DecodingInputStream(byte[] in) {
+      super(new ByteArrayInputStream(in));
     }
-    public int read() {
+    public int read() throws IOException {
       int c = super.read();
       if (c == '%') {
         int c1 = super.read();
@@ -140,7 +503,7 @@
       }
     }
     @Override
-    public synchronized int read(byte[] b, int off, int len) {
+    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) {
@@ -148,19 +511,73 @@
       }
       return 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 InputStreamReader {
-      public DecodingReader(byte[] buf) {
-        super(new DecodingInputStream(buf));
-      }
-      public DecodingReader(
-        byte[] buf, 
-        String encoding) 
-          throws UnsupportedEncodingException {
-        super(new DecodingInputStream(buf),encoding);
+    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, "UTF-8");
+    }
+    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;
+      }
+      return n - off;
+    }
+    @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) {

Modified: incubator/abdera/java/trunk/dependencies/i18n/src/main/java/org/apache/abdera/i18n/templates/HashMapContext.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/dependencies/i18n/src/main/java/org/apache/abdera/i18n/templates/HashMapContext.java?rev=600056&r1=600055&r2=600056&view=diff
==============================================================================
--- incubator/abdera/java/trunk/dependencies/i18n/src/main/java/org/apache/abdera/i18n/templates/HashMapContext.java
(original)
+++ incubator/abdera/java/trunk/dependencies/i18n/src/main/java/org/apache/abdera/i18n/templates/HashMapContext.java
Sat Dec  1 00:11:39 2007
@@ -39,6 +39,11 @@
   public HashMapContext(Map<String,Object> map) {
     super(map);
   }
+
+  public HashMapContext(Map<String,Object> map, boolean isiri) {
+    super(map);
+    this.isiri = isiri;
+  }
   
   public <T> T resolve(String var) {
     return (T)get(var);

Modified: incubator/abdera/java/trunk/dependencies/i18n/src/main/java/org/apache/abdera/i18n/templates/Operation.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/dependencies/i18n/src/main/java/org/apache/abdera/i18n/templates/Operation.java?rev=600056&r1=600055&r2=600056&view=diff
==============================================================================
--- incubator/abdera/java/trunk/dependencies/i18n/src/main/java/org/apache/abdera/i18n/templates/Operation.java
(original)
+++ incubator/abdera/java/trunk/dependencies/i18n/src/main/java/org/apache/abdera/i18n/templates/Operation.java
Sat Dec  1 00:11:39 2007
@@ -18,6 +18,7 @@
 package org.apache.abdera.i18n.templates;
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -103,25 +104,25 @@
     Object value = context.resolve(token);
     if (value != null) {
       if (value instanceof String) {
-        String val = (String) value;
+        String val = toString(value,context);
         if (val != null && val.length() > 0)
-          buf.append(encode(val,context.isIri(),context.isNormalizing()));
+          buf.append(val);
       } else if (value.getClass().isArray()) {
         Object[] values = (Object[])value;
         for (Object obj : values) {
-          String val = toString(obj);
+          String val = toString(obj,context);
           if (val != null && val.length() > 0) {
             if (buf.length() > 0) buf.append(sep);
-            buf.append(encode(val,context.isIri(),context.isNormalizing()));
+            buf.append(val);
           }
         }
       } else if (value instanceof Iterable) {
         Iterable iterable = (Iterable)value;
         for (Object obj : iterable) {
-          String val = toString(obj);
+          String val = toString(obj,context);
           if (val != null && val.length() > 0) {
             if (buf.length() > 0) buf.append(sep);
-            buf.append(encode(val,context.isIri(),context.isNormalizing()));
+            buf.append(val);
           }          
         }
       }
@@ -134,15 +135,113 @@
     String var = vardef[0];
     String def = vardef.length > 1 ? vardef[1] : null;
     Object rep = context.resolve(var);
-    String val = toString(rep);
+    String val = toString(rep,context);
     return val != null && val.length() > 0 ? 
-        encode(rep.toString(),context.isIri(),context.isNormalizing()) : 
-        def != null ? 
-          def : null;
+        val : def != null ? def : null;
   }
   
-  private static String toString(Object val) {
-    return val != null ? val.toString() : null;
+  private static String toString(Object val, Context context) {
+    if (val == null) return null;
+    if (val.getClass().isArray()) {
+      if (val instanceof byte[]) {
+        return Escaping.encode((byte[])val);
+      } else if (val instanceof char[]) {
+        try {
+          String chars = new String((char[])val);
+          return Escaping.encode(
+              !context.isNormalizing() ? chars : 
+              Normalizer.normalize(
+                chars, 
+                Normalizer.Form.C).toString(), 
+              context.isIri() ? 
+                CharUtils.Profile.IUNRESERVED : 
+                CharUtils.Profile.UNRESERVED);
+        } catch (IOException e) {
+          throw new RuntimeException(e);
+        }
+      } else if (val instanceof short[]) {
+        StringBuilder buf = new StringBuilder();
+        short[] array = (short[]) val;
+        for (short obj : array)
+          buf.append(String.valueOf(obj));
+        return buf.toString();
+      } else if (val instanceof int[]) {
+        StringBuilder buf = new StringBuilder();
+        int[] array = (int[]) val;
+        for (int obj : array)
+          buf.append(String.valueOf(obj));
+        return buf.toString();
+      } else if (val instanceof long[]) {
+        StringBuilder buf = new StringBuilder();
+        long[] array = (long[]) val;
+        for (long obj : array)
+          buf.append(String.valueOf(obj));
+        return buf.toString();
+      } else if (val instanceof double[]) {
+        StringBuilder buf = new StringBuilder();
+        double[] array = (double[]) val;
+        for (double obj : array)
+          buf.append(String.valueOf(obj));
+        return buf.toString();
+      } else if (val instanceof float[]) {
+        StringBuilder buf = new StringBuilder();
+        float[] array = (float[]) val;
+        for (float obj : array)
+          buf.append(String.valueOf(obj));
+        return buf.toString();
+      } else if (val instanceof boolean[]) {
+        StringBuilder buf = new StringBuilder();
+        boolean[] array = (boolean[]) val;
+        for (boolean obj : array)
+          buf.append(String.valueOf(obj));
+        return buf.toString();
+      } else {
+        StringBuilder buf = new StringBuilder();
+        Object[] array = (Object[]) val;
+        for (Object obj : array)
+          buf.append(toString(obj,context));
+        return buf.toString();
+      }
+    } else if (val instanceof Template) {
+      return toString(((Template)val).getPattern(),context);
+    } else if (val instanceof InputStream) {
+      try {
+        return Escaping.encode((InputStream)val);
+      } catch (IOException e) {
+        throw new RuntimeException(e);
+      }
+    } else if (val instanceof Readable) {
+      try {
+        return Escaping.encode(
+          (Readable)val, 
+          "UTF-8",
+          context.isIri() ? 
+            CharUtils.Profile.IUNRESERVED : 
+            CharUtils.Profile.UNRESERVED);
+      } catch (IOException e) {
+        throw new RuntimeException(e);
+      }
+    } else if (val instanceof CharSequence) {
+      return encode(
+        (CharSequence)val,
+        context.isIri(),
+        context.isNormalizing());
+    } else if (val instanceof Byte) {
+      return Escaping.encode(((Byte)val).byteValue());
+    } else if (val instanceof Iterable) {
+      StringBuilder buf = new StringBuilder();
+      Iterable i = (Iterable) val;
+      for (Object obj : i)
+        buf.append(toString(obj,context));
+      return buf.toString();
+    } else {
+      return encode(
+        val != null ? 
+          val.toString() : 
+          null,
+        context.isIri(),
+        context.isNormalizing());
+    }
   }
   
   protected static String eval(String token, String arg, Context context) {
@@ -155,31 +254,31 @@
       if (rep.getClass().isArray()) {
         Object[] array = (Object[]) rep;
         for (Object obj : array) {
-          String val = toString(obj);
+          String val = toString(obj,context);
           if (val != null && val.length() > 0) {
             if (buf.length() > 0) buf.append(arg);
             buf.append(var);
             buf.append("=");
-            buf.append(encode(val,context.isIri(),context.isNormalizing()));
+            buf.append(val);
           }
         }
       } else if (rep instanceof Iterable) {
         Iterable list = (Iterable)rep;
         for (Object obj : list) {
-          String val = toString(obj);
+          String val = toString(obj,context);
           if (val != null && val.length() > 0) {
             if (buf.length() > 0) buf.append(arg);
             buf.append(var);
             buf.append("=");
-            buf.append(encode(val,context.isIri(),context.isNormalizing()));
+            buf.append(val);
           }
         }
       } else {
-        String val = toString(rep);
+        String val = toString(rep,context);
         if (val != null && val.length() > 0) {
           buf.append(var);
           buf.append("=");
-          buf.append(encode(val,context.isIri(),context.isNormalizing()));
+          buf.append(val);
         }
       }
       return buf.toString();
@@ -202,11 +301,11 @@
     if (rep.getClass().isArray()) {
       Object[] a = (Object[])rep;
       return a.length > 0;
-    } else return true;
+    } else return toString(rep,context).length() > 0;
   }
   
   private static String encode(
-    String val, 
+    CharSequence val, 
     boolean isiri, 
     boolean normalizing) {
       try {
@@ -217,8 +316,7 @@
               Normalizer.Form.C).toString(), 
             isiri ? 
               CharUtils.Profile.IUNRESERVED : 
-              CharUtils.Profile.UNRESERVED, 
-            CharUtils.Profile.PCT);
+              CharUtils.Profile.UNRESERVED);
       } catch (IOException e) {
         throw new RuntimeException(e);
       }

Modified: incubator/abdera/java/trunk/dependencies/i18n/src/main/java/org/apache/abdera/i18n/templates/Template.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/dependencies/i18n/src/main/java/org/apache/abdera/i18n/templates/Template.java?rev=600056&r1=600055&r2=600056&view=diff
==============================================================================
--- incubator/abdera/java/trunk/dependencies/i18n/src/main/java/org/apache/abdera/i18n/templates/Template.java
(original)
+++ incubator/abdera/java/trunk/dependencies/i18n/src/main/java/org/apache/abdera/i18n/templates/Template.java
Sat Dec  1 00:11:39 2007
@@ -26,6 +26,8 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import org.apache.abdera.i18n.io.CharUtils;
+
 /**
  * Used to evaluate a URI Template.  
  * Instances are immutable, cloneable, serializable and threadsafe.
@@ -52,7 +54,7 @@
    */
   public Template(
     String pattern) {
-      this.pattern = pattern;
+      this.pattern = CharUtils.stripBidiInternal(pattern);
       this.tokens = initTokens();
       this.variables = initVariables();
   }
@@ -65,6 +67,35 @@
   }
   
   /**
+   * IRI Templates that contain bidirectional characters will 
+   * typically not display properly in unicode enabled environments.
+   * This method return the Template with appropriate bidi control
+   * characters to ensure that the Template can be rendered properly
+   * for display
+   */
+  public String getPatternForDisplay() {
+    String pattern = this.pattern;
+    for(String token : this) {
+      pattern = replace(
+        pattern, 
+        token, 
+        "{" + forDisplay(token) + "}");
+    }
+    return CharUtils.bidiLRM(pattern);
+  }
+  
+  private static String forDisplay(String token) {
+    //return token.replaceAll("([^{}|]*)", "\u200E$1\u200E");
+    String[] splits = token.split("\\|");
+    String d = "";
+    for (String s : splits) {
+      if (d.length() > 0) d+= "|";
+      d += CharUtils.bidiLRM(s);
+    }
+    return d;
+  }
+  
+  /**
    * Iterate the template tokens
    */
   public Iterator<String> iterator() {
@@ -141,7 +172,7 @@
       object instanceof Context ? 
         (Context)object :
         object instanceof Map ? 
-          new HashMapContext((Map)object) :
+          new HashMapContext((Map)object,isiri) :
           new ObjectContext(object,isiri));
   }
   

Modified: incubator/abdera/java/trunk/dependencies/i18n/src/main/java/org/apache/abdera/i18n/unicode/Normalizer.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/dependencies/i18n/src/main/java/org/apache/abdera/i18n/unicode/Normalizer.java?rev=600056&r1=600055&r2=600056&view=diff
==============================================================================
--- incubator/abdera/java/trunk/dependencies/i18n/src/main/java/org/apache/abdera/i18n/unicode/Normalizer.java
(original)
+++ incubator/abdera/java/trunk/dependencies/i18n/src/main/java/org/apache/abdera/i18n/unicode/Normalizer.java
Sat Dec  1 00:11:39 2007
@@ -65,7 +65,7 @@
   /**
    * Normalize the string using NFKC
    */
-  public static String normalize(String source) throws IOException {
+  public static String normalize(CharSequence source) throws IOException {
     return normalize(source, Form.KC);
   }
   
@@ -73,7 +73,7 @@
    * Normalize the string using the specified Form
    */
   public static String normalize(
-    String source, 
+    CharSequence source, 
     Form form) 
       throws IOException {
     return normalize(source, form, new StringBuilder());
@@ -83,7 +83,7 @@
    * Normalize the string into the given StringBuilder using the given Form
    */
   public static String normalize(
-    String source, 
+    CharSequence source, 
     Form form, 
     StringBuilder buf) 
       throws IOException {
@@ -95,7 +95,7 @@
   }
   
   private static void decompose(
-    String source, 
+    CharSequence source, 
     Form form, 
     StringBuilder buf) 
       throws IOException {

Modified: incubator/abdera/java/trunk/dependencies/i18n/src/test/java/org/apache/abdera/i18n/test/iri/TestTemplate.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/dependencies/i18n/src/test/java/org/apache/abdera/i18n/test/iri/TestTemplate.java?rev=600056&r1=600055&r2=600056&view=diff
==============================================================================
--- incubator/abdera/java/trunk/dependencies/i18n/src/test/java/org/apache/abdera/i18n/test/iri/TestTemplate.java
(original)
+++ incubator/abdera/java/trunk/dependencies/i18n/src/test/java/org/apache/abdera/i18n/test/iri/TestTemplate.java
Sat Dec  1 00:11:39 2007
@@ -17,6 +17,7 @@
 */
 package org.apache.abdera.i18n.test.iri;
 
+import java.io.ByteArrayInputStream;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
@@ -220,6 +221,10 @@
     map.put("reserved",":/?#[]@!$&'()*+,;=");
     map.put("u","\u2654\u2655");
     map.put("a_b","baz");
+    map.put("bytes", new byte[] {'a','b','c'});
+    map.put("stream", new ByteArrayInputStream(new byte[] {'a','b','c'}));
+    map.put("chars", new char[] {'a','b','c','/'});
+    map.put("ints", new int[] {1,2,3});
     
     Map<String,String> tests = new HashMap<String,String>();
     tests.put("http://example.org/?q={a}","http://example.org/?q=foo");
@@ -237,6 +242,10 @@
     tests.put("http://example.org/?d={-listjoin|&d=|points}","http://example.org/?d=10&d=20&d=30");
     tests.put("http://example.org/{a}{b}/{a_b}","http://example.org/foobar/baz");
     tests.put("http://example.org/{a}{-prefix|/-/|a}/","http://example.org/foo/-/foo/");
+    tests.put("{bytes}","%61%62%63");
+    tests.put("{stream}","%61%62%63");
+    tests.put("{chars}","abc%2F");
+    tests.put("{ints}","123");
     
     for (String t : tests.keySet())
       assertEquals(Template.expand(t,map),tests.get(t));



Mime
View raw message