You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@roller.apache.org by sn...@apache.org on 2005/09/18 21:11:27 UTC

svn commit: r289954 [1/2] - in /incubator/roller/branches/roller_2.0: ./ custom/ nbproject/ sandbox/atomprotocol/ sandbox/atomprotocol/lib/ sandbox/atomprotocol/src/ sandbox/atomprotocol/src/org/ sandbox/atomprotocol/src/org/roller/ sandbox/atomprotoco...

Author: snoopdave
Date: Sun Sep 18 12:11:04 2005
New Revision: 289954

URL: http://svn.apache.org/viewcvs?rev=289954&view=rev
Log:
Upgraded to ROME 0.7, moved Atom protocol impl. to sandbox

Added:
    incubator/roller/branches/roller_2.0/sandbox/atomprotocol/
    incubator/roller/branches/roller_2.0/sandbox/atomprotocol/lib/
    incubator/roller/branches/roller_2.0/sandbox/atomprotocol/lib/README.txt
    incubator/roller/branches/roller_2.0/sandbox/atomprotocol/lib/rome-0.8.jar   (with props)
    incubator/roller/branches/roller_2.0/sandbox/atomprotocol/lib/rome-atom-1.0.patch
    incubator/roller/branches/roller_2.0/sandbox/atomprotocol/lib/rome-fetcher-0.8.jar   (with props)
    incubator/roller/branches/roller_2.0/sandbox/atomprotocol/src/
    incubator/roller/branches/roller_2.0/sandbox/atomprotocol/src/org/
    incubator/roller/branches/roller_2.0/sandbox/atomprotocol/src/org/roller/
    incubator/roller/branches/roller_2.0/sandbox/atomprotocol/src/org/roller/presentation/
    incubator/roller/branches/roller_2.0/sandbox/atomprotocol/src/org/roller/presentation/atomapi/
    incubator/roller/branches/roller_2.0/sandbox/atomprotocol/src/org/roller/presentation/atomapi/AtomCollection.java
    incubator/roller/branches/roller_2.0/sandbox/atomprotocol/src/org/roller/presentation/atomapi/AtomHandler.java
    incubator/roller/branches/roller_2.0/sandbox/atomprotocol/src/org/roller/presentation/atomapi/AtomService.java
    incubator/roller/branches/roller_2.0/sandbox/atomprotocol/src/org/roller/presentation/atomapi/AtomServlet.java
    incubator/roller/branches/roller_2.0/sandbox/atomprotocol/src/org/roller/presentation/atomapi/RollerAtomHandler.java
    incubator/roller/branches/roller_2.0/sandbox/atomprotocol/src/org/roller/presentation/atomapi/WSSEUtilities.java
    incubator/roller/branches/roller_2.0/sandbox/atomprotocol/src/org/roller/presentation/atomapi/package.html
    incubator/roller/branches/roller_2.0/tools/lib/rome-0.7.jar   (with props)
    incubator/roller/branches/roller_2.0/tools/lib/rome-fetcher-0.7.jar   (with props)
Removed:
    incubator/roller/branches/roller_2.0/src/org/roller/presentation/atomapi/
Modified:
    incubator/roller/branches/roller_2.0/.classpath
    incubator/roller/branches/roller_2.0/build.xml
    incubator/roller/branches/roller_2.0/custom/custom-gen-web.xmlf
    incubator/roller/branches/roller_2.0/custom/custom-jars.xmlf
    incubator/roller/branches/roller_2.0/custom/custom-src-web.xmlf
    incubator/roller/branches/roller_2.0/custom/custom-web.xmlf
    incubator/roller/branches/roller_2.0/nbproject/project.xml
    incubator/roller/branches/roller_2.0/properties.xmlf

Modified: incubator/roller/branches/roller_2.0/.classpath
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_2.0/.classpath?rev=289954&r1=289953&r2=289954&view=diff
==============================================================================
--- incubator/roller/branches/roller_2.0/.classpath (original)
+++ incubator/roller/branches/roller_2.0/.classpath Sun Sep 18 12:11:04 2005
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
 	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" path="sandbox/atomprotocol/src"/>
 	<classpathentry kind="src" path="sandbox/standalone/src"/>
 	<classpathentry kind="src" path="contrib/plugins/src"/>
 	<classpathentry kind="src" path="tests"/>
@@ -23,14 +24,11 @@
 	<classpathentry kind="lib" path="tools/buildtime/ant-1.6.2/ant-junit.jar"/>
 	<classpathentry kind="lib" path="tools/buildtime/ant-1.6.2/ant-commons-net.jar"/>
 	<classpathentry kind="lib" path="tools/buildtime/ant-1.6.2/ant.jar"/>
-	<classpathentry kind="lib" path="tools/lib/xmlrpc-2.0.jar"/>
 	<classpathentry kind="lib" path="tools/lib/xmlrpc-1.2-b1.jar"/>
 	<classpathentry kind="lib" path="tools/lib/velocity-tools-1.1.jar"/>
 	<classpathentry kind="lib" path="tools/lib/velocity-dep-1.4.jar"/>
 	<classpathentry kind="lib" path="tools/lib/velocity-1.4.jar"/>
 	<classpathentry kind="lib" path="tools/lib/taglibs-string.jar"/>
-	<classpathentry kind="lib" path="tools/lib/rome-fetcher-0.6.jar"/>
-	<classpathentry kind="lib" path="tools/lib/rome-0.6.jar"/>
 	<classpathentry kind="lib" path="tools/lib/mm.mysql-2.0.14-bin.jar"/>
 	<classpathentry kind="lib" path="tools/lib/mail.jar"/>
 	<classpathentry kind="lib" path="tools/lib/lucene-1.4.3.jar"/>
@@ -70,5 +68,8 @@
 	<classpathentry kind="lib" path="tools/hibernate-3.0/lib/asm-attrs.jar"/>
 	<classpathentry kind="lib" path="tools/hibernate-3.0/lib/asm.jar"/>
 	<classpathentry kind="lib" path="tools/lib/jdom.jar"/>
+	<classpathentry kind="lib" path="sandbox/atomprotocol/lib/rome-fetcher-0.8.jar"/>
+	<classpathentry kind="lib" path="sandbox/atomprotocol/lib/rome-0.8.jar"/>
+	<classpathentry kind="lib" path="sandbox/standalone/lib/catalina.jar"/>
 	<classpathentry kind="output" path="classes.eclipse"/>
 </classpath>

Modified: incubator/roller/branches/roller_2.0/build.xml
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_2.0/build.xml?rev=289954&r1=289953&r2=289954&view=diff
==============================================================================
--- incubator/roller/branches/roller_2.0/build.xml (original)
+++ incubator/roller/branches/roller_2.0/build.xml Sun Sep 18 12:11:04 2005
@@ -404,10 +404,6 @@
         <fileset dir="${build.compile_web}" excludes="**/tomcat/**"/>
     </jar>
 
-
-    <!-- Copy web contents to staging, plus README files. -->
-    <antcall target="copy-web" />
-
     <!-- Copy database configs to classpath in staging -->
     <copy todir="${build.stage_web}/WEB-INF/classes">
         <fileset dir="./metadata/database/hibernate" includes="hibernate.cfg.xml"/>
@@ -441,12 +437,17 @@
             <include name="xmlParserAPIs-2.3.0.jar" if="resinServer"/>
         </fileset>
     </copy>
-    <!-- Copy DTDs and TLDs  -->
+
+	<!-- Copy DTDs and TLDs  -->
     <copy todir="${build.stage_web}/WEB-INF/tlds">
         <fileset dir="${ro.tools}/lib" includes="*.tld"/>
     </copy>
-    <!-- copy database related files -->
+
+	<!-- copy database related files -->
     <antcall target="stage-dbscripts" />
+
+    <!-- Copy web contents to staging, plus README files. -->
+    <antcall target="copy-web" />
 
     <ant inheritAll="false" dir="contrib" />
 

Modified: incubator/roller/branches/roller_2.0/custom/custom-gen-web.xmlf
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_2.0/custom/custom-gen-web.xmlf?rev=289954&r1=289953&r2=289954&view=diff
==============================================================================
--- incubator/roller/branches/roller_2.0/custom/custom-gen-web.xmlf (original)
+++ incubator/roller/branches/roller_2.0/custom/custom-gen-web.xmlf Sun Sep 18 12:11:04 2005
@@ -1,7 +1,10 @@
 
+<!--  Include experimental Atom Protocol impl. in build. 
+<fileset dir="${basedir}/sandbox/atomprotocol/src" includes="**/*Servlet.java" />
+-->
+
 <!--  Custom classes to include in Struts and web generation 
 <fileset dir="${basedir}/custom/src" includes="**/*Data.java" />
-
 <fileset dir="${basedir}/sandbox/planetroller/src" includes="**/*Data.java" />
 <fileset dir="${basedir}/sandbox/planetroller/src" includes="**/*Action.java" />
 <fileset dir="${basedir}/sandbox/planetroller/src" includes="**/*FormEx.java" />

Modified: incubator/roller/branches/roller_2.0/custom/custom-jars.xmlf
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_2.0/custom/custom-jars.xmlf?rev=289954&r1=289953&r2=289954&view=diff
==============================================================================
--- incubator/roller/branches/roller_2.0/custom/custom-jars.xmlf (original)
+++ incubator/roller/branches/roller_2.0/custom/custom-jars.xmlf Sun Sep 18 12:11:04 2005
@@ -1,6 +1,9 @@
 
+<!-- Include hacked ROME jars needed for experimental Atom Protocol impl.
+<fileset dir="${basedir}/sandbox/atomprotocol/lib" includes="*.jar" />
+-->
+
 <!-- Custom jars to be added to both rollerbeans and rollerweb compiles -->
 <!-- <fileset dir="${basedir}/custom/lib" includes="*.java" />
-
 <fileset dir="${basedir}/sandbox/planetroller/web/WEB-INF/lib" includes="*.jar" />
 -->

Modified: incubator/roller/branches/roller_2.0/custom/custom-src-web.xmlf
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_2.0/custom/custom-src-web.xmlf?rev=289954&r1=289953&r2=289954&view=diff
==============================================================================
--- incubator/roller/branches/roller_2.0/custom/custom-src-web.xmlf (original)
+++ incubator/roller/branches/roller_2.0/custom/custom-src-web.xmlf Sun Sep 18 12:11:04 2005
@@ -1,8 +1,12 @@
 
