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 2007/09/25 01:13:05 UTC

svn commit: r579015 - in /incubator/abdera/java/trunk/extensions/json: pom.xml src/main/java/org/apache/abdera/ext/json/JSONServlet.java src/main/java/org/apache/abdera/ext/json/JSONUtil.java src/main/java/org/apache/abdera/ext/json/JSONWriter.java

Author: jmsnell
Date: Mon Sep 24 16:13:02 2007
New Revision: 579015

URL: http://svn.apache.org/viewvc?rev=579015&view=rev
Log:
Reworking of the JSONWriter.  This provides a more complete Atom-to-JSON conversion that includes extensions, support for atom:feed, app:service, etc.  This should be considered to be a work in progress rewrite.

Oh, and this gets rid of the dependence on the third party json.jar.  There is one method in the new JSONUtil class that was taken from the json.jar.  I will be rewriting that method soon.  We should be able to completely drop that jar from the dist.

Added:
    incubator/abdera/java/trunk/extensions/json/src/main/java/org/apache/abdera/ext/json/JSONServlet.java
    incubator/abdera/java/trunk/extensions/json/src/main/java/org/apache/abdera/ext/json/JSONUtil.java
Modified:
    incubator/abdera/java/trunk/extensions/json/pom.xml
    incubator/abdera/java/trunk/extensions/json/src/main/java/org/apache/abdera/ext/json/JSONWriter.java

Modified: incubator/abdera/java/trunk/extensions/json/pom.xml
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/extensions/json/pom.xml?rev=579015&r1=579014&r2=579015&view=diff
==============================================================================
--- incubator/abdera/java/trunk/extensions/json/pom.xml (original)
+++ incubator/abdera/java/trunk/extensions/json/pom.xml Mon Sep 24 16:13:02 2007
@@ -42,26 +42,27 @@
       <groupId>org.apache.abdera</groupId>
       <artifactId>abdera-core</artifactId>
       <version>0.3.0-incubating-SNAPSHOT</version>
-      <scope>compile</scope>
     </dependency>    
     <dependency>
       <groupId>org.apache.abdera</groupId>
       <artifactId>abdera-parser</artifactId>
       <version>0.3.0-incubating-SNAPSHOT</version>
-      <scope>compile</scope>
     </dependency>   
     <dependency>
       <groupId>org.apache.abdera</groupId>
       <artifactId>abdera-protocol</artifactId>
       <version>0.3.0-incubating-SNAPSHOT</version>
-      <scope>compile</scope>
     </dependency>  
     <dependency>
       <groupId>org.apache.abdera</groupId>
       <artifactId>abdera-client</artifactId>
       <version>0.3.0-incubating-SNAPSHOT</version>
-      <scope>compile</scope>
     </dependency>  
+    <dependency>
+      <groupdId>org.apache.abdera</groupdId>
+      <artifactId>abdera-extensions-main</artifactId>
+      <version>0.3.0-incubating-SNAPSHOT</version>
+    </dependency>
     <dependency>
       <groupId>org.apache.abdera</groupId>
       <artifactId>json</artifactId>

Added: incubator/abdera/java/trunk/extensions/json/src/main/java/org/apache/abdera/ext/json/JSONServlet.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/extensions/json/src/main/java/org/apache/abdera/ext/json/JSONServlet.java?rev=579015&view=auto
==============================================================================
--- incubator/abdera/java/trunk/extensions/json/src/main/java/org/apache/abdera/ext/json/JSONServlet.java (added)
+++ incubator/abdera/java/trunk/extensions/json/src/main/java/org/apache/abdera/ext/json/JSONServlet.java Mon Sep 24 16:13:02 2007
@@ -0,0 +1,100 @@
+package org.apache.abdera.ext.json;
+/*
+ * 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.
+ */
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URLDecoder;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.abdera.Abdera;
+import org.apache.abdera.model.Document;
+import org.apache.abdera.protocol.client.AbderaClient;
+import org.apache.abdera.protocol.client.ClientResponse;
+import org.apache.abdera.writer.Writer;
+
+@SuppressWarnings("unchecked") 
+public class JSONServlet 
+  extends HttpServlet {
+
+  private static final long serialVersionUID = 1414392196430276024L;
+
+  private Abdera getAbdera() {
+    ServletContext sc = getServletContext();
+    Abdera abdera = null;
+    synchronized(sc) {
+      abdera = (Abdera)sc.getAttribute(Abdera.class.getName());
+      if (abdera == null) {
+        abdera = new Abdera();
+        sc.setAttribute(Abdera.class.getName(), abdera);
+      }      
+    }
+    return abdera;
+  }
+  
+  @Override 
+  protected void doGet(
+    HttpServletRequest request,
+    HttpServletResponse response) 
+      throws ServletException, IOException {
+    
+    String url = request.getPathInfo();
+    if (url != null) url = URLDecoder.decode(url, "UTF-8");
+    else {
+      response.sendError(400); 
+      return;
+    }
+
+    Abdera abdera = getAbdera();
+    AbderaClient client = new AbderaClient(abdera);
+    
+    Writer json = abdera.getWriterFactory().getWriter("json");
+    
+    ClientResponse resp = client.get(url);
+    switch(resp.getType()) {
+      case SUCCESS:
+        try {
+          Document doc = resp.getDocument();
+          response.setContentType("application/json");
+          response.setCharacterEncoding("UTF-8");
+          if (doc.getEntityTag() != null) 
+            response.setHeader("ETag", doc.getEntityTag().toString());
+          if (doc.getLanguage() != null)
+            response.setHeader("Content-Language", doc.getLanguage());
+          if (doc.getLastModified() != null)
+            response.setDateHeader("Last-Modified", doc.getLastModified().getTime());          
+          OutputStream out = response.getOutputStream();
+          json.writeTo(doc, out);
+        } catch (Exception e) {
+          response.sendError(500);
+          return;
+        }
+      case CLIENT_ERROR:
+      case SERVER_ERROR:
+        response.sendError(resp.getStatus(), resp.getStatusText());
+        return;
+    }
+  }
+
+  
+  
+}

