Author: nbelaevski
Date: 2010-07-27 12:26:04 -0400 (Tue, 27 Jul 2010)
New Revision: 18248
Added:
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/concurrent/
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/concurrent/CountingExecutorCompletionService.java
Modified:
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/Main.java
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/ResourceInfo.java
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/ResourceTaskFactory.java
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/faces/FacesImpl.java
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/faces/ResourceHandlerImpl.java
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/resource/ResourceWriterImpl.java
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/task/ResourceTaskFactoryImpl.java
Log:
Dynamic resources prerenderer: added handling for static resource depedencies
Modified:
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/Main.java
===================================================================
---
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/Main.java 2010-07-27
14:18:46 UTC (rev 18247)
+++
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/Main.java 2010-07-27
16:26:04 UTC (rev 18248)
@@ -21,12 +21,13 @@
*/
package org.richfaces.cdk;
-import java.util.concurrent.Callable;
+import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import org.richfaces.cdk.concurrent.CountingExecutorCompletionService;
import org.richfaces.cdk.faces.FacesImpl;
import org.richfaces.cdk.naming.FileNameMapperImpl;
import org.richfaces.cdk.resource.ResourceWriterImpl;
@@ -46,39 +47,40 @@
}
public static void main(String[] args) throws Exception {
+ String dstDir = args[0];
+ ResourceWriterImpl resourceWriter = new ResourceWriterImpl(dstDir);
+ ResourceTaskFactory taskFactory = new ResourceTaskFactoryImpl();
+ taskFactory.setResourceWriter(resourceWriter);
+
// TODO set webroot
- Faces faces = new FacesImpl(null, new FileNameMapperImpl());
+ Faces faces = new FacesImpl(null, new FileNameMapperImpl(), taskFactory);
faces.start();
- String dstDir = args[0];
-
ResourcesScanner resourcesScanner = new ResourcesScannerImpl();
resourcesScanner.scan();
- ResourceWriterImpl resourceWriter = new ResourceWriterImpl(dstDir);
- ResourceTaskFactory taskFactory = new ResourceTaskFactoryImpl(faces,
resourceWriter);
-
- taskFactory.setResources(resourcesScanner.getResources());
+ ExecutorService executorService = createExecutorService();
+ CompletionService<Object> completionService = new
CountingExecutorCompletionService<Object>(executorService);
+ taskFactory.setCompletionService(completionService);
taskFactory.setSkins(Lists.newArrayList("blueSky", "ruby",
"classic"));
+ for (ResourceInfo resourceInfo : resourcesScanner.getResources()) {
+ taskFactory.submit(resourceInfo);
+ }
- ExecutorService executorService = createExecutorService();
- ExecutorCompletionService<Object> completionService = new
ExecutorCompletionService<Object>(executorService);
-
try {
- int tasksCounter = 0;
- for (Callable<Object> task : taskFactory.createTasks()) {
- completionService.submit(task);
- tasksCounter++;
- }
-
- while (tasksCounter > 0) {
- try {
- completionService.take().get();
- } catch (ExecutionException e) {
- // TODO: handle exception
- e.getCause().printStackTrace();
+ Future<Object> future = null;
+ while (true) {
+ future = completionService.take();
+ if (future != null) {
+ try {
+ future.get();
+ } catch (ExecutionException e) {
+ // TODO: handle exception
+ e.getCause().printStackTrace();
+ }
+ } else {
+ break;
}
- tasksCounter--;
}
} finally {
executorService.shutdown();
Modified:
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/ResourceInfo.java
===================================================================
---
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/ResourceInfo.java 2010-07-27
14:18:46 UTC (rev 18247)
+++
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/ResourceInfo.java 2010-07-27
16:26:04 UTC (rev 18248)
@@ -21,6 +21,8 @@
*/
package org.richfaces.cdk;
+import com.google.common.base.Objects;
+
/**
* @author Nick Belaevski
*
@@ -89,4 +91,11 @@
return true;
}
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return Objects.toStringHelper(this).add("resourceName",
resourceName).add("libraryName", libraryName).toString();
+ }
}
Modified:
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/ResourceTaskFactory.java
===================================================================
---
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/ResourceTaskFactory.java 2010-07-27
14:18:46 UTC (rev 18247)
+++
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/ResourceTaskFactory.java 2010-07-27
16:26:04 UTC (rev 18248)
@@ -22,7 +22,7 @@
package org.richfaces.cdk;
import java.util.Collection;
-import java.util.concurrent.Callable;
+import java.util.concurrent.CompletionService;
/**
* @author Nick Belaevski
@@ -32,8 +32,12 @@
public void setSkins(Collection<String> skins);
- public void setResources(Collection<ResourceInfo> resources);
+ public void setCompletionService(CompletionService<Object> completionService);
+
+ public void setFaces(Faces faces);
+
+ public void setResourceWriter(ResourceWriter resourceWriter);
- public Collection<Callable<Object>> createTasks();
+ public void submit(ResourceInfo info);
}
Added:
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/concurrent/CountingExecutorCompletionService.java
===================================================================
---
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/concurrent/CountingExecutorCompletionService.java
(rev 0)
+++
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/concurrent/CountingExecutorCompletionService.java 2010-07-27
16:26:04 UTC (rev 18248)
@@ -0,0 +1,70 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * 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.richfaces.cdk.concurrent;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorCompletionService;
+import java.util.concurrent.Future;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class CountingExecutorCompletionService<T> extends
ExecutorCompletionService<T> {
+
+ private AtomicInteger tasksCounter = new AtomicInteger(0);
+
+ public CountingExecutorCompletionService(Executor executor) {
+ super(executor);
+ }
+
+ public CountingExecutorCompletionService(Executor executor,
BlockingQueue<Future<T>> completionQueue) {
+ super(executor, completionQueue);
+ }
+
+ @Override
+ public Future<T> submit(Callable<T> task) {
+ tasksCounter.getAndIncrement();
+ return super.submit(task);
+ }
+
+ public Future<T> submit(Runnable task, T result) {
+ tasksCounter.getAndIncrement();
+ return super.submit(task, result);
+ }
+
+ @Override
+ public Future<T> take() throws InterruptedException {
+ if (tasksCounter.get() == 0) {
+ return null;
+ }
+
+ try {
+ return super.take();
+ } finally {
+ tasksCounter.getAndDecrement();
+ }
+ }
+}
Modified:
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/faces/FacesImpl.java
===================================================================
---
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/faces/FacesImpl.java 2010-07-27
14:18:46 UTC (rev 18247)
+++
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/faces/FacesImpl.java 2010-07-27
16:26:04 UTC (rev 18248)
@@ -32,6 +32,7 @@
import org.richfaces.application.ServicesFactoryImpl;
import org.richfaces.cdk.Faces;
import org.richfaces.cdk.FileNameMapper;
+import org.richfaces.cdk.ResourceTaskFactory;
import org.richfaces.cdk.skin.SkinFactoryImpl;
import org.richfaces.skin.SkinFactory;
@@ -44,11 +45,15 @@
private String webroot;
private FileNameMapper fileNameMapper;
+
+ private ResourceTaskFactory resourceTaskFactory;
- public FacesImpl(String webroot, FileNameMapper fileNameMapper) {
+ public FacesImpl(String webroot, FileNameMapper fileNameMapper, ResourceTaskFactory
resourceTaskFactory) {
super();
this.webroot = webroot;
this.fileNameMapper = fileNameMapper;
+ this.resourceTaskFactory = resourceTaskFactory;
+ resourceTaskFactory.setFaces(this);
}
public void start() {
@@ -61,6 +66,7 @@
serviceFactory.setInstance(SkinFactory.class, skinFactory);
serviceFactory.setInstance(InitParametersStorage.class, new
InitParametersStorage());
serviceFactory.setInstance(FileNameMapper.class, fileNameMapper);
+ serviceFactory.setInstance(ResourceTaskFactory.class,
resourceTaskFactory);
}
};
serviceFactory.init(Collections.singleton(module));
Modified:
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/faces/ResourceHandlerImpl.java
===================================================================
---
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/faces/ResourceHandlerImpl.java 2010-07-27
14:18:46 UTC (rev 18247)
+++
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/faces/ResourceHandlerImpl.java 2010-07-27
16:26:04 UTC (rev 18248)
@@ -30,7 +30,9 @@
import javax.faces.context.FacesContext;
import org.reflections.util.Utils;
+import org.richfaces.application.ServiceTracker;
import org.richfaces.cdk.ResourceInfo;
+import org.richfaces.cdk.ResourceTaskFactory;
import org.richfaces.cdk.resource.URLResource;
import org.richfaces.resource.CompiledCSSResource;
import org.richfaces.resource.Java2DUserResource;
@@ -110,6 +112,9 @@
result.setContentType(contentType);
result.setResourceName(resourceName);
result.setLibraryName(libraryName);
+
+ ResourceTaskFactory resourceTaskFactory =
ServiceTracker.getService(ResourceTaskFactory.class);
+ resourceTaskFactory.submit(new ResourceInfo(resourceName, libraryName));
}
return result;
Modified:
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/resource/ResourceWriterImpl.java
===================================================================
---
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/resource/ResourceWriterImpl.java 2010-07-27
14:18:46 UTC (rev 18247)
+++
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/resource/ResourceWriterImpl.java 2010-07-27
16:26:04 UTC (rev 18248)
@@ -56,7 +56,6 @@
InputStream is = null;
try {
is = resource.getInputStream();
-
File skinDir = new File(baseDir, skinName);
File outFile = new File(skinDir, getFileNameMapper().createName(resource));
outFile.getParentFile().mkdirs();
Modified:
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/task/ResourceTaskFactoryImpl.java
===================================================================
---
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/task/ResourceTaskFactoryImpl.java 2010-07-27
14:18:46 UTC (rev 18247)
+++
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/task/ResourceTaskFactoryImpl.java 2010-07-27
16:26:04 UTC (rev 18248)
@@ -21,10 +21,12 @@
*/
package org.richfaces.cdk.task;
+import java.text.MessageFormat;
import java.util.Collection;
import java.util.Collections;
-import java.util.List;
import java.util.concurrent.Callable;
+import java.util.concurrent.CompletionService;
+import java.util.concurrent.ConcurrentMap;
import javax.faces.application.Resource;
import javax.faces.component.StateHolder;
@@ -36,8 +38,11 @@
import org.richfaces.cdk.ResourceWriter;
import org.richfaces.cdk.faces.CurrentResourceContext;
import org.richfaces.resource.StateHolderResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
@@ -47,6 +52,8 @@
*/
public class ResourceTaskFactoryImpl implements ResourceTaskFactory {
+ private static final Logger LOGGER =
LoggerFactory.getLogger(ResourceTaskFactoryImpl.class);
+
private class ResourcesRendererCallable implements Callable<Object> {
private String skinName;
@@ -63,7 +70,7 @@
resourceInfo.getLibraryName());
}
- public Object call() throws Exception {
+ private void renderResource() {
try {
faces.setSkin(skinName);
FacesContext facesContext = faces.startRequest();
@@ -72,7 +79,7 @@
if (resource == null) {
//TODO log null resource
- return null;
+ return;
}
CurrentResourceContext.getInstance(facesContext).setResource(resource);
@@ -93,12 +100,16 @@
//TODO check content type
resourceWriter.writeResource(skinName, resource);
+ } catch (Exception e) {
+ LOGGER.error(MessageFormat.format("Exception rendering resorce {0}
using skin {1}: {2}", resourceInfo, skinName, e.getMessage()), e);
} finally {
faces.setSkin(null);
faces.stopRequest();
}
-
- // TODO Auto-generated method stub
+ }
+
+ public Object call() throws Exception {
+ renderResource();
return null;
}
@@ -108,33 +119,35 @@
private ResourceWriter resourceWriter;
- private Collection<ResourceInfo> resources = Collections.emptySet();
+ private ConcurrentMap<ResourceInfo, Boolean> submittedResources =
Maps.newConcurrentMap();
+ private CompletionService<Object> completionService;
+
private Collection<String> skins = Collections.emptySet();
- public ResourceTaskFactoryImpl(Faces faces, ResourceWriter resourceWriter) {
- super();
+ public void setFaces(Faces faces) {
this.faces = faces;
+ }
+
+ public void setResourceWriter(ResourceWriter resourceWriter) {
this.resourceWriter = resourceWriter;
}
-
- public void setResources(Collection<ResourceInfo> resources) {
- this.resources = resources;
+
+ public void setSkins(Collection<String> skins) {
+ this.skins = Lists.newArrayList(skins);
}
- public void setSkins(Collection<String> skins) {
- this.skins = skins;
+ public void setCompletionService(CompletionService<Object> completionService)
{
+ this.completionService = completionService;
}
- public Collection<Callable<Object>> createTasks() {
- List<Callable<Object>> result = Lists.newArrayList();
-
- for (String skin : skins) {
- for (ResourceInfo resourceInfo : resources) {
- result.add(new ResourcesRendererCallable(skin, resourceInfo));
+ @Override
+ public void submit(ResourceInfo info) {
+ if (submittedResources.putIfAbsent(info, Boolean.TRUE) == null) {
+ for (String skinName: skins) {
+ completionService.submit(new ResourcesRendererCallable(skinName, info));
}
}
-
- return result;
}
+
}