-<!-- Custom classes to include in front-end compilation
+<!--  Include experimental Atom Protocol impl. in build. 
+<src path="${basedir}/sandbox/atomprotocol/src" />
+-->
+
+
+<!-- Exampe: custom classes to include in front-end compilation
  Your classes must be under the package org.roller.presentation.
 <src dir="${basedir}/sandbox/planetroller/src" />
-
 <src path="${basedir}/sandbox/planetroller/src" />
 -->
 

Modified: incubator/roller/branches/roller_2.0/custom/custom-web.xmlf
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_2.0/custom/custom-web.xmlf?rev=289954&r1=289953&r2=289954&view=diff
==============================================================================
--- incubator/roller/branches/roller_2.0/custom/custom-web.xmlf (original)
+++ incubator/roller/branches/roller_2.0/custom/custom-web.xmlf Sun Sep 18 12:11:04 2005
@@ -1,5 +1,16 @@
 
-<!-- Copy custom files into the Roller web context
+<!--  Substitute hacked ROME jars needed for experimental Atom Protocol impl.
+<delete file="${build.stage_web}/WEB-INF/lib/rome-0.7.jar" />
+<delete file="${build.stage_web}/WEB-INF/lib/rome-fetcher-0.7.jar" />
+<copy todir="${build.stage_web}/WEB-INF/lib" overwrite="true">
+   <fileset dir="${basedir}/sandbox/atomprotocol/lib">
+      <include name="rome-0.8.jar" />
+      <include name="rome-fetcher-0.8.jar" />
+   </fileset>
+</copy>
+-->
+
+<!-- Example: copy custom files into the Roller web context
 <copy todir="${build.stage_web}" overwrite="true">
    <fileset dir="${basedir}/sandbox/planetroller/web">
       <include name="**/**" />

Modified: incubator/roller/branches/roller_2.0/nbproject/project.xml
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_2.0/nbproject/project.xml?rev=289954&r1=289953&r2=289954&view=diff
==============================================================================
--- incubator/roller/branches/roller_2.0/nbproject/project.xml (original)
+++ incubator/roller/branches/roller_2.0/nbproject/project.xml Sun Sep 18 12:11:04 2005
@@ -48,6 +48,11 @@
                     <type>java</type>
                     <location>build/generated/src.presentation</location>
                 </source-folder>
+                <source-folder>
+                    <label>sandbox/atomprotocol/src</label>
+                    <type>java</type>
+                    <location>sandbox/atomprotocol/src</location>
+                </source-folder>
             </folders>
             <ide-actions>
                 <action name="build">
@@ -123,6 +128,10 @@
                         <label>build/generated/src.presentation</label>
                         <location>build/generated/src.presentation</location>
                     </source-folder>
+                    <source-folder style="packages">
+                        <label>sandbox/atomprotocol/src</label>
+                        <location>sandbox/atomprotocol/src</location>
+                    </source-folder>
                     <source-file>
                         <location>build.xml</location>
                     </source-file>
@@ -145,7 +154,8 @@
                 <package-root>contrib/plugins/src</package-root>
                 <package-root>build/generated/src.business</package-root>
                 <package-root>build/generated/src.presentation</package-root>
-                <classpath mode="compile">tools/hibernate-2.1/lib/jdom.jar:tools/buildtime/junit-3.8.1.jar:tools/lib/activation.jar:tools/lib/commons-betwixt-1.0-beta-1.jar:tools/lib/commons-codec-1.1.jar:tools/lib/commons-httpclient-2.0.2.jar:tools/lib/concurrent-1.3.2.jar:tools/lib/ekitapplet.jar:tools/lib/jazzy-core.jar:tools/lib/log4j-1.2.4.jar:tools/lib/lucene-1.4.3.jar:tools/lib/mail.jar:tools/lib/mm.mysql-2.0.14-bin.jar:tools/lib/rome-0.6.jar:tools/lib/rome-fetcher-0.6.jar:tools/lib/taglibs-string.jar:tools/lib/velocity-1.4.jar:tools/lib/velocity-dep-1.4.jar:tools/lib/velocity-tools-1.1.jar:tools/lib/xmlrpc-1.2-b1.jar:tools/struts-1.2.4/lib/antlr.jar:tools/struts-1.2.4/lib/commons-beanutils.jar:tools/struts-1.2.4/lib/commons-collections.jar:tools/struts-1.2.4/lib/commons-digester.jar:tools/struts-1.2.4/lib/commons-fileupload.jar:tools/struts-1.2.4/lib/commons-lang-2.0.jar:tools/struts-1.2.4/lib/commons-logging.jar:tools/struts-1.2.4/lib/commons-validator.jar:tools/struts-1.2.4/lib/jakarta-oro.jar:tools/struts-1.2.4/lib/struts-el.jar:tools/struts-1.2.4/lib/struts.jar:tools/hibernate-2.1/hibernate2.jar:tools/hibernate-2.1/lib/c3p0-0.8.4.5.jar:tools/hibernate-2.1/lib/cglib-full-2.0.1.jar:tools/hibernate-2.1/lib/dom4j-1.4.jar:tools/hibernate-2.1/lib/ehcache-0.7.jar:tools/hibernate-2.1/lib/jta.jar:tools/hibernate-2.1/lib/odmg-3.0.jar:tools/hibernate-2.1/lib/proxool-0.8.3.jar:tools/hibernate-2.1/lib/xalan-2.4.0.jar:tools/buildtime/mockrunner-0.35/lib/mockrunner-servlet.jar:tools/buildtime/mockrunner-0.35/lib/mockrunner-struts.jar:tools/buildtime/mockrunner-0.35/lib/mockrunner.jar:tools/buildtime/mockrunner-0.35/lib/nekohtml.jar:tools/standard-1.0.3/lib/jaxen-full.jar:tools/standard-1.0.3/lib/jstl.jar:tools/standard-1.0.3/lib/standard.jar:tools/buildtime/tomcat-5.0.28/servlet-api.jar:tools/buildtime/tomcat-5.0.28/jsp-api.jar</classpath>
+                <package-root>sandbox/atomprotocol/src</package-root>
+                <classpath mode="compile">tools/buildtime/junit-3.8.1.jar:tools/lib/activation.jar:tools/lib/commons-betwixt-1.0-beta-1.jar:tools/lib/commons-codec-1.1.jar:tools/lib/commons-httpclient-2.0.2.jar:tools/lib/concurrent-1.3.2.jar:tools/lib/ekitapplet.jar:tools/lib/jazzy-core.jar:tools/lib/log4j-1.2.4.jar:tools/lib/lucene-1.4.3.jar:tools/lib/mail.jar:tools/lib/mm.mysql-2.0.14-bin.jar:tools/lib/taglibs-string.jar:tools/lib/velocity-1.4.jar:tools/lib/velocity-dep-1.4.jar:tools/lib/velocity-tools-1.1.jar:tools/lib/xmlrpc-1.2-b1.jar:tools/struts-1.2.4/lib/antlr.jar:tools/struts-1.2.4/lib/commons-beanutils.jar:tools/struts-1.2.4/lib/commons-collections.jar:tools/struts-1.2.4/lib/commons-digester.jar:tools/struts-1.2.4/lib/commons-fileupload.jar:tools/struts-1.2.4/lib/commons-lang-2.0.jar:tools/struts-1.2.4/lib/commons-logging.jar:tools/struts-1.2.4/lib/commons-validator.jar:tools/struts-1.2.4/lib/jakarta-oro.jar:tools/struts-1.2.4/lib/struts-el.jar:tools/struts-1.2.4/lib/struts.jar:tools/buildtime/mockrunner-0.35/lib/mockrunner-servlet.jar:tools/buildtime/mockrunner-0.35/lib/mockrunner-struts.jar:tools/buildtime/mockrunner-0.35/lib/mockrunner.jar:tools/buildtime/mockrunner-0.35/lib/nekohtml.jar:tools/standard-1.0.3/lib/jaxen-full.jar:tools/standard-1.0.3/lib/jstl.jar:tools/standard-1.0.3/lib/standard.jar:tools/buildtime/tomcat-5.0.28/servlet-api.jar:tools/buildtime/tomcat-5.0.28/jsp-api.jar:sandbox/atomprotocol/lib/rome-0.8.jar:sandbox/atomprotocol/lib/rome-fetcher-0.8.jar:tools/hibernate-3.0/hibernate3.jar:tools/lib/jdom.jar</classpath>
                 <source-level>1.4</source-level>
             </compilation-unit>
         </java-data>

Modified: incubator/roller/branches/roller_2.0/properties.xmlf
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_2.0/properties.xmlf?rev=289954&r1=289953&r2=289954&view=diff
==============================================================================
--- incubator/roller/branches/roller_2.0/properties.xmlf (original)
+++ incubator/roller/branches/roller_2.0/properties.xmlf Sun Sep 18 12:11:04 2005
@@ -48,8 +48,8 @@
     <include name="jdom.jar"/>
     <include name="lucene-1.4.3.jar"/>
     <include name="log4j-1.2.4.jar"/>
-    <include name="rome-0.6.jar"/>
-    <include name="rome-fetcher-0.6.jar"/>
+    <include name="rome-0.7.jar"/>
+    <include name="rome-fetcher-0.7.jar"/>
     <include name="velocity-1.4.jar"/>
     <include name="velocity-dep-1.4.jar"/>
     <include name="velocity-tools-1.1.jar"/>

Added: incubator/roller/branches/roller_2.0/sandbox/atomprotocol/lib/README.txt
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_2.0/sandbox/atomprotocol/lib/README.txt?rev=289954&view=auto
==============================================================================
--- incubator/roller/branches/roller_2.0/sandbox/atomprotocol/lib/README.txt (added)
+++ incubator/roller/branches/roller_2.0/sandbox/atomprotocol/lib/README.txt Sun Sep 18 12:11:04 2005
@@ -0,0 +1,12 @@
+
+README for sandbox/atomprotocol/lib
+
+
+This directory contains a copy of ROME that has been modified to support Atom 1.0.
+
+The ROME code came from ROME CVS on September 17, 2005, the diffs are in a
+the file rome-atom-1.0.patch in this directory.
+
+ROME docs and CVS archive can be found here http://rome.dev.java.net.
+
+