Added: incubator/abdera/java/trunk/extensions/json/src/main/java/org/apache/abdera/ext/json/JSONUtil.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/extensions/json/src/main/java/org/apache/abdera/ext/json/JSONUtil.java?rev=579015&view=auto
==============================================================================
--- incubator/abdera/java/trunk/extensions/json/src/main/java/org/apache/abdera/ext/json/JSONUtil.java (added)
+++ incubator/abdera/java/trunk/extensions/json/src/main/java/org/apache/abdera/ext/json/JSONUtil.java Mon Sep 24 16:13:02 2007
@@ -0,0 +1,761 @@
+package org.apache.abdera.ext.json;
+/*
+ * 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.
+ */
+import java.io.IOException;
+import java.io.Writer;
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import org.apache.abdera.Abdera;
+import org.apache.abdera.ext.bidi.BidiHelper;
+import org.apache.abdera.ext.history.FeedPagingHelper;
+import org.apache.abdera.ext.thread.InReplyTo;
+import org.apache.abdera.ext.thread.ThreadHelper;
+import org.apache.abdera.ext.thread.Total;
+import org.apache.abdera.model.Base;
+import org.apache.abdera.model.Categories;
+import org.apache.abdera.model.Category;
+import org.apache.abdera.model.Collection;
+import org.apache.abdera.model.Content;
+import org.apache.abdera.model.Control;
+import org.apache.abdera.model.Div;
+import org.apache.abdera.model.Document;
+import org.apache.abdera.model.Element;
+import org.apache.abdera.model.Entry;
+import org.apache.abdera.model.ExtensibleElement;
+import org.apache.abdera.model.Feed;
+import org.apache.abdera.model.Generator;
+import org.apache.abdera.model.Link;
+import org.apache.abdera.model.Person;
+import org.apache.abdera.model.Service;
+import org.apache.abdera.model.Source;
+import org.apache.abdera.model.Text;
+import org.apache.abdera.model.TextValue;
+import org.apache.abdera.model.Workspace;
+import org.apache.abdera.util.Constants;
+import org.apache.abdera.xpath.XPath;
+
+@SuppressWarnings("unchecked")
+public class JSONUtil {
+
+  public static void toJson(Base base, Writer writer) throws IOException {
+    if (base instanceof Document)
+      toJson((Document)base,writer);
+    else if (base instanceof Element)
+      toJson((Element)base,writer);
+    writer.flush();
+  }
+  
+  private static Object[] getChildren(Element element) {
+    Abdera abdera = element.getFactory().getAbdera();
+    XPath xpath = abdera.getXPath();
+    List<Object> nodes = xpath.selectNodes("node()", element);
+    return nodes.toArray(new Object[nodes.size()]);
+  }
+  
+  private static void toJson(Element element, Writer writer) throws IOException {
+    writer.write('{');
+        
+    if (element instanceof Categories) {
+      Categories categories = (Categories) element;
+      writeField("fixed", categories.isFixed()?"true":"false", writer);
+      if (categories.getScheme() != null) {
+        writer.write(',');
+        writeField("scheme", categories.getScheme().toASCIIString(), writer);
+      } 
+      writer.write(',');
+      writeList("categories",categories.getCategories(),writer);
+      
+      writer.write(',');
+      writeExtensions((ExtensibleElement)element,writer);
+    } else if (element instanceof Category) {
+      Category category = (Category) element;
+
+      writeLanguageFields(element, writer);
+      
+      writer.write(',');
+      writeField("term", category.getTerm(), writer);
+      if (category.getScheme() != null) {
+        writer.write(',');
+        writeField("scheme", category.getScheme().toASCIIString(), writer);
+      }
+      if (category.getLabel() != null) {
+        writer.write(',');
+        writeField("label", category.getLabel(), writer);
+      }
+      
+      writer.write(',');
+      writeExtensions((ExtensibleElement)element,writer);
+    } else if (element instanceof Collection) {
+      Collection collection = (Collection)element;
+      if (collection.getResolvedHref() != null) {
+        writeField("href", collection.getResolvedHref().toASCIIString(), writer);
+        writer.write(',');
+      }
+      if (collection.getTitleElement() != null) {
+        writeElement("title",collection.getTitleElement(),writer);
+        writer.write(',');
+      }
+      writer.write("\"accept\":[");
+      String[] accepts = collection.getAccept();
+      for (int n = 0; n < accepts.length; n++) {
+        writer.write("\"" + escape(accepts[n]) + "\"");
+        if (n < accepts.length - 1) writer.write(',');
+      }
+      writer.write("]");
+      writer.write(',');
+      writeList("categories",collection.getCategories(),writer);
+      
+      writer.write(',');
+      writeExtensions((ExtensibleElement)element,writer);
+    } else if (element instanceof Content) {
+      Content content = (Content)element;      
+      writeLanguageFields(element, writer);
+      writer.write(',');      
+      if (element.getResolvedBaseUri() != null) {
+        writeField("base", element.getResolvedBaseUri().toASCIIString(), writer);
+        writer.write(',');
+      }      
+      if (content.getResolvedSrc() != null) {
+        writeField("src", content.getResolvedSrc().toASCIIString(), writer);
+        writer.write(',');
+      }
+     
+      switch(content.getContentType()) {
+        case TEXT:
+          writeField("type","text",writer);
+          writer.write(',');
+          writeField("value",content.getValue(),writer);
+          break;
+        case HTML:
+          writeField("type","html",writer);
+          writer.write(',');
+          writeField("value",content.getValue(),writer);
+          break;
+        case XHTML:
+          writeField("type","xhtml",writer);
+          writer.write(',');
+          writeXHTMLValue((Div)content.getValueElement(), writer);
+          writer.write(',');
+          writeField("display",content.getValue(), writer);
+          break;
+        case MEDIA:
+          writeField("type",content.getMimeType().toString(),writer);
+          if (content.getSrc() == null) {
+            writer.write(',');
+            writeField("value",content.getValue(),writer);
+          }
+          break;
+        case XML:
+          writeField("type",content.getMimeType().toString(),writer);
+          if (content.getSrc() == null) {
+            writer.write(',');
+            writeField("value",content.getValue(),writer);
+          }
+          break;
+      }
+    } else if (element instanceof Control) {
+      Control control = (Control)element;
+      writeField("draft", control.isDraft()?"true":"false",writer);
+      
+      writer.write(',');
+      writeExtensions((ExtensibleElement)element,writer);
+    } else if (element instanceof Entry) {
+      Entry entry = (Entry)element;
+
+      writeField("id", entry.getId().toASCIIString(),writer);
+      writer.write(',');
+      
+      writeElement("title", entry.getTitleElement(),writer);
+      writer.write(',');
+      
+      if (entry.getSummary() != null) {
+        writeElement("summary", entry.getSummaryElement(),writer);
+        writer.write(',');
+      }
+      
+      if (entry.getRights() != null) {
+        writeElement("rights", entry.getRightsElement(),writer);
+        writer.write(',');
+      }
+      
+      if (entry.getContentElement() != null) {
+        writeElement("content", entry.getContentElement(),writer);
+        writer.write(',');
+      }
+      
+      writeField("updated", entry.getUpdated().getTime(),writer);
+      writer.write(',');
+      
+      if (entry.getPublished() != null) {
+        writeField("published", entry.getPublished().getTime(),writer);
+        writer.write(',');
+      }
+      
+      if (entry.getEdited() != null) {
+        writeField("edited", entry.getEdited().getTime(),writer);
+        writer.write(',');
+      }
+      
+      if (entry.getSource() != null) {
+        writeElement("source", entry.getSource(),writer);
+        writer.write(',');
+      }
+      
+      writeList("authors",entry.getAuthors(),writer);
+      writer.write(',');
+
+      writeList("contributors",entry.getContributors(),writer);
+      writer.write(',');
+      
+      writeList("links",entry.getLinks(),writer);
+      writer.write(',');
+      
+      writeList("categories",entry.getCategories(),writer);
+      writer.write(',');
+      
+      writeList("inreplyto",ThreadHelper.getInReplyTos(entry),writer);
+      writer.write(',');
+      
+      List<Link> links = entry.getLinks("replies");
+      writer.write("\"replies\":[");
+      Total total = ThreadHelper.getTotal(entry);
+      if (total != null) {
+        writer.write("\n{");
+        writeField("count",total.getValue(),writer);
+        writer.write('}');
+        if (links.size() > 0) writer.write(',');
+      }
+      for (int n = 0; n < links.size(); n++) {
+        Link link = links.get(n);
+        writer.write("\n{");
+        writeField("href",link.getResolvedHref().toASCIIString(),writer);
+        writer.write(',');
+        if (link.getMimeType() != null) {
+          writeField("type",link.getMimeType().toString(),writer);
+          writer.write(',');
+        }
+        writeField("count",ThreadHelper.getCount(link),writer);
+        writer.write('}');
+        if (n < links.size()-1) writer.write(',');
+      }
+      writer.write("]");
+      writer.write(',');
+      
+      links = entry.getLinks("license");
+      writer.write("\"licenses\":[");
+      for (int n = 0; n < links.size(); n++) {
+        Link link = links.get(n);
+        writer.write("\n{");
+        writeField("href",link.getResolvedHref().toASCIIString(),writer);
+        if (link.getMimeType() != null) {
+          writer.write(',');
+          writeField("type",link.getMimeType().toString(),writer);
+        }
+        writer.write('}');
+        if (n < links.size()-1) writer.write(',');
+      }
+      writer.write("]");
+      
+      writer.write(',');
+      writeExtensions((ExtensibleElement)element,writer);
+      
+    } else if (element instanceof Generator) {
+      Generator generator = (Generator)element;
+      
+      writeLanguageFields(element, writer);
+      
+      if (generator.getVersion() != null) {
+        writer.write(',');
+        writeField("version", generator.getVersion(), writer);
+      }    
+      if (generator.getResolvedUri() != null) {
+        writer.write(',');  
+        writeField("uri", generator.getResolvedUri().toASCIIString(), writer);
+      }
+      if (generator.getText() != null) {
+        writer.write(',');
+        writeField("value", generator.getText(), writer);
+      }      
+    } else if (element instanceof Link) {
+      Link link = (Link)element;
+      
+      writeLanguageFields(element, writer);
+      
+      if (link.getResolvedHref() != null) {
+        writer.write(',');
+        writeField("href", link.getResolvedHref().toASCIIString(), writer);
+      }
+      if (link.getRel() != null) {
+        writer.write(',');
+        writeField("rel", link.getRel(), writer);
+      }
+      if (link.getTitle() != null) {
+        writer.write(',');
+        writeField("title", link.getTitle(), writer);
+      }
+      if (link.getMimeType() != null) {
+        writer.write(',');
+        writeField("type", link.getMimeType().toString(), writer);
+      }
+      if (link.getHrefLang() != null) {
+        writer.write(',');
+        writeField("hreflang", link.getHrefLang(), writer);
+      }
+      if (link.getLength() > -1) {
+        writer.write(',');
+        writeField("length", link.getLength(), writer);
+      }
+      
+      writer.write(',');
+      writeExtensions((ExtensibleElement)element,writer);
+    } else if (element instanceof Person) {
+      Person person = (Person)element;
+      
+      writeLanguageFields(element, writer);
+      
+      writer.write(',');
+      writeField("name",person.getName(),writer);
+      writer.write(',');
+      writeField("email",person.getEmail(),writer);
+      writer.write(',');
+      if (person.getUriElement() != null)
+        writeField("uri",person.getUriElement().getResolvedValue().toASCIIString(),writer);
+      
+      writer.write(',');
+      writeExtensions((ExtensibleElement)element,writer);
+    } else if (element instanceof Service) {
+      Service service = (Service)element;
+      writeList("workspaces",service.getWorkspaces(),writer);
+      
+      writer.write(',');
+      writeExtensions((ExtensibleElement)element,writer);
+    } else if (element instanceof Source) {
+      Source source = (Source)element;
+
+      writeField("id", source.getId().toASCIIString(),writer);
+      writer.write(',');
+      
+      writeElement("title", source.getTitleElement(),writer);
+      writer.write(',');
+      
+      if (source.getSubtitle() != null) {
+        writeElement("subtitle", source.getSubtitleElement(),writer);
+        writer.write(',');
+      }
+      
+      if (source.getRights() != null) {
+        writeElement("rights", source.getRightsElement(),writer);
+        writer.write(',');
+      }
+      
+      writeField("updated", source.getUpdated().getTime(),writer);
+      writer.write(',');
+
+      if (source.getGenerator() != null) {
+        writeElement("generator", source.getGenerator(),writer);
+        writer.write(',');
+      }
+      
+      if (source.getIconElement() != null) {
+        writeField("icon", source.getIconElement().getResolvedValue().toASCIIString(),writer);
+        writer.write(',');
+      }
+      
+      if (source.getLogoElement() != null) {
+        writeField("logo", source.getLogoElement().getResolvedValue().toASCIIString(),writer);
+        writer.write(',');
+      }
+      
+      writeList("authors",source.getAuthors(),writer);
+      writer.write(',');
+
+      writeList("contributors",source.getContributors(),writer);
+      writer.write(',');
+      
+      writeList("links",source.getLinks(),writer);
+      writer.write(',');
+      
+      writeList("categories",source.getCategories(),writer);
+      writer.write(',');
+      
+      writeField("complete",FeedPagingHelper.isComplete(source), writer);
+      writer.write(',');
+      
+      writeField("archive",FeedPagingHelper.isArchive(source), writer);
+      
+      if (source instanceof Feed) {
+        writer.write(',');
+        writeList("entries",((Feed)source).getEntries(),writer);
+      }
+      
+      writer.write(',');
+      writeExtensions((ExtensibleElement)element,writer);
+      
+    } else if (element instanceof Text) {
+      Text text = (Text)element;
+      
+      writeLanguageFields(element, writer);
+      
+      writer.write(',');
+      if (element.getResolvedBaseUri() != null) {
+        writeField("base", element.getResolvedBaseUri().toASCIIString(), writer);
+        writer.write(',');
+      }
+      
+      switch(text.getTextType()) {
+        case TEXT:
+          writeField("type","text",writer);
+          writer.write(',');
+          writeField("value",text.getValue(),writer);
+          break;
+        case HTML:
+          writeField("type","html",writer);
+          writer.write(',');
+          writeField("value",text.getValue(),writer);
+          break;
+        case XHTML:
+          writeField("type","xhtml",writer);
+          writer.write(',');
+          writeXHTMLValue(text.getValueElement(), writer);
+          writer.write(',');
+          writeField("display",text.getValue(), writer);
+          break;
+      }
+    } else if (element instanceof Workspace) {
+      Workspace workspace = (Workspace)element;
+
+      writeElement("title",workspace.getTitleElement(),writer);
+      writer.write(',');
+      writeList("collections",workspace.getCollections(),writer);
+      
+      writer.write(',');
+      writeExtensions((ExtensibleElement)element,writer);
+    } else if (element instanceof InReplyTo) {
+      InReplyTo irt = (InReplyTo)element;
+      
+      writeField("ref",irt.getRef().toASCIIString(),writer);
+      
+      if (irt.getHref() != null) {
+        writer.write(',');
+        writeField("href",irt.getResolvedHref().toASCIIString(),writer);
+      }
+      
+      if (irt.getMimeType() != null) {
+        writer.write(',');
+        writeField("type",irt.getMimeType().toString(),writer);
+      }
+      
+      if (irt.getSource() != null) {
+        writer.write(',');
+        writeField("source",irt.getResolvedSource().toASCIIString(),writer);
+      }
+      
+    } else {
+      writeQName(element.getQName(),writer);
+      writer.write(',');
+      writeLanguageFields(element, writer);
+      writer.write(',');
+      if (element.getResolvedBaseUri() != null) {
+        writeField("base", element.getResolvedBaseUri().toASCIIString(), writer);
+        writer.write(',');
+      }
+      writer.write("\"attributes\":");
+      writer.write('[');
+      List<QName> attributes = element.getAttributes();
+      for (int n = 0; n < attributes.size(); n++) {
+        QName qname = attributes.get(n);
+        writeAttribute(qname, element.getAttributeValue(qname), writer);
+        if (n < attributes.size()-1) writer.write(',');
+      }
+      writer.write(']');
+      writer.write(',');    
+      writer.write("\"children\":");
+      writeChildren(element, writer);
+    }
+    writer.write('}');
+  }
+    
+  private static void writeXHTMLValue(Div div, Writer writer) throws IOException {
+    writer.write("\n\"value\":");
+    writeXHTMLChildren(div, writer);
+  }
+
+  private static void writeXHTMLChildren(Element element, Writer writer) throws IOException {
+    writer.write('[');
+    Object[] children = getChildren(element);
+    for (int n = 0; n < children.length; n++) {
+      Object child = children[n];
+      if (child instanceof Element) {
+        Element childel = (Element) child;
+        QName childqname = childel.getQName();
+        writer.write("[\n");
+        if (childqname.getNamespaceURI() != null && childqname.getNamespaceURI().equals(Constants.XHTML_NS)) {
+          writer.write('"');
+          writer.write(escape(childqname.getLocalPart()));
+          writer.write('"');
+        } else {
+          writeQName(childqname,writer,false);
+        }
+        writer.write(',');
+        List<QName> attributes = childel.getAttributes();
+        writer.write('{');
+        for (int i = 0; i < attributes.size(); i++) {
+          QName attr = attributes.get(i);
+          writer.write('"');
+          writer.write(escape(attr.getLocalPart()));
+          writer.write('"');
+          writer.write(':');
+          writer.write('"');
+          writer.write(escape(childel.getAttributeValue(attr)));
+          writer.write('"');
+          if (i < attributes.size()-1) writer.write(',');
+        }
+        writer.write('}');
+        writer.write(',');
+        writeXHTMLChildren((Element)child,writer);
+        writer.write("]\n");      
+      } else if (child instanceof TextValue) {
+        TextValue textvalue = (TextValue) child;
+        writer.write("\"" + escape(textvalue.getText()) + "\"");
+      }
+      if (n < children.length-1) writer.write(',');
+    }
+    writer.write(']');
+  }
+  
+  private static void writeChildren(Element element, Writer writer) throws IOException {
+    writer.write('[');
+    Object[] children = getChildren(element);
+    for (int n = 0; n < children.length; n++) {
+      Object child = children[n];
+      if (child instanceof Element) {
+        toJson((Element)child, writer);
+      } else if (child instanceof TextValue) {
+        TextValue textvalue = (TextValue) child;
+        writer.write("\"" + escape(textvalue.getText()) + "\"");
+      }
+      if (n < children.length-1) writer.write(',');
+    }
+    writer.write(']');
+  }
+  
+  private static void writeExtensions(ExtensibleElement element, Writer writer) throws IOException {
+    writeList("extensions",element.getExtensions(),writer);
+    writer.write(',');
+    writer.write("\"attributes\":");
+    writer.write('[');
+    List<QName> attributes = element.getExtensionAttributes();
+    for (int n = 0; n < attributes.size(); n++) {
+      QName qname = attributes.get(n);
+      writeAttribute(qname, element.getAttributeValue(qname), writer);
+      if (n < attributes.size()-1) writer.write(',');
+    }
+    writer.write(']');
+  }
+  
+  private static void writeLanguageFields(Element element, Writer writer) throws IOException {
+    String lang = element.getLanguage();
+    boolean whitespace = element.getMustPreserveWhitespace();
+    if (lang != null) {
+      writeField("language",lang,writer);
+    }
+    
+    if (!whitespace) {
+      if (lang != null) writer.write(',');
+      writeField("whitespace", "false", writer);
+    }
+    
+    BidiHelper.Direction dir = BidiHelper.getDirection(element);
+    if (dir != null && dir != BidiHelper.Direction.UNSPECIFIED) {
+      if (lang != null || !whitespace) writer.write(',');
+      writeField("dir", dir.name().toLowerCase(), writer);
+    }
+  }
+  
+  private static void writeElement(String name, Element element, Writer writer) throws IOException {
+    if (element != null) {
+      writer.write("\n\"" + escape(name) + "\":");
+      toJson(element,writer);
+    }
+  }
+  
+  private static void writeList(String name, List list, Writer writer) throws IOException {
+    writer.write("\n\"" + escape(name) + "\":[");
+    for (int n = 0; n < list.size(); n++) {
+      toJson((Element)list.get(n),writer);
+      if (n < list.size()-1) writer.write(",\n");
+    }
+    writer.write("]");
+  }
+  
+  private static void toJson(Document document, Writer writer) throws IOException {
+    writer.write('{');
+    
+    if (document.getBaseUri() != null) {
+      writeField("base", document.getBaseUri().toASCIIString(), writer);
+      writer.write(',');
+    }
+    
+    if (document.getCharset() != null) {
+      writeField("charset", document.getCharset(), writer);
+      writer.write(',');
+    }
+    
+    if (document.getContentType() != null) {
+      writeField("contenttype", document.getContentType().toString(), writer);
+      writer.write(',');
+    }    
+    
+    if (document.getEntityTag() != null) {
+      writeField("etag", document.getEntityTag().toString(), writer);
+      writer.write(',');
+    }
+    
+    if (document.getLanguage() != null) {
+      writeField("language", document.getLanguage().toString(), writer);
+      writer.write(',');
+    }
+    
+    if (document.getSlug() != null) {
+      writeField("slug", document.getSlug(), writer);
+      writer.write(',');
+    }
+    
+    if (document.getLastModified() != null) {
+      writeField("lastmodified", document.getLastModified().getTime(), writer);
+      writer.write(',');
+    }
+    
+    if (!document.getMustPreserveWhitespace()) {
+      writeField("whitespace", "false", writer);
+      writer.write(',');
+    }
+    
+    Element root = document.getRoot();
+    if (root != null) {
+      writer.write("\n\"root\":");
+      toJson(root,writer);
+    } else {
+      writer.write("\"root\":null");
+    }
+    
+    writer.write('}');
+  }
+
+  private static void writeField(String name, boolean value, Writer writer) throws IOException {
+    writer.write("\n\"");
+    writer.write(escape(name));
+    writer.write('"');
+    writer.write(':');
+    writer.write(value?"true":"false");
+  }
+  
+  private static void writeField(String name, String value, Writer writer) throws IOException {
+    if (value == null) return;
+    writer.write("\n\"");
+    writer.write(escape(name));
+    writer.write('"');
+    writer.write(':');
+    writer.write('"');
+    writer.write(escape(value));
+    writer.write('"');
+  }
+  
+  private static void writeField(String name, Number value, Writer writer) throws IOException {
+    if (value == null) return;
+    writer.write("\n\"");
+    writer.write(escape(name));
+    writer.write('"');
+    writer.write(':');
+    writer.write(value.toString());
+  }
+  
+  private static void writeQName(QName qname, Writer writer) throws IOException {
+    writeQName(qname,writer,true);
+  }
+  
+  private static void writeQName(QName qname, Writer writer, boolean includefieldname) throws IOException {
+    if (includefieldname) writer.write("\n\"qname\":");
+    writer.write('{');
+    writeField("name",escape(qname.getLocalPart()),writer);
+    if (qname.getNamespaceURI() != null) {
+      writer.write(',');
+      writeField("ns",escape(qname.getNamespaceURI()),writer);
+    }
+    if (qname.getPrefix() != null) {
+      writer.write(',');
+      writeField("prefix",escape(qname.getPrefix()),writer);
+    }
+    writer.write('}');
+  }
+  
+  private static void writeAttribute(QName qname, String value, Writer writer) throws IOException {
+    writer.write("\n{");
+    writeQName(qname,writer);
+    writer.write(',');
+    writeField("value",escape(value),writer);
+    writer.write('}');
+  }
+  
+  private static String escape(String value) {
+    StringBuffer buf = new StringBuffer();
+    char[] chars = value.toCharArray();
+    char b = 0;
+    String t = null;
+    for (char c : chars) {
+      switch(c) {
+        case '\\':
+        case '"':
+          buf.append('\\');
+          buf.append(c);
+          break;
+        case '/':
+          if (b == '<') buf.append('\\');
+          buf.append(c);
+          break;
+        case '\b':
+          buf.append("\\b");
+          break;
+        case '\t':
+          buf.append("\\t");
+          break;
+        case '\n':
+          buf.append("\\n");
+          break;
+        case '\f':
+          buf.append("\\f");
+          break;
+        case '\r':
+          buf.append("\\r");
+          break;
+        default:
+          if (c < ' ' || c > 127) {
+            t = "000" + Integer.toHexString(c);
+            buf.append("\\u" + t.substring(t.length() - 4));
+          } else {
+            buf.append(c);
+          }
+        }
+        b = c;
+      }
+    return buf.toString();
+    }
+    
+}

