You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@abdera.apache.org by jm...@apache.org on 2006/10/17 21:24:41 UTC

svn commit: r465012 - in /incubator/abdera/java/trunk: core/src/main/java/org/apache/abdera/util/io/CharUtils.java extensions/src/main/java/org/apache/abdera/ext/bidi/ extensions/src/main/java/org/apache/abdera/ext/bidi/BidiHelper.java

Author: jmsnell
Date: Tue Oct 17 12:24:39 2006
New Revision: 465012

URL: http://svn.apache.org/viewvc?view=rev&rev=465012
Log:
Initial preliminary checkin of bidi support.  BidiHelper can be used to determine the directionality
of text in a feed based on the presence of a dir attribute (in a variety of namespaces).

Added:
    incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/bidi/
    incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/bidi/BidiHelper.java
Modified:
    incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/util/io/CharUtils.java

Modified: incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/util/io/CharUtils.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/util/io/CharUtils.java?view=diff&rev=465012&r1=465011&r2=465012
==============================================================================
--- incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/util/io/CharUtils.java (original)
+++ incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/util/io/CharUtils.java Tue Oct 17 12:24:39 2006
@@ -273,45 +273,54 @@
     c == PDF;
   }
   
+  private static String wrap(String s, char c1, char c2) {
+    StringBuffer buf = new StringBuffer(s);
+    if (buf.length() > 1) {
+      if (buf.charAt(0) != c1) buf.insert(0, c1);
+      if (buf.charAt(buf.length()-1) != c2) buf.append(c2);
+    }
+    return buf.toString();
+  }
+  
   /**
    * Wrap the string with Bidi Right-to-Left embed
    */
   public static String bidiRLE(String s) {
-    return RLE + s + PDF;
+    return wrap(s,RLE,PDF);
   }
   
   /**
    * Wrap the string with Bidi Right-to-Left override 
    */
   public static String bidiRLO(String s) {
-    return RLO + s + PDF;
+    return wrap(s,RLO,PDF);
   }
   
   /**
    * Wrap the string with Bidi Left-to-Right embed
    */
   public static String bidiLRE(String s) {
-    return LRE + s + PDF;
+    return wrap(s,LRE,PDF);
   }
   
   /**
    * Wrap the string with Bidi Left-to-Right override
    */
   public static String bidiLRO(String s) {
-    return LRO + s + PDF;
+    return wrap(s,LRO,PDF);
   }
   
   /**
    * Wrap the string with Bidi RML marks
    */
   public static String bidiRLM(String s) {
-    return RLM + s + RLM;
+    return wrap(s,RLM,RLM);
   }
   
   /**
    * Wrap the string with Bidi LRM marks
    */
   public static String bidiLRM(String s) {
-    return LRM + s + RLM;
+    return wrap(s,LRM,LRM);
   }
 }