Added: incubator/roller/branches/roller_2.0/sandbox/atomprotocol/lib/rome-0.8.jar
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_2.0/sandbox/atomprotocol/lib/rome-0.8.jar?rev=289954&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/roller/branches/roller_2.0/sandbox/atomprotocol/lib/rome-0.8.jar
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/roller/branches/roller_2.0/sandbox/atomprotocol/lib/rome-atom-1.0.patch
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_2.0/sandbox/atomprotocol/lib/rome-atom-1.0.patch?rev=289954&view=auto
==============================================================================
--- incubator/roller/branches/roller_2.0/sandbox/atomprotocol/lib/rome-atom-1.0.patch (added)
+++ incubator/roller/branches/roller_2.0/sandbox/atomprotocol/lib/rome-atom-1.0.patch Sun Sep 18 12:11:04 2005
@@ -0,0 +1,1754 @@
+Index: src/java/com/sun/syndication/feed/atom/Category.java
+===================================================================
+RCS file: src/java/com/sun/syndication/feed/atom/Category.java
+diff -N src/java/com/sun/syndication/feed/atom/Category.java
+--- /dev/null	1 Jan 1970 00:00:00 -0000
++++ src/java/com/sun/syndication/feed/atom/Category.java	1 Jan 1970 00:00:00 -0000
+@@ -0,0 +1,142 @@
++/*
++ * Copyright 2004 Sun Microsystems, Inc.
++ *
++ * Licensed 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.
++ *
++ */
++package com.sun.syndication.feed.atom;
++
++import com.sun.syndication.feed.impl.ObjectBean;
++
++import java.io.Serializable;
++
++/**
++ * Bean for category elements of Atom feeds.
++ * <p>
++ * @author Dave Johnson (added for Atom 1.0)
++ */
++public class Category implements Cloneable, Serializable  {
++    
++    private ObjectBean _objBean;
++    
++    private String _term;
++    private String _scheme;  
++    private String _label;
++
++    /**
++     * Default constructor. All properties are set to <b>null</b>.
++     * <p>
++     *
++     */
++    public Category() {
++        _objBean = new ObjectBean(this.getClass(),this);
++    }
++
++    /**
++     * Creates a deep 'bean' clone of the object.
++     * <p>
++     * @return a clone of the object.
++     * @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
++     *
++     */
++    public Object clone() throws CloneNotSupportedException {
++        return _objBean.clone();
++    }
++
++    /**
++     * Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
++     * <p>
++     * @param other he reference object with which to compare.
++     * @return <b>true</b> if 'this' object is equal to the 'other' object.
++     *
++     */
++    public boolean equals(Object other) {
++        return _objBean.equals(other);
++    }
++
++    /**
++     * Returns a hashcode value for the object.
++     * <p>
++     * It follows the contract defined by the Object hashCode() method.
++     * <p>
++     * @return the hashcode of the bean object.
++     *
++     */
++    public int hashCode() {
++        return _objBean.hashCode();
++    }
++
++    /**
++     * Returns the String representation for the object.
++     * <p>
++     * @return String representation for the object.
++     *
++     */
++    public String toString() {
++        return _objBean.toString();
++    }
++    
++    /** 
++     * Get label for category.
++     * <p>
++     * @return Label for category.
++     */
++    public String getLabel() {
++        return _label;
++    }
++    
++    /**
++     * Set label for category.
++     * <p>
++     * @param Label for category.
++     */
++    public void setLabel(String label) {
++        this._label = label;
++    }
++    
++    /**
++     * Get Scheme URI for category.
++     * <p>
++     * @return Scheme URI for category.
++     */
++    public String getScheme() {
++        return _scheme;
++    }
++    
++    /**
++     * Set scheme URI for category.
++     * <p>
++     * @param Scheme URI for category.
++     */
++    public void setScheme(String scheme) {
++        this._scheme = scheme;
++    }
++    
++    /**
++     * Return term for category.
++     * <p>
++     * @return Term for category.
++     */
++    public String getTerm() {
++        return _term;
++    }
++    
++    /**
++     * Set term for category.
++     * <p>
++     * @param Term for category.
++     */
++    public void setTerm(String term) {
++        this._term = term;
++    }
++}
+Index: src/java/com/sun/syndication/feed/synd/SyndLink.java
+===================================================================
+RCS file: src/java/com/sun/syndication/feed/synd/SyndLink.java
+diff -N src/java/com/sun/syndication/feed/synd/SyndLink.java
+--- /dev/null	1 Jan 1970 00:00:00 -0000
++++ src/java/com/sun/syndication/feed/synd/SyndLink.java	1 Jan 1970 00:00:00 -0000
+@@ -0,0 +1,151 @@
++/*
++ * Copyright 2004 Sun Microsystems, Inc.
++ *
++ * Licensed 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.
++ *
++ */
++package com.sun.syndication.feed.synd;
++
++/**
++ * Represents a link or enclosure associated with entry.
++ * @author Dave Johnson
++ */
++public interface SyndLink {
++    /**
++     * Creates a deep 'bean' clone of the object.
++     * <p>
++     * @return a clone of the object.
++     * @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
++     *
++     */
++    public abstract Object clone() throws CloneNotSupportedException;
++
++    /**
++     * Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
++     * <p>
++     * @param other he reference object with which to compare.
++     * @return <b>true</b> if 'this' object is equal to the 'other' object.
++     *
++     */
++    public abstract boolean equals(Object other);
++
++    /**
++     * Returns a hashcode value for the object.
++     * <p>
++     * It follows the contract defined by the Object hashCode() method.
++     * <p>
++     * @return the hashcode of the bean object.
++     *
++     */
++    public abstract int hashCode();
++
++    /**
++     * Returns the String representation for the object.
++     * <p>
++     * @return String representation for the object.
++     *
++     */
++    public abstract String toString();
++
++    /**
++     * Returns the link rel.
++     * <p>
++     * @return the link rel, <b>null</b> if none.
++     *
++     */
++    public abstract String getRel();
++
++    /**
++     * Sets the link rel.
++     * <p>
++     * @param rel the link rel,, <b>null</b> if none.
++     *
++     */
++    public abstract void setRel(String rel);
++
++    /**
++     * Returns the link type.
++     * <p>
++     * @return the link type, <b>null</b> if none.
++     *
++     */
++    public abstract String getType();
++
++    /**
++     * Sets the link type.
++     * <p>
++     * @param type the link type, <b>null</b> if none.
++     *
++     */
++    public abstract void setType(String type);
++
++    /**
++     * Returns the link href.
++     * <p>
++     * @return the link href, <b>null</b> if none.
++     *
++     */
++    public abstract String getHref();
++
++    /**
++     * Sets the link href.
++     * <p>
++     * @param href the link href, <b>null</b> if none.
++     *
++     */
++    public abstract void setHref(String href);
++
++    /**
++     * Returns the link title.
++     * <p>
++     * @return the link title, <b>null</b> if none.
++     *
++     */
++    public abstract String getTitle();
++
++    /**
++     * Sets the link title.
++     * <p>
++     * @param title the link title, <b>null</b> if none.
++     *
++     */
++    public abstract void setTitle(String title);
++
++    /**
++     * Returns the hreflang
++     * <p>
++     * @return Returns the hreflang.
++     */
++    public abstract String getHreflang();
++
++    /**
++     * Set the hreflang
++     * <p>
++     * @param hreflang The hreflang to set.
++     */
++    public abstract void setHreflang(String hreflang);
++
++    /**
++     * Returns the length
++     * <p>
++     * @return Returns the length.
++     */
++    public abstract long getLength();
++
++    /**
++     * Set the length
++     * <p>
++     * @param length The length to set.
++     */
++    public abstract void setLength(long length);
++}
+Index: src/java/com/sun/syndication/feed/synd/SyndLinkImpl.java
+===================================================================
+RCS file: src/java/com/sun/syndication/feed/synd/SyndLinkImpl.java
+diff -N src/java/com/sun/syndication/feed/synd/SyndLinkImpl.java
+--- /dev/null	1 Jan 1970 00:00:00 -0000
++++ src/java/com/sun/syndication/feed/synd/SyndLinkImpl.java	1 Jan 1970 00:00:00 -0000
+@@ -0,0 +1,209 @@
++/*
++ * Copyright 2004 Sun Microsystems, Inc.
++ *
++ * Licensed 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.
++ *
++ */
++package com.sun.syndication.feed.synd;
++
++import com.sun.syndication.feed.impl.ObjectBean;
++
++import java.io.Serializable;
++
++/**
++ * Represents a link or an enclosure.
++ * <p>
++ * @author Alejandro Abdelnur
++ * @author Dave Johnson (updated for Atom 1.0)
++ */
++public class SyndLinkImpl implements Cloneable,Serializable, SyndLink {
++    
++    private ObjectBean _objBean;
++    
++    private String _href;
++    private String _rel;
++    private String _type;
++    private String _hreflang; 
++    private String _title;
++    private long   _length;  
++
++    /**
++     * Default constructor. All properties are set to <b>null</b>.
++     * <p>
++     *
++     */
++    public SyndLinkImpl() {
++        _objBean = new ObjectBean(this.getClass(),this);
++    }
++
++    /**
++     * Creates a deep 'bean' clone of the object.
++     * <p>
++     * @return a clone of the object.
++     * @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
++     *
++     */
++    public Object clone() throws CloneNotSupportedException {
++        return _objBean.clone();
++    }
++
++    /**
++     * Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
++     * <p>
++     * @param other he reference object with which to compare.
++     * @return <b>true</b> if 'this' object is equal to the 'other' object.
++     *
++     */
++    public boolean equals(Object other) {
++        return _objBean.equals(other);
++    }
++
++    /**
++     * Returns a hashcode value for the object.
++     * <p>
++     * It follows the contract defined by the Object hashCode() method.
++     * <p>
++     * @return the hashcode of the bean object.
++     *
++     */
++    public int hashCode() {
++        return _objBean.hashCode();
++    }
++
++    /**
++     * Returns the String representation for the object.
++     * <p>
++     * @return String representation for the object.
++     *
++     */
++    public String toString() {
++        return _objBean.toString();
++    }
++
++    /**
++     * Returns the link rel.
++     * <p>
++     * @return the link rel, <b>null</b> if none.
++     *
++     */
++    public String getRel() {
++        return _rel;
++    }
++
++    /**
++     * Sets the link rel.
++     * <p>
++     * @param rel the link rel,, <b>null</b> if none.
++     *
++     */
++    public void setRel(String rel) {
++        //TODO add check, ask P@ about the check
++        _rel = rel;
++    }
++
++    /**
++     * Returns the link type.
++     * <p>
++     * @return the link type, <b>null</b> if none.
++     *
++     */
++    public String getType() {
++        return _type;
++    }
++
++    /**
++     * Sets the link type.
++     * <p>
++     * @param type the link type, <b>null</b> if none.
++     *
++     */
++    public void setType(String type) {
++        _type = type;
++    }
++
++    /**
++     * Returns the link href.
++     * <p>
++     * @return the link href, <b>null</b> if none.
++     *
++     */
++    public String getHref() {
++        return _href;
++    }
++
++    /**
++     * Sets the link href.
++     * <p>
++     * @param href the link href, <b>null</b> if none.
++     *
++     */
++    public void setHref(String href) {
++        _href = href;
++    }
++
++    /**
++     * Returns the link title.
++     * <p>
++     * @return the link title, <b>null</b> if none.
++     *
++     */
++    public String getTitle() {
++        return _title;
++    }
++
++    /**
++     * Sets the link title.
++     * <p>
++     * @param title the link title, <b>null</b> if none.
++     *
++     */
++    public void setTitle(String title) {
++        _title = title;
++    }
++
++    /**
++     * Returns the hreflang
++     * <p>
++     * @return Returns the hreflang.
++     */
++    public String getHreflang() {
++        return _hreflang;
++    }
++    
++    /**
++     * Set the hreflang
++     * <p>
++     * @param hreflang The hreflang to set.
++     */
++    public void setHreflang(String hreflang) {
++        _hreflang = hreflang;
++    }
++    
++    /**
++     * Returns the length
++     * <p>
++     * @return Returns the length.
++     */
++    public long getLength() {
++        return _length;
++    }
++    
++    /**
++     * Set the length
++     * <p>
++     * @param length The length to set.
++     */
++    public void setLength(long length) {
++        _length = length;
++    }
++}
+Index: src/java/com/sun/syndication/feed/synd/impl/ConverterForAtom10.java
+===================================================================
+RCS file: src/java/com/sun/syndication/feed/synd/impl/ConverterForAtom10.java
+diff -N src/java/com/sun/syndication/feed/synd/impl/ConverterForAtom10.java
+--- /dev/null	1 Jan 1970 00:00:00 -0000
++++ src/java/com/sun/syndication/feed/synd/impl/ConverterForAtom10.java	1 Jan 1970 00:00:00 -0000
+@@ -0,0 +1,374 @@
++/*
++ * Copyright 2004 Sun Microsystems, Inc.
++ *
++ * Licensed 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.
++ *
++ */
++package com.sun.syndication.feed.synd.impl;
++
++import java.util.ArrayList;
++import java.util.Date;
++import java.util.Iterator;
++import java.util.List;
++
++import com.sun.syndication.feed.WireFeed;
++import com.sun.syndication.feed.atom.Category;
++import com.sun.syndication.feed.atom.Content;
++import com.sun.syndication.feed.atom.Entry;
++import com.sun.syndication.feed.atom.Feed;
++import com.sun.syndication.feed.atom.Link;
++import com.sun.syndication.feed.atom.Person;
++import com.sun.syndication.feed.module.impl.ModuleUtils;
++import com.sun.syndication.feed.synd.Converter;
++import com.sun.syndication.feed.synd.SyndCategory;
++import com.sun.syndication.feed.synd.SyndCategoryImpl;
++import com.sun.syndication.feed.synd.SyndContent;
++import com.sun.syndication.feed.synd.SyndContentImpl;
++import com.sun.syndication.feed.synd.SyndEntry;
++import com.sun.syndication.feed.synd.SyndEntryImpl;
++import com.sun.syndication.feed.synd.SyndFeed;
++import com.sun.syndication.feed.synd.SyndLink;
++import com.sun.syndication.feed.synd.SyndLinkImpl;
++
++/**
++ */
++public class ConverterForAtom10 implements Converter {
++    private String _type;
++
++    public ConverterForAtom10() {
++        this("atom_1.0");
++    }
++
++    protected ConverterForAtom10(String type) {
++        _type = type;
++    }
++
++    public String getType() {
++        return _type;
++    }
++
++    public void copyInto(WireFeed feed,SyndFeed syndFeed) {
++        Feed aFeed = (Feed) feed;
++
++        syndFeed.setModules(ModuleUtils.cloneModules(aFeed.getModules()));
++
++        syndFeed.setEncoding(aFeed.getEncoding());
++
++        syndFeed.setUri(aFeed.getId());
++
++        syndFeed.setTitle(aFeed.getTitle());
++
++        String linkHref = null;
++        if (aFeed.getLinks().size() > 0) {
++            linkHref = ((Link) aFeed.getLinks().get(0)).getHref();
++        }
++        syndFeed.setLink(linkHref);
++
++        String aSubtitle = aFeed.getSubtitle();
++        if (aSubtitle!=null) {
++            syndFeed.setDescription(aSubtitle);
++        }
++
++        List aEntries = aFeed.getEntries();
++        if (aEntries!=null) {
++            syndFeed.setEntries(createSyndEntries(aFeed, aEntries));
++        }
++
++        // Core Atom language/author/copyright/modified elements have precedence
++        // over DC equivalent info.
++
++        Person author = aFeed.getAuthor();
++        if (author!=null && author.getName()!=null) {
++            syndFeed.setAuthor(author.getName());
++        }
++
++        String rights = aFeed.getRights();
++        if (rights!=null) {
++            syndFeed.setCopyright(rights);
++        }
++
++        Date date = aFeed.getUpdated();
++        if (date!=null) {
++            syndFeed.setPublishedDate(date);
++        }
++    }
++
++    protected List createSyndEntries(Feed feed, List atomEntries) {
++        List syndEntries = new ArrayList();
++        for (int i=0;i<atomEntries.size();i++) {
++            syndEntries.add(createSyndEntry(feed, (Entry) atomEntries.get(i)));
++        }
++        return syndEntries;
++    }
++
++    protected SyndEntry createSyndEntry(Feed feed, Entry entry) {
++        SyndEntry syndEntry = new SyndEntryImpl();
++        syndEntry.setModules(ModuleUtils.cloneModules(entry.getModules()));
++
++        syndEntry.setTitle(entry.getTitle());
++
++        String id = entry.getId();
++        if (id!=null) {
++            syndEntry.setUri(entry.getId());
++        }
++        else {
++            syndEntry.setUri(syndEntry.getLink());
++        }
++
++        Content content = entry.getContent();
++        if (content!=null) {
++            SyndContent sContent = new SyndContentImpl();
++            sContent.setType(content.getType());
++            sContent.setValue(content.getValue());
++            syndEntry.setDescription(sContent);
++        }
++
++        Content summary = entry.getSummary();
++        if (summary!=null) {
++            SyndContent sSummary = new SyndContentImpl();
++            sSummary.setType(summary.getType());
++            sSummary.setValue(summary.getValue());
++            syndEntry.setSummary(sSummary);
++        }
++
++        Person author = entry.getAuthor();
++        if (author!=null && author.getName()!=null) {
++            syndEntry.setAuthor(author.getName());
++        }
++
++        Date date = entry.getPublished();
++        if (date!=null) {
++            syndEntry.setPublishedDate(date);
++        }
++
++        date = entry.getUpdated();
++        if (date!=null) {
++            syndEntry.setUpdatedDate(date);
++        }
++        
++        List categories = entry.getCategories();
++        if (categories!=null) {
++            List syndCategories = new ArrayList();
++            for (Iterator iter=categories.iterator(); iter.hasNext();) {
++                Category c = (Category)iter.next();
++                SyndCategory syndCategory = new SyndCategoryImpl();
++                syndCategory.setName(c.getTerm()); 
++                syndCategory.setTaxonomyUri(c.getScheme());
++                // TODO: categories MAY have labels 
++                //       syndCategory.setLabel(c.getLabel());
++                syndCategories.add(syndCategory);
++            }
++            syndEntry.setCategories(syndCategories);
++        }
++        
++        List links = entry.getLinks();
++        if (links != null) {
++            List syndLinks = new ArrayList();
++            for (Iterator iter=links.iterator(); iter.hasNext();) {
++                Link link = (Link)iter.next();
++                SyndLink syndLink = new SyndLinkImpl(); 
++                syndLink.setRel(link.getRel());
++                syndLink.setType(link.getType());
++                syndLink.setHref(resolveLink(feed, entry, link.getHref()));
++                syndLink.setHreflang(link.getHreflang());
++                syndLink.setLength(link.getLength());
++                syndLinks.add(syndLink);                
++                // use first alt link found as entry link
++                if (syndEntry.getLink() == null && 
++                      (link.getRel() == null || link.getRel().equals("alternate"))) {
++                   syndEntry.setLink(resolveLink(feed, entry, link.getHref()));
++                }
++            }
++            syndEntry.setLinks(syndLinks);
++        }
++
++        return syndEntry;
++    }
++    
++    /** Use xml:base attributes at feed and entry level to resolve relative links */
++    private String resolveLink(Feed feed, Entry entry, String link) {
++        if (link.startsWith("http://") || link.startsWith("https://")) return link;       
++        StringBuffer sb = new StringBuffer();
++        if (feed != null && feed.getXmlBase() != null) {
++            sb.append(feed.getXmlBase());
++            if (!feed.getXmlBase().endsWith("/")) sb.append("/");
++        }
++        if (entry != null && entry.getXmlBase() != null) {
++            sb.append(entry.getXmlBase());
++            if (!entry.getXmlBase().endsWith("/")) sb.append("/");
++        }
++        sb.append(link);
++        return sb.toString();
++    }
++
++    public WireFeed createRealFeed(SyndFeed syndFeed) {
++        Feed aFeed = new Feed(getType());
++        aFeed.setModules(ModuleUtils.cloneModules(syndFeed.getModules()));
++
++        aFeed.setEncoding(syndFeed.getEncoding());
++
++        aFeed.setId(syndFeed.getUri());
++
++        aFeed.setTitle(syndFeed.getTitle());
++
++        List aLinks = new ArrayList();
++        String sLink = syndFeed.getLink();
++        if (sLink != null) {
++            Link link = new Link();
++            link.setRel("alternate");
++            link.setHref(sLink);
++            aLinks.add(link);
++        }
++        List slinks = syndFeed.getLinks();
++        if (slinks != null) {
++            for (Iterator iter=slinks.iterator(); iter.hasNext();) {       
++                SyndLink syndLink = (SyndLink)iter.next();
++                String rel = syndLink.getRel();
++                if (sLink != null && (rel==null || rel.equals("alternate"))) {
++                    continue; // don't add more than one alterate link
++                }
++                Link link = new Link();
++                link.setRel(syndLink.getRel());
++                link.setHref(syndLink.getHref());
++                link.setHreflang(syndLink.getHreflang());
++                link.setLength(syndLink.getLength());
++                aLinks.add(link);
++            }
++        }
++        if (aLinks.size() > 0) aFeed.setLinks(aLinks);
++        
++        List sCats = syndFeed.getCategories();
++        List aCats = new ArrayList();
++        if (sCats != null) {
++            for (Iterator iter=sCats.iterator(); iter.hasNext();) { 
++                SyndCategory sCat = (SyndCategory)iter.next();
++                Category aCat = new Category();
++                aCat.setTerm(sCat.getName());
++                // TODO: aCat.setLabel(sCat.getLabel());
++                aCat.setScheme(sCat.getTaxonomyUri());
++                aCats.add(aCat);
++            }
++        }
++        if (aCats.size() > 0) aFeed.setCategories(aCats);
++
++        String sDesc = syndFeed.getDescription();
++        if (sDesc!=null) {
++            aFeed.setSubtitle(sDesc);
++        }
++
++        String sAuthor = syndFeed.getAuthor();
++        if (sAuthor!=null) {
++            Person person = new Person();
++            person.setName(sAuthor);
++            aFeed.setAuthor(person);
++        }
++
++        aFeed.setRights(syndFeed.getCopyright());
++
++        aFeed.setUpdated(syndFeed.getPublishedDate());
++
++        List sEntries = syndFeed.getEntries();
++        if (sEntries!=null) {
++            aFeed.setEntries(createAtomEntries(sEntries));
++        }
++
++        return aFeed;
++    }
++
++
++    protected List createAtomEntries(List syndEntries) {
++        List atomEntries = new ArrayList();
++        for (int i=0;i<syndEntries.size();i++) {
++            atomEntries.add(createAtomEntry((SyndEntry)syndEntries.get(i)));
++        }
++        return atomEntries;
++    }
++
++    protected Entry createAtomEntry(SyndEntry sEntry) {
++        Entry aEntry = new Entry();
++        aEntry.setModules(ModuleUtils.cloneModules(sEntry.getModules()));
++
++        aEntry.setId(sEntry.getUri());
++
++        aEntry.setTitle(sEntry.getTitle());
++
++        List aLinks = new ArrayList();
++        String sLink = sEntry.getLink();
++        if (sLink != null) {
++            Link link = new Link();
++            link.setRel("alternate");
++            link.setHref(sLink);
++            aLinks.add(link);
++        }
++        List slinks = sEntry.getLinks();
++        if (slinks != null) {
++            for (Iterator iter=slinks.iterator(); iter.hasNext();) {       
++                SyndLink syndLink = (SyndLink)iter.next();
++                String rel = syndLink.getRel();
++                if (sLink != null && (rel==null || rel.equals("alternate"))) {
++                    continue; // don't add more than one alterate link
++                }
++                Link link = new Link();
++                link.setRel(syndLink.getRel());
++                link.setHref(syndLink.getHref());
++                link.setHreflang(syndLink.getHreflang());
++                link.setLength(syndLink.getLength());
++                aLinks.add(link);
++            }
++        }
++        if (aLinks.size() > 0) aEntry.setLinks(aLinks);
++        
++        List sCats = sEntry.getCategories();
++        List aCats = new ArrayList();
++        if (sCats != null) {
++            for (Iterator iter=sCats.iterator(); iter.hasNext();) { 
++                SyndCategory sCat = (SyndCategory)iter.next();
++                Category aCat = new Category();
++                aCat.setTerm(sCat.getName());
++                // TODO: aCat.setLabel(sCat.getLabel());
++                aCat.setScheme(sCat.getTaxonomyUri());
++                aCats.add(aCat);
++            }
++        }
++        if (aCats.size() > 0) aEntry.setCategories(aCats);
++        
++        SyndContent sDescription = sEntry.getDescription();
++        if (sDescription!=null) {
++            Content content = new Content();
++            content.setType(sDescription.getType());
++            content.setValue(sDescription.getValue());
++            aEntry.setContent(content);
++        }
++
++        SyndContent sSummary = sEntry.getSummary();
++        if (sSummary!=null) {
++            Content summary = new Content();
++            summary.setType(sSummary.getType());
++            summary.setValue(sSummary.getValue());
++            aEntry.setSummary(summary);
++        }
++
++        String sAuthor = sEntry.getAuthor();
++        if (sAuthor!=null) {
++            Person person = new Person();
++            person.setName(sAuthor);
++            aEntry.setAuthor(person);
++        }
++
++        aEntry.setPublished(sEntry.getPublishedDate());
++        aEntry.setUpdated(sEntry.getUpdatedDate()); 
++
++        return aEntry;
++    }
++
++}
+Index: src/java/com/sun/syndication/io/impl/Atom10Generator.java
+===================================================================
+RCS file: src/java/com/sun/syndication/io/impl/Atom10Generator.java
+diff -N src/java/com/sun/syndication/io/impl/Atom10Generator.java
+--- /dev/null	1 Jan 1970 00:00:00 -0000
++++ src/java/com/sun/syndication/io/impl/Atom10Generator.java	1 Jan 1970 00:00:00 -0000
+@@ -0,0 +1,378 @@
++/*
++ * Copyright 2004 Sun Microsystems, Inc.
++ *
++ * Licensed 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.
++ *
++ */
++package com.sun.syndication.io.impl;
++
++import java.io.StringReader;
++import java.util.Iterator;
++import java.util.List;
++
++import org.jdom.Attribute;
++import org.jdom.Document;
++import org.jdom.Element;
++import org.jdom.Namespace;
++import org.jdom.input.SAXBuilder;
++
++import com.sun.syndication.feed.WireFeed;
++import com.sun.syndication.feed.atom.Category;
++import com.sun.syndication.feed.atom.Content;
++import com.sun.syndication.feed.atom.Entry;
++import com.sun.syndication.feed.atom.Feed;
++import com.sun.syndication.feed.atom.Generator;
++import com.sun.syndication.feed.atom.Link;
++import com.sun.syndication.feed.atom.Person;
++import com.sun.syndication.io.FeedException;
++
++/**
++ * Feed Generator for Atom
++ * <p/>
++ *
++ * @author Elaine Chien
++ * @author Dave Johnson (updated for Atom 1.0)
++ *
++ */
++
++public class Atom10Generator extends BaseWireFeedGenerator {
++    private static final String ATOM_URI = "http://www.w3.org/2005/Atom";
++    private static final Namespace ATOM_NS = Namespace.getNamespace(ATOM_URI);
++
++    private String _version;
++
++    public Atom10Generator() {
++        this("atom_1.0","1.0");
++    }
++
++    protected Atom10Generator(String type,String version) {
++        super(type);
++        _version = version;
++    }
++
++    protected String getVersion() {
++        return _version;
++    }
++
++    protected Namespace getFeedNamespace() {
++        return ATOM_NS;
++    }
++
++    public Document generate(WireFeed wFeed) throws FeedException {
++        Feed feed = (Feed) wFeed;
++        Element root = createRootElement(feed);
++        populateFeed(feed,root);
++        return createDocument(root);
++    }
++
++    protected Document createDocument(Element root) {
++        return new Document(root);
++    }
++
++    protected Element createRootElement(Feed feed) {
++        Element root = new Element("feed",getFeedNamespace());
++        root.addNamespaceDeclaration(getFeedNamespace());
++        Attribute version = new Attribute("version", getVersion());
++        root.setAttribute(version);
++        if (feed.getXmlBase() != null) {
++            root.setAttribute("base", feed.getXmlBase(), Namespace.XML_NAMESPACE);
++        }
++        generateModuleNamespaceDefs(root);
++        return root;
++    }
++
++    protected void populateFeed(Feed feed,Element parent) throws FeedException  {
++        addFeed(feed,parent);
++        addEntries(feed,parent);
++    }
++
++    protected void addFeed(Feed feed,Element parent) throws FeedException {
++        Element eFeed = parent;
++        populateFeedHeader(feed,eFeed);
++        checkFeedHeaderConstraints(eFeed);
++        generateFeedModules(feed.getModules(),eFeed);
++    }
++
++    protected void addEntries(Feed feed,Element parent) throws FeedException {
++        List items = feed.getEntries();
++        for (int i=0;i<items.size();i++) {
++            addEntry((Entry)items.get(i),parent);
++        }
++        checkEntriesConstraints(parent);
++    }
++
++    protected void addEntry(Entry entry,Element parent) throws FeedException {
++        Element eEntry = new Element("entry", getFeedNamespace());
++        if (entry.getXmlBase() != null) {
++            eEntry.setAttribute("base", entry.getXmlBase(), Namespace.XML_NAMESPACE);
++        }
++        populateEntry(entry,eEntry);
++        checkEntryConstraints(eEntry);
++        generateItemModules(entry.getModules(),eEntry);
++        parent.addContent(eEntry);
++    }
++
++    protected void populateFeedHeader(Feed feed,Element eFeed) throws FeedException {
++        if (feed.getTitle() != null) {
++            eFeed.addContent(generateSimpleElement("title", feed.getTitle()));
++        }
++
++        List links = feed.getLinks();
++        if (links != null) for (int i = 0; i < links.size(); i++) {
++            eFeed.addContent(generateLinkElement((Link)links.get(i)));
++        }
++
++        List cats = feed.getCategories();
++        if (cats != null) for (Iterator iter=cats.iterator(); iter.hasNext();) {
++            eFeed.addContent(generateCategoryElement((Category)iter.next()));
++        }
++        
++        if (feed.getAuthor() != null) {
++            Element authorElement = new Element("author", getFeedNamespace());
++            fillPersonElement(authorElement, feed.getAuthor());
++            eFeed.addContent(authorElement);
++        }
++
++        List contributors = feed.getContributors();
++        for (int i = 0; i < contributors.size(); i++) {
++            Element contributorElement = new Element("contributor", getFeedNamespace());
++            fillPersonElement(contributorElement, (Person)contributors.get(i));
++            eFeed.addContent(contributorElement);
++        }
++
++        if (feed.getSubtitle() != null) {
++            eFeed.addContent(generateSimpleElement("subtitle", feed.getSubtitle()));
++        }
++
++        if (feed.getId() != null) {
++            eFeed.addContent(generateSimpleElement("id", feed.getId()));
++        }
++
++        if (feed.getGenerator() != null) {
++            eFeed.addContent(generateGeneratorElement(feed.getGenerator()));
++        }
++
++        if (feed.getRights() != null) {
++            eFeed.addContent(generateSimpleElement("rights", feed.getRights()));
++        }
++
++        if (feed.getUpdated() != null) {
++            Element updatedElement = new Element("updated", getFeedNamespace());
++            updatedElement.addContent(DateParser.formatW3CDateTime(feed.getUpdated()));
++            eFeed.addContent(updatedElement);
++        }
++    }
++
++    protected void populateEntry(Entry entry, Element eEntry) throws FeedException {
++        if (entry.getTitle() != null) {
++            eEntry.addContent(generateSimpleElement("title", entry.getTitle()));
++        }
++        List links = entry.getLinks();
++        if (links != null) for (int i = 0; i < links.size(); i++) {
++            eEntry.addContent(generateLinkElement((Link)links.get(i)));
++        }
++
++        List cats = entry.getCategories();
++        if (cats != null) for (Iterator iter=cats.iterator(); iter.hasNext();) {
++            eEntry.addContent(generateCategoryElement((Category)iter.next()));
++        }
++        
++        if (entry.getAuthor() != null) {
++            Element authorElement = new Element("author", getFeedNamespace());
++            fillPersonElement(authorElement, entry.getAuthor());
++            eEntry.addContent(authorElement);
++        }
++
++        List contributors = entry.getContributors();
++        for (int i = 0; i < contributors.size(); i++) {
++            Element contributorElement = new Element("contributor", getFeedNamespace());
++            fillPersonElement(contributorElement, (Person)contributors.get(i));
++            eEntry.addContent(contributorElement);
++        }
++        if (entry.getId() != null) {
++            eEntry.addContent(generateSimpleElement("id", entry.getId()));
++        }
++
++        if (entry.getUpdated() != null) {
++            Element updatedElement = new Element("updated", getFeedNamespace());
++            updatedElement.addContent(DateParser.formatW3CDateTime(entry.getUpdated()));
++            eEntry.addContent(updatedElement);
++        }
++
++        if (entry.getPublished() != null) {
++            Element publishedElement = new Element("published", getFeedNamespace());
++            publishedElement.addContent(DateParser.formatW3CDateTime(entry.getPublished()));
++            eEntry.addContent(publishedElement);
++        }
++
++        if (entry.getContent() != null) {
++            Element contentElement = new Element("content", getFeedNamespace());
++            fillContentElement(contentElement, entry.getContent());
++            eEntry.addContent(contentElement);
++        }
++
++        if (entry.getSummary() != null) {
++            Element summaryElement = new Element("summary", getFeedNamespace());
++            fillContentElement(summaryElement, entry.getSummary());
++            eEntry.addContent(summaryElement);
++        }
++    }
++
++    protected void checkFeedHeaderConstraints(Element eFeed) throws FeedException {
++    }
++
++    protected void checkEntriesConstraints(Element parent) throws FeedException {
++    }
++
++    protected void checkEntryConstraints(Element eEntry) throws FeedException {
++    }
++
++
++    protected Element generateCategoryElement(Category cat) {
++        Element catElement = new Element("category", getFeedNamespace());
++
++        if (cat.getTerm() != null) {
++            Attribute termAttribute = new Attribute("term", cat.getTerm());
++            catElement.setAttribute(termAttribute);
++        }
++
++        if (cat.getLabel() != null) {
++            Attribute labelAttribute = new Attribute("label", cat.getLabel());
++            catElement.setAttribute(labelAttribute);
++        }
++
++        if (cat.getScheme() != null) {
++            Attribute schemeAttribute = new Attribute("scheme", cat.getScheme());
++            catElement.setAttribute(schemeAttribute);
++        }
++        return catElement;
++    }
++
++    protected Element generateLinkElement(Link link) {
++        Element linkElement = new Element("link", getFeedNamespace());
++
++        if (link.getRel() != null) {
++            Attribute relAttribute = new Attribute("rel", link.getRel().toString());
++            linkElement.setAttribute(relAttribute);
++        }
++
++        if (link.getType() != null) {
++            Attribute typeAttribute = new Attribute("type", link.getType());
++            linkElement.setAttribute(typeAttribute);
++        }
++
++        if (link.getHref() != null) {
++            Attribute hrefAttribute = new Attribute("href", link.getHref());
++            linkElement.setAttribute(hrefAttribute);
++        }
++        
++        if (link.getHreflang() != null) {
++            Attribute hreflangAttribute = new Attribute("hreflang", link.getHreflang());
++            linkElement.setAttribute(hreflangAttribute);
++        }
++        return linkElement;
++    }
++
++
++    protected void fillPersonElement(Element element, Person person) {
++        if (person.getName() != null) {
++            element.addContent(generateSimpleElement("name", person.getName()));
++        }
++        if (person.getUri() != null) {
++            element.addContent(generateSimpleElement("uri", person.getUri()));
++        }
++
++        if (person.getEmail() != null) {
++            element.addContent(generateSimpleElement("email", person.getEmail()));
++        }
++    }
++
++    protected Element generateTagLineElement(Content tagline) {
++        Element taglineElement = new Element("subtitle", getFeedNamespace());
++
++        if (tagline.getType() != null) {
++            Attribute typeAttribute = new Attribute("type", tagline.getType());
++            taglineElement.setAttribute(typeAttribute);
++        }
++
++        if (tagline.getValue() != null) {
++            taglineElement.addContent(tagline.getValue());
++        }
++        return taglineElement;
++    }
++
++    protected void fillContentElement(Element contentElement, Content content)
++        throws FeedException {
++
++        String type = content.getType();
++        if (type != null) {
++            Attribute modeAttribute = new Attribute("type", content.getType().toString());
++            contentElement.setAttribute(modeAttribute);
++        }
++
++        if (content.getValue() != null) {
++
++            if (type == null || type.equals(Content.TEXT)) {
++                contentElement.addContent(content.getValue());
++            } else if (type.equals(Content.HTML)) {
++                contentElement.addContent(content.getValue());
++            } else if (type.equals(Content.XHTML)) {
++
++                StringBuffer tmpDocString = new StringBuffer("<tmpdoc>");
++                tmpDocString.append(content.getValue());
++                tmpDocString.append("</tmpdoc>");
++                StringReader tmpDocReader = new StringReader(tmpDocString.toString());
++                Document tmpDoc;
++
++                try {
++                    SAXBuilder saxBuilder = new SAXBuilder();
++                    tmpDoc = saxBuilder.build(tmpDocReader);
++                }
++                catch (Exception ex) {
++                    throw new FeedException("Invalid XML",ex);
++                }
++
++                List children = tmpDoc.getRootElement().removeContent();
++                contentElement.addContent(children);
++            }
++        }
++    }
++
++    protected Element generateGeneratorElement(Generator generator) {
++        Element generatorElement = new Element("generator", getFeedNamespace());
++
++        if (generator.getUrl() != null) {
++            Attribute urlAttribute = new Attribute("url", generator.getUrl());
++            generatorElement.setAttribute(urlAttribute);
++        }
++
++        if (generator.getVersion() != null) {
++            Attribute versionAttribute = new Attribute("version", generator.getVersion());
++            generatorElement.setAttribute(versionAttribute);
++        }
++
++        if (generator.getValue() != null) {
++            generatorElement.addContent(generator.getValue());
++        }
++
++        return generatorElement;
++
++    }
++
++    protected Element generateSimpleElement(String name, String value) {
++        Element element = new Element(name, getFeedNamespace());
++        element.addContent(value);
++        return element;
++    }
++
++}
+Index: src/java/com/sun/syndication/io/impl/Atom10Parser.java
+===================================================================
+RCS file: src/java/com/sun/syndication/io/impl/Atom10Parser.java
+diff -N src/java/com/sun/syndication/io/impl/Atom10Parser.java
+--- /dev/null	1 Jan 1970 00:00:00 -0000
++++ src/java/com/sun/syndication/io/impl/Atom10Parser.java	1 Jan 1970 00:00:00 -0000
+@@ -0,0 +1,352 @@
++/*
++ * Copyright 2004 Sun Microsystems, Inc.
++ *
++ * Licensed 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.
++ *
++ */
++package com.sun.syndication.io.impl;
++
++import com.sun.syndication.feed.WireFeed;
++import com.sun.syndication.feed.atom.*;
++import com.sun.syndication.io.FeedException;
++import org.jdom.Document;
++import org.jdom.Element;
++import org.jdom.Namespace;
++import org.jdom.output.XMLOutputter;
++
++import java.util.*;
++
++/**
++ * @author Dave Johnson (updated for Atom 1.0)
++ */
++public class Atom10Parser extends BaseWireFeedParser {
++    private static final String ATOM_URI = "http://www.w3.org/2005/Atom";
++
++    public Atom10Parser() {
++        this("atom_1.0");
++    }
++
++    protected Atom10Parser(String type) {
++        super(type);
++    }
++
++    protected Namespace getAtomNamespace() {
++        return Namespace.getNamespace(ATOM_URI);
++    }
++
++    public boolean isMyType(Document document) {
++        Element rssRoot = document.getRootElement();
++        Namespace defaultNS = rssRoot.getNamespace();
++        return (defaultNS!=null) && defaultNS.equals(getAtomNamespace());
++    }
++
++    public WireFeed parse(Document document, boolean validate) throws IllegalArgumentException,FeedException {
++        if (validate) {
++            validateFeed(document);
++        }
++        Element rssRoot = document.getRootElement();
++        return parseFeed(rssRoot);
++    }
++
++    protected void validateFeed(Document document) throws FeedException {
++        // TBD
++        // here we have to validate the Feed against a schema or whatever
++        // not sure how to do it
++        // one posibility would be to produce an ouput and attempt to parse it again
++        // with validation turned on.
++        // otherwise will have to check the document elements by hand.
++    }
++
++    protected WireFeed parseFeed(Element eFeed) {
++
++        com.sun.syndication.feed.atom.Feed feed = new com.sun.syndication.feed.atom.Feed(getType());
++
++        String xmlBase = eFeed.getAttributeValue("base", Namespace.XML_NAMESPACE);
++        if (xmlBase != null) {
++            feed.setXmlBase(xmlBase);
++        }
++        
++        Element e = eFeed.getChild("title",getAtomNamespace());
++        if (e!=null) {
++            feed.setTitle(e.getText());
++        }
++
++        List eList = eFeed.getChildren("link",getAtomNamespace());
++        feed.setLinks(parseLinks(eList));
++
++        List cList = eFeed.getChildren("category",getAtomNamespace());
++        feed.setCategories(parseCategories(cList));
++
++        e = eFeed.getChild("author",getAtomNamespace());
++        if (e!=null) {
++            feed.setAuthor(parsePerson(e));
++        }
++
++        eList = eFeed.getChildren("contributor",getAtomNamespace());
++        if (eList.size()>0) {
++            feed.setContributors(parsePersons(eList));
++        }
++
++        e = eFeed.getChild("subtitle",getAtomNamespace());
++        if (e!=null) {
++            feed.setSubtitle(e.getText());
++        }
++
++        e = eFeed.getChild("id",getAtomNamespace());
++        if (e!=null) {
++            feed.setId(e.getText());
++        }
++
++        e = eFeed.getChild("generator",getAtomNamespace());
++        if (e!=null) {
++            Generator gen = new Generator();
++            gen.setValue(e.getText());
++            String att = e.getAttributeValue("url");//getAtomNamespace()); DONT KNOW WHY DOESN'T WORK
++            if (att!=null) {
++                gen.setUrl(att);
++            }
++            att = e.getAttributeValue("version");//getAtomNamespace()); DONT KNOW WHY DOESN'T WORK
++            if (att!=null) {
++                gen.setVersion(att);
++            }
++            feed.setGenerator(gen);
++        }
++
++        e = eFeed.getChild("rights",getAtomNamespace());
++        if (e!=null) {
++            feed.setRights(e.getText());
++        }
++
++        e = eFeed.getChild("icon",getAtomNamespace());
++        if (e!=null) {
++            feed.setIcon(e.getText());
++        }
++
++        e = eFeed.getChild("logo",getAtomNamespace());
++        if (e!=null) {
++            feed.setLogo(e.getText());
++        }
++
++        e = eFeed.getChild("updated",getAtomNamespace());
++        if (e!=null) {
++            feed.setUpdated(DateParser.parseDate(e.getText()));
++        }
++
++        eList = eFeed.getChildren("entry",getAtomNamespace());
++        if (eList.size()>0) {
++            feed.setEntries(parseEntries(eList));
++        }
++
++        feed.setModules(parseFeedModules(eFeed));
++
++        return feed;
++    }
++
++    private Link parseLink(Element eLink) {
++        Link link = new Link();
++        String att = eLink.getAttributeValue("rel");//getAtomNamespace()); DONT KNOW WHY DOESN'T WORK
++        if (att!=null) {
++            link.setRel(att);
++        }
++        att = eLink.getAttributeValue("type");//getAtomNamespace()); DONT KNOW WHY DOESN'T WORK
++        if (att!=null) {
++            link.setType(att);
++        }
++        att = eLink.getAttributeValue("href");//getAtomNamespace()); DONT KNOW WHY DOESN'T WORK
++        if (att!=null) {
++            link.setHref(att);
++        }
++        att = eLink.getAttributeValue("hreflang");//getAtomNamespace()); DONT KNOW WHY DOESN'T WORK
++        if (att!=null) {
++            link.setHreflang(att);
++        }
++        att = eLink.getAttributeValue("length");//getAtomNamespace()); DONT KNOW WHY DOESN'T WORK
++        if (att!=null) {
++            link.setLength(Long.parseLong(att));
++        }
++        return link;
++    }
++
++    // List(Elements) -> List(Link)
++    private List parseLinks(List eLinks) {
++        List links = new ArrayList();
++        for (int i=0;i<eLinks.size();i++) {
++            Element eLink = (Element) eLinks.get(i);
++            links.add(parseLink(eLink));
++        }
++        return (links.size()>0) ? links : null;
++    }
++
++    private Person parsePerson(Element ePerson) {
++        Person person = new Person();
++        Element e = ePerson.getChild("name",getAtomNamespace());
++        if (e!=null) {
++            person.setName(e.getText());
++        }
++        e = ePerson.getChild("uri",getAtomNamespace());
++        if (e!=null) {
++            person.setUri(e.getText());
++        }
++        e = ePerson.getChild("email",getAtomNamespace());
++        if (e!=null) {
++            person.setEmail(e.getText());
++        }
++        return person;
++    }
++
++    // List(Elements) -> List(Persons)
++    private List parsePersons(List ePersons) {
++        List persons = new ArrayList();
++        for (int i=0;i<ePersons.size();i++) {
++            persons.add(parsePerson((Element)ePersons.get(i)));
++        }
++        return (persons.size()>0) ? persons : null;
++    }
++
++    private Content parseContent(Element e) {
++        String value = null;
++        String type = e.getAttributeValue("type");//getAtomNamespace()); DONT KNOW WHY DOESN'T WORK
++        type = (type!=null) ? type : Content.TEXT;
++        if (type.equals(Content.TEXT)) {
++            // do nothing XML Parser took care of this
++            value = e.getText();
++        }
++        else if (type.equals(Content.HTML)) {
++            value = e.getText();
++        }
++        else if (type.equals(Content.XHTML)) {
++            XMLOutputter outputter = new XMLOutputter();
++            List eContent = e.getContent();
++            Iterator i = eContent.iterator();
++            while (i.hasNext()) {
++                org.jdom.Content c = (org.jdom.Content) i.next();
++                if (c instanceof Element) {
++                    Element eC = (Element) c;
++                    if (eC.getNamespace().equals(getAtomNamespace())) {
++                        ((Element)c).setNamespace(Namespace.NO_NAMESPACE);
++                    }
++                }
++            }
++            value = outputter.outputString(eContent);
++        }
++        
++        // TODO: handle Atom Content's src attribute
++
++        Content content = new Content();
++        content.setType(type);
++        content.setValue(value);
++        return content;
++    }
++
++    // List(Elements) -> List(Entries)
++    private List parseEntries(List eEntries) {
++        List entries = new ArrayList();
++        for (int i=0;i<eEntries.size();i++) {
++            entries.add(parseEntry((Element)eEntries.get(i)));
++        }
++        return (entries.size()>0) ? entries : null;
++    }
++
++    private Entry parseEntry(Element eEntry) {
++        Entry entry = new Entry();
++
++        String xmlBase = eEntry.getAttributeValue("base", Namespace.XML_NAMESPACE);
++        if (xmlBase != null) {
++            entry.setXmlBase(xmlBase);
++        }
++        
++        Element e = eEntry.getChild("title",getAtomNamespace());
++        if (e!=null) {
++            entry.setTitle(e.getText());
++        }
++
++        List eList = eEntry.getChildren("link",getAtomNamespace());
++        entry.setLinks(parseLinks(eList));
++
++        e = eEntry.getChild("author",getAtomNamespace());
++        if (e!=null) {
++            entry.setAuthor(parsePerson(e));
++        }
++
++        eList = eEntry.getChildren("contributor",getAtomNamespace());
++        if (eList.size()>0) {
++            entry.setContributors(parsePersons(eList));
++        }
++
++        e = eEntry.getChild("id",getAtomNamespace());
++        if (e!=null) {
++            entry.setId(e.getText());
++        }
++
++        e = eEntry.getChild("updated",getAtomNamespace());
++        if (e!=null) {
++            entry.setUpdated(DateParser.parseDate(e.getText()));
++        }
++
++        e = eEntry.getChild("published",getAtomNamespace());
++        if (e!=null) {
++            entry.setPublished(DateParser.parseDate(e.getText()));
++        }
++
++        e = eEntry.getChild("summary",getAtomNamespace());
++        if (e!=null) {
++            entry.setSummary(parseContent(e));
++        }
++
++        e = eEntry.getChild("content",getAtomNamespace());
++        if (e!=null) {
++            entry.setContent(parseContent(e));
++        }
++
++        e = eEntry.getChild("rights",getAtomNamespace());
++        if (e!=null) {
++            entry.setRights(e.getText());
++        }
++
++        List cList = eEntry.getChildren("category",getAtomNamespace());
++        entry.setCategories(parseCategories(cList));
++
++        // TODO: SHOULD handle Atom entry source element
++        
++        entry.setModules(parseItemModules(eEntry));
++
++        return entry;
++    }
++
++    private List parseCategories(List eCategories) {
++        List cats = new ArrayList();
++        for (int i=0;i<eCategories.size();i++) {
++            Element eCategory = (Element) eCategories.get(i);
++            cats.add(parseCategory(eCategory));
++        }
++        return (cats.size()>0) ? cats : null;
++    }
++    
++    private Category parseCategory(Element eCategory) {
++        Category category = new Category();
++        String att = eCategory.getAttributeValue("term");//getAtomNamespace()); DONT KNOW WHY DOESN'T WORK
++        if (att!=null) {
++            category.setTerm(att);
++        }
++        att = eCategory.getAttributeValue("scheme");//getAtomNamespace()); DONT KNOW WHY DOESN'T WORK
++        if (att!=null) {
++            category.setScheme(att);
++        }
++        att = eCategory.getAttributeValue("label");//getAtomNamespace()); DONT KNOW WHY DOESN'T WORK
++        if (att!=null) {
++            category.setLabel(att);
++        }
++        return category;
++
++    }
++}
+Index: src/test/com/sun/syndication/unittest/TestOpsAtom10.java
+===================================================================
+RCS file: src/test/com/sun/syndication/unittest/TestOpsAtom10.java
+diff -N src/test/com/sun/syndication/unittest/TestOpsAtom10.java
+--- /dev/null	1 Jan 1970 00:00:00 -0000
++++ src/test/com/sun/syndication/unittest/TestOpsAtom10.java	1 Jan 1970 00:00:00 -0000
+@@ -0,0 +1,15 @@
++package com.sun.syndication.unittest;
++
++/**
++ *
++ * <p>
++ * @author Dave Johnson
++ *
++ */
++public class TestOpsAtom10 extends FeedOpsTest {
++
++    public TestOpsAtom10() {
++        super("atom_0.3");
++    }
++
++}
+Index: src/test/com/sun/syndication/unittest/TestSyndFeedAtom10.java
+===================================================================
+RCS file: src/test/com/sun/syndication/unittest/TestSyndFeedAtom10.java
+diff -N src/test/com/sun/syndication/unittest/TestSyndFeedAtom10.java
+--- /dev/null	1 Jan 1970 00:00:00 -0000
++++ src/test/com/sun/syndication/unittest/TestSyndFeedAtom10.java	1 Jan 1970 00:00:00 -0000
+@@ -0,0 +1,77 @@
++/*
++ * Created on Jun 24, 2004
++ *
++ */
++package com.sun.syndication.unittest;
++
++import com.sun.syndication.feed.synd.SyndEntry;
++import com.sun.syndication.feed.synd.SyndContent;
++import com.sun.syndication.io.impl.DateParser;
++
++import java.util.List;
++import java.util.Date;
++
++/**
++ * @author pat
++ * @author Dave Johnson (modified for Atom 1.0)
++ *
++ */
++public class TestSyndFeedAtom10 extends SyndFeedTest {
++
++	public TestSyndFeedAtom10() {
++		super("atom_1.0");
++	}
++
++    protected TestSyndFeedAtom10(String type) {
++        super(type);
++    }
++
++    protected TestSyndFeedAtom10(String feedType,String feedFileName) {
++        super(feedType,feedFileName);
++    }
++
++    public void testTitle() throws Exception {
++        assertProperty(getCachedSyndFeed().getTitle(),"feed.title");
++    }
++
++    public void testLink() throws Exception {
++        assertProperty( getCachedSyndFeed().getLink(),"feed.link^href");
++    }
++
++    public void getAuthor() throws Exception {
++        assertProperty(getCachedSyndFeed().getAuthor(),"feed.author.name");
++    }
++
++    public void testCopyright() throws Exception {
++        assertProperty(getCachedSyndFeed().getCopyright(),"feed.rights");
++    }
++
++    public void testPublishedDate() throws Exception {
++        Date d = DateParser.parseW3CDateTime("2000-01-01T00:00:00Z");
++        assertEquals(getCachedSyndFeed().getPublishedDate(),d);
++    }
++
++
++    protected void _testEntry(int i) throws Exception {
++        List items = getCachedSyndFeed().getEntries();
++        SyndEntry entry = (SyndEntry) items.get(i);
++        assertProperty(entry.getTitle(),"feed.entry["+i+"].title");
++        assertProperty(entry.getLink(),"feed.entry["+i+"].link^href");
++        assertProperty(entry.getAuthor(),"feed.entry["+i+"].author.name");
++        Date d = DateParser.parseW3CDateTime("2000-0"+(i+1)+"-01T00:00:00Z");
++        assertEquals(entry.getPublishedDate(),d);
++        assertProperty(entry.getDescription().getValue(),"feed.entry["+i+"].summary");
++        assertProperty(((SyndContent)entry.getContents().get(0)).getValue(),"feed.entry["+i+"].content[0]");
++        assertProperty(((SyndContent)entry.getContents().get(1)).getValue(),"feed.entry["+i+"].content[1]");
++    }
++
++    public void testEntry0() throws Exception {
++        _testEntry(0);
++    }
++
++    public void testEntry1() throws Exception {
++        _testEntry(1);
++    }
++
++
++}