Modified: incubator/abdera/java/trunk/extensions/json/src/main/java/org/apache/abdera/ext/json/JSONWriter.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/extensions/json/src/main/java/org/apache/abdera/ext/json/JSONWriter.java?rev=579015&r1=579014&r2=579015&view=diff
==============================================================================
--- incubator/abdera/java/trunk/extensions/json/src/main/java/org/apache/abdera/ext/json/JSONWriter.java (original)
+++ incubator/abdera/java/trunk/extensions/json/src/main/java/org/apache/abdera/ext/json/JSONWriter.java Mon Sep 24 16:13:02 2007
@@ -18,30 +18,16 @@
 
 package org.apache.abdera.ext.json;
 
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
-import java.util.List;
+import java.io.OutputStreamWriter;
 
 import org.apache.abdera.model.Base;
-import org.apache.abdera.model.Category;
-import org.apache.abdera.model.Collection;
-import org.apache.abdera.model.Content;
-import org.apache.abdera.model.Document;
-import org.apache.abdera.model.Entry;
-import org.apache.abdera.model.Feed;
-import org.apache.abdera.model.Generator;
-import org.apache.abdera.model.Link;
-import org.apache.abdera.model.Person;
-import org.apache.abdera.model.Service;
-import org.apache.abdera.model.Workspace;
-import org.apache.abdera.model.Content.Type;
 import org.apache.abdera.util.AbstractNamedWriter;
 import org.apache.abdera.util.AbstractWriterOptions;
 import org.apache.abdera.writer.NamedWriter;
 import org.apache.abdera.writer.WriterOptions;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
 
 public class JSONWriter
   extends AbstractNamedWriter
