Author: julien(a)jboss.com
Date: 2007-07-06 06:20:08 -0400 (Fri, 06 Jul 2007)
New Revision: 7678
Added:
trunk/widget/src/main/org/jboss/portal/test/widget/google/QueryResultParserTestCase.java
trunk/widget/src/main/org/jboss/portal/widget/google/GGWidgetInfo.java
trunk/widget/src/main/org/jboss/portal/widget/google/provider/GGQueryResultEntry.java
trunk/widget/src/main/org/jboss/portal/widget/google/provider/GGWidgetInfoBuilder.java
trunk/widget/src/resources/test/google/queryresult1.xml
Removed:
trunk/core/src/main/org/jboss/portal/core/controller/handler/UIServerResponse.java
trunk/uiserver/
trunk/widget/src/main/org/jboss/portal/widget/google/provider/GGWidgetBuilder.java
Modified:
trunk/build/build.xml
trunk/common/src/main/org/jboss/portal/common/xml/XMLTools.java
trunk/core/build.xml
trunk/core/src/main/org/jboss/portal/core/controller/Controller.java
trunk/core/src/main/org/jboss/portal/core/controller/ajax/AjaxResponseHandler.java
trunk/core/src/main/org/jboss/portal/core/model/portal/PortalObjectResponseHandler.java
trunk/core/src/main/org/jboss/portal/core/theme/PageRendition.java
trunk/core/src/resources/portal-core-sar/META-INF/jboss-service.xml
trunk/widget/build.xml
trunk/widget/src/main/org/jboss/portal/test/widget/google/PreferencesTestCase.java
trunk/widget/src/main/org/jboss/portal/widget/google/GGWidget.java
trunk/widget/src/main/org/jboss/portal/widget/google/provider/GGProvider.java
trunk/widget/src/main/org/jboss/portal/widget/google/provider/GGQuery.java
trunk/widget/src/main/org/jboss/portal/widget/google/provider/GGQueryResult.java
trunk/widget/src/main/org/jboss/portal/widget/google/provider/GGQueryResultBuilder.java
trunk/widget/src/resources/widget-war/WEB-INF/jsp/edit.jsp
Log:
rollback uiserver prototype
Modified: trunk/build/build.xml
===================================================================
--- trunk/build/build.xml 2007-07-05 23:41:21 UTC (rev 7677)
+++ trunk/build/build.xml 2007-07-06 10:20:08 UTC (rev 7678)
@@ -127,7 +127,6 @@
<module name="bridge"/>
<module name="cms"/>
<module name="format"/>
- <module name="uiserver"/>
<module name="core"/>
<module name="core-cms"/>
<module name="core-management"/>
@@ -137,14 +136,14 @@
<module name="wsrp"/>
<module name="registration"/>
<module name="workflow"/>
- <module name="widget"/>
+ <module name="widget"/>
<!--<module name="core-admin"/>-->
<!-- Module groups -->
<group name="portal">
<include
- modules="common, test, api, web, jems, server, security, identity,
search, format, portlet, portlet-server, bridge, faces, portlet-federation, theme,
workflow, cms, registration, uiserver, core, wsrp, core-admin, core-cms, core-management,
core-samples, widget"/>
+ modules="common, test, api, web, jems, server, security, identity,
search, format, portlet, portlet-server, bridge, faces, portlet-federation, theme,
workflow, cms, registration, core, wsrp, core-admin, core-cms, core-management,
core-samples, widget"/>
</group>
<group name="cms">
Modified: trunk/common/src/main/org/jboss/portal/common/xml/XMLTools.java
===================================================================
--- trunk/common/src/main/org/jboss/portal/common/xml/XMLTools.java 2007-07-05 23:41:21
UTC (rev 7677)
+++ trunk/common/src/main/org/jboss/portal/common/xml/XMLTools.java 2007-07-06 10:20:08
UTC (rev 7678)
@@ -313,7 +313,25 @@
public static Element getUniqueChild(Element element, String name, boolean strict)
throws IllegalArgumentException,
NoSuchElementException, TooManyElementException
{
- List list = getChildren(element, name);
+ return getUniqueChild(element, null, name, strict);
+ }
+
+ /**
+ * Return an optional child of an element with the specified name and the optionally
specified namespace uri.
+ *
+ * @param element the parent element
+ * @param name the child name
+ * @param uri the child uri
+ * @param strict if the child must be present
+ * @return the child element or null if it does not exist and strict is set to false
+ * @throws IllegalArgumentException if an argument is null
+ * @throws NoSuchElementException if strict is true and the element is not present
+ * @throws TooManyElementException if more than one element is found
+ */
+ public static Element getUniqueChild(Element element, String uri, String name, boolean
strict) throws IllegalArgumentException,
+ NoSuchElementException, TooManyElementException
+ {
+ List list = getChildren(element, uri, name);
switch (list.size())
{
case 0:
@@ -346,6 +364,21 @@
}
/**
+ * Return an iterator for all the children of the given element having the specified
name and the optionally
+ * specified namesspace uri.
+ *
+ * @param element the parent element
+ * @param uri the children uri
+ * @param name the children name
+ * @return an iterator for the designated elements
+ * @throws IllegalArgumentException if the element is null or the name is null
+ */
+ public static Iterator getChildrenIterator(Element element, String uri, String name)
throws IllegalArgumentException
+ {
+ return getChildren(element, uri, name).iterator();
+ }
+
+ /**
* Return all the children of the given element having the specified name. The
collection object can be modified.
*
* @param element the parent element
@@ -355,6 +388,21 @@
*/
public static List getChildren(Element element, String name) throws
IllegalArgumentException
{
+ return getChildren(element, null, name);
+ }
+
+ /**
+ * Return all the children of the given element having the specified name and the
optionally specified namespace URI.
+ * The collection object can be modified.
+ *
+ * @param element the parent element
+ * @param uri the children uri
+ * @param name the children name
+ * @return a list of elements
+ * @throws IllegalArgumentException if the element is null or the name is null
+ */
+ public static List getChildren(Element element, String uri, String name) throws
IllegalArgumentException
+ {
if (element == null)
{
throw new IllegalArgumentException("No element found");
@@ -371,7 +419,9 @@
if (node.getNodeType() == Node.ELEMENT_NODE)
{
Element childElt = (Element)node;
- if (childElt.getTagName().equals(name))
+
+ //
+ if ((uri == null || uri.equals(childElt.getNamespaceURI())) &&
childElt.getLocalName().equals(name))
{
result.add(childElt);
}
Modified: trunk/core/build.xml
===================================================================
--- trunk/core/build.xml 2007-07-05 23:41:21 UTC (rev 7677)
+++ trunk/core/build.xml 2007-07-06 10:20:08 UTC (rev 7678)
@@ -134,7 +134,6 @@
<path refid="jboss.portal-theme.classpath"/>
<path refid="jboss.portal-security.classpath"/>
<path refid="jboss.portal-test.classpath"/>
- <path refid="jboss.portal-uiserver.classpath"/>
</path>
<!--+=======================================+-->
@@ -335,7 +334,6 @@
<fileset dir="${jboss.portal-search.root}/lib"
includes="portal-search-lib.jar"/>
<fileset dir="${jboss.portal-identity.root}/lib"
includes="portal-identity-lib.jar"/>
<fileset dir="${jboss.portal-registration.root}/lib"
includes="portal-registration-lib.jar"/>
- <fileset dir="${jboss.portal-uiserver.root}/lib"
includes="portal-uiserver-lib.jar"/>
<fileset dir="${ehcache.ehcache.lib}"
includes="ehcache.jar"/>
<fileset dir="${apache.collections.lib}"
includes="commons-collections.jar"/>
<fileset dir="${javassist.javassist.lib}"
includes="javassist.jar"/>
Modified: trunk/core/src/main/org/jboss/portal/core/controller/Controller.java
===================================================================
--- trunk/core/src/main/org/jboss/portal/core/controller/Controller.java 2007-07-05
23:41:21 UTC (rev 7677)
+++ trunk/core/src/main/org/jboss/portal/core/controller/Controller.java 2007-07-06
10:20:08 UTC (rev 7678)
@@ -46,10 +46,6 @@
import org.jboss.portal.server.ServerException;
import org.jboss.portal.web.spi.ServletContainerContext;
-import org.jboss.portal.uiserver.UIServer;
-import org.jboss.portal.uiserver.UIServerRequest;
-import org.jboss.portal.core.controller.handler.UIServerResponse;
-
import javax.servlet.ServletException;
import java.io.IOException;
@@ -96,12 +92,6 @@
/** . */
protected PageControlPolicy pageControlPolicy;
-
- /**
- *
- */
- protected UIServer uiServer = null;
-
public ContentRendererRegistry getContentRendererRegistry()
{
@@ -217,25 +207,7 @@
{
this.pageControlPolicy = pageControlPolicy;
}
-
- /**
- *
- * @return
- */
- public UIServer getUIServer()
- {
- return uiServer;
- }
- /**
- *
- * @param uiServer
- */
- public void setUIServer(UIServer uiServer)
- {
- this.uiServer = uiServer;
- }
-
public final void handle(ServerInvocation invocation) throws ServerException
{
// Create controller context
@@ -345,19 +317,6 @@
AjaxResponse ar = (AjaxResponse)handlerResponse;
sendResponse(controllerContext, ar);
}
-
- //This condition hands over UI aggregation function to the
- //UI Server, regardless of what type of UI is being catered to
- else if(handlerResponse instanceof UIServerResponse)
- {
- //Create a request to be handled by the UIServer
- UIServerRequest request = new UIServerRequest();
- request.setAttribute(UIServerRequest.SERVER_INVOCATION,
controllerContext.getServerInvocation());
- request.setAttribute(UIServerRequest.UI_INDICATOR,
((UIServerResponse)handlerResponse).getUiIndicator());
-
- //Perform aggregation of the UI to be sent back to the client
- this.uiServer.aggregate(request);
- }
}
/**
Modified:
trunk/core/src/main/org/jboss/portal/core/controller/ajax/AjaxResponseHandler.java
===================================================================
---
trunk/core/src/main/org/jboss/portal/core/controller/ajax/AjaxResponseHandler.java 2007-07-05
23:41:21 UTC (rev 7677)
+++
trunk/core/src/main/org/jboss/portal/core/controller/ajax/AjaxResponseHandler.java 2007-07-06
10:20:08 UTC (rev 7678)
@@ -68,8 +68,6 @@
import org.jboss.portal.theme.page.Region;
import org.apache.log4j.Logger;
-import org.jboss.portal.core.controller.handler.UIServerResponse;
-
import java.io.StringWriter;
import java.util.Set;
import java.util.HashSet;
@@ -176,7 +174,7 @@
ViewPageCommand rpc = new ViewPageCommand(upr.getPageId());
String url = controllerContext.renderURL(rpc, null, null);
UpdatePageLocationResponse dresp = new UpdatePageLocationResponse(url);
- return new UIServerResponse(dresp);
+ return new AjaxResponse(dresp);
}
else if (controllerResponse instanceof UpdateWindowResponse)
{
@@ -368,7 +366,7 @@
//
if (!fullRefresh)
{
- return new UIServerResponse(updatePage);
+ return new AjaxResponse(updatePage);
}
}
@@ -376,7 +374,7 @@
ViewPageCommand rpc = new ViewPageCommand(page.getId());
String url = controllerContext.renderURL(rpc, null, null);
UpdatePageLocationResponse dresp = new UpdatePageLocationResponse(url);
- return new UIServerResponse(dresp);
+ return new AjaxResponse(dresp);
}
else
{
Deleted:
trunk/core/src/main/org/jboss/portal/core/controller/handler/UIServerResponse.java
===================================================================
---
trunk/core/src/main/org/jboss/portal/core/controller/handler/UIServerResponse.java 2007-07-05
23:41:21 UTC (rev 7677)
+++
trunk/core/src/main/org/jboss/portal/core/controller/handler/UIServerResponse.java 2007-07-06
10:20:08 UTC (rev 7678)
@@ -1,83 +0,0 @@
-/******************************************************************************
- * JBoss, a division of Red Hat *
- * Copyright 2006, Red Hat Middleware, LLC, and individual *
- * contributors as indicated by the @authors tag. See the *
- * copyright.txt in the distribution for a full listing of *
- * individual contributors. *
- * *
- * This is free software; you can redistribute it and/or modify it *
- * under the terms of the GNU Lesser General Public License as *
- * published by the Free Software Foundation; either version 2.1 of *
- * the License, or (at your option) any later version. *
- * *
- * This software is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
- * Lesser General Public License for more details. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with this software; if not, write to the Free *
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
- * 02110-1301 USA, or see the FSF site:
http://www.fsf.org. *
- ******************************************************************************/
-package org.jboss.portal.core.controller.handler;
-
-import org.jboss.portal.core.controller.handler.HandlerResponse;
-import org.jboss.portal.server.ServerInvocationContext;
-
-import javax.servlet.ServletException;
-import java.io.IOException;
-
-/**
- *
- * @author <a href="mailto:sshah@redhat.com">Sohil Shah</a>
- *
- */
-public class UIServerResponse extends HandlerResponse
-{
- /**
- *
- */
- private Object uiIndicator = null;
-
- /**
- *
- * @param controllerResponse
- */
- public UIServerResponse(Object uiIndicator)
- {
- this.uiIndicator = uiIndicator;
- }
-
-
- /**
- *
- * @return
- */
- public Object getUiIndicator()
- {
- return uiIndicator;
- }
-
-
- /**
- *
- * @param uiIndicator
- */
- public void setUiIndicator(Object uiIndicator)
- {
- this.uiIndicator = uiIndicator;
- }
-
- /**
- * Leave this empty.....The UIServer will take care of sending the response
- *
- *
- * @param ctx
- * @throws IOException
- * @throws ServletException
- */
- public void sendResponse(ServerInvocationContext ctx) throws IOException,
ServletException
- {
- }
-}
Modified:
trunk/core/src/main/org/jboss/portal/core/model/portal/PortalObjectResponseHandler.java
===================================================================
---
trunk/core/src/main/org/jboss/portal/core/model/portal/PortalObjectResponseHandler.java 2007-07-05
23:41:21 UTC (rev 7677)
+++
trunk/core/src/main/org/jboss/portal/core/model/portal/PortalObjectResponseHandler.java 2007-07-06
10:20:08 UTC (rev 7678)
@@ -41,9 +41,6 @@
import org.jboss.portal.web.ServletContextDispatcher;
import org.jboss.portal.common.util.MarkupInfo;
-import org.jboss.portal.core.controller.handler.UIServerResponse;
-import org.jboss.portal.uiserver.UIServerPageRendition;
-
import javax.servlet.ServletException;
import java.io.IOException;
@@ -79,11 +76,17 @@
//
if (resp instanceof PageRendition)
{
- PageRendition pageRendition = (PageRendition)resp;
- UIServerPageRendition uiServerPageRendition = new UIServerPageRendition(
-
pageRendition.getLayout(),pageRendition.getTheme(),pageRendition.getPageResult(),pageRendition.getPageService()
- );
- return new UIServerResponse(uiServerPageRendition);
+ final PageRendition rendition = (PageRendition)resp;
+ final ServerInvocation invocation =
controllerContext.getServerInvocation();
+ return new HTTPResponse()
+ {
+ public void sendResponse(ServerInvocationContext ctx) throws
IOException, ServletException
+ {
+ ServletContextDispatcher dispatcher = new
ServletContextDispatcher(invocation.getServerContext().getClientRequest(),
invocation.getServerContext().getClientResponse(),
invocation.getRequest().getServer().getServletContainerContext());
+ MarkupInfo markupInfo =
(MarkupInfo)invocation.getResponse().getContentInfo();
+ rendition.render(markupInfo, dispatcher);
+ }
+ };
}
else
{
Modified: trunk/core/src/main/org/jboss/portal/core/theme/PageRendition.java
===================================================================
--- trunk/core/src/main/org/jboss/portal/core/theme/PageRendition.java 2007-07-05 23:41:21
UTC (rev 7677)
+++ trunk/core/src/main/org/jboss/portal/core/theme/PageRendition.java 2007-07-06 10:20:08
UTC (rev 7678)
@@ -68,7 +68,7 @@
this.pageResult = markupResult;
this.pageService = pageService;
}
-
+
/** Performs the page rendition. */
public void render(MarkupInfo markupInfo, ServletContextDispatcher dispatcher) throws
IOException, ServletException
{
@@ -102,19 +102,4 @@
{
return pageResult;
}
-
- public PortalLayout getLayout()
- {
- return this.layout;
- }
-
- public PortalTheme getTheme()
- {
- return this.theme;
- }
-
- public PageService getPageService()
- {
- return this.pageService;
- }
}
Modified: trunk/core/src/resources/portal-core-sar/META-INF/jboss-service.xml
===================================================================
--- trunk/core/src/resources/portal-core-sar/META-INF/jboss-service.xml 2007-07-05
23:41:21 UTC (rev 7677)
+++ trunk/core/src/resources/portal-core-sar/META-INF/jboss-service.xml 2007-07-06
10:20:08 UTC (rev 7678)
@@ -1090,9 +1090,6 @@
<depends
optional-attribute-name="PageControlPolicy"
proxy-type="attribute">portal:service=ControlPolicy,type=Page</depends>
- <depends
- optional-attribute-name="UIServer"
- proxy-type="attribute">portal:service=UIServer</depends>
</mbean>
<!-- The controller factory -->
@@ -1289,24 +1286,5 @@
optional-attribute-name="JBossAppEntityResolver"
proxy-type="attribute">portal:service=EntityResolver</depends>
</mbean>
-
- <!-- Using the new UIServer -->
- <mbean
- code="org.jboss.portal.uiserver.UIServerImpl"
- name="portal:service=UIServer"
- xmbean-dd=""
- xmbean-code="org.jboss.portal.jems.as.system.JBossServiceModelMBean">
- <xmbean/>
- <!--
- A map of some UIIndicator object provided from the Controller Layer to the
corresponding Client Side
- UI technology which will be used to handle the UI related tasks
- -->
- <attribute name="ClientUiConfig">
- <properties>
- <entry
key="org.jboss.portal.uiserver.UIServerPageRendition">org.jboss.portal.uiserver.ClassicUI</entry>
- <entry
key="org.jboss.portal.theme.impl.render.dynamic.response.UpdatePageStateResponse">org.jboss.portal.uiserver.PartialRefreshUI</entry>
- <entry
key="org.jboss.portal.theme.impl.render.dynamic.response.UpdatePageLocationResponse">org.jboss.portal.uiserver.PartialRefreshUI</entry>
- </properties>
- </attribute>
- </mbean>
+
</server>
Modified: trunk/widget/build.xml
===================================================================
--- trunk/widget/build.xml 2007-07-05 23:41:21 UTC (rev 7677)
+++ trunk/widget/build.xml 2007-07-06 10:20:08 UTC (rev 7678)
@@ -250,17 +250,19 @@
<target name="tests" depends="init, package-tests">
<property name="proto-libs"
value="${project.root}/proto-libs"/>
<execute-tests>
+
<!--
-
<x-sysproperty>
<jvmarg value="-Xdebug"/>
<jvmarg
value="-Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y"/>
</x-sysproperty>
-->
-
<x-test>
+<!--
<test todir="${test.reports}"
name="org.jboss.portal.test.widget.google.PreferencesTestCase"/>
+-->
+ <test todir="${test.reports}"
name="org.jboss.portal.test.widget.google.QueryResultParserTestCase"/>
</x-test>
<x-classpath>
<pathelement location="${build.lib}/widget-lib.jar"/>
Modified:
trunk/widget/src/main/org/jboss/portal/test/widget/google/PreferencesTestCase.java
===================================================================
---
trunk/widget/src/main/org/jboss/portal/test/widget/google/PreferencesTestCase.java 2007-07-05
23:41:21 UTC (rev 7677)
+++
trunk/widget/src/main/org/jboss/portal/test/widget/google/PreferencesTestCase.java 2007-07-06
10:20:08 UTC (rev 7678)
@@ -23,10 +23,10 @@
package org.jboss.portal.test.widget.google;
import junit.framework.TestCase;
-import org.jboss.portal.widget.google.provider.GGWidgetBuilder;
-import org.jboss.portal.widget.google.GGWidget;
+import org.jboss.portal.widget.google.provider.GGWidgetInfoBuilder;
import org.jboss.portal.widget.google.GGPreferencesInfo;
import org.jboss.portal.widget.google.GGPreferenceInfo;
+import org.jboss.portal.widget.google.GGWidgetInfo;
import org.jboss.portal.widget.google.type.DataType;
import org.jboss.portal.widget.google.type.EnumType;
import org.jboss.portal.common.io.IOTools;
@@ -47,12 +47,12 @@
ClassLoader tcl = Thread.currentThread().getContextClassLoader();
URL url = tcl.getResource("google/gadget1.xml");
- GGWidgetBuilder ggwb = constructBuilder(url);
- GGWidget ggw = ggwb.create();
+ GGWidgetInfoBuilder ggwb = constructBuilder(url);
+ GGWidgetInfo ggw = ggwb.create();
assertNotNull(ggw);
- assertEquals("TestTitle",ggw.getTitle().getDefaultString());
- assertEquals("TestDescription",ggw.getDescription().getDefaultString());
+// assertEquals("TestTitle",ggw.getTitle().getDefaultString());
+//
assertEquals("TestDescription",ggw.getDescription().getDefaultString());
}
public void testUserPrefs() throws Exception
@@ -60,12 +60,12 @@
ClassLoader tcl = Thread.currentThread().getContextClassLoader();
URL url = tcl.getResource("google/gadget2.xml");
- GGWidgetBuilder ggwb = constructBuilder(url);
- GGWidget ggw = ggwb.create();
+ GGWidgetInfoBuilder ggwb = constructBuilder(url);
+ GGWidgetInfo ggw = ggwb.create();
assertNotNull(ggw);
- GGPreferencesInfo prefs = ggw.getPreferencesInfo();
+ GGPreferencesInfo prefs = ggw.getPreferences();
// String
GGPreferenceInfo pi = prefs.getPreference("testString");
@@ -138,9 +138,9 @@
}
- public GGWidgetBuilder constructBuilder(URL url) throws Exception
+ public GGWidgetInfoBuilder constructBuilder(URL url) throws Exception
{
- return new GGWidgetBuilder(url)
+ return new GGWidgetInfoBuilder(url)
{
protected byte[] obtainWidget(URL url) throws Exception
{
Added:
trunk/widget/src/main/org/jboss/portal/test/widget/google/QueryResultParserTestCase.java
===================================================================
---
trunk/widget/src/main/org/jboss/portal/test/widget/google/QueryResultParserTestCase.java
(rev 0)
+++
trunk/widget/src/main/org/jboss/portal/test/widget/google/QueryResultParserTestCase.java 2007-07-06
10:20:08 UTC (rev 7678)
@@ -0,0 +1,64 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual *
+ * contributors as indicated by the @authors tag. See the *
+ * copyright.txt in the distribution for a full listing of *
+ * individual contributors. *
+ * *
+ * This is free software; you can redistribute it and/or modify it *
+ * under the terms of the GNU Lesser General Public License as *
+ * published by the Free Software Foundation; either version 2.1 of *
+ * the License, or (at your option) any later version. *
+ * *
+ * This software is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this software; if not, write to the Free *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org. *
+ ******************************************************************************/
+package org.jboss.portal.test.widget.google;
+
+import junit.framework.TestCase;
+
+import java.net.URL;
+import java.net.MalformedURLException;
+import java.util.Iterator;
+
+import org.jboss.portal.widget.google.provider.GGQueryResultBuilder;
+import org.jboss.portal.widget.google.provider.GGQueryResult;
+import org.jboss.portal.widget.google.provider.GGQueryResultEntry;
+
+/**
+ * @author <a href="mailto:julien@jboss.org">Julien Viet</a>
+ * @version $Revision: 1.1 $
+ */
+public class QueryResultParserTestCase extends TestCase
+{
+
+ public void testA() throws MalformedURLException
+ {
+ ClassLoader tcl = Thread.currentThread().getContextClassLoader();
+ URL url = tcl.getResource("google/queryresult1.xml");
+ assertNotNull(url);
+ GGQueryResultBuilder builder = new GGQueryResultBuilder(url);
+ GGQueryResult result = builder.build();
+ assertNotNull(result);
+ Iterator i = result.entries();
+ assertNotNull(i);
+ assertTrue(i.hasNext());
+ GGQueryResultEntry entry = (GGQueryResultEntry)i.next();
+ assertNotNull(entry);
+ assertEquals("Date & Time", entry.getTitle());
+ assertEquals("Add a clock to your page. Click edit to change it to the color
of your choice.", entry.getDescription());
+
assertEquals("http://www.google.com/ig/modules/datetime.png",
entry.getScreenshot());
+
assertEquals("http://www.google.com/ig/modules/datetime-thm.png",
entry.getThumbnail());
+ assertEquals("matt.feedback+datetime(a)gmail.com", entry.getAuthor());
+ assertEquals(320, entry.getWidth());
+ assertEquals(136, entry.getHeight());
+ assertEquals(new
URL("http://www.google.com/ig/modules/datetime.xml"),
entry.getURL());
+ }
+}
Modified: trunk/widget/src/main/org/jboss/portal/widget/google/GGWidget.java
===================================================================
--- trunk/widget/src/main/org/jboss/portal/widget/google/GGWidget.java 2007-07-05 23:41:21
UTC (rev 7677)
+++ trunk/widget/src/main/org/jboss/portal/widget/google/GGWidget.java 2007-07-06 10:20:08
UTC (rev 7678)
@@ -26,12 +26,18 @@
import org.jboss.portal.common.util.UUIDGenerator;
import org.jboss.portal.common.text.FastURLEncoder;
import org.jboss.portal.widget.Widget;
+import org.jboss.portal.widget.google.provider.GGWidgetInfoBuilder;
import java.util.Iterator;
import java.util.Map;
+import java.net.URL;
+import edu.emory.mathcs.backport.java.util.concurrent.FutureTask;
+import edu.emory.mathcs.backport.java.util.concurrent.Callable;
+
/**
- * A Google Gadget widget For more details please see the <a
href="http://www.google.com/apis/gadgets/reference.html">API Developer
Guide</a>.
+ * A Google Gadget widget.
+ * For more details please see the <a
href="http://www.google.com/apis/gadgets/reference.html">API Developer
Guide</a>.
*
* @todo
* - Resource bundles implementation
@@ -46,10 +52,10 @@
private static final UUIDGenerator generator = new UUIDGenerator();
/** . */
- private final String url;
+ private final URL url;
/** . */
- private final GGPreferencesInfo prefsInfo;
+ private final String id;
/** . */
private final LocalizedString title;
@@ -63,29 +69,60 @@
/** . */
private final int height;
- public GGWidget(String url,
- GGPreferencesInfo prefsInfo,
- LocalizedString title,
- LocalizedString description,
- int width,
- int height)
+ /** . */
+ private final FutureTask future;
+
+ public GGWidget(URL url,
+ LocalizedString title,
+ LocalizedString description,
+ int width,
+ int height)
{
+ Callable callable = new Callable()
+ {
+ public Object call() throws Exception
+ {
+ try
+ {
+ GGWidgetInfoBuilder builder = new GGWidgetInfoBuilder(GGWidget.this.url);
+ return builder.create();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ return null;
+ }
+ }
+ };
+
+ //
+ this.id = url.toString();
this.url = url;
- this.prefsInfo = prefsInfo;
this.title = title;
this.description = description;
this.width = width;
this.height = height;
+ this.future = new FutureTask(callable);
}
public String getId()
{
- return url;
+ return id;
}
- public GGPreferencesInfo getPreferencesInfo()
+ public GGWidgetInfo getInfo()
{
- return prefsInfo;
+ try
+ {
+ return (GGWidgetInfo)future.get();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+
+ //
+ return null;
+ }
}
public LocalizedString getTitle()
@@ -111,38 +148,49 @@
tmp.append("&border=%23ffffff%7C3px%2C1px+none+%23999999"); //
"&border=%23ffffff%7C3px%2C1px+solid+%23999999"
tmp.append("&output=js");
- // Append default values
- for (Iterator i = prefsInfo.getPreferences().iterator();i.hasNext();)
+ //
+ GGWidgetInfo info = getInfo();
+
+ //
+ if (info != null)
{
- GGPreferenceInfo prefInfo = (GGPreferenceInfo)i.next();
- String prefName = prefInfo.getName();
- String[] values = (String[])parameters.get(prefName);
- String value = values != null ? values[0] : prefInfo.getDefaultValue();
- if (value != null)
+ GGPreferencesInfo prefsInfo = info.getPreferences();
+
+ // Append default values
+ for (Iterator i = prefsInfo.getPreferences().iterator();i.hasNext();)
{
-
tmp.append("&up_").append(FastURLEncoder.DEFAULT_ENCODER.encode(prefName)).append("=").append(FastURLEncoder.DEFAULT_ENCODER.encode(value));
+ GGPreferenceInfo prefInfo = (GGPreferenceInfo)i.next();
+ String prefName = prefInfo.getName();
+ String[] values = (String[])parameters.get(prefName);
+ String value = values != null ? values[0] : prefInfo.getDefaultValue();
+ if (value != null)
+ {
+
tmp.append("&up_").append(FastURLEncoder.DEFAULT_ENCODER.encode(prefName)).append("=").append(FastURLEncoder.DEFAULT_ENCODER.encode(value));
+ }
}
- }
- //
- String clipper = "" +
- "(function(){\n" +
- "var a = document.getElementById('" + id + "');\n"
+
- "var b = a.childNodes.item(2);\n" + // table
- "var c = b.childNodes.item(0);\n" + // tbody
- "var d = c.childNodes.item(0);\n" + // tr
- "var e = c.childNodes.item(1);\n" + // tr
- "var f = c.childNodes.item(3);\n" + // tr
- "c.removeChild(d);\n" +
- "c.removeChild(e);\n" +
- "c.removeChild(f);\n" +
- "})();";
+ //
+ String clipper = "" +
+ "(function(){\n" +
+ "var a = document.getElementById('" + id +
"');\n" +
+ "var b = a.childNodes.item(2);\n" + // table
+ "var c = b.childNodes.item(0);\n" + // tbody
+ "var d = c.childNodes.item(0);\n" + // tr
+ "var e = c.childNodes.item(1);\n" + // tr
+ "var f = c.childNodes.item(3);\n" + // tr
+ "c.removeChild(d);\n" +
+ "c.removeChild(e);\n" +
+ "c.removeChild(f);\n" +
+ "})();";
- return "<div id=\"" + id + "\">\n" +
- "<script src=\"" + tmp +
"\"></script>\n" +
- "<script>" + clipper + "</script>\n" +
- "</div>\n";
+ return "<div id=\"" + id + "\">\n" +
+ "<script src=\"" + tmp +
"\"></script>\n" +
+ "<script>" + clipper + "</script>\n" +
+ "</div>\n";
+ }
+ else
+ {
+ return "Error";
+ }
}
-
-
}
Added: trunk/widget/src/main/org/jboss/portal/widget/google/GGWidgetInfo.java
===================================================================
--- trunk/widget/src/main/org/jboss/portal/widget/google/GGWidgetInfo.java
(rev 0)
+++ trunk/widget/src/main/org/jboss/portal/widget/google/GGWidgetInfo.java 2007-07-06
10:20:08 UTC (rev 7678)
@@ -0,0 +1,46 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual *
+ * contributors as indicated by the @authors tag. See the *
+ * copyright.txt in the distribution for a full listing of *
+ * individual contributors. *
+ * *
+ * This is free software; you can redistribute it and/or modify it *
+ * under the terms of the GNU Lesser General Public License as *
+ * published by the Free Software Foundation; either version 2.1 of *
+ * the License, or (at your option) any later version. *
+ * *
+ * This software is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this software; if not, write to the Free *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org. *
+ ******************************************************************************/
+package org.jboss.portal.widget.google;
+
+/**
+ * Meta data retrieved from the XML file.
+ *
+ * @author <a href="mailto:julien@jboss.org">Julien Viet</a>
+ * @version $Revision: 1.1 $
+ */
+public class GGWidgetInfo
+{
+
+ /** . */
+ private final GGPreferencesInfo preferences;
+
+ public GGWidgetInfo(GGPreferencesInfo preferences)
+ {
+ this.preferences = preferences;
+ }
+
+ public GGPreferencesInfo getPreferences()
+ {
+ return preferences;
+ }
+}
Modified: trunk/widget/src/main/org/jboss/portal/widget/google/provider/GGProvider.java
===================================================================
---
trunk/widget/src/main/org/jboss/portal/widget/google/provider/GGProvider.java 2007-07-05
23:41:21 UTC (rev 7677)
+++
trunk/widget/src/main/org/jboss/portal/widget/google/provider/GGProvider.java 2007-07-06
10:20:08 UTC (rev 7678)
@@ -172,7 +172,7 @@
}
catch (Exception e)
{
- e.printStackTrace(); //To change body of catch statement use File | Settings
| File Templates.
+ e.printStackTrace();
return null;
}
}
@@ -181,7 +181,7 @@
{
try
{
- GGWidgetBuilder builder = new GGWidgetBuilder(url);
+ GGWidgetInfoBuilder builder = new GGWidgetInfoBuilder(url);
return builder.create();
}
catch (Exception e)
@@ -221,14 +221,23 @@
catch (Exception e)
{
e.printStackTrace(); //To change body of catch statement use File | Settings
| File Templates.
- return new GGQueryResult(query, Collections.EMPTY_LIST);
+ return new GGQueryResult(Collections.EMPTY_LIST);
}
}
public Object call()
{
- GGQueryResultBuilder builder = new GGQueryResultBuilder(query);
- return builder.build(context);
+ try
+ {
+ return new GGQueryResultBuilder(query).build();
+ }
+ catch (MalformedURLException e)
+ {
+ e.printStackTrace();
+
+ // todo
+ return null;
+ }
}
}
}
Modified: trunk/widget/src/main/org/jboss/portal/widget/google/provider/GGQuery.java
===================================================================
--- trunk/widget/src/main/org/jboss/portal/widget/google/provider/GGQuery.java 2007-07-05
23:41:21 UTC (rev 7677)
+++ trunk/widget/src/main/org/jboss/portal/widget/google/provider/GGQuery.java 2007-07-06
10:20:08 UTC (rev 7678)
@@ -22,6 +22,9 @@
******************************************************************************/
package org.jboss.portal.widget.google.provider;
+import java.net.URL;
+import java.net.MalformedURLException;
+
/**
* @author <a href="mailto:julien@jboss.org">Julien Viet</a>
* @version $Revision: 1.1 $
@@ -109,4 +112,26 @@
{
return hashCode;
}
+
+ URL buildQueryURL() throws MalformedURLException
+ {
+ StringBuffer buffer = new
StringBuffer("http://www.google.com/ig/directory?synd=open&outpu...;
+ if (start > 0)
+ {
+ buffer.append("&start=").append(start);
+ }
+ if (num > 0)
+ {
+ buffer.append("&num=").append(num);
+ }
+ if (cat != null)
+ {
+ buffer.append("&cat=").append(cat);
+ }
+ if (q != null)
+ {
+ buffer.append("&q=").append(q);
+ }
+ return new URL(buffer.toString());
+ }
}
Modified:
trunk/widget/src/main/org/jboss/portal/widget/google/provider/GGQueryResult.java
===================================================================
---
trunk/widget/src/main/org/jboss/portal/widget/google/provider/GGQueryResult.java 2007-07-05
23:41:21 UTC (rev 7677)
+++
trunk/widget/src/main/org/jboss/portal/widget/google/provider/GGQueryResult.java 2007-07-06
10:20:08 UTC (rev 7678)
@@ -22,11 +22,9 @@
******************************************************************************/
package org.jboss.portal.widget.google.provider;
-import org.jboss.portal.widget.google.GGWidget;
-
import java.util.List;
import java.util.Iterator;
-import java.util.NoSuchElementException;
+import java.util.ArrayList;
/**
* @author <a href="mailto:julien@jboss.org">Julien Viet</a>
@@ -36,78 +34,21 @@
{
/** . */
- private final GGQuery query;
+ private List entries;
- /** . */
- private List widgetEntries;
-
- GGQueryResult(GGQuery query, List widgetEntries)
+ GGQueryResult(List entries)
{
- if (query == null)
+ if (entries == null)
{
throw new IllegalArgumentException();
}
- if (widgetEntries == null)
- {
- throw new IllegalArgumentException();
- }
- this.query = query;
- this.widgetEntries = widgetEntries;
- }
- public GGQuery getQuery()
- {
- return query;
+ //
+ this.entries = entries;
}
- public Iterator getWidgetIterator()
+ public Iterator entries()
{
- return new WidgetIterator();
+ return entries.iterator();
}
-
- private class WidgetIterator implements Iterator
- {
-
- Iterator iterator = widgetEntries.iterator();
-
- GGWidget next;
-
- public boolean hasNext()
- {
- if (next == null)
- {
- findNext();
- }
- return next != null;
- }
-
- public Object next()
- {
- if (next == null)
- {
- findNext();
- }
- if (next == null)
- {
- throw new NoSuchElementException();
- }
- GGWidget tmp = next;
- next = null;
- return tmp;
- }
-
- void findNext()
- {
- while (iterator.hasNext() && next == null)
- {
- GGProvider.GGWidgetEntry entry = (GGProvider.GGWidgetEntry)iterator.next();
- next = entry.getWidget();
- }
- }
-
- public void remove()
- {
- throw new UnsupportedOperationException();
- }
- }
}
Modified:
trunk/widget/src/main/org/jboss/portal/widget/google/provider/GGQueryResultBuilder.java
===================================================================
---
trunk/widget/src/main/org/jboss/portal/widget/google/provider/GGQueryResultBuilder.java 2007-07-05
23:41:21 UTC (rev 7677)
+++
trunk/widget/src/main/org/jboss/portal/widget/google/provider/GGQueryResultBuilder.java 2007-07-06
10:20:08 UTC (rev 7678)
@@ -23,156 +23,135 @@
package org.jboss.portal.widget.google.provider;
import org.jboss.portal.common.net.URLTools;
+import org.jboss.portal.common.xml.XMLTools;
+import org.jboss.portal.common.io.IOTools;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
-import javax.swing.text.html.HTMLEditorKit;
-import javax.swing.text.html.HTML;
-import javax.swing.text.MutableAttributeSet;
+import javax.xml.parsers.DocumentBuilderFactory;
import java.net.URL;
import java.net.MalformedURLException;
-import java.util.LinkedHashSet;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.StringTokenizer;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Collections;
import java.util.List;
-import java.io.InputStreamReader;
import java.io.ByteArrayInputStream;
+import java.io.InputStream;
/**
+ * @todo make the timeouts parameterizable
+ *
* @author <a href="mailto:julien@jboss.org">Julien Viet</a>
* @version $Revision: 1.1 $
*/
-class GGQueryResultBuilder
+public class GGQueryResultBuilder
{
/** . */
- private final GGQuery query;
+ public static final String GHAPI_URI =
"http://www.google.com/apis/homepage";
- public GGQueryResultBuilder(GGQuery query)
+ /** . */
+ private final URL url;
+
+ public GGQueryResultBuilder(GGQuery query) throws MalformedURLException
{
if (query == null)
{
throw new IllegalArgumentException();
}
- this.query = query;
+ this.url = query.buildQueryURL();
}
- private URL getURLQuery() throws MalformedURLException
+
+ public GGQueryResultBuilder(URL url)
{
- StringBuffer buffer = new
StringBuffer("http://www.google.com/ig/directory?synd=open");
- if (query.getStart() > 0)
+ if (url == null)
{
- buffer.append("&start=").append(query.getStart());
+ throw new IllegalArgumentException();
}
- if (query.getNum() > 0)
- {
- buffer.append("&num=").append(query.getNum());
- }
- if (query.getCat() != null)
- {
- buffer.append("&cat=").append(query.getCat());
- }
- if (query.getQ() != null)
- {
- buffer.append("&q=").append(query.getQ());
- }
- return new URL(buffer.toString());
+ this.url = url;
}
- public GGQueryResult build(GGProvider.Context context)
+ public GGQueryResult build()
{
try
{
- // Find widget URLs
- URL url = getURLQuery() ;
-
// Read fully the URL content first
- // log.info("Retrieving " + url);
- byte[] bytes = URLTools.performGET(url, 5000, 5000);
+ byte[] bytes;
+ if ("http".equals(url.getProtocol()))
+ {
+ bytes = URLTools.performGET(url, 5000, 5000);
+ }
+ else
+ {
+ InputStream in = url.openStream();
+ try
+ {
+ bytes = IOTools.getBytes(in);
+ }
+ finally
+ {
+ IOTools.safeClose(in);
+ }
+ }
+
+ //
if (bytes == null)
{
throw new Exception("Cannot retrieve " + url);
}
- // log.info("Document " + url + " has been retrieved");
//
- final LinkedHashSet urls = new LinkedHashSet();
- HTMLEditorKit.ParserCallback callback = new HTMLEditorKit.ParserCallback()
- {
- public void handleStartTag(HTML.Tag t, MutableAttributeSet attrSet, int pos)
- {
- if (t == HTML.Tag.A)
- {
- try
- {
- String href = (String)attrSet.getAttribute(HTML.Attribute.HREF);
- URL url = new URL(href);
- String query = url.getQuery();
- if (query != null)
- {
- Map params = new HashMap();
- StringTokenizer st = new StringTokenizer(query,
"&");
- while (st.hasMoreTokens())
- {
- String pair = st.nextToken();
- int separator = pair.indexOf('=');
- if (separator != -1)
- {
- String left = pair.substring(0, separator);
- String right = pair.substring(separator + 1);
- params.put(left, right);
- }
- }
+ DocumentBuilderFactory factory = XMLTools.getDocumentBuilderFactory();
+ factory.setNamespaceAware(true);
- //
- if (params.containsKey("url"))
- {
- String tmp = (String)params.get("url");
- if (tmp.endsWith(".xml"))
- {
- url = new URL(tmp);
- urls.add(url);
- }
- }
- }
- }
- catch (MalformedURLException ignore)
- {
- }
- }
- }
- };
- HTMLEditorKit.Parser parser = new ParserAccessor().getParser();
- parser.parse(new InputStreamReader(new ByteArrayInputStream(bytes),
"UTF-8"), callback, true);
+ //
+ Document doc = factory.newDocumentBuilder().parse(new
ByteArrayInputStream(bytes));
- // Now parse each
- List widgetEntries = new ArrayList(urls.size());
- for (Iterator i = urls.iterator();i.hasNext();)
+ //
+ Element rssElt = doc.getDocumentElement();
+ Element channelElt = XMLTools.getUniqueChild(rssElt, "channel",
true);
+
+ //
+ List entries = new ArrayList();
+ for (Iterator i = XMLTools.getChildrenIterator(channelElt,
"item");i.hasNext();)
{
- URL widgetURL = (URL)i.next();
- GGProvider.GGWidgetEntry entry = context.getWidgetEntry(widgetURL);
- widgetEntries.add(entry);
+ Element itemElt = (Element)i.next();
+
+ //
+ Element titleElt = XMLTools.getUniqueChild(itemElt, "title",
true);
+ Element linkElt = XMLTools.getUniqueChild(itemElt, "link", true);
+ Element descriptionElt = XMLTools.getUniqueChild(itemElt,
"description", true);
+ Element authorElt = XMLTools.getUniqueChild(itemElt, "author",
false);
+ Element screenshotElt = XMLTools.getUniqueChild(itemElt, GHAPI_URI,
"screenshot", true);
+ Element thumbnailElt = XMLTools.getUniqueChild(itemElt, GHAPI_URI,
"thumbnail", true);
+ Element widthElt = XMLTools.getUniqueChild(itemElt, GHAPI_URI,
"width", true);
+ Element heightElt = XMLTools.getUniqueChild(itemElt, GHAPI_URI,
"height", true);
+
+ //
+ String title = XMLTools.asString(titleElt);
+ URL link = new URL(XMLTools.asString(linkElt));
+ String description = XMLTools.asString(descriptionElt);
+ String screenshot = XMLTools.asString(screenshotElt);
+ String thumbnail = XMLTools.asString(thumbnailElt);
+ String author = authorElt != null ? XMLTools.asString(authorElt) :
"";
+ int width = Integer.parseInt(XMLTools.asString(widthElt));
+ int height = Integer.parseInt(XMLTools.asString(heightElt));
+
+ //
+ GGQueryResultEntry entry = new GGQueryResultEntry(link, title, description,
screenshot, thumbnail, author, width, height);
+ entries.add(entry);
}
//
- return new GGQueryResult(query, widgetEntries);
+ return new GGQueryResult(entries);
}
catch (Exception e)
{
e.printStackTrace();
}
- return new GGQueryResult(query, Collections.EMPTY_LIST);
+ //
+ return new GGQueryResult(Collections.EMPTY_LIST);
}
-
- private static class ParserAccessor extends HTMLEditorKit
- {
- public Parser getParser()
- {
- return super.getParser();
- }
- }
-
}
Added:
trunk/widget/src/main/org/jboss/portal/widget/google/provider/GGQueryResultEntry.java
===================================================================
--- trunk/widget/src/main/org/jboss/portal/widget/google/provider/GGQueryResultEntry.java
(rev 0)
+++
trunk/widget/src/main/org/jboss/portal/widget/google/provider/GGQueryResultEntry.java 2007-07-06
10:20:08 UTC (rev 7678)
@@ -0,0 +1,119 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual *
+ * contributors as indicated by the @authors tag. See the *
+ * copyright.txt in the distribution for a full listing of *
+ * individual contributors. *
+ * *
+ * This is free software; you can redistribute it and/or modify it *
+ * under the terms of the GNU Lesser General Public License as *
+ * published by the Free Software Foundation; either version 2.1 of *
+ * the License, or (at your option) any later version. *
+ * *
+ * This software is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this software; if not, write to the Free *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org. *
+ ******************************************************************************/
+package org.jboss.portal.widget.google.provider;
+
+import java.net.URL;
+
+/**
+ * @todo parse all meta data
+ *
+ * @author <a href="mailto:julien@jboss.org">Julien Viet</a>
+ * @version $Revision: 1.1 $
+ */
+public class GGQueryResultEntry
+{
+
+ /** . */
+ private final URL url;
+
+ /** . */
+ private final String title;
+
+ /** . */
+ private final String description;
+
+ /** . */
+ private final String screenshot;
+
+ /** . */
+ private final String thumbnail;
+
+ /** . */
+ private final String author;
+
+ /** . */
+ private final int width;
+
+ /** . */
+ private final int height;
+
+ public GGQueryResultEntry(
+ URL url,
+ String title,
+ String description,
+ String screenshot,
+ String thumbnail,
+ String author,
+ int width,
+ int height)
+ {
+ this.url = url;
+ this.title = title;
+ this.description = description;
+ this.screenshot = screenshot;
+ this.thumbnail = thumbnail;
+ this.author = author;
+ this.width = width;
+ this.height = height;
+ }
+
+ public URL getURL()
+ {
+ return url;
+ }
+
+ public String getTitle()
+ {
+ return title;
+ }
+
+ public String getDescription()
+ {
+ return description;
+ }
+
+ public String getScreenshot()
+ {
+ return screenshot;
+ }
+
+ public String getThumbnail()
+ {
+ return thumbnail;
+ }
+
+ public String getAuthor()
+ {
+ return author;
+ }
+
+ public int getWidth()
+ {
+ return width;
+ }
+
+ public int getHeight()
+ {
+ return height;
+ }
+}
Deleted:
trunk/widget/src/main/org/jboss/portal/widget/google/provider/GGWidgetBuilder.java
===================================================================
---
trunk/widget/src/main/org/jboss/portal/widget/google/provider/GGWidgetBuilder.java 2007-07-05
23:41:21 UTC (rev 7677)
+++
trunk/widget/src/main/org/jboss/portal/widget/google/provider/GGWidgetBuilder.java 2007-07-06
10:20:08 UTC (rev 7678)
@@ -1,208 +0,0 @@
-/******************************************************************************
- * JBoss, a division of Red Hat *
- * Copyright 2006, Red Hat Middleware, LLC, and individual *
- * contributors as indicated by the @authors tag. See the *
- * copyright.txt in the distribution for a full listing of *
- * individual contributors. *
- * *
- * This is free software; you can redistribute it and/or modify it *
- * under the terms of the GNU Lesser General Public License as *
- * published by the Free Software Foundation; either version 2.1 of *
- * the License, or (at your option) any later version. *
- * *
- * This software is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
- * Lesser General Public License for more details. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with this software; if not, write to the Free *
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
- * 02110-1301 USA, or see the FSF site:
http://www.fsf.org. *
- ******************************************************************************/
-package org.jboss.portal.widget.google.provider;
-
-import org.jboss.portal.common.xml.XMLTools;
-import org.jboss.portal.common.i18n.LocalizedString;
-import org.jboss.portal.common.net.URLTools;
-import org.jboss.portal.common.concurrent.loader.ObjectLoader;
-import org.jboss.portal.widget.google.type.DataType;
-import org.jboss.portal.widget.google.type.StringType;
-import org.jboss.portal.widget.google.type.LocationType;
-import org.jboss.portal.widget.google.type.HiddenType;
-import org.jboss.portal.widget.google.type.BoolType;
-import org.jboss.portal.widget.google.type.ListType;
-import org.jboss.portal.widget.google.type.EnumType;
-import org.jboss.portal.widget.google.GGWidget;
-import org.jboss.portal.widget.google.GGPreferenceInfo;
-import org.jboss.portal.widget.google.GGPreferencesInfo;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.DocumentBuilder;
-import java.net.URL;
-import java.util.Iterator;
-import java.util.Locale;
-import java.util.Collection;
-import java.util.ArrayList;
-import java.io.ByteArrayInputStream;
-
-/**
- * @author <a href="mailto:julien@jboss.org">Julien Viet</a>
- * @version $Revision: 1.1 $
- */
-public class GGWidgetBuilder implements ObjectLoader
-{
-
- /** . */
- private final URL url;
-
- public GGWidgetBuilder(URL url)
- {
- if (url == null)
- {
- throw new IllegalArgumentException("No null URL");
- }
- this.url = url;
- }
-
- public URL getURL()
- {
- return url;
- }
-
-
- public Object load()
- {
- try
- {
- return create();
- }
- catch (Exception e)
- {
- e.printStackTrace(); //To change body of catch statement use File | Settings |
File Templates.
-
- //
- return null;
- }
- }
-
- public GGWidget create() throws Exception
- {
- DocumentBuilderFactory factory = XMLTools.getDocumentBuilderFactory();
- DocumentBuilder builder = factory.newDocumentBuilder();
- byte[] bytes = obtainWidget(url);
- if (bytes == null)
- {
- throw new Exception("Cannot retrieve document " + url);
- }
- Document doc = builder.parse(new ByteArrayInputStream(bytes));
- Element moduleElt = doc.getDocumentElement();
-
- //
- Collection tmp = null;
- Iterator userPrefsEltIterator = XMLTools.getChildrenIterator(moduleElt,
"UserPref");
- while (userPrefsEltIterator.hasNext())
- {
- Element userPref = (Element)userPrefsEltIterator.next();
- String nameAttr = userPref.getAttribute("name");
- String displayNameAttr = userPref.getAttribute("display_name");
- String urlParamAttr = userPref.getAttribute("urlparam");
- String dataTypeAttr = userPref.getAttribute("datatype");
- String requiredAttr = userPref.getAttribute("required");
- String defaultValueAttr = userPref.getAttribute("default_value");
-
- // We don't support that for now
- if (urlParamAttr.length() > 0)
- {
- throw new Exception();
- }
-
- // String is default type when not specified
- DataType dataType = StringType.getInstance();
- if (dataTypeAttr.length() > 0)
- {
- int dataTypeOrdinal = DataType.parseDataTypeLiteral(dataTypeAttr);
- switch(dataTypeOrdinal)
- {
- case DataType.HIDDEN:
- dataType = HiddenType.getInstance();
- break;
- case DataType.BOOL:
- dataType = BoolType.getInstance();
- break;
- case DataType.STRING:
- dataType = StringType.getInstance();
- break;
- case DataType.LIST:
- dataType = ListType.getInstance();
- break;
- case DataType.ENUM:
- Collection values = new ArrayList();
- for (Iterator i = XMLTools.getChildrenIterator(userPref,
"EnumValue");i.hasNext();)
- {
- Element enumValueElt = (Element)i.next();
- String valueAttr = enumValueElt.getAttribute("value");
- String displayValueAttr =
enumValueElt.getAttribute("display_value");
- EnumType.Value value = new EnumType.Value(valueAttr,
displayValueAttr.length() > 0 ? displayValueAttr : null);
- values.add(value);
- }
- dataType = new EnumType(values);
- break;
- case DataType.LOCATION:
- dataType = LocationType.getInstance();
- break;
- }
- }
-
- //
- GGPreferenceInfo prefInfo = new GGPreferenceInfo(
- nameAttr,
- dataType,
- displayNameAttr.length() > 0 ? displayNameAttr : null,
- requiredAttr.length() > 0 ? Boolean.valueOf(requiredAttr).booleanValue() :
false,
- defaultValueAttr.length() > 0 ? defaultValueAttr : null
- );
-
- //
- if (tmp == null)
- {
- tmp = new ArrayList();
- }
- tmp.add(prefInfo);
- }
- GGPreferencesInfo prefsInfo = GGPreferencesInfo.EMPTY_PREFS;
- if (tmp != null)
- {
- prefsInfo = new GGPreferencesInfo(tmp);
- }
-
- //
- Iterator modulePrefsEltIterator = XMLTools.getChildrenIterator(moduleElt,
"ModulePrefs");
- if (modulePrefsEltIterator.hasNext())
- {
- Element modulePrefsElt = (Element)modulePrefsEltIterator.next();
- String titleAttr = modulePrefsElt.getAttribute("title");
- String descriptionAttr = modulePrefsElt.getAttribute("description");
- String widthAttr = modulePrefsElt.getAttribute("width");
- String heightAttr = modulePrefsElt.getAttribute("height");
-
- //
- LocalizedString title = titleAttr != null ? new LocalizedString(titleAttr,
Locale.ENGLISH) : null;
- LocalizedString description = descriptionAttr != null ? new
LocalizedString(descriptionAttr, Locale.ENGLISH) : null;
- int width = (widthAttr != null && widthAttr.length() > 0) ?
Integer.parseInt(widthAttr) : 320;
- int height = (heightAttr != null && heightAttr.length() > 0) ?
Integer.parseInt(heightAttr) : 200;
- return new GGWidget(url.toString(), prefsInfo, title, description, width,
height);
- }
- else
- {
- throw new Exception(); // Basic for now
- }
- }
-
- protected byte[] obtainWidget(URL url) throws Exception
- {
- return URLTools.performGET(url, 5000, 5000);
- }
-}
Copied:
trunk/widget/src/main/org/jboss/portal/widget/google/provider/GGWidgetInfoBuilder.java
(from rev 7663,
trunk/widget/src/main/org/jboss/portal/widget/google/provider/GGWidgetBuilder.java)
===================================================================
---
trunk/widget/src/main/org/jboss/portal/widget/google/provider/GGWidgetInfoBuilder.java
(rev 0)
+++
trunk/widget/src/main/org/jboss/portal/widget/google/provider/GGWidgetInfoBuilder.java 2007-07-06
10:20:08 UTC (rev 7678)
@@ -0,0 +1,196 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual *
+ * contributors as indicated by the @authors tag. See the *
+ * copyright.txt in the distribution for a full listing of *
+ * individual contributors. *
+ * *
+ * This is free software; you can redistribute it and/or modify it *
+ * under the terms of the GNU Lesser General Public License as *
+ * published by the Free Software Foundation; either version 2.1 of *
+ * the License, or (at your option) any later version. *
+ * *
+ * This software is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this software; if not, write to the Free *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org. *
+ ******************************************************************************/
+package org.jboss.portal.widget.google.provider;
+
+import org.jboss.portal.common.xml.XMLTools;
+import org.jboss.portal.common.i18n.LocalizedString;
+import org.jboss.portal.common.net.URLTools;
+import org.jboss.portal.common.concurrent.loader.ObjectLoader;
+import org.jboss.portal.widget.google.type.DataType;
+import org.jboss.portal.widget.google.type.StringType;
+import org.jboss.portal.widget.google.type.LocationType;
+import org.jboss.portal.widget.google.type.HiddenType;
+import org.jboss.portal.widget.google.type.BoolType;
+import org.jboss.portal.widget.google.type.ListType;
+import org.jboss.portal.widget.google.type.EnumType;
+import org.jboss.portal.widget.google.GGWidget;
+import org.jboss.portal.widget.google.GGPreferenceInfo;
+import org.jboss.portal.widget.google.GGPreferencesInfo;
+import org.jboss.portal.widget.google.GGWidgetInfo;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.DocumentBuilder;
+import java.net.URL;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Collection;
+import java.util.ArrayList;
+import java.io.ByteArrayInputStream;
+
+/**
+ * Build widget meta data from its URL.
+ *
+ * @author <a href="mailto:julien@jboss.org">Julien Viet</a>
+ * @version $Revision: 1.1 $
+ */
+public class GGWidgetInfoBuilder
+{
+
+ /** . */
+ private final URL url;
+
+ public GGWidgetInfoBuilder(URL url)
+ {
+ if (url == null)
+ {
+ throw new IllegalArgumentException("No null URL");
+ }
+ this.url = url;
+ }
+
+ public URL getURL()
+ {
+ return url;
+ }
+
+ public GGWidgetInfo create() throws Exception
+ {
+ DocumentBuilderFactory factory = XMLTools.getDocumentBuilderFactory();
+ DocumentBuilder builder = factory.newDocumentBuilder();
+ byte[] bytes = obtainWidget(url);
+ if (bytes == null)
+ {
+ throw new Exception("Cannot retrieve document " + url);
+ }
+ Document doc = builder.parse(new ByteArrayInputStream(bytes));
+ Element moduleElt = doc.getDocumentElement();
+
+ //
+ Collection tmp = null;
+ Iterator userPrefsEltIterator = XMLTools.getChildrenIterator(moduleElt,
"UserPref");
+ while (userPrefsEltIterator.hasNext())
+ {
+ Element userPref = (Element)userPrefsEltIterator.next();
+ String nameAttr = userPref.getAttribute("name");
+ String displayNameAttr = userPref.getAttribute("display_name");
+ String urlParamAttr = userPref.getAttribute("urlparam");
+ String dataTypeAttr = userPref.getAttribute("datatype");
+ String requiredAttr = userPref.getAttribute("required");
+ String defaultValueAttr = userPref.getAttribute("default_value");
+
+ // We don't support that for now
+ if (urlParamAttr.length() > 0)
+ {
+ throw new Exception();
+ }
+
+ // String is default type when not specified
+ DataType dataType = StringType.getInstance();
+ if (dataTypeAttr.length() > 0)
+ {
+ int dataTypeOrdinal = DataType.parseDataTypeLiteral(dataTypeAttr);
+ switch(dataTypeOrdinal)
+ {
+ case DataType.HIDDEN:
+ dataType = HiddenType.getInstance();
+ break;
+ case DataType.BOOL:
+ dataType = BoolType.getInstance();
+ break;
+ case DataType.STRING:
+ dataType = StringType.getInstance();
+ break;
+ case DataType.LIST:
+ dataType = ListType.getInstance();
+ break;
+ case DataType.ENUM:
+ Collection values = new ArrayList();
+ for (Iterator i = XMLTools.getChildrenIterator(userPref,
"EnumValue");i.hasNext();)
+ {
+ Element enumValueElt = (Element)i.next();
+ String valueAttr = enumValueElt.getAttribute("value");
+ String displayValueAttr =
enumValueElt.getAttribute("display_value");
+ EnumType.Value value = new EnumType.Value(valueAttr,
displayValueAttr.length() > 0 ? displayValueAttr : null);
+ values.add(value);
+ }
+ dataType = new EnumType(values);
+ break;
+ case DataType.LOCATION:
+ dataType = LocationType.getInstance();
+ break;
+ }
+ }
+
+ //
+ GGPreferenceInfo prefInfo = new GGPreferenceInfo(
+ nameAttr,
+ dataType,
+ displayNameAttr.length() > 0 ? displayNameAttr : null,
+ requiredAttr.length() > 0 ? Boolean.valueOf(requiredAttr).booleanValue() :
false,
+ defaultValueAttr.length() > 0 ? defaultValueAttr : null
+ );
+
+ //
+ if (tmp == null)
+ {
+ tmp = new ArrayList();
+ }
+ tmp.add(prefInfo);
+ }
+ GGPreferencesInfo prefsInfo = GGPreferencesInfo.EMPTY_PREFS;
+ if (tmp != null)
+ {
+ prefsInfo = new GGPreferencesInfo(tmp);
+ }
+
+ //
+ return new GGWidgetInfo(prefsInfo);
+// Iterator modulePrefsEltIterator = XMLTools.getChildrenIterator(moduleElt,
"ModulePrefs");
+// if (modulePrefsEltIterator.hasNext())
+// {
+// Element modulePrefsElt = (Element)modulePrefsEltIterator.next();
+// String titleAttr = modulePrefsElt.getAttribute("title");
+// String descriptionAttr =
modulePrefsElt.getAttribute("description");
+// String widthAttr = modulePrefsElt.getAttribute("width");
+// String heightAttr = modulePrefsElt.getAttribute("height");
+//
+// //
+// LocalizedString title = titleAttr != null ? new LocalizedString(titleAttr,
Locale.ENGLISH) : null;
+// LocalizedString description = descriptionAttr != null ? new
LocalizedString(descriptionAttr, Locale.ENGLISH) : null;
+// int width = (widthAttr != null && widthAttr.length() > 0) ?
Integer.parseInt(widthAttr) : 320;
+// int height = (heightAttr != null && heightAttr.length() > 0) ?
Integer.parseInt(heightAttr) : 200;
+// return new GGWidget(url.toString(), prefsInfo, title, description, width,
height);
+// }
+// else
+// {
+// throw new Exception(); // Basic for now
+// }
+ }
+
+ protected byte[] obtainWidget(URL url) throws Exception
+ {
+ return URLTools.performGET(url, 5000, 5000);
+ }
+}
Added: trunk/widget/src/resources/test/google/queryresult1.xml
===================================================================
--- trunk/widget/src/resources/test/google/queryresult1.xml (rev
0)
+++ trunk/widget/src/resources/test/google/queryresult1.xml 2007-07-06 10:20:08 UTC (rev
7678)
@@ -0,0 +1,429 @@
+<rss version="2.0"
+xmlns="http://backend.userland.com/rss2"
+xmlns:ghapi="http://www.google.com/apis/homepage">
+<channel>
+<title>Homepage Content</title>
+<link>http://www.google.com/ig/</link>
+<image>http://www.google.com/ig/images/igoogle_logo_sm.gif</image>
+<description>Homepage Content search results.</description>
+<language>en</language>
+<copyright>Copyright 2007 and onwards Google, Inc.</copyright>
+<!-- number of items total, the actual items are affected by pagination
--><ghapi:num_items>9939</ghapi:num_items>
+<ghapi:search_example>e.g. calendar, Dilbert, Washington
Post</ghapi:search_example>
+<ghapi:weekly_pageviews_info>Gadget pageview statistics are approximate only-- for
precise statistics, we recommend the use of Google Analytics inside your gadgets. Gadget
pageviews represent the actual number of times that the gadget was rendered, including
Google Personalized Homepage, Google Pages, Google Desktop and across thousands of
independent pages around the web.</ghapi:weekly_pageviews_info>
+<item>
+<title>Date & Time</title>
+<link>http://www.google.com/ig/modules/datetime.xml</link>
+<guid>http://www.google.com/ig/modules/datetime.xml</guid>
+<description>Add a clock to your page. Click edit to change it to the color of
your choice.</description>
+<ghapi:screenshot>http://www.google.com/ig/modules/datetime.png</ghapi:screenshot>
+<ghapi:thumbnail>http://www.google.com/ig/modules/datetime-thm.png</ghapi:thumbnail>
+<ghapi:category>tools</ghapi:category>
+<author>matt.feedback+datetime(a)gmail.com</author>
+<ghapi:author_name>Matt M.</ghapi:author_name>
+<ghapi:author_location>Mountain View, CA</ghapi:author_location>
+<ghapi:author_affiliation>Google Inc.</ghapi:author_affiliation>
+<ghapi:type>ghapi</ghapi:type>
+<ghapi:hosted>true</ghapi:hosted>
+<ghapi:width>320</ghapi:width>
+<ghapi:height>136</ghapi:height>
+<ghapi:num_userprefs>1</ghapi:num_userprefs>
+<ghapi:weekly_pageviews>175740286</ghapi:weekly_pageviews></item><item>
+<title>Search YouTube</title>
+<link>http://throttled.org/googlegadgets/youtubesearch.xml</link>
+<guid>http://throttled.org/googlegadgets/youtubesearch.xml</guid>
+<description>A search module, which searches YouTube by tags.</description>
+<ghapi:screenshot>http://www.google.com/ig/cache/28/a3/28a39282258f1ba32b6f6468ae6d12bc.png</ghapi:screenshot>
+<ghapi:thumbnail>http://www.google.com/ig/cache/28/a3/28a39282258f1ba32b6f6468ae6d12bc-thm.png</ghapi:thumbnail>
+<ghapi:category>tools</ghapi:category>
+<ghapi:category2>funandgames</ghapi:category2>
+<author>ewilliams1(a)gmail.com</author>
+<ghapi:author_name>Eddie Williams</ghapi:author_name>
+<ghapi:author_location>Arizona</ghapi:author_location>
+<ghapi:author_affiliation>eddiewilliams.org</ghapi:author_affiliation>
+<ghapi:author_photo>/ig/cache/28/a3/28a39282258f1ba32b6f6468ae6d12bc-author.png</ghapi:author_photo>
+<ghapi:type>ghapi</ghapi:type>
+<ghapi:hosted>false</ghapi:hosted>
+<ghapi:width>320</ghapi:width>
+<ghapi:height>200</ghapi:height>
+<ghapi:num_userprefs>0</ghapi:num_userprefs>
+<ghapi:weekly_pageviews>11928552</ghapi:weekly_pageviews></item><item>
+<title>PacMan v2.4</title>
+<link>http://www.schulz.dk/pacman.xml</link>
+<guid>http://www.schulz.dk/pacman.xml</guid>
+<description>The good old Pacman game. Instructions: Use the arrow keys to guide
Pac-Man. P - Pause/unpause game Q - Quit game M - Mute/unmute sound L - Low quality
on/off</description>
+<ghapi:screenshot>http://www.google.com/ig/modules/ov/module_pacman_full.png</ghapi:screenshot>
+<ghapi:thumbnail>http://www.google.com/ig/modules/ov/module_pacman.png</ghapi:thumbnail>
+<ghapi:category>funandgames</ghapi:category>
+<author>kimusan(a)gmail.com</author>
+<ghapi:author_name>Kim Schulz.</ghapi:author_name>
+<ghapi:author_location>Aalborg, Denmark</ghapi:author_location>
+<ghapi:author_affiliation>Opensource world.</ghapi:author_affiliation>
+<ghapi:author_photo>/ig/cache/8f/2a/8f2aa11b287f5072ff77bc19e66ff78f-author.png</ghapi:author_photo>
+<ghapi:type>ghapi</ghapi:type>
+<ghapi:hosted>false</ghapi:hosted>
+<ghapi:width>320</ghapi:width>
+<ghapi:height>420</ghapi:height>
+<ghapi:num_userprefs>0</ghapi:num_userprefs>
+<ghapi:weekly_pageviews>7248983</ghapi:weekly_pageviews></item><item>
+<title>Bowling</title>
+<link>http://googlegadgets.neoteksystems.com/bowlinggadget.xml</link>
+<guid>http://googlegadgets.neoteksystems.com/bowlinggadget.xml</guid>
+<description>With a little practice you be knocking down pins like the pros with
this cool game.</description>
+<ghapi:screenshot>http://www.google.com/ig/cache/60/a2/60a251befa8f2eceb1dd877b29a7c685.png</ghapi:screenshot>
+<ghapi:thumbnail>http://www.google.com/ig/cache/60/a2/60a251befa8f2eceb1dd877b29a7c685-thm.png</ghapi:thumbnail>
+<ghapi:category>funandgames</ghapi:category>
+<author>googleGadgets(at)neoteksystems.com</author>
+<ghapi:author_name>NeoTekSystems</ghapi:author_name>
+<ghapi:author_location>Greer, SC</ghapi:author_location>
+<ghapi:author_affiliation>NeoTekSystems</ghapi:author_affiliation>
+<ghapi:type>ghapi</ghapi:type>
+<ghapi:hosted>false</ghapi:hosted>
+<ghapi:width>320</ghapi:width>
+<ghapi:height>500</ghapi:height>
+<ghapi:num_userprefs>0</ghapi:num_userprefs>
+<ghapi:weekly_pageviews>451998</ghapi:weekly_pageviews></item><item>
+<title>Fitness Tip of the Day</title>
+<link>http://phillip132.googlepages.com/fitness.xml</link>
+<guid>http://phillip132.googlepages.com/fitness.xml</guid>
+<description>Daily tips and quotes about fitness and exercise.</description>
+<ghapi:screenshot>http://www.google.com/ig/cache/c2/5d/c25dc64c96b128a50c313cb3ddf20be4.png</ghapi:screenshot>
+<ghapi:thumbnail>http://www.google.com/ig/cache/c2/5d/c25dc64c96b128a50c313cb3ddf20be4-thm.png</ghapi:thumbnail>
+<ghapi:category>lifestyle</ghapi:category>
+<ghapi:category2>communication</ghapi:category2>
+<author>phillip132(a)gmail.com</author>
+<ghapi:author_name>Phillip Olsen</ghapi:author_name>
+<ghapi:type>ghapi</ghapi:type>
+<ghapi:hosted>false</ghapi:hosted>
+<ghapi:width>320</ghapi:width>
+<ghapi:height>140</ghapi:height>
+<ghapi:num_userprefs>0</ghapi:num_userprefs>
+<ghapi:weekly_pageviews>1594201</ghapi:weekly_pageviews></item><item>
+<title>myWeather</title>
+<link>http://www.notkewl.com/myWeather/myWeather.xml</link>
+<guid>http://www.notkewl.com/myWeather/myWeather.xml</guid>
+<description>View the weather for your area! Just enter your zip code / location
code for international cities (click the gadget title to go to the page to use the
location code lookup) and choose the unit. 3 Day + Detailed forecast for each day. Enjoy
this stylish obnocktious design. Gets weather information f...</description>
+<ghapi:screenshot>http://www.google.com/ig/images/no_preview.gif</ghapi:screenshot>
+<ghapi:thumbnail>http://www.google.com/ig/images/no_image/en_ALL.gif</ghapi:thumbnail>
+<ghapi:category>tools</ghapi:category>
+<ghapi:category2>news</ghapi:category2>
+<author>info(a)notkewl.com</author>
+<ghapi:author_name>Jani Lehti</ghapi:author_name>
+<ghapi:author_location>Flower Mound, TX</ghapi:author_location>
+<ghapi:author_affiliation>None</ghapi:author_affiliation>
+<ghapi:type>ghapi</ghapi:type>
+<ghapi:hosted>false</ghapi:hosted>
+<ghapi:width>280</ghapi:width>
+<ghapi:height>250</ghapi:height>
+<ghapi:num_userprefs>2</ghapi:num_userprefs>
+<ghapi:weekly_pageviews>872154</ghapi:weekly_pageviews></item><item>
+<title>MP3 Player</title>
+<link>http://mike.s.duffy.googlepages.com/mp3player.xml</link>
+<guid>http://mike.s.duffy.googlepages.com/mp3player.xml</guid>
+<description>A simple, elegant flash MP3 player from ODEO. Use the edit menu to
enter the URL of the MP3 file you wish to listen to.</description>
+<ghapi:screenshot>http://www.google.com/ig/cache/44/13/44135cfdb83465944f63f794f875d0c0.png</ghapi:screenshot>
+<ghapi:thumbnail>http://www.google.com/ig/cache/44/13/44135cfdb83465944f63f794f875d0c0-thm.png</ghapi:thumbnail>
+<ghapi:category>funandgames</ghapi:category>
+<ghapi:category2>tools</ghapi:category2>
+<author>mike.s.duffy+gadget_feedback(a)gmail.com</author>
+<ghapi:author_name>Mike Duffy</ghapi:author_name>
+<ghapi:author_location>Davis, CA</ghapi:author_location>
+<ghapi:type>ghapi</ghapi:type>
+<ghapi:hosted>false</ghapi:hosted>
+<ghapi:width>320</ghapi:width>
+<ghapi:height>50</ghapi:height>
+<ghapi:num_userprefs>1</ghapi:num_userprefs>
+<ghapi:weekly_pageviews>159032</ghapi:weekly_pageviews></item><item>
+<title>Google Talk</title>
+<link>http://www.google.com/ig/modules/googletalk.xml</link>
+<guid>http://www.google.com/ig/modules/googletalk.xml</guid>
+<description>See your contacts and send instant messages.</description>
+<ghapi:screenshot>http://www.google.com/ig/cache/46/44/464445ab3ca9500a5558fdc7d7051365.png</ghapi:screenshot>
+<ghapi:thumbnail>http://www.google.com/ig/cache/46/44/464445ab3ca9500a5558fdc7d7051365-thm.png</ghapi:thumbnail>
+<ghapi:category>communication</ghapi:category>
+<ghapi:category2>tools</ghapi:category2>
+<ghapi:author_name>Google Talk Team</ghapi:author_name>
+<ghapi:author_location>Kirkland, WA</ghapi:author_location>
+<ghapi:author_affiliation>Google, Inc.</ghapi:author_affiliation>
+<ghapi:type>ghapi</ghapi:type>
+<ghapi:hosted>true</ghapi:hosted>
+<ghapi:width>320</ghapi:width>
+<ghapi:height>451</ghapi:height>
+<ghapi:num_userprefs>0</ghapi:num_userprefs>
+<ghapi:weekly_pageviews>3710027</ghapi:weekly_pageviews></item><item>
+<title>Mini Web</title>
+<link>http://blog.outer-court.com/homepage/miniweb.xml</link>
+<guid>http://blog.outer-court.com/homepage/miniweb.xml</guid>
+<description>Displays a mini search which results in mini websites to be read on
the personalized homepage. This module uses (or abuses) the Google Mobile search
service.</description>
+<ghapi:screenshot>http://www.google.com/ig/modules/ov/module_miniweb_full.png</ghapi:screenshot>
+<ghapi:thumbnail>http://www.google.com/ig/modules/ov/module_miniweb.png</ghapi:thumbnail>
+<ghapi:category>tools</ghapi:category>
+<author>philipp.lenssen+widget(a)gmail.com</author>
+<ghapi:author_name>Philipp Lenssen</ghapi:author_name>
+<ghapi:author_location>Stuttgart, Germany</ghapi:author_location>
+<ghapi:author_affiliation>Google Blogoscoped</ghapi:author_affiliation>
+<ghapi:type>ghapi</ghapi:type>
+<ghapi:hosted>false</ghapi:hosted>
+<ghapi:width>320</ghapi:width>
+<ghapi:height>190</ghapi:height>
+<ghapi:num_userprefs>0</ghapi:num_userprefs>
+<ghapi:weekly_pageviews>22504</ghapi:weekly_pageviews></item><item>
+<title>Google Docs & Spreadsheets</title>
+<link>http://www.google.com/ig/modules/docs.xml</link>
+<guid>http://www.google.com/ig/modules/docs.xml</guid>
+<description>View your active Google documents and
spreadsheets</description>
+<ghapi:screenshot>http://www.google.com/ig/modules/docs.png</ghapi:screenshot>
+<ghapi:thumbnail>http://www.google.com/ig/modules/docs-thm.png</ghapi:thumbnail>
+<ghapi:category>communication</ghapi:category>
+<ghapi:category2>tools</ghapi:category2>
+<author>claudiac.feedback+docs(a)gmail.com</author>
+<ghapi:author_name>Claudia C.</ghapi:author_name>
+<ghapi:author_location>Mountain View, CA</ghapi:author_location>
+<ghapi:author_affiliation>Google Inc.</ghapi:author_affiliation>
+<ghapi:type>ghapi</ghapi:type>
+<ghapi:hosted>true</ghapi:hosted>
+<ghapi:width>320</ghapi:width>
+<ghapi:height>50</ghapi:height>
+<ghapi:num_userprefs>2</ghapi:num_userprefs>
+<ghapi:weekly_pageviews>4296863</ghapi:weekly_pageviews></item><item>
+<title>Google Calendar Viewer</title>
+<link>http://ralph.feedback.googlepages.com/googlecalendarviewer.xml</link>
+<guid>http://ralph.feedback.googlepages.com/googlecalendarviewer.xml</guid>
+<description>Google Calendar Viewer</description>
+<ghapi:screenshot>http://www.google.com/ig/cache/8e/13/8e13d2ff945a0d45c66ff8665e017eab.png</ghapi:screenshot>
+<ghapi:thumbnail>http://www.google.com/ig/cache/8e/13/8e13d2ff945a0d45c66ff8665e017eab-thm.png</ghapi:thumbnail>
+<ghapi:category>tools</ghapi:category>
+<author>ralph.feedback+googlecalendarviewer(a)gmail.com</author>
+<ghapi:author_name>Alex Sherwin, Eugen Kremer, Ralph S.</ghapi:author_name>
+<ghapi:author_location>Brighton, MI</ghapi:author_location>
+<ghapi:author_affiliation>Google Inc.</ghapi:author_affiliation>
+<ghapi:type>ghapi</ghapi:type>
+<ghapi:hosted>false</ghapi:hosted>
+<ghapi:width>320</ghapi:width>
+<ghapi:height>200</ghapi:height>
+<ghapi:num_userprefs>4</ghapi:num_userprefs>
+<ghapi:weekly_pageviews>1863052</ghapi:weekly_pageviews></item><item>
+<title>World Clocks</title>
+<link>http://www.ljmsite.com/google/gadgets/worldclocks.xml</link>
+<guid>http://www.ljmsite.com/google/gadgets/worldclocks.xml</guid>
+<description>Gadget for your Google homepage or website that displays multiple
analog or digital clocks at the times in the selected time zones or countries/cities. The
clocks can be synchronized with our server to always display the correct times. This
gadget is especially useful when working with Globally Disp...</description>
+<ghapi:screenshot>http://www.google.com/ig/cache/38/24/382452f1075b88ce7e71312ce9b66329.png</ghapi:screenshot>
+<ghapi:thumbnail>http://www.google.com/ig/cache/38/24/382452f1075b88ce7e71312ce9b66329-thm.png</ghapi:thumbnail>
+<ghapi:category>tools</ghapi:category>
+<author>worldclocks_feedback(a)ljmsite.com</author>
+<ghapi:author_name>Jerome Mouton</ghapi:author_name>
+<ghapi:author_location>Huntsville, AL, USA</ghapi:author_location>
+<ghapi:author_affiliation>None</ghapi:author_affiliation>
+<ghapi:type>ghapi</ghapi:type>
+<ghapi:hosted>false</ghapi:hosted>
+<ghapi:width>320</ghapi:width>
+<ghapi:height>300</ghapi:height>
+<ghapi:num_userprefs>26</ghapi:num_userprefs>
+<ghapi:weekly_pageviews>3865626</ghapi:weekly_pageviews></item><item>
+<title>YouTube Player</title>
+<link>http://padmanijain.googlepages.com/1YTP_6.xml</link>
+<guid>http://padmanijain.googlepages.com/1YTP_6.xml</guid>
+<description>You can search, play and download YouTube videos on your
webpage.</description>
+<ghapi:screenshot>http://www.google.com/ig/cache/10/a4/10a4db9d35393ca04c34474dbae6290a.png</ghapi:screenshot>
+<ghapi:thumbnail>http://www.google.com/ig/cache/10/a4/10a4db9d35393ca04c34474dbae6290a-thm.png</ghapi:thumbnail>
+<ghapi:category>funandgames</ghapi:category>
+<ghapi:category2>tools</ghapi:category2>
+<author>vi_ja(a)hotmail.com</author>
+<ghapi:author_name>Vineet Jain</ghapi:author_name>
+<ghapi:author_location>Ottawa, ON, Canada.</ghapi:author_location>
+<ghapi:author_affiliation>Cisco Systems.</ghapi:author_affiliation>
+<ghapi:type>ghapi</ghapi:type>
+<ghapi:hosted>false</ghapi:hosted>
+<ghapi:width>220</ghapi:width>
+<ghapi:height>330</ghapi:height>
+<ghapi:num_userprefs>2</ghapi:num_userprefs>
+<ghapi:weekly_pageviews>85715</ghapi:weekly_pageviews></item><item>
+<title>Google Calendar</title>
+<link>http://www.google.com/ig/modules/calendar-for-your-site.xml</link>
+<guid>http://www.google.com/ig/modules/calendar-for-your-site.xml</guid>
+<description>Google Calendar for your site, webpage or blog</description>
+<ghapi:screenshot>http://www.google.com/ig/modules/calendar.png</ghapi:screenshot>
+<ghapi:thumbnail>http://www.google.com/ig/modules/calendar-thm.png</ghapi:thumbnail>
+<ghapi:category>communication</ghapi:category>
+<ghapi:category2>tools</ghapi:category2>
+<author>michael.feedback(a)gmail.com</author>
+<ghapi:author_name>Michael B.</ghapi:author_name>
+<ghapi:author_location>Palo Alto, CA</ghapi:author_location>
+<ghapi:author_affiliation>Google Inc.</ghapi:author_affiliation>
+<ghapi:type>ghapi</ghapi:type>
+<ghapi:hosted>true</ghapi:hosted>
+<ghapi:width>320</ghapi:width>
+<ghapi:height>450</ghapi:height>
+<ghapi:num_userprefs>19</ghapi:num_userprefs>
+<ghapi:weekly_pageviews>524170</ghapi:weekly_pageviews></item><item>
+<title>The Weather Channel</title>
+<link>http://gadgets.weather.com/services/gadgets/googlegadget/gadget.xml</link>
+<guid>http://gadgets.weather.com/services/gadgets/googlegadget/gadget.xml</guid>
+<description>The Weather Channel Google Gadget provides local weather forecasts
based upon city or US Zip Code</description>
+<ghapi:screenshot>http://www.google.com/ig/cache/da/c4/dac4011be823372e081fda0bbd81d470.png</ghapi:screenshot>
+<ghapi:thumbnail>http://www.google.com/ig/cache/da/c4/dac4011be823372e081fda0bbd81d470-thm.png</ghapi:thumbnail>
+<ghapi:category>news</ghapi:category>
+<ghapi:category2>tools</ghapi:category2>
+<author>googlegadget(a)talk2.weather.com</author>
+<ghapi:author_name>The Weather Channel</ghapi:author_name>
+<ghapi:author_affiliation>The Weather Channel
Interactive</ghapi:author_affiliation>
+<ghapi:type>ghapi</ghapi:type>
+<ghapi:hosted>false</ghapi:hosted>
+<ghapi:width>320</ghapi:width>
+<ghapi:height>380</ghapi:height>
+<ghapi:num_userprefs>0</ghapi:num_userprefs>
+<ghapi:weekly_pageviews>1129521</ghapi:weekly_pageviews></item><item>
+<title>Music Box</title>
+<link>http://widget4u.googlepages.com/gmusicbox.xml</link>
+<guid>http://widget4u.googlepages.com/gmusicbox.xml</guid>
+<description>a Music Box which you can add music</description>
+<ghapi:screenshot>http://www.google.com/ig/images/no_preview.gif</ghapi:screenshot>
+<ghapi:thumbnail>http://www.google.com/ig/images/no_image/en_ALL.gif</ghapi:thumbnail>
+<ghapi:category>tools</ghapi:category>
+<ghapi:category2>funandgames</ghapi:category2>
+<author>steven4u(a)gmailo.com</author>
+<ghapi:author_name>Steven</ghapi:author_name>
+<ghapi:author_location>Macau</ghapi:author_location>
+<ghapi:type>ghapi</ghapi:type>
+<ghapi:hosted>false</ghapi:hosted>
+<ghapi:width>320</ghapi:width>
+<ghapi:height>150</ghapi:height>
+<ghapi:num_userprefs>0</ghapi:num_userprefs>
+<ghapi:weekly_pageviews>8994</ghapi:weekly_pageviews></item><item>
+<title>Microsoft Outlook</title>
+<link>http://andyast.googlepages.com/MSOutlookWidget.xml</link>
+<guid>http://andyast.googlepages.com/MSOutlookWidget.xml</guid>
+<description>MS Outlook Inbox and Calendar</description>
+<ghapi:screenshot>http://www.google.com/ig/cache/1d/04/1d04b237d695e00f7345d8b32deda210.png</ghapi:screenshot>
+<ghapi:thumbnail>http://www.google.com/ig/cache/1d/04/1d04b237d695e00f7345d8b32deda210-thm.png</ghapi:thumbnail>
+<ghapi:category>tools</ghapi:category>
+<author>andyast(a)gmail.com</author>
+<ghapi:author_name>Andy Steinmann</ghapi:author_name>
+<ghapi:author_location>Nixa, MO</ghapi:author_location>
+<ghapi:type>ghapi</ghapi:type>
+<ghapi:hosted>false</ghapi:hosted>
+<ghapi:width>400</ghapi:width>
+<ghapi:height>600</ghapi:height>
+<ghapi:num_userprefs>1</ghapi:num_userprefs>
+<ghapi:weekly_pageviews>365631</ghapi:weekly_pageviews></item><item>
+<title>Mario is Back!</title>
+<link>http://homepagegadgets.googlepages.com/mario.xml</link>
+<guid>http://homepagegadgets.googlepages.com/mario.xml</guid>
+<description>The most played game ever - Mario is Back! Add to your homepage now
and get back to classic arcade action...</description>
+<ghapi:screenshot>http://www.google.com/ig/cache/4d/6b/4d6bf0c2f809d2301c0f708f8dc9596d.png</ghapi:screenshot>
+<ghapi:thumbnail>http://www.google.com/ig/cache/4d/6b/4d6bf0c2f809d2301c0f708f8dc9596d-thm.png</ghapi:thumbnail>
+<ghapi:category>funandgames</ghapi:category>
+<author>bijoy(a)jsplash.com</author>
+<ghapi:author_name>Bijoy Thangaraj</ghapi:author_name>
+<ghapi:author_location>Trivandrum, Kerala, India</ghapi:author_location>
+<ghapi:author_affiliation>None</ghapi:author_affiliation>
+<ghapi:author_photo>/ig/cache/4d/6b/4d6bf0c2f809d2301c0f708f8dc9596d-author.png</ghapi:author_photo>
+<ghapi:type>ghapi</ghapi:type>
+<ghapi:hosted>false</ghapi:hosted>
+<ghapi:width>320</ghapi:width>
+<ghapi:height>200</ghapi:height>
+<ghapi:num_userprefs>0</ghapi:num_userprefs>
+<ghapi:weekly_pageviews>1198197</ghapi:weekly_pageviews></item><item>
+<title>Yahoo! Messenger</title>
+<link>http://whizzgadgets.googlepages.com/yahoo.xml</link>
+<guid>http://whizzgadgets.googlepages.com/yahoo.xml</guid>
+<description>Chat with your Yahoo! buddies anywhere, anytime. All you need is your
personalized homepage.</description>
+<ghapi:screenshot>http://www.google.com/ig/cache/d9/75/d975f79b14a9d2ad5f1038a231d86362.png</ghapi:screenshot>
+<ghapi:thumbnail>http://www.google.com/ig/cache/d9/75/d975f79b14a9d2ad5f1038a231d86362-thm.png</ghapi:thumbnail>
+<ghapi:category>tools</ghapi:category>
+<ghapi:category2>communication</ghapi:category2>
+<author>grenardus(a)gmail.com</author>
+<ghapi:author_name>Whizz</ghapi:author_name>
+<ghapi:author_location>The Netherlands</ghapi:author_location>
+<ghapi:type>ghapi</ghapi:type>
+<ghapi:hosted>false</ghapi:hosted>
+<ghapi:width>320</ghapi:width>
+<ghapi:height>400</ghapi:height>
+<ghapi:num_userprefs>0</ghapi:num_userprefs>
+<ghapi:weekly_pageviews>151198</ghapi:weekly_pageviews></item><item>
+<title>Weather by Weather.com</title>
+<link>http://timcwebman.googlepages.com/weather.xml</link>
+<guid>http://timcwebman.googlepages.com/weather.xml</guid>
+<description>This module is designed to give you the weather as
Weather.com reports
it. Enter your zip code (required), choose your unit of measure, pick from the list of
available styles, and display either vertically (nice for small resolutions) or
horizontally (default). This module currently only works fo...</description>
+<ghapi:screenshot>http://www.google.com/ig/cache/46/63/46631770b202d7d4f6cf46d3f3650394.png</ghapi:screenshot>
+<ghapi:thumbnail>http://www.google.com/ig/cache/46/63/46631770b202d7d4f6cf46d3f3650394-thm.png</ghapi:thumbnail>
+<ghapi:category>news</ghapi:category>
+<author>timcwebman(a)gmail.com</author>
+<ghapi:author_name>Tim</ghapi:author_name>
+<ghapi:author_location>Lawrence, KS</ghapi:author_location>
+<ghapi:author_affiliation>None</ghapi:author_affiliation>
+<ghapi:type>ghapi</ghapi:type>
+<ghapi:hosted>false</ghapi:hosted>
+<ghapi:width>320</ghapi:width>
+<ghapi:height>180</ghapi:height>
+<ghapi:num_userprefs>4</ghapi:num_userprefs>
+<ghapi:weekly_pageviews>666303</ghapi:weekly_pageviews></item><item>
+<title>Laszlo ClockBlox</title>
+<link>http://www.openlaszlo.org/apps/clockblox.xml</link>
+<guid>http://www.openlaszlo.org/apps/clockblox.xml</guid>
+<description>a small clock written using Laszlo's LZX
language</description>
+<ghapi:screenshot>http://www.google.com/ig/modules/ov/module_laszloclock_full.png</ghapi:screenshot>
+<ghapi:thumbnail>http://www.google.com/ig/modules/ov/module_laszloclock.png</ghapi:thumbnail>
+<ghapi:category>tools</ghapi:category>
+<ghapi:category2></ghapi:category2>
+<author>enw(a)laszlosystems.com</author>
+<ghapi:author_name>Elliot Winard</ghapi:author_name>
+<ghapi:author_location>San Francisco, CA</ghapi:author_location>
+<ghapi:author_affiliation>Laszlo Systems, Inc.</ghapi:author_affiliation>
+<ghapi:author_photo>/ig/modules/ov/developer_elliot.jpg</ghapi:author_photo>
+<ghapi:type>ghapi</ghapi:type>
+<ghapi:hosted>false</ghapi:hosted>
+<ghapi:width>320</ghapi:width>
+<ghapi:height>150</ghapi:height>
+<ghapi:num_userprefs>0</ghapi:num_userprefs>
+<ghapi:weekly_pageviews>575022</ghapi:weekly_pageviews></item><item>
+<title>Spider</title>
+<link>http://abowman.googlepages.com/spider.xml</link>
+<guid>http://abowman.googlepages.com/spider.xml</guid>
+<description>Add this spider to your page and watch it crawl around and follow your
mouse. The latest update added more realism to the spider and allows you to change its
color, size, and speed. You can also add an image behind the spider.</description>
+<ghapi:screenshot>http://www.google.com/ig/cache/df/7f/df7fc65a0a97e3365af350f8f6a58c3f.png</ghapi:screenshot>
+<ghapi:thumbnail>http://www.google.com/ig/cache/df/7f/df7fc65a0a97e3365af350f8f6a58c3f-thm.png</ghapi:thumbnail>
+<ghapi:category>funandgames</ghapi:category>
+<author>adbocode(a)gmail.com</author>
+<ghapi:author_name>Adam Bowman</ghapi:author_name>
+<ghapi:author_location>Hallowell, Maine</ghapi:author_location>
+<ghapi:author_photo>/ig/cache/df/7f/df7fc65a0a97e3365af350f8f6a58c3f-author.png</ghapi:author_photo>
+<ghapi:type>ghapi</ghapi:type>
+<ghapi:hosted>false</ghapi:hosted>
+<ghapi:width>320</ghapi:width>
+<ghapi:height>200</ghapi:height>
+<ghapi:num_userprefs>13</ghapi:num_userprefs>
+<ghapi:weekly_pageviews>864280</ghapi:weekly_pageviews></item><item>
+<title>Micro-TV</title>
+<link>http://www.cammap.net/tvlive/microtv.xml</link>
+<guid>http://www.cammap.net/tvlive/microtv.xml</guid>
+<description>Watch live international TV channels</description>
+<ghapi:screenshot>http://www.google.com/ig/cache/ce/4f/ce4fc514cce72178f072bc781fc245ca.png</ghapi:screenshot>
+<ghapi:thumbnail>http://www.google.com/ig/cache/ce/4f/ce4fc514cce72178f072bc781fc245ca-thm.png</ghapi:thumbnail>
+<ghapi:category>lifestyle</ghapi:category>
+<ghapi:category2>tools</ghapi:category2>
+<author>only_serious_mail_can_be_sent_to_info(a)cammap.net</author>
+<ghapi:author_name>CamMap.net</ghapi:author_name>
+<ghapi:author_location>Amsterdam, Netherlands</ghapi:author_location>
+<ghapi:type>ghapi</ghapi:type>
+<ghapi:hosted>false</ghapi:hosted>
+<ghapi:width>160</ghapi:width>
+<ghapi:height>160</ghapi:height>
+<ghapi:num_userprefs>1</ghapi:num_userprefs>
+<ghapi:weekly_pageviews>17854</ghapi:weekly_pageviews></item><item>
+<title>Mini-Clock</title>
+<link>http://www.labpixies.com/campaigns/clock/mini_clock.xml</link>
+<guid>http://www.labpixies.com/campaigns/clock/mini_clock.xml</guid>
+<description>Mini-Clock, the coolest clock for your homepage, now mini-sized! Click
the gallery button to select your favorite skin. Make your homepage come alive with our
cool selection of skins, see the date and time with style.</description>
+<ghapi:screenshot>http://www.google.com/ig/cache/f4/c1/f4c1fcb3fa9dd6a01fc0cf2910f497b9.png</ghapi:screenshot>
+<ghapi:thumbnail>http://www.google.com/ig/cache/f4/c1/f4c1fcb3fa9dd6a01fc0cf2910f497b9-thm.png</ghapi:thumbnail>
+<ghapi:category>tools</ghapi:category>
+<ghapi:category2>funandgames</ghapi:category2>
+<author>info+mini_clock(a)labpixies.com</author>
+<ghapi:author_name>LabPixies</ghapi:author_name>
+<ghapi:type>ghapi</ghapi:type>
+<ghapi:hosted>false</ghapi:hosted>
+<ghapi:width>320</ghapi:width>
+<ghapi:height>215</ghapi:height>
+<ghapi:num_userprefs>0</ghapi:num_userprefs>
+<ghapi:weekly_pageviews>422834</ghapi:weekly_pageviews></item></channel></rss>
Modified: trunk/widget/src/resources/widget-war/WEB-INF/jsp/edit.jsp
===================================================================
--- trunk/widget/src/resources/widget-war/WEB-INF/jsp/edit.jsp 2007-07-05 23:41:21 UTC
(rev 7677)
+++ trunk/widget/src/resources/widget-war/WEB-INF/jsp/edit.jsp 2007-07-06 10:20:08 UTC
(rev 7678)
@@ -69,7 +69,7 @@
<p>
<table style="width:100%;border:1px solid" cellspacing="0"
cellpadding="0">
<%
- for (IteratorStatus i = new IteratorStatus(result.getWidgetIterator());
i.hasNext();)
+ for (IteratorStatus i = new IteratorStatus(result.entries()); i.hasNext();)
{
GGWidget widget = (GGWidget)i.next();
boolean selected = selWidget != null &&
selWidget.getId().equals(widget.getId());