Added: incubator/roller/branches/roller_2.0/sandbox/atomprotocol/lib/rome-fetcher-0.8.jar
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_2.0/sandbox/atomprotocol/lib/rome-fetcher-0.8.jar?rev=289954&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/roller/branches/roller_2.0/sandbox/atomprotocol/lib/rome-fetcher-0.8.jar
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/roller/branches/roller_2.0/sandbox/atomprotocol/src/org/roller/presentation/atomapi/AtomCollection.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_2.0/sandbox/atomprotocol/src/org/roller/presentation/atomapi/AtomCollection.java?rev=289954&view=auto
==============================================================================
--- incubator/roller/branches/roller_2.0/sandbox/atomprotocol/src/org/roller/presentation/atomapi/AtomCollection.java (added)
+++ incubator/roller/branches/roller_2.0/sandbox/atomprotocol/src/org/roller/presentation/atomapi/AtomCollection.java Sun Sep 18 12:11:04 2005
@@ -0,0 +1,263 @@
+/*
+ * Copyright 2005 David M Johnson (For RSS and Atom In Action)
+ *
+ * Licensed 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.
+ */
+package org.roller.presentation.atomapi;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.Namespace;
+
+/**
+ * Models an Atom collection.
+ * 
+ * @author Dave Johnson
+ */
+/*
+ * Based on: draft-ietf-atompub-protocol-04.txt 
+ * 
+ * appCollection = element
+ *    app:collection { 
+ *       attribute next { text } ?, 
+ *       appMember* 
+ *    }
+ * 
+ * Here is an example Atom collection:
+ * 
+ * <?xml version="1.0" encoding='utf-8'?> 
+ * <collection xmlns="http://purl.org/atom/app#"> 
+ * <member href="http://example.org/1"
+ *    hrefreadonly="http://example.com/1/bar" 
+ *    title="Sample 1"
+ *    updated="2003-12-13T18:30:02Z" /> 
+ * <member href="http://example.org/2"
+ *    hrefreadonly="http://example.com/2/bar" 
+ *    title="Sample 2"
+ *    updated="2003-12-13T18:30:02Z" /> 
+ * <member href="http://example.org/3"
+ *    hrefreadonly="http://example.com/3/bar" 
+ *    title="Sample 3"
+ *    updated="2003-12-13T18:30:02Z" /> 
+ * <member href="http://example.org/4"
+ *    title="Sample 4" 
+ *    updated="2003-12-13T18:30:02Z" /> 
+ * </collection>
+ */
+public class AtomCollection
+{
+    public static final Namespace ns = 
+        Namespace.getNamespace("http://purl.org/atom/app#");
+    
+    private static SimpleDateFormat df =
+        new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ssZ" );
+    private String next    = null;
+    private List   members = new ArrayList();
+
+    public AtomCollection()
+    {
+    }
+
+    /** URI of collection containing member elements updated earlier in time */
+    public String getNext()
+    {
+        return next;
+    }
+
+    public void setNext(String next)
+    {
+        this.next = next;
+    }
+
+    public List getMembers()
+    {
+        return members;
+    }
+
+    public void setMembers(List members)
+    {
+        this.members = members;
+    }
+
+    public void addMember(Member member)
+    {
+        members.add(member);
+    }
+
+    /** Models an Atom collection member */
+    /*
+     * appMember = element app:member { attribute title { text }, attribute href {
+     * text }, attribute hrefreadonly { text } ?, attribute updated { text } }
+     */
+    public static class Member
+    {
+        private String title;
+        private String href;
+        private String hrefreadonly;
+        private Date   updated;
+
+        public Member()
+        {
+        }
+
+        /** Human readable title */
+        public String getTitle()
+        {
+            return title;
+        }
+
+        public void setTitle(String title)
+        {
+            this.title = title;
+        }
+
+        /** The URI used to edit the member source */
+        public String getHref()
+        {
+            return href;
+        }
+
+        public void setHref(String href)
+        {
+            this.href = href;
+        }
+
+        /** The URI for readonly access to member source */
+        public String getHrefreadonly()
+        {
+            return hrefreadonly;
+        }
+
+        public void setHrefreadonly(String hrefreadonly)
+        {
+            this.hrefreadonly = hrefreadonly;
+        }
+
+        /** Same as updated value of collection member */
+        public Date getUpdated()
+        {
+            return updated;
+        }
+
+        public void setUpdated(Date updated)
+        {
+            this.updated = updated;
+        }
+    }
+
+    /** Deserialize an Atom Collection XML document into an object */
+    public static AtomCollection documentToCollection(Document document)
+            throws Exception
+    {
+        AtomCollection collection = new AtomCollection();
+        Element root = document.getRootElement();
+        if (root.getAttribute("next") != null)
+        {
+            collection.setNext(root.getAttribute("next").getValue());
+        }
+        List mems = root.getChildren("member", ns);
+        Iterator iter = mems.iterator();
+        while (iter.hasNext())
+        {
+            Element e = (Element) iter.next();
+            collection.addMember(AtomCollection.elementToMember(e));
+        }
+        return collection;
+    }
+
+    /** Serialize an AtomCollection object into an XML document */
+    public static Document collectionToDocument(AtomCollection collection)
+    {
+        Document doc = new Document();
+        Element root = new Element("collection", ns);
+        doc.setRootElement(root);
+        if (collection.getNext() != null)
+        {
+            root.setAttribute("next", collection.getNext());
+        }
+        Iterator iter = collection.getMembers().iterator();
+        while (iter.hasNext())
+        {
+            Member member = (Member) iter.next();
+            root.addContent(AtomCollection.memberToElement(member));
+        }
+        return doc;
+    }
+
+    /** Deserialize an Atom collection member XML element into an object */
+    public static Member elementToMember(Element element) throws Exception
+    {
+        Member member = new Member();
+        member.setTitle(element.getAttribute("title").getValue());
+        member.setHref(element.getAttribute("href").getValue());
+        if (element.getAttribute("href") != null)
+        {
+            member.setHref(element.getAttribute("href").getValue());
+        }
+        member.setUpdated(df.parse(element.getAttribute("updated").getValue()));
+        return member;
+    }
+
+    /** Serialize a collection member into an XML element */
+    public static Element memberToElement(Member member)
+    {
+        Element element = new Element("member", ns);
+        element.setAttribute("title", member.getTitle()); // TODO: escape/strip HTML?
+        element.setAttribute("href", member.getHref());
+        if (member.getHrefreadonly() != null)
+        {
+            element.setAttribute("hrefreadonly", member.getHrefreadonly());
+        }
+        element.setAttribute("updated", df.format(member.getUpdated()));
+        return element;
+    }
+
+    /** Start and end date range */
+    public static class Range { Date start=null; Date end=null; }
+    
+    /** Parse HTTP Range header into a start and end date range */
+    public static Range parseRange(String rangeString) throws ParseException 
+    {
+        // Range: updated=<isodate>/<isodate>   
+        // Range: updated=<isodate>/ 
+        // Range: updated=/<isodate>  
+
+        Range range = new Range();
+        String[] split = rangeString.split("=");
+        if (split[1].startsWith("/")) 
+        {
+            // we have only end date
+            range.end = df.parse(split[1].split("/")[1]);
+        }
+        else if (split[1].endsWith("/"))
+        {
+            // we have only start date
+            range.start = df.parse(split[1].split("/")[0]);
+        }
+        else
+        {
+            // both dates present
+            String[] dates = split[1].split("/");
+            range.start = df.parse(dates[0]);
+            range.end = df.parse(dates[1]);
+        }
+        return range;
+    }
+}