@@ -60,6 +46,11 @@
   public JSONWriter() {
     super(NAME,FORMATS);
   }
+
+  @Override 
+  protected WriterOptions initDefaultWriterOptions() {
+    return new AbstractWriterOptions() {};
+  }
   
   public String getName() {
     return NAME;
@@ -67,232 +58,28 @@
 
   public Object write(Base base, WriterOptions options) throws IOException {
     try {
-      return toJSON(base).toString();
-    } catch (Exception e) {
+      ByteArrayOutputStream out = new ByteArrayOutputStream();
+      writeTo(base,out,options);
+      return new String(out.toByteArray(),options.getCharset());
+    } catch (IOException i) {
+      throw i;
+    } catch (Exception e) { 
       throw new IOException(e.getMessage());
     }
   }
 
   public void writeTo(Base base, OutputStream out, WriterOptions options) throws IOException {
-    try {
-      Object result = toJSON(base);
-      out.write(result.toString().getBytes());
-      if (options.getAutoClose()) out.close();
-    } catch (Exception e) {
-      throw new IOException(e.getMessage());
-    }
+    writeTo(base,new OutputStreamWriter(out,options.getCharset()),options);
   }
 
   public void writeTo(Base base, java.io.Writer out, WriterOptions options) throws IOException {
     try {
-      Object result = toJSON(base);
-      out.write(result.toString());
+      JSONUtil.toJson(base, out);
       if (options.getAutoClose()) out.close();
     } catch (Exception e) {
+      e.printStackTrace();
       throw new IOException(e.getMessage());
     }
-  }
-
-  public static Object toJSON(Object object) throws Exception {
-    if (object instanceof Feed) {
-      return toJSON((Feed) object);
-    } else if (object instanceof Entry) {
-      return toJSON((Entry) object);
-    } else if (object instanceof Service) {
-      return toJSON((Service) object);
-    } else if (object instanceof Document) {
-      return toJSON(((Document) object).getRoot());
-    }
-    return new IllegalArgumentException("Element is not supported by JSONWriter.");
-  }
-
-  public static JSONObject toJSON(Entry entry) throws Exception {
-    JSONObject jsentry = new JSONObject();
-    if (entry.getTitle() != null)
-      jsentry.put("title", entry.getTitle());
-
-    if (entry.getSummary() != null)
-      jsentry.put("summary", entry.getSummary());
-
-    if (entry.getId() != null)
-      jsentry.put("id", entry.getId().toString());
-
-    if (entry.getUpdated() != null)
-      jsentry.put("updated", entry.getUpdated().toString());
-
-    if (entry.getPublished() != null)
-      jsentry.put("published", entry.getPublished().toString());
-
-    jsentry.put("authors", personsToJSON(entry.getAuthors()));
-
-    jsentry.put("contributors", personsToJSON(entry.getContributors()));
-
-    jsentry.put("categories", categoriesToJSON(entry.getCategories()));
-
-    jsentry.put("links", linksToJSON(entry.getLinks()));
-
-    JSONObject jscontent = new JSONObject();
-    if (entry.getContentElement() != null) {
-
-      Content content = entry.getContentElement();
-      Type type = entry.getContentType();
-      if (type.equals(Content.Type.HTML) || type.equals(Content.Type.XHTML) || type.equals(Content.Type.TEXT)) {
-        jscontent.put("type", type.toString().toLowerCase());
-      } else {
-        jscontent.put("type", content.getMimeType().toString());
-      }
-      jscontent.put("value", content.getValue());;
-      jsentry.put("content", jscontent);
-    }
-
-    return jsentry;
-  }
-
-  public static JSONObject toJSON(Feed feed) throws Exception {
-    JSONObject jsfeed = new JSONObject();
-
-    if (feed.getGenerator() != null) {
-      Generator gen = feed.getGenerator();
-      JSONObject jsgen = new JSONObject();
-      jsgen.put("uri", gen.getUri().toString());
-      jsgen.put("value", gen.getText());
-    }
-
-    if (feed.getTitle() != null) {
-      jsfeed.put("title", feed.getTitle());
-    }
-
-    if (feed.getSubtitle() != null) {
-      jsfeed.put("subtitle", feed.getSubtitle());
-    }
-
-    if (feed.getId() != null) {
-      jsfeed.put("id", feed.getId().toString());
-    }
-
-    if (feed.getRights() != null) {
-      jsfeed.put("rights", feed.getRights());
-    }
-
-    if (feed.getLogo() != null) {
-      jsfeed.put("logo", feed.getLogo().toString());
-    }
-
-    if (feed.getIcon() != null) {
-      jsfeed.put("icon", feed.getIcon().toString());
-    }
-
-    if (feed.getUpdatedString() != null) {
-      jsfeed.put("updated", feed.getUpdatedString());
-    }
-
-    jsfeed.put("authors", personsToJSON(feed.getAuthors()));
-
-    jsfeed.put("contributors", personsToJSON(feed.getContributors()));
-
-    jsfeed.put("categories", categoriesToJSON(feed.getCategories()));
-
-    jsfeed.put("links", linksToJSON(feed.getLinks()));
-
-    JSONArray jsentries = new JSONArray();
-    List<Entry> entries = feed.getEntries();
-    for (Entry entry : entries) {
-      jsentries.put(toJSON(entry));
-    }
-
-    jsfeed.put("entries", jsentries);
-
-    return jsfeed;
-  }
-
-  public static JSONObject toJSON(Service service) throws Exception {
-    JSONObject jssvc = new JSONObject();
-    JSONArray jsworkspaces = new JSONArray();
-    List<Workspace> workspaces = service.getWorkspaces();
-    for (Workspace workspace : workspaces) {
-      JSONObject jsworkspace = new JSONObject();
-      JSONArray jscollections = new JSONArray();
-      jsworkspace.put("title", workspace.getTitle());
-      List<Collection> collections = workspace.getCollections();
-      for (Collection collection : collections) {
-        JSONObject jscollection = new JSONObject();
-        JSONArray jsaccepts = new JSONArray();
-        String[] accepts = collection.getAccept();
-        for (String accept : accepts) {
-          jsaccepts.put(accept);
-        }
-        jscollection.put("href", collection.getHref().toString());
-        jscollection.put("accept", jsaccepts);
-        jscollections.put(jscollection);
-      }
-      jsworkspace.put("collections", jscollections);
-      jsworkspaces.put(jsworkspace);
-    }
-    jssvc.put("workspaces", jsworkspaces);
-
-    return jssvc;
-  }
-
-  private static JSONArray categoriesToJSON(List<Category> categories) throws JSONException {
-    JSONArray jscategories = new JSONArray();
-    for (Category category : categories) {
-      if (category.getScheme() != null || category.getLabel() != null || category.getTerm() != null) {
-        JSONObject jscategory = new JSONObject();
-        if (category.getScheme() != null)
-          jscategory.put("scheme", category.getScheme().toString());
-
-        if (category.getTerm() != null)
-          jscategory.put("term", category.getTerm());
-
-        if (category.getLabel() != null)
-          jscategory.put("label", category.getLabel());
-        jscategories.put(jscategory);
-      }
-    }
-    return jscategories;
-  }
-
-  private static JSONArray personsToJSON(List<Person> persons) throws JSONException {
-    JSONArray jspersons = new JSONArray();
-    for (Person p : persons) {
-      if (p.getName() != null || p.getUri() != null || p.getEmail() != null) {
-        JSONObject jsperson = new JSONObject();
-        if (p.getName() != null)
-          jsperson.put("name", p.getName());
-        if (p.getUri() != null)
-          jsperson.put("uri", p.getUri().toString());
-        if (p.getEmail() != null)
-          jsperson.put("email", p.getEmail());
-        jspersons.put(jsperson);
-      }
-    }
-    return jspersons;
-  }
-
-  private static JSONArray linksToJSON(List<Link> links) throws JSONException {
-    JSONArray jslinks = new JSONArray();
-    for (Link link : links) {
-      JSONObject jslink = new JSONObject();
-      if (link.getHref() != null) {
-        jslink.put("href", link.getHref().toString());
-
-        if (link.getRel() != null)
-          jslink.put("rel", link.getRel());
-
-        if (link.getMimeType() != null)
-          jslink.put("type", link.getMimeType().getBaseType());
-
-        if (link.getHrefLang() != null)
-          jslink.put("hreflang", link.getHrefLang());
-      }
-      jslinks.put(jslink);
-    }
-    return jslinks;
-  }
-
-  @Override
-  protected WriterOptions initDefaultWriterOptions() {
-    return new AbstractWriterOptions() {};
   }
 
 }



