Author: julien(a)jboss.com
Date: 2007-03-07 17:44:19 -0500 (Wed, 07 Mar 2007)
New Revision: 6587
Added:
trunk/common/src/main/org/jboss/portal/common/concurrent/loader/
trunk/common/src/main/org/jboss/portal/common/concurrent/loader/LoaderContext.java
trunk/common/src/main/org/jboss/portal/common/concurrent/loader/LoadingPolicy.java
trunk/common/src/main/org/jboss/portal/common/concurrent/loader/ObjectBatch.java
trunk/common/src/main/org/jboss/portal/common/concurrent/loader/ObjectLoader.java
trunk/common/src/main/org/jboss/portal/test/common/ObjectLoaderTestCase.java
trunk/widget/src/main/org/jboss/portal/widget/google/GGWidgetBatch.java
Removed:
trunk/widget/src/main/org/jboss/portal/widget/google/GGWidgetRetrieval.java
Modified:
trunk/common/build.xml
trunk/widget/src/main/org/jboss/portal/widget/google/GGWidgetFactory.java
trunk/widget/src/main/org/jboss/portal/widget/google/GGWidgetProvider.java
Log:
- extracted batch loading stuff into common.concurrent as it can be reused in other
places.
- also refactored the implementation to allow easy reuse
Modified: trunk/common/build.xml
===================================================================
--- trunk/common/build.xml 2007-03-07 22:33:06 UTC (rev 6586)
+++ trunk/common/build.xml 2007-03-07 22:44:19 UTC (rev 6587)
@@ -72,6 +72,7 @@
<path refid="apache.log4j.classpath"/>
<path refid="jboss.test.classpath"/>
<path refid="junit.junit.classpath"/>
+ <path refid="jboss/backport.concurrent.classpath"/>
<path refid="apache.httpclient.classpath"/>
<pathelement
location="../tools/lib/cargo-core-uberjar-0.8.jar"/>
<pathelement location="../tools/lib/cargo-ant-0.8.jar"/>
@@ -202,6 +203,8 @@
-->
<x-test>
+ <test todir="${test.reports}"
name="org.jboss.portal.test.common.ObjectLoaderTestCase"/>
+<!--
<test todir="${test.reports}"
name="org.jboss.portal.test.common.MarkupTestCase"/>
<test todir="${test.reports}"
name="org.jboss.portal.test.common.TypedMapTestCase"/>
<test todir="${test.reports}"
name="org.jboss.portal.test.common.test.InfoTestCase"/>
@@ -229,6 +232,7 @@
<test todir="${test.reports}"
name="org.jboss.portal.test.common.CopyOnWriteRegistryTestCase"/>
<test todir="${test.reports}"
name="org.jboss.portal.test.common.URLToolsTestCase"/>
<test todir="${test.reports}"
name="org.jboss.portal.test.common.ToolsTestCase"/>
+-->
</x-test>
<x-classpath>
<pathelement location="${build.classes}"/>
Added: trunk/common/src/main/org/jboss/portal/common/concurrent/loader/LoaderContext.java
===================================================================
--- trunk/common/src/main/org/jboss/portal/common/concurrent/loader/LoaderContext.java
(rev 0)
+++
trunk/common/src/main/org/jboss/portal/common/concurrent/loader/LoaderContext.java 2007-03-07
22:44:19 UTC (rev 6587)
@@ -0,0 +1,52 @@
+/******************************************************************************
+ * 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.common.concurrent.loader;
+
+import edu.emory.mathcs.backport.java.util.concurrent.CompletionService;
+
+/**
+ * Defines contextual services used for object batch loading service.
+ *
+ * @author <a href="mailto:julien@jboss.org">Julien Viet</a>
+ * @version $Revision: 1.1 $
+ */
+public class LoaderContext
+{
+
+ /** . */
+ private final CompletionService completionService;
+
+ public LoaderContext(CompletionService completionService)
+ {
+ if (completionService == null)
+ {
+ throw new IllegalArgumentException();
+ }
+ this.completionService = completionService;
+ }
+
+ public CompletionService getCompletionService()
+ {
+ return completionService;
+ }
+}
Added: trunk/common/src/main/org/jboss/portal/common/concurrent/loader/LoadingPolicy.java
===================================================================
--- trunk/common/src/main/org/jboss/portal/common/concurrent/loader/LoadingPolicy.java
(rev 0)
+++
trunk/common/src/main/org/jboss/portal/common/concurrent/loader/LoadingPolicy.java 2007-03-07
22:44:19 UTC (rev 6587)
@@ -0,0 +1,54 @@
+/******************************************************************************
+ * 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.common.concurrent.loader;
+
+/**
+ * Defines the loading policy for an object batch.
+ *
+ * @author <a href="mailto:julien@jboss.org">Julien Viet</a>
+ * @version $Revision: 1.1 $
+ */
+public class LoadingPolicy
+{
+
+ /**
+ * When an attempt is made to load one object, all objects are loaded and the current
thread waits
+ * until all objects have been either loaded or failed.
+ */
+ public static final LoadingPolicy LOAD_ALL_SYNC = new LoadingPolicy();
+
+ /**
+ * When an attempt is made to load one object, all objects are loaded but the current
thread will
+ * only have to wait the object it is requesting.
+ */
+ public static final LoadingPolicy LOAD_ALL_ASYNC = new LoadingPolicy();
+
+ /**
+ * When an attempt is made to load object object, only the requested object will be
loaded.
+ */
+ public static final LoadingPolicy LOAD_ONE = new LoadingPolicy();
+
+ private LoadingPolicy()
+ {
+ }
+}
Added: trunk/common/src/main/org/jboss/portal/common/concurrent/loader/ObjectBatch.java
===================================================================
--- trunk/common/src/main/org/jboss/portal/common/concurrent/loader/ObjectBatch.java
(rev 0)
+++
trunk/common/src/main/org/jboss/portal/common/concurrent/loader/ObjectBatch.java 2007-03-07
22:44:19 UTC (rev 6587)
@@ -0,0 +1,158 @@
+/******************************************************************************
+ * 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.common.concurrent.loader;
+
+import edu.emory.mathcs.backport.java.util.concurrent.locks.Lock;
+import edu.emory.mathcs.backport.java.util.concurrent.locks.ReentrantLock;
+import edu.emory.mathcs.backport.java.util.concurrent.Future;
+import edu.emory.mathcs.backport.java.util.concurrent.Callable;
+import edu.emory.mathcs.backport.java.util.concurrent.ExecutionException;
+
+/**
+ * Defines a batch of virtual objects.
+ *
+ * @author <a href="mailto:julien@jboss.org">Julien Viet</a>
+ * @version $Revision: 1.1 $
+ */
+public class ObjectBatch
+{
+
+ /** . */
+ private Lock lock = new ReentrantLock();
+
+ /** . */
+ private ObjectLoader[] objectLoaders;
+
+ /** . */
+ private LoadingPolicy policy;
+
+ /** . */
+ private Future[] futures;
+
+ public ObjectBatch(ObjectLoader[] objectLoaders, LoadingPolicy policy)
+ {
+ this.objectLoaders = objectLoaders;
+ this.policy = policy;
+ }
+
+ public int getSize()
+ {
+ return objectLoaders.length;
+ }
+
+ public Object getObject(final LoaderContext ctx, int index) throws
InterruptedException
+ {
+
+ //
+ lock.lock();
+ try
+ {
+ if (futures == null)
+ {
+ futures = new Future[objectLoaders.length];
+ }
+ if (futures[index] == null)
+ {
+ if (policy == LoadingPolicy.LOAD_ONE)
+ {
+ futures[index] = ctx.getCompletionService().submit(new
CallableImpl(index));
+ }
+ else
+ {
+ // Fill holes
+ for (int i = 0; i < objectLoaders.length; i++)
+ {
+ if (futures[i] == null)
+ {
+ futures[i] = ctx.getCompletionService().submit(new
CallableImpl(i));
+ }
+ }
+
+ // Wait for all to be done
+ if (policy == LoadingPolicy.LOAD_ALL_SYNC)
+ {
+ for (int i = 0; i < futures.length; i++)
+ {
+ try
+ {
+ futures[i].get();
+ }
+ catch (ExecutionException e)
+ {
+ Throwable t = e.getCause();
+
+ //
+ if (t instanceof Error)
+ {
+ throw (Error)t;
+ }
+ else
+ {
+ throw new Error("Unexpected exception", t);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ finally
+ {
+ lock.unlock();
+ }
+
+ //
+ try
+ {
+ return futures[index].get();
+ }
+ catch (ExecutionException e)
+ {
+ return null;
+ }
+ }
+
+ private class CallableImpl implements Callable
+ {
+
+ /** . */
+ private final int index;
+
+ public CallableImpl(int index)
+ {
+ this.index = index;
+ }
+
+ public Object call() throws Exception
+ {
+ try
+ {
+ return objectLoaders[index].load();
+ }
+ catch (Exception e)
+ {
+ return null;
+ }
+ }
+ }
+}
Added: trunk/common/src/main/org/jboss/portal/common/concurrent/loader/ObjectLoader.java
===================================================================
--- trunk/common/src/main/org/jboss/portal/common/concurrent/loader/ObjectLoader.java
(rev 0)
+++
trunk/common/src/main/org/jboss/portal/common/concurrent/loader/ObjectLoader.java 2007-03-07
22:44:19 UTC (rev 6587)
@@ -0,0 +1,37 @@
+/******************************************************************************
+ * 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.common.concurrent.loader;
+
+/**
+ * Defines loading capabilities for an object.
+ *
+ * @author <a href="mailto:julien@jboss.org">Julien Viet</a>
+ * @version $Revision: 1.1 $
+ */
+public interface ObjectLoader
+{
+ /**
+ * Loads an object or return null.
+ */
+ Object load();
+}
Added: trunk/common/src/main/org/jboss/portal/test/common/ObjectLoaderTestCase.java
===================================================================
--- trunk/common/src/main/org/jboss/portal/test/common/ObjectLoaderTestCase.java
(rev 0)
+++
trunk/common/src/main/org/jboss/portal/test/common/ObjectLoaderTestCase.java 2007-03-07
22:44:19 UTC (rev 6587)
@@ -0,0 +1,235 @@
+/******************************************************************************
+ * 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.common;
+
+import junit.framework.TestCase;
+import org.jboss.portal.common.concurrent.loader.ObjectLoader;
+import org.jboss.portal.common.concurrent.loader.ObjectBatch;
+import org.jboss.portal.common.concurrent.loader.LoadingPolicy;
+import org.jboss.portal.common.concurrent.loader.LoaderContext;
+import edu.emory.mathcs.backport.java.util.concurrent.Executor;
+import edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor;
+import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
+import edu.emory.mathcs.backport.java.util.concurrent.LinkedBlockingQueue;
+import edu.emory.mathcs.backport.java.util.concurrent.ExecutorCompletionService;
+
+/**
+ * @author <a href="mailto:julien@jboss.org">Julien Viet</a>
+ * @version $Revision: 1.1 $
+ */
+public class ObjectLoaderTestCase extends TestCase
+{
+
+ private static volatile int counter;
+
+ private abstract static class AbstractObjectLoader implements ObjectLoader
+ {
+ int loadCount;
+ }
+
+ private static class SimpleObjectLoader extends AbstractObjectLoader
+ {
+
+ /** . */
+ final Object o;
+
+ public SimpleObjectLoader()
+ {
+ this.o = null;
+ }
+
+ public SimpleObjectLoader(Object o)
+ {
+ if (o == null)
+ {
+ throw new IllegalArgumentException();
+ }
+ this.o = o;
+ }
+
+ public synchronized Object load()
+ {
+ loadCount++;
+ return o;
+ }
+ }
+
+ private static class RuntimeExceptionObjectLoader extends AbstractObjectLoader
+ {
+ public synchronized Object load()
+ {
+ loadCount++;
+ throw new RuntimeException();
+ }
+ }
+
+ private static class ErrorObjectLoader extends AbstractObjectLoader
+ {
+ public synchronized Object load()
+ {
+ loadCount++;
+ throw new Error();
+ }
+ }
+
+ private Executor executor;
+
+
+ protected void setUp() throws Exception
+ {
+ executor = new ThreadPoolExecutor(1, 1, 0, TimeUnit.SECONDS, new
LinkedBlockingQueue());
+ }
+
+ protected void tearDown() throws Exception
+ {
+ executor = null;
+ }
+
+ public void testLoadAsync() throws Exception
+ {
+ LoaderContext ctx = new LoaderContext(new ExecutorCompletionService(executor));
+ SimpleObjectLoader l0 = new SimpleObjectLoader(new Object());
+ RuntimeExceptionObjectLoader l1 = new RuntimeExceptionObjectLoader();
+ SimpleObjectLoader l2 = new SimpleObjectLoader();
+ AbstractObjectLoader[] loaders = new AbstractObjectLoader[]{l0,l1,l2};
+ ObjectBatch o_l = new ObjectBatch(loaders, LoadingPolicy.LOAD_ALL_SYNC);
+
+ //
+ Object o0 = o_l.getObject(ctx, 0);
+ assertEquals(o0, l0.o);
+ assertEquals(1, l0.loadCount);
+ assertEquals(1, l1.loadCount);
+ assertEquals(1, l2.loadCount);
+
+ //
+ Object o2 = o_l.getObject(ctx, 2);
+ assertEquals(o2, l2.o);
+ assertEquals(1, l0.loadCount);
+ assertEquals(1, l1.loadCount);
+ assertEquals(1, l2.loadCount);
+
+ //
+ Object o1 = o_l.getObject(ctx, 1);
+ assertEquals(o1, null);
+ assertEquals(1, l0.loadCount);
+ assertEquals(1, l1.loadCount);
+ assertEquals(1, l2.loadCount);
+
+ //
+ Object o3 = o_l.getObject(ctx, 1);
+ assertEquals(o3, null);
+ assertEquals(1, l0.loadCount);
+ assertEquals(1, l1.loadCount);
+ assertEquals(1, l2.loadCount);
+ }
+
+ public void testLoadSync() throws Exception
+ {
+ LoaderContext ctx = new LoaderContext(new ExecutorCompletionService(executor));
+ SimpleObjectLoader l0 = new SimpleObjectLoader(new Object());
+ RuntimeExceptionObjectLoader l1 = new RuntimeExceptionObjectLoader();
+ SimpleObjectLoader l2 = new SimpleObjectLoader();
+ AbstractObjectLoader[] loaders = new AbstractObjectLoader[]{l0,l1,l2};
+ ObjectBatch o_l = new ObjectBatch(loaders, LoadingPolicy.LOAD_ALL_SYNC);
+
+ //
+ Object o0 = o_l.getObject(ctx, 0);
+ assertEquals(o0, l0.o);
+ assertEquals(1, l0.loadCount);
+ assertEquals(1, l1.loadCount);
+ assertEquals(1, l2.loadCount);
+
+ //
+ Object o2 = o_l.getObject(ctx, 2);
+ assertEquals(o2, l2.o);
+ assertEquals(1, l0.loadCount);
+ assertEquals(1, l1.loadCount);
+ assertEquals(1, l2.loadCount);
+
+ //
+ Object o1 = o_l.getObject(ctx, 1);
+ assertEquals(o1, null);
+ assertEquals(1, l0.loadCount);
+ assertEquals(1, l1.loadCount);
+ assertEquals(1, l2.loadCount);
+
+ //
+ Object o3 = o_l.getObject(ctx, 1);
+ assertEquals(o3, null);
+ assertEquals(1, l0.loadCount);
+ assertEquals(1, l1.loadCount);
+ assertEquals(1, l2.loadCount);
+ }
+
+ public void testLoadOne() throws Exception
+ {
+ LoaderContext ctx = new LoaderContext(new ExecutorCompletionService(executor));
+ SimpleObjectLoader l0 = new SimpleObjectLoader(new Object());
+ RuntimeExceptionObjectLoader l1 = new RuntimeExceptionObjectLoader();
+ SimpleObjectLoader l2 = new SimpleObjectLoader();
+ AbstractObjectLoader[] loaders = new AbstractObjectLoader[]{l0,l1,l2};
+ ObjectBatch o_l = new ObjectBatch(loaders, LoadingPolicy.LOAD_ONE);
+
+ //
+ Object o0 = o_l.getObject(ctx, 0);
+ assertEquals(o0, l0.o);
+ assertEquals(1, loaders[0].loadCount);
+ assertEquals(0, loaders[1].loadCount);
+ assertEquals(0, loaders[2].loadCount);
+
+ //
+ Object o2 = o_l.getObject(ctx, 2);
+ assertEquals(o2, l2.o);
+ assertEquals(1, loaders[0].loadCount);
+ assertEquals(0, loaders[1].loadCount);
+ assertEquals(1, loaders[2].loadCount);
+
+ //
+ Object o1 = o_l.getObject(ctx, 1);
+ assertEquals(o1, null);
+ assertEquals(1, loaders[0].loadCount);
+ assertEquals(1, loaders[1].loadCount);
+ assertEquals(1, loaders[2].loadCount);
+
+ //
+ o0 = o_l.getObject(ctx, 0);
+ assertEquals(o0, l0.o);
+ assertEquals(1, loaders[0].loadCount);
+ assertEquals(1, loaders[1].loadCount);
+ assertEquals(1, loaders[2].loadCount);
+
+ //
+ o2 = o_l.getObject(ctx, 2);
+ assertEquals(o2, l2.o);
+ assertEquals(1, loaders[0].loadCount);
+ assertEquals(1, loaders[1].loadCount);
+ assertEquals(1, loaders[2].loadCount);
+
+ //
+ o1 = o_l.getObject(ctx, 1);
+ assertEquals(o1, null);
+ assertEquals(1, loaders[0].loadCount);
+ assertEquals(1, loaders[1].loadCount);
+ assertEquals(1, loaders[2].loadCount);
+ }
+}
Copied: trunk/widget/src/main/org/jboss/portal/widget/google/GGWidgetBatch.java (from rev
6579, trunk/widget/src/main/org/jboss/portal/widget/google/GGWidgetRetrieval.java)
===================================================================
--- trunk/widget/src/main/org/jboss/portal/widget/google/GGWidgetBatch.java
(rev 0)
+++ trunk/widget/src/main/org/jboss/portal/widget/google/GGWidgetBatch.java 2007-03-07
22:44:19 UTC (rev 6587)
@@ -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.widget.google;
+
+import org.apache.log4j.Logger;
+import org.jboss.portal.common.concurrent.loader.ObjectBatch;
+import org.jboss.portal.common.concurrent.loader.LoadingPolicy;
+import org.jboss.portal.common.concurrent.loader.LoaderContext;
+
+/**
+ * @author <a href="mailto:julien@jboss.org">Julien Viet</a>
+ * @version $Revision: 1.1 $
+ */
+public class GGWidgetBatch
+{
+
+ /** . */
+ private static final Logger log = Logger.getLogger(GGWidgetBatch.class);
+
+ /** . */
+ private final ObjectBatch batch;
+
+ public GGWidgetBatch(GGWidgetFactory[] factories)
+ {
+ this.batch = new ObjectBatch(factories, LoadingPolicy.LOAD_ALL_ASYNC);
+ }
+
+ public int getSize()
+ {
+ return batch.getSize();
+ }
+
+ public GGWidget getWidget(LoaderContext loaderContext, int index)
+ {
+ try
+ {
+ return (GGWidget)batch.getObject(loaderContext, index);
+ }
+ catch (InterruptedException e)
+ {
+ return null;
+ }
+ }
+}
Modified: trunk/widget/src/main/org/jboss/portal/widget/google/GGWidgetFactory.java
===================================================================
--- trunk/widget/src/main/org/jboss/portal/widget/google/GGWidgetFactory.java 2007-03-07
22:33:06 UTC (rev 6586)
+++ trunk/widget/src/main/org/jboss/portal/widget/google/GGWidgetFactory.java 2007-03-07
22:44:19 UTC (rev 6587)
@@ -25,6 +25,7 @@
import org.jboss.portal.common.util.XML;
import org.jboss.portal.common.util.LocalizedString;
import org.jboss.portal.common.util.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;
@@ -48,7 +49,7 @@
* @author <a href="mailto:julien@jboss.org">Julien Viet</a>
* @version $Revision: 1.1 $
*/
-public class GGWidgetFactory
+public class GGWidgetFactory implements ObjectLoader
{
/** . */
@@ -68,6 +69,22 @@
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 = XML.getDocumentBuilderFactory();
Modified: trunk/widget/src/main/org/jboss/portal/widget/google/GGWidgetProvider.java
===================================================================
--- trunk/widget/src/main/org/jboss/portal/widget/google/GGWidgetProvider.java 2007-03-07
22:33:06 UTC (rev 6586)
+++ trunk/widget/src/main/org/jboss/portal/widget/google/GGWidgetProvider.java 2007-03-07
22:44:19 UTC (rev 6587)
@@ -39,20 +39,21 @@
import org.jboss.portal.widget.WidgetProvider;
import org.jboss.portal.widget.Widget;
import org.jboss.portal.common.util.URLTools;
+import org.jboss.portal.common.concurrent.loader.ObjectBatch;
+import org.jboss.portal.common.concurrent.loader.ObjectLoader;
+import org.jboss.portal.common.concurrent.loader.LoadingPolicy;
+import org.jboss.portal.common.concurrent.loader.LoaderContext;
import org.apache.log4j.Logger;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.MutableAttributeSet;
-import edu.emory.mathcs.backport.java.util.concurrent.FutureTask;
-import edu.emory.mathcs.backport.java.util.concurrent.Callable;
import edu.emory.mathcs.backport.java.util.concurrent.ExecutorService;
import edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor;
import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
import edu.emory.mathcs.backport.java.util.concurrent.LinkedBlockingDeque;
-import edu.emory.mathcs.backport.java.util.concurrent.locks.Lock;
-import edu.emory.mathcs.backport.java.util.concurrent.locks.ReentrantLock;
+import edu.emory.mathcs.backport.java.util.concurrent.ExecutorCompletionService;
/**
* @todo first :
@@ -77,61 +78,53 @@
private static final Logger log = Logger.getLogger(GGWidgetProvider.class);
/** . */
- private volatile FutureTask future;
+ private ObjectBatch batch;
/** . */
- private final Lock lock = new ReentrantLock();
+ private ExecutorService executor;
/** . */
- private final ExecutorService executor = new ThreadPoolExecutor(3, 3, 0,
TimeUnit.SECONDS, new LinkedBlockingDeque());
+ private LoaderContext loaderContext;
+ public GGWidgetProvider()
+ {
+ }
+
public void start()
{
+ executor = new ThreadPoolExecutor(4, 4, 0, TimeUnit.SECONDS, new
LinkedBlockingDeque());
+ loaderContext = new LoaderContext(new ExecutorCompletionService(executor));
+ batch = new ObjectBatch(new ObjectLoader[]{new WidgetBuilder()},
LoadingPolicy.LOAD_ONE);
}
public void stop()
{
executor.shutdownNow();
+ executor = null;
+ loaderContext = null;
+ batch = null;
}
private Map getMap()
{
try
{
- lock.lock();
- try
- {
- if (future == null)
- {
- future = new FutureTask(new Callable()
- {
- public Object call() throws Exception
- {
- WidgetBuilder map = new WidgetBuilder();
- map.start();
- return map;
- }
- });
- executor.execute(future);
- }
- }
- finally
- {
- lock.unlock();
- }
- WidgetBuilder wmap = (WidgetBuilder)future.get();
- return wmap.map;
+ return (Map)batch.getObject(loaderContext, 0);
}
- catch (Exception e)
+ catch (InterruptedException e)
{
- e.printStackTrace();
- return Collections.EMPTY_MAP;
+ return null;
}
}
public Collection getKeys()
{
- return getMap().keySet();
+ Map map = getMap();
+ if (map == null)
+ {
+ return Collections.EMPTY_SET;
+ }
+ return map.keySet();
}
public Widget getWidget(String key)
@@ -140,14 +133,25 @@
{
throw new IllegalArgumentException();
}
- Map tmp = getMap();
- GGWidgetRetrieval.List retrievals = (GGWidgetRetrieval.List)tmp.get(key);
- if (retrievals != null)
+
+ //
+ Map map = getMap();
+ if (map == null)
{
- GGWidgetRetrieval retrieval = retrievals.getRetrieval(key);
- if (retrieval.getStatus() == GGWidgetRetrieval.AVAILABLE)
+ return null;
+ }
+
+ //
+ GGWidgetBatch batch = (GGWidgetBatch)map.get(key);
+ if (batch != null)
+ {
+ for (int i = 0;i < batch.getSize();i++)
{
- return retrieval.getWidget();
+ GGWidget widget = batch.getWidget(loaderContext, i);
+ if (widget != null && widget.getId().equals(key))
+ {
+ return widget;
+ }
}
}
@@ -155,13 +159,10 @@
return null;
}
- private class WidgetBuilder
+ private class WidgetBuilder implements ObjectLoader
{
- /** . */
- private Map map;
-
- public void start()
+ public Object load()
{
try
{
@@ -244,12 +245,13 @@
}
else
{
- GGWidgetRetrieval.List retrievals = new
GGWidgetRetrieval.List(executor, tmp);
- for (int j = 0;j < retrievals.getSize();j++)
+ GGWidgetFactory[] factories = (GGWidgetFactory[])tmp.toArray(new
GGWidgetFactory[tmp.size()]);
+ GGWidgetBatch retrievals = new GGWidgetBatch(factories);
+ for (int j = 0;j < factories.length;j++)
{
- GGWidgetFactory t = retrievals.getFactory(j);
- map.put(t.getURL().toString(), retrievals);
- log.info("Added widget for later retrieval" +
t.getURL());
+ String furl = factories[j].getURL().toString();
+ map.put(furl, retrievals);
+ log.info("Added widget for later retrieval" + furl);
}
//
@@ -259,11 +261,12 @@
}
//
- this.map = Collections.unmodifiableMap(map);
+ return Collections.unmodifiableMap(map);
}
catch (Exception e)
{
e.printStackTrace();
+ return null;
}
}
}
Deleted: trunk/widget/src/main/org/jboss/portal/widget/google/GGWidgetRetrieval.java
===================================================================
--- trunk/widget/src/main/org/jboss/portal/widget/google/GGWidgetRetrieval.java 2007-03-07
22:33:06 UTC (rev 6586)
+++ trunk/widget/src/main/org/jboss/portal/widget/google/GGWidgetRetrieval.java 2007-03-07
22:44:19 UTC (rev 6587)
@@ -1,202 +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;
-
-import edu.emory.mathcs.backport.java.util.concurrent.FutureTask;
-import edu.emory.mathcs.backport.java.util.concurrent.Callable;
-import edu.emory.mathcs.backport.java.util.concurrent.CompletionService;
-import edu.emory.mathcs.backport.java.util.concurrent.ExecutorCompletionService;
-import edu.emory.mathcs.backport.java.util.concurrent.Future;
-import edu.emory.mathcs.backport.java.util.concurrent.Executor;
-import edu.emory.mathcs.backport.java.util.concurrent.locks.Lock;
-import edu.emory.mathcs.backport.java.util.concurrent.locks.ReentrantLock;
-
-import java.util.Collection;
-
-import org.apache.log4j.Logger;
-
-/**
- * @author <a href="mailto:julien@jboss.org">Julien Viet</a>
- * @version $Revision: 1.1 $
- */
-public class GGWidgetRetrieval
-{
-
- /** . */
- private static final Logger log = Logger.getLogger(GGWidgetRetrieval.class);
-
- /** . */
- public static int UNAVAILABLE = 0;
-
- /** . */
- public static int AVAILABLE = 1;
-
- /** . */
- private GGWidget widget;
-
- public GGWidgetRetrieval(GGWidget widget)
- {
- this.widget = widget;
- }
-
- public GGWidget getWidget() throws IllegalStateException
- {
- if (widget == null)
- {
- throw new IllegalStateException("Widget not available");
- }
- return widget;
- }
-
- public int getStatus()
- {
- return widget != null ? AVAILABLE : UNAVAILABLE;
- }
-
- public static class List
- {
-
- /** . */
- private final GGWidgetFactory[] factories;
-
- /** . */
- private final Executor executor;
-
- /** . */
- private final Lock lock = new ReentrantLock();
-
- /** . */
- private FutureTask future;
-
- public List(Executor executor, Collection c)
- {
- this.executor = executor;
- this.factories = (GGWidgetFactory[])c.toArray(new GGWidgetFactory[c.size()]);
- }
-
- public int getSize()
- {
- return factories.length;
- }
-
- public GGWidgetFactory getFactory(int index)
- {
- return factories[index];
- }
-
- public GGWidgetRetrieval getRetrieval(String key)
- {
- for (int i = 0;i < factories.length;i++)
- {
- GGWidgetFactory factory = factories[i];
- if (key.equals(factory.getURL().toString()))
- {
- return getRetrieval(i);
- }
- }
- return null;
- }
-
- private class Fetcher implements Callable
- {
-
- /** . */
- private final int index;
-
- /** . */
- private GGWidgetRetrieval retrieval;
-
- public Fetcher(int index)
- {
- this.index = index;
- }
-
- public Object call() throws Exception
- {
- GGWidgetFactory factory = factories[index];
- try
- {
- log.info("Creating widget " + factory.getURL());
- GGWidget widget = factory.create();
- retrieval = new GGWidgetRetrieval(widget);
- }
- catch (Exception e)
- {
- log.error("Widget " + factory.getURL() + " was not
retrievable", e);
- retrieval = new GGWidgetRetrieval(null);
- }
- return this;
- }
- }
-
- public GGWidgetRetrieval getRetrieval(int index)
- {
- //
- lock.lock();
- try
- {
- if (future == null)
- {
- future = new FutureTask(new Callable()
- {
- public Object call() throws Exception
- {
- log.info("Creating widget batch");
- CompletionService completionService = new
ExecutorCompletionService(executor);
- for (int i = 0; i < factories.length; i++)
- {
- completionService.submit(new Fetcher(i));
- }
- GGWidgetRetrieval[] retrievals = new
GGWidgetRetrieval[factories.length];
- for (int i = 0; i < factories.length; i++)
- {
- Future future = completionService.take();
- Fetcher fetcher = (Fetcher)future.get();
- retrievals[fetcher.index] = fetcher.retrieval;
- }
- return retrievals;
- }
- });
- executor.execute(future);
- }
- }
- finally
- {
- lock.unlock();
- }
-
- try
- {
- //
- GGWidgetRetrieval[] retrievals = (GGWidgetRetrieval[])future.get();
-
- //
- return retrievals[index];
- }
- catch (Exception e)
- {
- return new GGWidgetRetrieval(null);
- }
- }
- }
-}