diff --git a/google-taglib/.cvsignore b/.gitignore
similarity index 100%
rename from google-taglib/.cvsignore
rename to .gitignore
diff --git a/google-taglib/CHANGES.txt b/CHANGES.txt
similarity index 100%
rename from google-taglib/CHANGES.txt
rename to CHANGES.txt
diff --git a/google-taglib/GoogleTagLib.iml b/GoogleTagLib.iml
similarity index 100%
rename from google-taglib/GoogleTagLib.iml
rename to GoogleTagLib.iml
diff --git a/google-taglib/GoogleTagLib.ipr b/GoogleTagLib.ipr
similarity index 100%
rename from google-taglib/GoogleTagLib.ipr
rename to GoogleTagLib.ipr
diff --git a/google-taglib/GoogleTagLib.iws b/GoogleTagLib.iws
similarity index 100%
rename from google-taglib/GoogleTagLib.iws
rename to GoogleTagLib.iws
diff --git a/google-taglib/README-BUILD.txt b/README-BUILD.txt
similarity index 100%
rename from google-taglib/README-BUILD.txt
rename to README-BUILD.txt
diff --git a/google-taglib/README.txt b/README.txt
similarity index 100%
rename from google-taglib/README.txt
rename to README.txt
diff --git a/google-taglib/build.properties b/build.properties
similarity index 100%
rename from google-taglib/build.properties
rename to build.properties
diff --git a/google-taglib/build.xml b/build.xml
similarity index 99%
rename from google-taglib/build.xml
rename to build.xml
index 1fad8de..dca0cc0 100644
--- a/google-taglib/build.xml
+++ b/build.xml
@@ -112,7 +112,7 @@
-
+
diff --git a/google-taglib/google-examples/README.txt b/google-examples/README.txt
similarity index 100%
rename from google-taglib/google-examples/README.txt
rename to google-examples/README.txt
diff --git a/google-taglib/google-examples/WEB-INF/web.xml b/google-examples/WEB-INF/web.xml
similarity index 100%
rename from google-taglib/google-examples/WEB-INF/web.xml
rename to google-examples/WEB-INF/web.xml
diff --git a/google-taglib/google-examples/advanced.html b/google-examples/advanced.html
similarity index 100%
rename from google-taglib/google-examples/advanced.html
rename to google-examples/advanced.html
diff --git a/google-taglib/google-examples/advanced.jsp b/google-examples/advanced.jsp
similarity index 100%
rename from google-taglib/google-examples/advanced.jsp
rename to google-examples/advanced.jsp
diff --git a/google-taglib/google-examples/cache.html b/google-examples/cache.html
similarity index 100%
rename from google-taglib/google-examples/cache.html
rename to google-examples/cache.html
diff --git a/google-taglib/google-examples/cache.jsp b/google-examples/cache.jsp
similarity index 100%
rename from google-taglib/google-examples/cache.jsp
rename to google-examples/cache.jsp
diff --git a/google-taglib/google-examples/index.html b/google-examples/index.html
similarity index 100%
rename from google-taglib/google-examples/index.html
rename to google-examples/index.html
diff --git a/google-taglib/google-examples/key.html b/google-examples/key.html
similarity index 100%
rename from google-taglib/google-examples/key.html
rename to google-examples/key.html
diff --git a/google-taglib/google-examples/key.jsp b/google-examples/key.jsp
similarity index 100%
rename from google-taglib/google-examples/key.jsp
rename to google-examples/key.jsp
diff --git a/google-taglib/google-examples/search.html b/google-examples/search.html
similarity index 100%
rename from google-taglib/google-examples/search.html
rename to google-examples/search.html
diff --git a/google-taglib/google-examples/search.jsp b/google-examples/search.jsp
similarity index 100%
rename from google-taglib/google-examples/search.jsp
rename to google-examples/search.jsp
diff --git a/google-taglib/google-examples/spelling.html b/google-examples/spelling.html
similarity index 100%
rename from google-taglib/google-examples/spelling.html
rename to google-examples/spelling.html
diff --git a/google-taglib/google-examples/spelling.jsp b/google-examples/spelling.jsp
similarity index 100%
rename from google-taglib/google-examples/spelling.jsp
rename to google-examples/spelling.jsp
diff --git a/google-taglib/google-tagunit/WEB-INF/web.xml b/google-tagunit/WEB-INF/web.xml
similarity index 100%
rename from google-taglib/google-tagunit/WEB-INF/web.xml
rename to google-tagunit/WEB-INF/web.xml
diff --git a/google-taglib/google-tagunit/index.html b/google-tagunit/index.html
similarity index 100%
rename from google-taglib/google-tagunit/index.html
rename to google-tagunit/index.html
diff --git a/google-taglib/google-tagunit/index.jsp b/google-tagunit/index.jsp
similarity index 100%
rename from google-taglib/google-tagunit/index.jsp
rename to google-tagunit/index.jsp
diff --git a/google-taglib/google-tagunit/test/error.jsp b/google-tagunit/test/error.jsp
similarity index 100%
rename from google-taglib/google-tagunit/test/error.jsp
rename to google-tagunit/test/error.jsp
diff --git a/google-taglib/google-tagunit/test/google/cachedPage/testSpecification.jsp b/google-tagunit/test/google/cachedPage/testSpecification.jsp
similarity index 100%
rename from google-taglib/google-tagunit/test/google/cachedPage/testSpecification.jsp
rename to google-tagunit/test/google/cachedPage/testSpecification.jsp
diff --git a/google-taglib/google-tagunit/test/google/element/testSpecification.jsp b/google-tagunit/test/google/element/testSpecification.jsp
similarity index 100%
rename from google-taglib/google-tagunit/test/google/element/testSpecification.jsp
rename to google-tagunit/test/google/element/testSpecification.jsp
diff --git a/google-taglib/google-tagunit/test/google/endIndex/testSpecification.jsp b/google-tagunit/test/google/endIndex/testSpecification.jsp
similarity index 100%
rename from google-taglib/google-tagunit/test/google/endIndex/testSpecification.jsp
rename to google-tagunit/test/google/endIndex/testSpecification.jsp
diff --git a/google-taglib/google-tagunit/test/google/estimatedTotal/testSpecification.jsp b/google-tagunit/test/google/estimatedTotal/testSpecification.jsp
similarity index 100%
rename from google-taglib/google-tagunit/test/google/estimatedTotal/testSpecification.jsp
rename to google-tagunit/test/google/estimatedTotal/testSpecification.jsp
diff --git a/google-taglib/google-tagunit/test/google/index.jsp b/google-tagunit/test/google/index.jsp
similarity index 100%
rename from google-taglib/google-tagunit/test/google/index.jsp
rename to google-tagunit/test/google/index.jsp
diff --git a/google-taglib/google-tagunit/test/google/next/testSpecification.jsp b/google-tagunit/test/google/next/testSpecification.jsp
similarity index 100%
rename from google-taglib/google-tagunit/test/google/next/testSpecification.jsp
rename to google-tagunit/test/google/next/testSpecification.jsp
diff --git a/google-taglib/google-tagunit/test/google/previous/testSpecification.jsp b/google-tagunit/test/google/previous/testSpecification.jsp
similarity index 100%
rename from google-taglib/google-tagunit/test/google/previous/testSpecification.jsp
rename to google-tagunit/test/google/previous/testSpecification.jsp
diff --git a/google-taglib/google-tagunit/test/google/search/testSpecification.jsp b/google-tagunit/test/google/search/testSpecification.jsp
similarity index 100%
rename from google-taglib/google-tagunit/test/google/search/testSpecification.jsp
rename to google-tagunit/test/google/search/testSpecification.jsp
diff --git a/google-taglib/google-tagunit/test/google/searchComments/testSpecification.jsp b/google-tagunit/test/google/searchComments/testSpecification.jsp
similarity index 100%
rename from google-taglib/google-tagunit/test/google/searchComments/testSpecification.jsp
rename to google-tagunit/test/google/searchComments/testSpecification.jsp
diff --git a/google-taglib/google-tagunit/test/google/searchQuery/testSpecification.jsp b/google-tagunit/test/google/searchQuery/testSpecification.jsp
similarity index 100%
rename from google-taglib/google-tagunit/test/google/searchQuery/testSpecification.jsp
rename to google-tagunit/test/google/searchQuery/testSpecification.jsp
diff --git a/google-taglib/google-tagunit/test/google/searchResult/testSpecification.jsp b/google-tagunit/test/google/searchResult/testSpecification.jsp
similarity index 100%
rename from google-taglib/google-tagunit/test/google/searchResult/testSpecification.jsp
rename to google-tagunit/test/google/searchResult/testSpecification.jsp
diff --git a/google-taglib/google-tagunit/test/google/searchTime/testSpecification.jsp b/google-tagunit/test/google/searchTime/testSpecification.jsp
similarity index 100%
rename from google-taglib/google-tagunit/test/google/searchTime/testSpecification.jsp
rename to google-tagunit/test/google/searchTime/testSpecification.jsp
diff --git a/google-taglib/google-tagunit/test/google/searchTips/testSpecification.jsp b/google-tagunit/test/google/searchTips/testSpecification.jsp
similarity index 100%
rename from google-taglib/google-tagunit/test/google/searchTips/testSpecification.jsp
rename to google-tagunit/test/google/searchTips/testSpecification.jsp
diff --git a/google-taglib/google-tagunit/test/google/spelling/testSpecification.jsp b/google-tagunit/test/google/spelling/testSpecification.jsp
similarity index 100%
rename from google-taglib/google-tagunit/test/google/spelling/testSpecification.jsp
rename to google-tagunit/test/google/spelling/testSpecification.jsp
diff --git a/google-taglib/google-tagunit/test/google/startIndex/testSpecification.jsp b/google-tagunit/test/google/startIndex/testSpecification.jsp
similarity index 100%
rename from google-taglib/google-tagunit/test/google/startIndex/testSpecification.jsp
rename to google-tagunit/test/google/startIndex/testSpecification.jsp
diff --git a/google-taglib/google-tagunit/test/images/spacer.gif b/google-tagunit/test/images/spacer.gif
similarity index 100%
rename from google-taglib/google-tagunit/test/images/spacer.gif
rename to google-tagunit/test/images/spacer.gif
diff --git a/google-taglib/google-tagunit/test/images/tagunit.gif b/google-tagunit/test/images/tagunit.gif
similarity index 100%
rename from google-taglib/google-tagunit/test/images/tagunit.gif
rename to google-tagunit/test/images/tagunit.gif
diff --git a/google-taglib/google-tagunit/test/images/white-separator.gif b/google-tagunit/test/images/white-separator.gif
similarity index 100%
rename from google-taglib/google-tagunit/test/images/white-separator.gif
rename to google-tagunit/test/images/white-separator.gif
diff --git a/google-taglib/google-tagunit/test/index.jsp b/google-tagunit/test/index.jsp
similarity index 100%
rename from google-taglib/google-tagunit/test/index.jsp
rename to google-tagunit/test/index.jsp
diff --git a/google-taglib/google-tagunit/test/license.html b/google-tagunit/test/license.html
similarity index 100%
rename from google-taglib/google-tagunit/test/license.html
rename to google-tagunit/test/license.html
diff --git a/google-taglib/google-tagunit/test/page.css b/google-tagunit/test/page.css
similarity index 100%
rename from google-taglib/google-tagunit/test/page.css
rename to google-tagunit/test/page.css
diff --git a/google-taglib/google-tagunit/test/results.jsp b/google-tagunit/test/results.jsp
similarity index 100%
rename from google-taglib/google-tagunit/test/results.jsp
rename to google-tagunit/test/results.jsp
diff --git a/google-taglib/htdocs/about.html b/htdocs/about.html
similarity index 98%
rename from google-taglib/htdocs/about.html
rename to htdocs/about.html
index faaae68..2c81905 100644
--- a/google-taglib/htdocs/about.html
+++ b/htdocs/about.html
@@ -30,6 +30,7 @@ body,td,font,p,a{font-family:arial,sans-serif}
HowTo Javadoc TLD
+ UML About
diff --git a/google-taglib/htdocs/docs.html b/htdocs/docs.html
similarity index 99%
rename from google-taglib/htdocs/docs.html
rename to htdocs/docs.html
index 30b3cc4..0e57832 100644
--- a/google-taglib/htdocs/docs.html
+++ b/htdocs/docs.html
@@ -35,6 +35,7 @@ code {font-size:10pt}
HowTo Javadoc TLD
+ UMLAbout
diff --git a/google-taglib/htdocs/howto.html b/htdocs/howto.html
similarity index 99%
rename from google-taglib/htdocs/howto.html
rename to htdocs/howto.html
index d68ab72..3b37d62 100644
--- a/google-taglib/htdocs/howto.html
+++ b/htdocs/howto.html
@@ -34,6 +34,7 @@ body,td,font,.p,a{font-family:arial,sans-serif}
HowTo Javadoc TLD
+ UMLAbout
diff --git a/google-taglib/htdocs/images/arrow.gif b/htdocs/images/arrow.gif
similarity index 100%
rename from google-taglib/htdocs/images/arrow.gif
rename to htdocs/images/arrow.gif
diff --git a/google-taglib/htdocs/images/arrow.jpg b/htdocs/images/arrow.jpg
similarity index 100%
rename from google-taglib/htdocs/images/arrow.jpg
rename to htdocs/images/arrow.jpg
diff --git a/google-taglib/htdocs/images/cached.jpg b/htdocs/images/cached.jpg
similarity index 100%
rename from google-taglib/htdocs/images/cached.jpg
rename to htdocs/images/cached.jpg
diff --git a/google-taglib/htdocs/images/cachedresults.jpg b/htdocs/images/cachedresults.jpg
similarity index 100%
rename from google-taglib/htdocs/images/cachedresults.jpg
rename to htdocs/images/cachedresults.jpg
diff --git a/google-taglib/htdocs/images/duktumbl.gif b/htdocs/images/duktumbl.gif
similarity index 100%
rename from google-taglib/htdocs/images/duktumbl.gif
rename to htdocs/images/duktumbl.gif
diff --git a/google-taglib/htdocs/images/duktumbl.png b/htdocs/images/duktumbl.png
similarity index 100%
rename from google-taglib/htdocs/images/duktumbl.png
rename to htdocs/images/duktumbl.png
diff --git a/google-taglib/htdocs/images/google_sm.gif b/htdocs/images/google_sm.gif
similarity index 100%
rename from google-taglib/htdocs/images/google_sm.gif
rename to htdocs/images/google_sm.gif
diff --git a/google-taglib/htdocs/images/google_sm.png b/htdocs/images/google_sm.png
similarity index 100%
rename from google-taglib/htdocs/images/google_sm.png
rename to htdocs/images/google_sm.png
diff --git a/htdocs/images/jars25.gif b/htdocs/images/jars25.gif
new file mode 100644
index 0000000..04c1fe8
Binary files /dev/null and b/htdocs/images/jars25.gif differ
diff --git a/google-taglib/htdocs/images/search.jpg b/htdocs/images/search.jpg
similarity index 100%
rename from google-taglib/htdocs/images/search.jpg
rename to htdocs/images/search.jpg
diff --git a/google-taglib/htdocs/images/searchresults.jpg b/htdocs/images/searchresults.jpg
similarity index 100%
rename from google-taglib/htdocs/images/searchresults.jpg
rename to htdocs/images/searchresults.jpg
diff --git a/google-taglib/htdocs/images/spelling.jpg b/htdocs/images/spelling.jpg
similarity index 100%
rename from google-taglib/htdocs/images/spelling.jpg
rename to htdocs/images/spelling.jpg
diff --git a/htdocs/images/uml.jpg b/htdocs/images/uml.jpg
new file mode 100644
index 0000000..cb6b432
Binary files /dev/null and b/htdocs/images/uml.jpg differ
diff --git a/google-taglib/htdocs/images/yellowarrow.gif b/htdocs/images/yellowarrow.gif
similarity index 100%
rename from google-taglib/htdocs/images/yellowarrow.gif
rename to htdocs/images/yellowarrow.gif
diff --git a/google-taglib/htdocs/includes/google.css b/htdocs/includes/google.css
similarity index 100%
rename from google-taglib/htdocs/includes/google.css
rename to htdocs/includes/google.css
diff --git a/google-taglib/htdocs/index.html b/htdocs/index.html
similarity index 96%
rename from google-taglib/htdocs/index.html
rename to htdocs/index.html
index 46fb03e..80ce6d9 100644
--- a/google-taglib/htdocs/index.html
+++ b/htdocs/index.html
@@ -30,6 +30,7 @@ body,td,font,p,a{font-family:arial,sans-serif}
HowTo Javadoc TLD
+ UMLAbout
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/rss/LICENSE.txt b/rss/LICENSE.txt
new file mode 100644
index 0000000..001be53
--- /dev/null
+++ b/rss/LICENSE.txt
@@ -0,0 +1,30 @@
+Google RSS Tag Library License
+
+Copyright (c) 2003-2004, clevercactus ltd.
+Copyright (c) 2003-2004, Erik C. Thauvin (erik@thauvin.net)
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this list
+of conditions and the following disclaimer.
+
+Redistributions in binary form must reproduce the above copyright notice, this
+list of conditions and the following disclaimer in the documentation and/or
+other materials provided with the distribution.
+
+Neither the name of the author nor the names of its contributors may be used to
+endorse or promote products derived from this software without specific prior
+written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/rss/README-BUILD.txt b/rss/README-BUILD.txt
new file mode 100644
index 0000000..e8cafe9
--- /dev/null
+++ b/rss/README-BUILD.txt
@@ -0,0 +1,67 @@
+Google RSS Tag Library README (BUILD)
+=====================================
+
+
+Overview
+========
+
+This README file describes the Google RSS Tag Library source distribution.
+
+The Google RSS Tag Library is an extension to, and thus requires, the
+Google Tag Library, which can be found at:
+
+
+
+
+See the "LICENSE.txt" file for licensing details.
+
+The Google RSS Tag Library uses the Google Web APIs, but is not associated
+with or sponsored by Google, Inc.
+
+Google Web APIs
+===============
+
+The Google Web APIs Java library is required in order to build the Google
+RSS Tag Library. The library's JAR file (googleapi.jar) should be placed
+into the lib directory.
+
+ http://www.google.com/apis/download.html
+
+
+Building the Source
+===================
+
+The Google RSS Tag Library is intended to be build directly within the
+Google Tag Library source tree:
+
+ /google-taglib/rss/
+
+
+The Google RSS Tag Library is built using Ant.
+
+ http://ant.apache.org/
+
+
+To build the JAR, to do the following:
+
+ ant
+
+To build the TLD, do the following:
+
+ ant tld
+
+To build the release archive, do the following:
+
+ ant release
+
+To build the Examples WAR, do the following:
+
+ ant examples
+
+To list all available build targets, do the following:
+
+ ant -projecthelp
+
+
+===========================================================================
+$Id$
\ No newline at end of file
diff --git a/rss/README.txt b/rss/README.txt
new file mode 100644
index 0000000..b90b5ad
--- /dev/null
+++ b/rss/README.txt
@@ -0,0 +1,71 @@
+Google RSS Tag Library README
+=============================
+
+
+Overview
+========
+
+This README file describes the Google RSS Tag Library distribution.
+
+The Google RSS Tag Library is an extension to, and thus requires, the
+Google Tag Library, which can be found at:
+
+
+
+
+See the "LICENSE.txt" file for licensing details.
+
+The Google RSS Tag Library uses the Google Web APIs, but is not associated
+with or sponsored by Google, Inc.
+
+
+Installation
+============
+
+The Google RSS Tag Library requires a JSP (1.1 or higher) container, such
+as Tomcat.
+
+To use the Google RSS Tag Library, simply copy the library's JAR file
+(google-rss.jar) to your application's WEB-INF/lib directory. The Tag Library
+Descriptor (google-rss.tld) should be placed in your application's WEB-INF
+directory.
+
+You should also modify your web application deployment descriptor (web.xml)
+file to map the Google RSS Tag Library TLD URI to its location:
+
+
+ /google-rss-taglib
+ /WEB-INF/google-rss.tld
+
+
+
+TagLib Directive
+================
+
+Using the Google RSS Tag Library is easy; you simply need to import it into
+your JSP pages using the taglib directive. For instance, you would include
+the following line at the top of your JSP page:
+
+ <%@taglib uri="/google-rss-taglib" prefix="rss"%>
+
+
+SearchResults Tag
+=================
+
+The tag is used to display the search results returned
+by a Google search (performed using the Google Tag Library) in RSS format.
+
+For example:
+
+ <%@ page contentType="text/xml" %>
+ <%@ taglib uri="/google-taglib" prefix="google" %>
+ <%@ taglib uri="/google-rss-taglib" prefix="rss" %>
+ my search query
+
+
+Please refer to the Google Tag Library documentation for detailed information
+on performing searches.
+
+
+===========================================================================
+$Id$
\ No newline at end of file
diff --git a/rss/build.properties b/rss/build.properties
new file mode 100644
index 0000000..0171c3d
--- /dev/null
+++ b/rss/build.properties
@@ -0,0 +1,30 @@
+# Version
+version=1.0
+
+# Project
+project.name=google-rss
+release.name=${project.name}-taglib-${version}
+
+# Google Tag Library
+google.dir=..
+google.target=jar
+google.jar=../dist/google.jar
+google.tld=../dist/google.tld
+
+# Locations
+src.dir=src
+build.dir=build
+dist.dir=dist
+lib.dir=${google.dir}/lib
+tlds.dir=tlds
+
+# Examples
+ex.dir=${project.name}-examples
+
+# Source
+src.excludes=${lib.dir}/googleapi.jar
+
+# Docs
+doc.license=LICENSE.txt
+doc.readme=README.txt
+doc.src=README-BUILD.txt
\ No newline at end of file
diff --git a/rss/build.xml b/rss/build.xml
new file mode 100644
index 0000000..d51e9e0
--- /dev/null
+++ b/rss/build.xml
@@ -0,0 +1,128 @@
+
+
+ Google RSS Tag Library
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/rss/google-rss-examples/README.txt b/rss/google-rss-examples/README.txt
new file mode 100644
index 0000000..9bdbd8b
--- /dev/null
+++ b/rss/google-rss-examples/README.txt
@@ -0,0 +1,66 @@
+Google RSS Tag Library Examples README
+======================================
+
+
+Overview
+========
+
+This README file describes the Google RSS Tag Library Examples web
+application.
+
+This web application contains a collection of examples demonstrating the
+usage of the Google JSP RSS Tag Library. For more information about using
+the custom tag library in your own web applications, please refer to the
+Google RSS Tag Library documentation.
+
+The Google RSS Tag Library is an extension to the Google Tag Library, which
+can be found at:
+
+
+
+See the "LICENSE.txt" file for licensing details.
+
+The Google RSS Tag Library uses the Google Web APIs, but is not associated
+with or sponsored by Google, Inc.
+
+
+Google Web APIs
+===============
+
+The Google Web APIs Java library is required in order to use the Examples web
+application. The library's JAR file (googleapi.jar) should be placed into the
+application's WEB-INF/lib directory.
+
+ http://www.google.com/apis/download.html
+
+You must also register with Google (free) in order to obtain a license key.
+The license key is required to access Google's Web Services.
+
+ https://www.google.com/accounts/NewAccount
+
+
+Google License Key
+==================
+
+The license key can be specified as a context parameter in the web
+application deployment descriptor (web.xml) as follows:
+
+
+ google_key
+ 000000000000000000000000
+
+
+The license key can also be temporarily specified from the index page of
+the web application.
+
+
+Examples
+========
+
+The following example is included:
+
+ - Perform a simple Google RSS search
+
+
+===========================================================================
+$Id$
\ No newline at end of file
diff --git a/rss/google-rss-examples/WEB-INF/web.xml b/rss/google-rss-examples/WEB-INF/web.xml
new file mode 100644
index 0000000..2d63d72
--- /dev/null
+++ b/rss/google-rss-examples/WEB-INF/web.xml
@@ -0,0 +1,42 @@
+
+
+
+ google-rss-examples
+ Google RSS Examples Web Application
+
+ google_key
+
+ The Google Web APIs client authorization key.
+
+
+ google_proxy_host
+
+ The host to use as an HTTP proxy.
+
+
+ google_proxy_port
+
+ The port to use as an HTTP proxy.
+
+
+ google_proxy_username
+
+ The username required for the HTTP proxy.
+
+
+ google_proxy_password
+
+ The password required for the HTTP proxy.
+
+
+ index.html
+
+
+ /google-taglib
+ /WEB-INF/google.tld
+
+
+ /google-rss-taglib
+ /WEB-INF/google-rss.tld
+
+
diff --git a/rss/google-rss-examples/index.html b/rss/google-rss-examples/index.html
new file mode 100644
index 0000000..9639482
--- /dev/null
+++ b/rss/google-rss-examples/index.html
@@ -0,0 +1,71 @@
+
+
+
+Google RSS Tag Library Examples
+
+
+
+
+
+Google RSS Tag Library Examples
+
+The Google RSS Tag Library is an extension to the Google Tag Library.
+
+
+The Google Web APIs Java library is required in order to use the Google RSS Tag
+Library. The library's JAR file (googleapi.jar) should be placed
+into the application's WEB-INF/lib directory.
+
+The Google RSS Tag Library uses the Google Web APIs, but is not associated with or sponsored by Google, Inc.
+Click here for licensing information.
+
+
+
diff --git a/rss/google-rss-examples/key.html b/rss/google-rss-examples/key.html
new file mode 100644
index 0000000..4fa97a3
--- /dev/null
+++ b/rss/google-rss-examples/key.html
@@ -0,0 +1,16 @@
+
+
+
+Set Google Key
+
+
+
+
+
+
+
diff --git a/rss/google-rss-examples/key.jsp b/rss/google-rss-examples/key.jsp
new file mode 100644
index 0000000..cf30658
--- /dev/null
+++ b/rss/google-rss-examples/key.jsp
@@ -0,0 +1,21 @@
+<%
+ // Copyright (c) 2002-2004, Erik C. Thauvin
+ // All rights reserved.
+
+ String key = request.getParameter("key");
+
+ if ((key != null)&& (key.trim().length() > 0))
+ {
+ pageContext.setAttribute("google_key", key, PageContext.APPLICATION_SCOPE);
+%>
+ <%@include file="search.html"%>
+<%
+ }
+ else
+ {
+%>
+ <%@include file="key.html"%>
+<%
+ }
+%>
+
diff --git a/rss/google-rss-examples/rss.jsp b/rss/google-rss-examples/rss.jsp
new file mode 100644
index 0000000..0c7d8b5
--- /dev/null
+++ b/rss/google-rss-examples/rss.jsp
@@ -0,0 +1 @@
+<%@ page contentType="text/xml" %><%@ taglib uri="/google-taglib" prefix="google" %><%@ taglib uri="/google-rss-taglib" prefix="rss" %>
diff --git a/rss/google-rss-examples/search.html b/rss/google-rss-examples/search.html
new file mode 100644
index 0000000..9367268
--- /dev/null
+++ b/rss/google-rss-examples/search.html
@@ -0,0 +1,16 @@
+
+
+
+Search Google
+
+
+
+
+
+
+
diff --git a/rss/src/com/clevercactus/google/AtomGenerator.java b/rss/src/com/clevercactus/google/AtomGenerator.java
new file mode 100644
index 0000000..292111c
--- /dev/null
+++ b/rss/src/com/clevercactus/google/AtomGenerator.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2003-2004 clevercactus ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the author nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+package com.clevercactus.google;
+
+import org.xml.sax.SAXException;
+
+import java.io.PrintWriter;
+import java.util.Date;
+
+/**
+ * A class that uses JAXP and SAX to print an SearchResults 2.0 feed to a PrintWriter.
+ * Output of the SearchResults happens as data is added. See the main() method for a
+ * simple usage example.
+ *
+ * @version 1.0, 29/08/2003
+ * @author Diego Doval
+ */
+public
+class AtomGenerator
+ extends FeedGenerator
+{
+ /**
+ * The one and only constructor.
+ */
+ public
+ AtomGenerator()
+ {
+ }
+
+ /**
+ * Prints a valid SearchResults 2.0 header based on the information passed.
+ *
+ * @param title feed title
+ * @param link feed link
+ * @param description feed description
+ * @param author feed author (must be an email address)
+ * @param lastBuildDate the date the feed was built
+ * @throws FeedGenerationException
+ */
+ public
+ void
+ printHeader(String title, String link, String description, String author, Date lastBuildDate)
+ throws FeedGenerationException
+ {
+ try {
+ String language = "en-us";
+ String generatorName = "clevercactus atom generator 1.0";
+ String generatorURL = "http://www.clevercactus.com/google/";
+ String copyright = "Copyright (c) 2003-2004 clevercactus ltd.";
+ String authorName = "Diego Doval";
+
+ feedAttributes_d.clear();
+ feedAttributes_d.addAttribute("", "", "version", "", "0.2");
+ feedAttributes_d.addAttribute("", "", "xmlns", "", "http://purl.org/atom/ns#");
+ feedAttributes_d.addAttribute("", "", "xml:lang", "", "en");
+ transformerHandler_d.startElement("","","feed",feedAttributes_d);
+
+ feedAttributes_d.clear();
+ transformerHandler_d.startElement("","","author",feedAttributes_d);
+ transformerHandler_d.startElement("","","name",feedAttributes_d);
+ transformerHandler_d.characters(authorName.toCharArray(),0,authorName.length());
+ transformerHandler_d.endElement("","","name");
+ transformerHandler_d.endElement("","","author");
+
+ feedAttributes_d.clear();
+ transformerHandler_d.startElement("","","title",feedAttributes_d);
+ transformerHandler_d.characters(title.toCharArray(),0,title.length());
+ transformerHandler_d.endElement("","","title");
+ transformerHandler_d.startElement("","","link",feedAttributes_d);
+ transformerHandler_d.characters(link.toCharArray(),0,link.length());
+ transformerHandler_d.endElement("","","link");
+ transformerHandler_d.startElement("","","tagline", feedAttributes_d);
+ transformerHandler_d.characters(description.toCharArray(),0,description.length());
+ transformerHandler_d.endElement("","","tagline");
+ transformerHandler_d.startElement("","","modified",elementAttributes_d);
+ String dtString = getAsISO8601String(lastBuildDate);
+ transformerHandler_d.characters(dtString.toCharArray(),0,dtString.length());
+ transformerHandler_d.endElement("","","modified");
+ feedAttributes_d.addAttribute("", "", "name", "", generatorName);
+ transformerHandler_d.startElement("","","generator", feedAttributes_d);
+ transformerHandler_d.characters(generatorURL.toCharArray(),0, generatorURL.length());
+ transformerHandler_d.endElement("","","generator");
+ feedAttributes_d.clear();
+ transformerHandler_d.startElement("","","copyright", feedAttributes_d);
+ transformerHandler_d.characters(copyright.toCharArray(),0,copyright.length());
+ transformerHandler_d.endElement("","","copyright");
+ }
+ catch (SAXException e) {
+ throw new FeedGenerationException(e);
+ }
+ }
+
+ /**
+ * Prints a valid SearchResults 2.0 item based on the information passed.
+ *
+ * @param title the entry title
+ * @param description the entry body/description
+ * @param link the entry's GUID
+ * @param date the entry publication date
+ * @throws FeedGenerationException
+ */
+ public
+ void
+ printItem(String title, String description, String link, Date date)
+ throws FeedGenerationException
+ {
+ try {
+ elementAttributes_d.clear();
+
+ transformerHandler_d.startElement("","","entry",elementAttributes_d);
+ transformerHandler_d.startElement("","","title",elementAttributes_d);
+ transformerHandler_d.characters(title.toCharArray(),0,title.length());
+ transformerHandler_d.endElement("","","title");
+
+ transformerHandler_d.startElement("","","issued",elementAttributes_d);
+ String dtString = getAsISO8601String(date);
+ transformerHandler_d.characters(dtString.toCharArray(),0,dtString.length());
+ transformerHandler_d.endElement("","","issued");
+
+ transformerHandler_d.startElement("","","modified",elementAttributes_d);
+ transformerHandler_d.characters(dtString.toCharArray(),0,dtString.length());
+ transformerHandler_d.endElement("","","modified");
+
+ transformerHandler_d.startElement("","","created",elementAttributes_d);
+ transformerHandler_d.characters(dtString.toCharArray(),0,dtString.length());
+ transformerHandler_d.endElement("","","created");
+
+ transformerHandler_d.startElement("","","link",elementAttributes_d);
+ transformerHandler_d.characters(link.toCharArray(),0,link.length());
+ transformerHandler_d.endElement("","","link");
+
+ transformerHandler_d.startElement("","","id",elementAttributes_d);
+ transformerHandler_d.characters(link.toCharArray(),0,link.length());
+ transformerHandler_d.endElement("","","id");
+
+ elementAttributes_d.clear();
+ elementAttributes_d.addAttribute("", "", "type", "", "text/html");
+ elementAttributes_d.addAttribute("", "", "mode", "", "escaped");
+ elementAttributes_d.addAttribute("", "", "xml:lang", "", "en");
+
+ transformerHandler_d.startElement("","","content",elementAttributes_d);
+ transformerHandler_d.startCDATA();
+ transformerHandler_d.characters(description.toCharArray(),0,description.length());
+ transformerHandler_d.endCDATA();
+ transformerHandler_d.endElement("","","content");
+
+ transformerHandler_d.endElement("","","entry");
+ }
+ catch (SAXException e) {
+ throw new FeedGenerationException(e);
+ }
+
+ }
+
+ /**
+ * Closes the feed's main elements (i.e., "rss" and "channel").
+ * @throws FeedGenerationException
+ */
+ public
+ void
+ close()
+ throws FeedGenerationException
+ {
+ try {
+ transformerHandler_d.endElement("","","feed");
+ transformerHandler_d.endDocument();
+ }
+ catch (SAXException e) {
+ throw new FeedGenerationException(e);
+ }
+ }
+
+ /**
+ * Simple test to generate a 2.0 feed.
+ */
+ public static
+ void
+ main(String[] args)
+ {
+ try {
+ AtomGenerator gen = new AtomGenerator();
+ gen.init(new PrintWriter(System.out));
+ gen.printHeader("Test feed", "http://something/", "test feed desc", "test@test.com", new Date());
+ gen.printItem("Item title 1", "Item desc 1", "http://guid/1234", new Date());
+ gen.printItem("Item title 2", "Item desc 2", "http://guid/12342", new Date());
+ gen.close();
+ }
+ catch (FeedGenerationException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/rss/src/com/clevercactus/google/FeedGenerationException.java b/rss/src/com/clevercactus/google/FeedGenerationException.java
new file mode 100644
index 0000000..fb33e0f
--- /dev/null
+++ b/rss/src/com/clevercactus/google/FeedGenerationException.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2003-2004 clevercactus ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the author nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+package com.clevercactus.google;
+
+/**
+ * Used to simplify exception handling in the RSSGenerator class. Internal
+ * Exceptions in that class will be wrapped in an FeedGenerationException.
+ *
+ * @version 1.0, 29/08/2003
+ * @author Diego Doval
+ */
+public
+class FeedGenerationException
+ extends Exception
+{
+ public
+ FeedGenerationException()
+ {
+ }
+
+ public
+ FeedGenerationException(Throwable cause)
+ {
+ super(cause);
+ }
+
+ public
+ FeedGenerationException(String message)
+ {
+ super(message);
+ }
+
+ public
+ FeedGenerationException(String message, Throwable cause)
+ {
+ super(message, cause);
+ }
+}
diff --git a/rss/src/com/clevercactus/google/FeedGenerator.java b/rss/src/com/clevercactus/google/FeedGenerator.java
new file mode 100644
index 0000000..5879e6e
--- /dev/null
+++ b/rss/src/com/clevercactus/google/FeedGenerator.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2003-2004 clevercactus ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the author nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+package com.clevercactus.google;
+
+import org.xml.sax.helpers.AttributesImpl;
+import org.xml.sax.SAXException;
+
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.sax.SAXTransformerFactory;
+import javax.xml.transform.sax.TransformerHandler;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.OutputKeys;
+import java.io.Writer;
+import java.util.Date;
+import java.util.Locale;
+import java.text.SimpleDateFormat;
+
+/**
+ * A class that uses JAXP and SAX to print an feed to a PrintWriter.
+ * Output of the actual happens as data is added on the subclass. See the main() method for a
+ * simple usage example.
+ *
+ * @version 1.0, 29/08/2003
+ * @author Diego Doval
+ */
+public abstract
+class FeedGenerator
+{
+ protected Writer output_d;
+ protected StreamResult streamResult_d;
+ protected TransformerHandler transformerHandler_d;
+ protected SAXTransformerFactory saxTransformerFactory_d;
+ protected AttributesImpl elementAttributes_d;
+ protected AttributesImpl feedAttributes_d;
+
+ public static SimpleDateFormat iso8601DateFormat_sd = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
+ public static SimpleDateFormat rfc822DateFormat_sd = new SimpleDateFormat("EEE', 'dd' 'MMM' 'yy' 'HH:mm:ss' 'z", Locale.US);
+
+ /**
+ * The one and only constructor.
+ */
+ public
+ FeedGenerator()
+ {
+ }
+
+ /**
+ * @param output writer to use for outputting the SearchResults
+ * @throws FeedGenerationException
+ */
+ public
+ void
+ init(Writer output)
+ throws FeedGenerationException
+ {
+ output_d = output;
+ streamResult_d = new StreamResult(output_d);
+ feedAttributes_d = new AttributesImpl();
+ elementAttributes_d = new AttributesImpl();
+ try {
+ saxTransformerFactory_d = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
+ transformerHandler_d = saxTransformerFactory_d.newTransformerHandler();
+ Transformer trans = transformerHandler_d.getTransformer();
+ trans.setOutputProperty(OutputKeys.ENCODING,"ISO-8859-1");
+ trans.setOutputProperty(OutputKeys.INDENT,"yes");
+ transformerHandler_d.setResult(streamResult_d);
+ transformerHandler_d.startDocument();
+ }
+ catch (Exception e) {
+ throw new FeedGenerationException(e);
+ }
+ }
+
+ /**
+ * Prints a valid header based on the information passed.
+ *
+ * @param title feed title
+ * @param link feed link
+ * @param description feed description
+ * @param author feed author (must be an email address)
+ * @param lastBuildDate the date the feed was built
+ * @throws FeedGenerationException
+ */
+ public abstract
+ void
+ printHeader(String title, String link, String description, String author, Date lastBuildDate)
+ throws FeedGenerationException;
+
+ /**
+ * Prints a valid SearchResults 2.0 item based on the information passed.
+ *
+ * @param title the entry title
+ * @param description the entry body/description
+ * @param link the entry's GUID
+ * @param date the entry publication date
+ * @throws FeedGenerationException
+ */
+ public abstract
+ void
+ printItem(String title, String description, String link, Date date)
+ throws FeedGenerationException;
+
+ /**
+ * Closes the feed's main elements
+ * @throws FeedGenerationException
+ */
+ public abstract
+ void
+ close()
+ throws FeedGenerationException;
+
+ /**
+ * Utility method to obtain a date in a string in RFC 822 date format
+ *
+ * @param date the date to
+ * @return a string with the date in RFC 822 format
+ */
+ public final
+ String
+ getAsISO8601String(Date date)
+ {
+ String result = iso8601DateFormat_sd.format(date);
+ //convert 20030509T00:32:35+0100 returned by Java into 20030509T00:32:35+01:00
+ //from the spec date/time 19980717T14:08:55
+ result = result.substring(0, result.length()-2) + ":" + result.substring(result.length()-2);
+ return result;
+ }
+
+
+ /**
+ * Utility method to obtain a date in a string in RFC 822 date format
+ *
+ * @param date the date to
+ * @return a string with the date in RFC 822 format
+ */
+ public final
+ String
+ getAsRFC822String(Date date)
+ {
+ return rfc822DateFormat_sd.format(date);
+ }
+}
diff --git a/rss/src/com/clevercactus/google/FeedGeneratorFactory.java b/rss/src/com/clevercactus/google/FeedGeneratorFactory.java
new file mode 100644
index 0000000..a07fe81
--- /dev/null
+++ b/rss/src/com/clevercactus/google/FeedGeneratorFactory.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2003-2004 clevercactus ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the author nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+package com.clevercactus.google;
+
+import java.util.HashMap;
+
+/**
+ * Date: 05-Sep-2003
+ * Time: 20:41:19
+ */
+public
+class FeedGeneratorFactory
+{
+ public static HashMap feedTypes_sd = new HashMap();
+
+ public static final String FEED_TYPE_RSS = "rss";
+ public static final String FEED_TYPE_ATOM = "atom";
+
+ static {
+ addGenerator(FEED_TYPE_RSS, RSSGenerator.class);
+ addGenerator(FEED_TYPE_ATOM, AtomGenerator.class);
+ }
+
+ public static
+ boolean
+ supportsFormat(String type)
+ {
+ return type != null && (type.equals(FEED_TYPE_RSS) || type.equals(FEED_TYPE_ATOM));
+ }
+
+ public static
+ void
+ addGenerator(String type, Class cls)
+ {
+ feedTypes_sd.put(type, cls);
+ }
+
+ public static
+ FeedGenerator
+ getGeneratorForType(String type)
+ {
+ Class cls = (Class) feedTypes_sd.get(type);
+ try {
+ return (FeedGenerator) cls.newInstance();
+ }
+ catch (InstantiationException e) {
+ e.printStackTrace();
+ }
+ catch (IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+}
diff --git a/rss/src/com/clevercactus/google/GoogleResultsWrapper.java b/rss/src/com/clevercactus/google/GoogleResultsWrapper.java
new file mode 100644
index 0000000..128ad70
--- /dev/null
+++ b/rss/src/com/clevercactus/google/GoogleResultsWrapper.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2003-2004 clevercactus ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the author nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+package com.clevercactus.google;
+
+import com.google.soap.search.GoogleSearchResultElement;
+
+import java.io.Writer;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Date;
+import java.util.ArrayList;
+
+/**
+ * Date: 30-Oct-2003
+ * Time: 13:41:41
+ * @author Diego Doval
+ * @author Erik C. Thauvin
+ */
+public
+class GoogleResultsWrapper
+{
+ ArrayList items_d = new ArrayList();
+
+
+ private
+ GoogleResultsWrapper()
+ {
+ }
+
+ private
+ Iterator
+ iterator()
+ {
+ return items_d.iterator();
+ }
+
+ private
+ void
+ addItem(GoogleResultsWrapperItem it)
+ {
+ items_d.add(it);
+ }
+
+ private static
+ GoogleResultsWrapper
+ createWrapper(GoogleSearchResultElement[] elements)
+ {
+ if (elements == null || elements.length == 0) {
+ return null;
+ }
+ GoogleResultsWrapper wrapper = new GoogleResultsWrapper();
+ for (int i = 0; i < elements.length; i++) {
+ GoogleSearchResultElement element = elements[i];
+ wrapper.addItem(new GoogleResultsWrapperItem(element.getTitle(), element.getURL(), element.getSnippet()));
+ }
+ return wrapper;
+ }
+
+ /**
+ * Output the results to a writer.
+ *
+ * @param out the writer to use
+ * @param elements the search result elements
+ * @param query the search query
+ * @param feedType the type of feed to use (options are "rss" and "atom")
+ */
+ public static
+ void
+ outputResults(Writer out, GoogleSearchResultElement[] elements, String query, String feedType)
+ {
+ outputResults(out, createWrapper(elements), query, feedType);
+ }
+
+ /**
+ * Output the results to a writer.
+ *
+ * @param out the writer to use
+ * @param wrapper the results object obtained from the parsing of results
+ * @param query the search query
+ * @param feedType the type of feed to use (options are "rss" and "atom")
+ */
+ private static
+ void
+ outputResults(Writer out, GoogleResultsWrapper wrapper, String query, String feedType)
+ {
+ try {
+ if (out == null || feedType == null) {
+ try {
+ out.write("Null parameter in output results.\n");
+ }
+ catch (IOException e1) {
+ }
+ return;
+ }
+ if (!feedType.equals(FeedGeneratorFactory.FEED_TYPE_RSS)
+ && !feedType.equals(FeedGeneratorFactory.FEED_TYPE_ATOM)) {
+ try {
+ out.write("Invalid feed type ("+feedType+"). Supported types are 'rss' and 'atom'.\n");
+ }
+ catch (IOException e1) {
+ }
+ return;
+ }
+ try {
+ FeedGenerator gen = FeedGeneratorFactory.getGeneratorForType(feedType);
+ gen.init(out);
+ Date date = new Date();
+
+ String description;
+ if ((query == null) || (query.trim().length() == 0)) {
+ description = "Google Tag Library";
+ } else {
+ description = "Search results for: \"" + query + '"';
+ }
+
+ gen.printHeader("Google Search Feed Output", "http://google-taglib.sourceforge.net/", description, "check@page.for.info", date);
+ if (wrapper != null) {
+ Iterator items = wrapper.iterator();
+ while (items.hasNext()) {
+ GoogleResultsWrapperItem item = (GoogleResultsWrapperItem) items.next();
+ gen.printItem(item.getTitle(), item.getSnippet(), item.getURL(), date);
+ }
+ }
+ gen.close();
+ }
+ catch (FeedGenerationException e) {
+ try {
+ out.write("Error.\n");
+ out.write(e.getMessage());
+ }
+ catch (IOException e1) {
+ }
+ }
+ }
+ finally {
+ try {
+ out.close();
+ }
+ catch (IOException e) {
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/rss/src/com/clevercactus/google/GoogleResultsWrapperItem.java b/rss/src/com/clevercactus/google/GoogleResultsWrapperItem.java
new file mode 100644
index 0000000..848c216
--- /dev/null
+++ b/rss/src/com/clevercactus/google/GoogleResultsWrapperItem.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2003-2004 clevercactus ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the author nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+package com.clevercactus.google;
+
+/**
+ * Date: 30-Oct-2003
+ * Time: 13:51:43
+ * @author Diego Doval
+ */
+public
+class GoogleResultsWrapperItem
+{
+ String title_d;
+ String text_d;
+ String url_d;
+
+ public
+ GoogleResultsWrapperItem(String title, String url, String text)
+ {
+ title_d = title;
+ url_d = url;
+ text_d = text;
+ }
+
+ public
+ String
+ getTitle()
+ {
+ return title_d;
+ }
+
+ public
+ String
+ getSnippet()
+ {
+ return text_d;
+ }
+
+ public
+ String
+ getURL()
+ {
+ return url_d;
+ }
+
+ public
+ String
+ toString()
+ {
+ return "Title: "+title_d+"\nURL:"+url_d+"\nText:"+text_d+"\n";
+ }
+}
diff --git a/rss/src/com/clevercactus/google/RSSGenerator.java b/rss/src/com/clevercactus/google/RSSGenerator.java
new file mode 100644
index 0000000..e6a4b25
--- /dev/null
+++ b/rss/src/com/clevercactus/google/RSSGenerator.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2003-2004 clevercactus ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the author nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+package com.clevercactus.google;
+
+import org.xml.sax.SAXException;
+
+import java.io.PrintWriter;
+import java.util.Date;
+
+/**
+ * A class that uses JAXP and SAX to print an SearchResults 2.0 feed to a PrintWriter.
+ * Output of the SearchResults happens as data is added. See the main() method for a
+ * simple usage example.
+ *
+ * @version 1.0, 29/08/2003
+ * @author Diego Doval
+ */
+public
+class RSSGenerator
+ extends FeedGenerator
+{
+
+ /**
+ * The one and only constructor.
+ */
+ public
+ RSSGenerator()
+ {
+ }
+
+ /**
+ * Prints a valid SearchResults 2.0 header based on the information passed.
+ *
+ * @param title feed title
+ * @param link feed link
+ * @param description feed description
+ * @param author feed author (must be an email address)
+ * @param lastBuildDate the date the feed was built
+ * @throws FeedGenerationException
+ */
+ public
+ void
+ printHeader(String title, String link, String description, String author, Date lastBuildDate)
+ throws FeedGenerationException
+ {
+ try {
+ String language = "en-us";
+ String generator = "clevercactus rss generator 1.0";
+
+ feedAttributes_d.clear();
+ feedAttributes_d.addAttribute("", "", "version", "", "2.0");
+ transformerHandler_d.startElement("","","rss",feedAttributes_d);
+ feedAttributes_d.clear();
+ transformerHandler_d.startElement("","","channel",feedAttributes_d);
+ transformerHandler_d.startElement("","","title",feedAttributes_d);
+ transformerHandler_d.characters(title.toCharArray(),0,title.length());
+ transformerHandler_d.endElement("","","title");
+ transformerHandler_d.startElement("","","link",feedAttributes_d);
+ transformerHandler_d.characters(link.toCharArray(),0,link.length());
+ transformerHandler_d.endElement("","","link");
+ transformerHandler_d.startElement("","","description", feedAttributes_d);
+ transformerHandler_d.characters(description.toCharArray(),0,description.length());
+ transformerHandler_d.endElement("","","description");
+ transformerHandler_d.startElement("","","language", feedAttributes_d);
+ transformerHandler_d.characters(language.toCharArray(),0,language.length());
+ transformerHandler_d.endElement("","","language");
+ transformerHandler_d.startElement("","","lastBuildDate",elementAttributes_d);
+ String dtString = getAsRFC822String(lastBuildDate);
+ transformerHandler_d.characters(dtString.toCharArray(),0,dtString.length());
+ transformerHandler_d.endElement("","","lastBuildDate");
+ transformerHandler_d.startElement("","","generator", feedAttributes_d);
+ transformerHandler_d.characters(generator.toCharArray(),0,generator.length());
+ transformerHandler_d.endElement("","","generator");
+ transformerHandler_d.startElement("","","managingEditor", feedAttributes_d);
+ transformerHandler_d.characters(author.toCharArray(),0,author.length());
+ transformerHandler_d.endElement("","","managingEditor");
+ transformerHandler_d.startElement("","","webMaster", feedAttributes_d);
+ transformerHandler_d.characters(author.toCharArray(),0,author.length());
+ transformerHandler_d.endElement("","","webMaster");
+ }
+ catch (SAXException e) {
+ throw new FeedGenerationException(e);
+ }
+ }
+
+ /**
+ * Prints a valid SearchResults 2.0 item based on the information passed.
+ *
+ * @param title the entry title
+ * @param description the entry body/description
+ * @param link the entry's GUID
+ * @param date the entry publication date
+ * @throws FeedGenerationException
+ */
+ public
+ void
+ printItem(String title, String description, String link, Date date)
+ throws FeedGenerationException
+ {
+ try {
+ elementAttributes_d.clear();
+ transformerHandler_d.startElement("","","item",elementAttributes_d);
+ elementAttributes_d.clear();
+ transformerHandler_d.startElement("","","title",elementAttributes_d);
+ transformerHandler_d.characters(title.toCharArray(),0,title.length());
+ transformerHandler_d.endElement("","","title");
+ elementAttributes_d.clear();
+ transformerHandler_d.startElement("","","description",elementAttributes_d);
+ transformerHandler_d.characters(description.toCharArray(),0,description.length());
+ transformerHandler_d.endElement("","","description");
+ elementAttributes_d.clear();
+ transformerHandler_d.startElement("","","pubDate",elementAttributes_d);
+ String dtString = getAsRFC822String(date);
+ transformerHandler_d.characters(dtString.toCharArray(),0,dtString.length());
+ transformerHandler_d.endElement("","","pubDate");
+ elementAttributes_d.clear();
+ transformerHandler_d.startElement("","","link",elementAttributes_d);
+ transformerHandler_d.characters(link.toCharArray(),0,link.length());
+ transformerHandler_d.endElement("","","link");
+
+ transformerHandler_d.endElement("","","item");
+ }
+ catch (SAXException e) {
+ throw new FeedGenerationException(e);
+ }
+
+ }
+
+ /**
+ * Closes the feed's main elements (i.e., "rss" and "channel").
+ * @throws FeedGenerationException
+ */
+ public
+ void
+ close()
+ throws FeedGenerationException
+ {
+ try {
+ transformerHandler_d.endElement("","","channel");
+ transformerHandler_d.endElement("","","rss");
+ transformerHandler_d.endDocument();
+ }
+ catch (SAXException e) {
+ throw new FeedGenerationException(e);
+ }
+ }
+
+
+ /**
+ * Simple test to generate a 2.0 feed.
+ */
+ public static
+ void
+ main(String[] args)
+ {
+ try {
+ RSSGenerator gen = new RSSGenerator();
+ gen.init(new PrintWriter(System.out));
+ gen.printHeader("Test feed", "http://something/", "test feed desc", "test@test.com", new Date());
+ gen.printItem("Item title 1", "Item desc 1", "guid", new Date());
+ gen.printItem("Item title 2", "Item desc 2", "guid", new Date());
+ gen.close();
+ }
+ catch (FeedGenerationException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/rss/src/com/clevercactus/google/taglibs/SearchResults.java b/rss/src/com/clevercactus/google/taglibs/SearchResults.java
new file mode 100644
index 0000000..61f44f0
--- /dev/null
+++ b/rss/src/com/clevercactus/google/taglibs/SearchResults.java
@@ -0,0 +1,132 @@
+/*
+ * @(#)SearchResults.java
+ *
+ * Copyright (c) 2003-2004, Erik C. Thauvin (erik@thauvin.net)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the author nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id$
+ *
+ */
+package com.clevercactus.google.taglibs;
+
+import com.clevercactus.google.GoogleResultsWrapper;
+
+import net.thauvin.google.GoogleSearchBean;
+import net.thauvin.google.TagUtility;
+
+import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.tagext.BodyTagSupport;
+
+
+/**
+ * A custom tag used to display Google search results in RSS format.
+ *
+ * @author Erik C. Thauvin
+ * @version $Revision$, $Date$
+ *
+ * @created Oct 30, 2003
+ * @since 1.0
+ */
+public class SearchResults extends BodyTagSupport
+{
+ /**
+ * The Google search bean.
+ */
+ protected GoogleSearchBean bean = null;
+
+ /**
+ * doEndTag method.
+ *
+ * @return EVAL_PAGE
+ *
+ * @throws JspException
+ */
+ public int doEndTag() throws JspException
+ {
+ try
+ {
+ // Is the result valid?
+ if (bean != null)
+ {
+ // Output the feed
+ GoogleResultsWrapper.outputResults(pageContext.getOut(),
+ bean.getResultElements(),
+ bean.getResultProperty("searchKeywords"),
+ "rss");
+ }
+ }
+ catch (Exception e)
+ {
+ throw TagUtility.outputError("rss", e);
+ }
+
+ // Reset the values
+ reset();
+
+ return EVAL_PAGE;
+ }
+
+ /**
+ * doStartTag method.
+ *
+ * @return SKIP_BODY.
+ *
+ * @throws JspException
+ */
+ public int doStartTag() throws JspException
+ {
+ // Get the Google bean
+ bean = TagUtility.getGoogleSearchBean(pageContext);
+
+ return SKIP_BODY;
+ }
+
+ /**
+ * Release method.
+ */
+ public void release()
+ {
+ super.release();
+
+ // Reset the bean
+ bean = null;
+
+ // Reset the values
+ reset();
+ }
+
+ /**
+ * Reset the values.
+ */
+ protected void reset()
+ {
+ // super.reset();
+ }
+}
diff --git a/rss/tlds/google-rss.tld b/rss/tlds/google-rss.tld
new file mode 100644
index 0000000..06ee349
--- /dev/null
+++ b/rss/tlds/google-rss.tld
@@ -0,0 +1,22 @@
+
+
+
+
+
+ @version@
+
+ 1.1
+
+ google-rss
+
+ http://www.thauvin.net/taglibs/google-rss-taglib-@version@
+
+ The Google RSS Tag Library.
+
+
+ searchResults
+ com.clevercactus.google.taglibs.SearchResults
+ empty
+ Displays Google search results in RSS format.
+
+
diff --git a/google-taglib/src/net/thauvin/google/GoogleSearchBean.java b/src/net/thauvin/google/GoogleSearchBean.java
similarity index 100%
rename from google-taglib/src/net/thauvin/google/GoogleSearchBean.java
rename to src/net/thauvin/google/GoogleSearchBean.java
diff --git a/google-taglib/src/net/thauvin/google/TagUtility.java b/src/net/thauvin/google/TagUtility.java
similarity index 100%
rename from google-taglib/src/net/thauvin/google/TagUtility.java
rename to src/net/thauvin/google/TagUtility.java
diff --git a/google-taglib/src/net/thauvin/google/package.html b/src/net/thauvin/google/package.html
similarity index 100%
rename from google-taglib/src/net/thauvin/google/package.html
rename to src/net/thauvin/google/package.html
diff --git a/google-taglib/src/net/thauvin/google/taglibs/CachedPage.java b/src/net/thauvin/google/taglibs/CachedPage.java
similarity index 100%
rename from google-taglib/src/net/thauvin/google/taglibs/CachedPage.java
rename to src/net/thauvin/google/taglibs/CachedPage.java
diff --git a/google-taglib/src/net/thauvin/google/taglibs/Element.java b/src/net/thauvin/google/taglibs/Element.java
similarity index 100%
rename from google-taglib/src/net/thauvin/google/taglibs/Element.java
rename to src/net/thauvin/google/taglibs/Element.java
diff --git a/google-taglib/src/net/thauvin/google/taglibs/EndIndex.java b/src/net/thauvin/google/taglibs/EndIndex.java
similarity index 100%
rename from google-taglib/src/net/thauvin/google/taglibs/EndIndex.java
rename to src/net/thauvin/google/taglibs/EndIndex.java
diff --git a/google-taglib/src/net/thauvin/google/taglibs/EstimatedTotal.java b/src/net/thauvin/google/taglibs/EstimatedTotal.java
similarity index 100%
rename from google-taglib/src/net/thauvin/google/taglibs/EstimatedTotal.java
rename to src/net/thauvin/google/taglibs/EstimatedTotal.java
diff --git a/google-taglib/src/net/thauvin/google/taglibs/KeySupport.java b/src/net/thauvin/google/taglibs/KeySupport.java
similarity index 100%
rename from google-taglib/src/net/thauvin/google/taglibs/KeySupport.java
rename to src/net/thauvin/google/taglibs/KeySupport.java
diff --git a/google-taglib/src/net/thauvin/google/taglibs/Next.java b/src/net/thauvin/google/taglibs/Next.java
similarity index 100%
rename from google-taglib/src/net/thauvin/google/taglibs/Next.java
rename to src/net/thauvin/google/taglibs/Next.java
diff --git a/google-taglib/src/net/thauvin/google/taglibs/Previous.java b/src/net/thauvin/google/taglibs/Previous.java
similarity index 100%
rename from google-taglib/src/net/thauvin/google/taglibs/Previous.java
rename to src/net/thauvin/google/taglibs/Previous.java
diff --git a/google-taglib/src/net/thauvin/google/taglibs/QuerySupport.java b/src/net/thauvin/google/taglibs/QuerySupport.java
similarity index 100%
rename from google-taglib/src/net/thauvin/google/taglibs/QuerySupport.java
rename to src/net/thauvin/google/taglibs/QuerySupport.java
diff --git a/google-taglib/src/net/thauvin/google/taglibs/Search.java b/src/net/thauvin/google/taglibs/Search.java
similarity index 100%
rename from google-taglib/src/net/thauvin/google/taglibs/Search.java
rename to src/net/thauvin/google/taglibs/Search.java
diff --git a/google-taglib/src/net/thauvin/google/taglibs/SearchComments.java b/src/net/thauvin/google/taglibs/SearchComments.java
similarity index 100%
rename from google-taglib/src/net/thauvin/google/taglibs/SearchComments.java
rename to src/net/thauvin/google/taglibs/SearchComments.java
diff --git a/google-taglib/src/net/thauvin/google/taglibs/SearchQuery.java b/src/net/thauvin/google/taglibs/SearchQuery.java
similarity index 100%
rename from google-taglib/src/net/thauvin/google/taglibs/SearchQuery.java
rename to src/net/thauvin/google/taglibs/SearchQuery.java
diff --git a/google-taglib/src/net/thauvin/google/taglibs/SearchResult.java b/src/net/thauvin/google/taglibs/SearchResult.java
similarity index 100%
rename from google-taglib/src/net/thauvin/google/taglibs/SearchResult.java
rename to src/net/thauvin/google/taglibs/SearchResult.java
diff --git a/google-taglib/src/net/thauvin/google/taglibs/SearchResultSupport.java b/src/net/thauvin/google/taglibs/SearchResultSupport.java
similarity index 100%
rename from google-taglib/src/net/thauvin/google/taglibs/SearchResultSupport.java
rename to src/net/thauvin/google/taglibs/SearchResultSupport.java
diff --git a/google-taglib/src/net/thauvin/google/taglibs/SearchTime.java b/src/net/thauvin/google/taglibs/SearchTime.java
similarity index 100%
rename from google-taglib/src/net/thauvin/google/taglibs/SearchTime.java
rename to src/net/thauvin/google/taglibs/SearchTime.java
diff --git a/google-taglib/src/net/thauvin/google/taglibs/SearchTips.java b/src/net/thauvin/google/taglibs/SearchTips.java
similarity index 100%
rename from google-taglib/src/net/thauvin/google/taglibs/SearchTips.java
rename to src/net/thauvin/google/taglibs/SearchTips.java
diff --git a/google-taglib/src/net/thauvin/google/taglibs/Spelling.java b/src/net/thauvin/google/taglibs/Spelling.java
similarity index 100%
rename from google-taglib/src/net/thauvin/google/taglibs/Spelling.java
rename to src/net/thauvin/google/taglibs/Spelling.java
diff --git a/google-taglib/src/net/thauvin/google/taglibs/StartIndex.java b/src/net/thauvin/google/taglibs/StartIndex.java
similarity index 100%
rename from google-taglib/src/net/thauvin/google/taglibs/StartIndex.java
rename to src/net/thauvin/google/taglibs/StartIndex.java
diff --git a/google-taglib/src/net/thauvin/google/taglibs/StyleSupport.java b/src/net/thauvin/google/taglibs/StyleSupport.java
similarity index 100%
rename from google-taglib/src/net/thauvin/google/taglibs/StyleSupport.java
rename to src/net/thauvin/google/taglibs/StyleSupport.java
diff --git a/google-taglib/src/net/thauvin/google/taglibs/package.html b/src/net/thauvin/google/taglibs/package.html
similarity index 100%
rename from google-taglib/src/net/thauvin/google/taglibs/package.html
rename to src/net/thauvin/google/taglibs/package.html
diff --git a/google-taglib/tlds/google-1.2.tld b/tlds/google-1.2.tld
similarity index 100%
rename from google-taglib/tlds/google-1.2.tld
rename to tlds/google-1.2.tld
diff --git a/google-taglib/tlds/google.tld b/tlds/google.tld
similarity index 100%
rename from google-taglib/tlds/google.tld
rename to tlds/google.tld