Added: incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/bidi/BidiHelper.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/bidi/BidiHelper.java?view=auto&rev=465012
==============================================================================
--- incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/bidi/BidiHelper.java (added)
+++ incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/bidi/BidiHelper.java Tue Oct 17 12:24:39 2006
@@ -0,0 +1,143 @@
+/*
+* 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.abdera.ext.bidi;
+
+import javax.xml.namespace.QName;
+
+import org.apache.abdera.model.Base;
+import org.apache.abdera.model.Element;
+import org.apache.abdera.util.Constants;
+import org.apache.abdera.util.io.CharUtils;
+
+/**
+ * This is (hopefully) temporary.  Ideally, this would be wrapped into the 
+ * core model API so that the bidi stuff is handled seamlessly.  There are 
+ * still details being worked out on the Atom WG list and it's likely that
+ * at least one other impl (mozilla) will do something slightly different.
+ * 
+ * The behavior implemented here is very simple.  The code looks for a dir
+ * attribute either in the Atom namespace, the XHTML namespace or the 
+ * Atom Bidi namespace (http://www.ietf.org/internet-drafts/draft-snell-atompub-bidi-00.txt).
+ * 
+ * The getBidi___ elements use the in-scope direction to wrap the text with 
+ * the appropriate Unicode control characters. e.g. if dir="rlo", the text is
+ * wrapped with the RLO and PDF controls.  If the text already contains the 
+ * control chars, the dir attribute is ignored.
+ * 
+ * <pre>
+ *    org.apache.abdera.Abdera abdera = new org.apache.abdera.Abdera();
+ *    org.apache.abdera.model.Feed feed = abdera.getFactory().newFeed();
+ *    feed.setAttributeValue("dir", "rlo");
+ *    feed.setTitle("Testing");
+ *    feed.addCategory("foo");
+ *    
+ *    System.out.println(
+ *      BidiHelper.getBidiElementText(
+ *        feed.getTitleElement()));
+ *    System.out.println(
+ *      BidiHelper.getBidiAttributeValue(
+ *        feed.getCategories().get(0),"term"));
+ *    
+ *    // Output: 
+ *    //
+ *    // > gnitseT
+ *    // > oof
+ *    //
+ * </pre>
+ * 
+ */
+public final class BidiHelper {
+
+  private static final QName XHTML_DIR = new QName(Constants.XHTML_NS,"dir");
+  private static final QName ABIDI_DIR = new QName("http://purl.org/atompub/bidi","dir");
+  
+  BidiHelper() {}
+  
+  public enum Direction { UNSPECIFIED, LTR, RTL, LRO, RLO };
+  
+  /**
+   * Get the in-scope direction for an element.  Currently, this is less
+   * than ideal because there currently isn't any standard way of expressing
+   * the direction in an Atom feed.  So, let's just support multiple approaches
+   * and hope that we get to the same place in the end. 
+   */
+  public static <T extends Element>Direction getDirection(T element) {
+    // Couple of options since this hasn't yet been nailed down by the WG
+    Direction direction = Direction.UNSPECIFIED;
+    // First try looking for a non-prefixed dir attribute
+    String dir = element.getAttributeValue("dir");
+    // failing that, try looking for the XHTML dir attribute
+    if (dir == null) dir = element.getAttributeValue(XHTML_DIR);
+    // failing that, try looking for the proposed Atom bidi dir attribute
+    if (dir == null) dir = element.getAttributeValue(ABIDI_DIR);
+    // failing that, try looking for any attribute with the name dir in any 
+    // namespace and values that look appropriate
+    if (dir == null) {
+      for (QName qname : element.getAttributes()) {
+        if (qname.getLocalPart().equalsIgnoreCase("dir")) {
+          String value = element.getAttributeValue(qname);
+          if (value != null && value.length() > 0) {
+            try {
+              direction = Direction.valueOf(value.toUpperCase());
+              if (direction != null) return direction;
+            } catch (Exception e) {}
+          }
+        }
+      }
+    }
+    if (dir != null && dir.length() > 0)
+      direction = Direction.valueOf(dir.toUpperCase());
+    else if (dir == null) {
+      // if the direction is unspecified on this element, 
+      // let's see if we've inherited it
+      Base parent = element.getParentElement(); 
+      if (parent != null && 
+          parent instanceof Element)
+        direction = getDirection((Element)parent);
+    }
+    return direction;
+  }
+  
+  public static String getBidiText(Direction direction, String text) {
+    switch (direction) {
+      case LTR: return CharUtils.bidiLRE(text);
+      case RTL: return CharUtils.bidiRLE(text);
+      case LRO: return CharUtils.bidiLRO(text);
+      case RLO: return CharUtils.bidiRLO(text);
+      default:  return text;
+    }
+  }
+  
+  public static <T extends Element>String getBidiChildText(T element, QName child) {
+    Element el = element.getFirstChild(child);
+    return (el != null) ? getBidiText(getDirection(el),el.getText()) : null;
+  }
+  
+  public static <T extends Element>String getBidiElementText(T element) {
+    return getBidiText(getDirection(element),element.getText());
+  }
+  
+  public static <T extends Element>String getBidiAttributeValue(T element, String name) {
+    return getBidiText(getDirection(element),element.getAttributeValue(name));
+  }
+  
+  public static <T extends Element>String getBidiAttributeValue(T element, QName name) {
+    return getBidiText(getDirection(element),element.getAttributeValue(name));
+  }
+  
+}