Re: svn commit: r579015 - in /incubator/abdera/java/trunk/extensions/json: pom.xml src/main/java/org/apache/abdera/ext/json/JSONServlet.java src/main/java/org/apache/abdera/ext/json/JSONUtil.java src/main/java/org/apache/abdera/ext/json/JSONWriter.java

Posted by James M Snell <ja...@gmail.com>.
*If* we ever get into parsing JSON, looking at a library like this would
make sense. As it stands now, all we're doing is serializing, which
turns out to be quite simple.  For that, a library is really not needed.

- James

Dan Diephouse wrote:
> jmsnell@apache.org wrote:
>> Author: jmsnell
>> Date: Mon Sep 24 16:13:02 2007
>> New Revision: 579015
>>
>> URL: http://svn.apache.org/viewvc?rev=579015&view=rev
>> Log:
>> Reworking of the JSONWriter.  This provides a more complete
>> Atom-to-JSON conversion that includes extensions, support for
>> atom:feed, app:service, etc.  This should be considered to be a work
>> in progress rewrite.
>>
>> Oh, and this gets rid of the dependence on the third party json.jar. 
>> There is one method in the new JSONUtil class that was taken from the
>> json.jar.  I will be rewriting that method soon.  We should be able to
>> completely drop that jar from the dist.
>>
>>   
> Could be overkill, but there is a new comer to JSON & Java: Jackson
> (written by Tatu who wrote woodstox):
> 
> http://www.cowtowncoder.com/hatchery/jackson/index.html
> http://www.cowtowncoder.com/blog/archives/2007/09/entry_47.html
> 
> - Dan
> 

Re: svn commit: r579015 - in /incubator/abdera/java/trunk/extensions/json: pom.xml src/main/java/org/apache/abdera/ext/json/JSONServlet.java src/main/java/org/apache/abdera/ext/json/JSONUtil.java src/main/java/org/apache/abdera/ext/json/JSONWriter.java

Posted by Dan Diephouse <da...@mulesource.com>.
jmsnell@apache.org wrote:
> Author: jmsnell
> Date: Mon Sep 24 16:13:02 2007
> New Revision: 579015
>
> URL: http://svn.apache.org/viewvc?rev=579015&view=rev
> Log:
> Reworking of the JSONWriter.  This provides a more complete Atom-to-JSON conversion that includes extensions, support for atom:feed, app:service, etc.  This should be considered to be a work in progress rewrite.
>
> Oh, and this gets rid of the dependence on the third party json.jar.  There is one method in the new JSONUtil class that was taken from the json.jar.  I will be rewriting that method soon.  We should be able to completely drop that jar from the dist.
>
>   
Could be overkill, but there is a new comer to JSON & Java: Jackson 
(written by Tatu who wrote woodstox):

http://www.cowtowncoder.com/hatchery/jackson/index.html
http://www.cowtowncoder.com/blog/archives/2007/09/entry_47.html

- Dan

-- 
Dan Diephouse
MuleSource
http://mulesource.com | http://netzooid.com/blog