[richfaces-svn-commits] JBoss Rich Faces SVN: r18325 - in root/trunk/core: api/src/main/java/org/richfaces/skin and 6 other directories.

richfaces-svn-commits at lists.jboss.org richfaces-svn-commits at lists.jboss.org
Mon Aug 2 15:36:32 EDT 2010


Author: nbelaevski
Date: 2010-08-02 15:36:31 -0400 (Mon, 02 Aug 2010)
New Revision: 18325

Added:
   root/trunk/core/api/src/main/java/org/richfaces/resource/ResourceCodecData.java
   root/trunk/core/api/src/main/java/org/richfaces/resource/ResourceFactory.java
   root/trunk/core/impl/src/main/java/org/richfaces/resource/DefaultResourceCodecData.java
   root/trunk/core/impl/src/main/java/org/richfaces/resource/ResourceFactoryImpl.java
   root/trunk/core/impl/src/main/java/org/richfaces/resource/ResourceLogger.java
   root/trunk/core/impl/src/main/java/org/richfaces/util/PropertiesUtil.java
Modified:
   root/trunk/core/api/src/main/java/org/richfaces/resource/ResourceCodec.java
   root/trunk/core/api/src/main/java/org/richfaces/skin/SkinFactory.java
   root/trunk/core/impl/src/main/java/org/richfaces/VersionBean.java
   root/trunk/core/impl/src/main/java/org/richfaces/renderkit/html/BaseGradient.java
   root/trunk/core/impl/src/main/java/org/richfaces/resource/AbstractBaseResource.java
   root/trunk/core/impl/src/main/java/org/richfaces/resource/DefaultResourceCodec.java
   root/trunk/core/impl/src/main/java/org/richfaces/resource/ResourceHandlerImpl.java
   root/trunk/core/impl/src/main/java/org/richfaces/skin/AbstractSkinFactory.java
   root/trunk/core/impl/src/test/java/org/richfaces/resource/AbstractBaseResourceTest.java
   root/trunk/core/impl/src/test/java/org/richfaces/resource/ResourceHandlerImplTest.java
   root/trunk/core/impl/src/test/java/org/richfaces/resource/StateHolderResourceImpl.java
Log:
ResourceHandler -> ResourceFactory separation refactoring

Modified: root/trunk/core/api/src/main/java/org/richfaces/resource/ResourceCodec.java
===================================================================
--- root/trunk/core/api/src/main/java/org/richfaces/resource/ResourceCodec.java	2010-08-02 19:10:54 UTC (rev 18324)
+++ root/trunk/core/api/src/main/java/org/richfaces/resource/ResourceCodec.java	2010-08-02 19:36:31 UTC (rev 18325)
@@ -16,13 +16,5 @@
     
     public String encodeJSFMapping(FacesContext context, String resourcePath);
     
-    public String decodeResourceName(FacesContext context, String requestPath);
-
-    public String decodeLibraryName(FacesContext context, String requestPath);
-
-    public Object decodeResourceData(FacesContext context, String requestPath);
-
-    public String decodeResourceVersion(FacesContext context, String requestPath);
-
-    public String getResourceKey(FacesContext context, String requestPath);
+    public ResourceCodecData decodeResource(FacesContext context, String requestPath);
 }

Added: root/trunk/core/api/src/main/java/org/richfaces/resource/ResourceCodecData.java
===================================================================
--- root/trunk/core/api/src/main/java/org/richfaces/resource/ResourceCodecData.java	                        (rev 0)
+++ root/trunk/core/api/src/main/java/org/richfaces/resource/ResourceCodecData.java	2010-08-02 19:36:31 UTC (rev 18325)
@@ -0,0 +1,39 @@
+/*
+ * 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.resource;
+
+/**
+ * @author Nick Belaevski
+ * 
+ */
+public interface ResourceCodecData {
+
+    public String getResourceName();
+    
+    public String getLibraryName();
+    
+    public String getVersion();
+    
+    public Object getData();
+    
+    public String getResourceKey();
+}

Added: root/trunk/core/api/src/main/java/org/richfaces/resource/ResourceFactory.java
===================================================================
--- root/trunk/core/api/src/main/java/org/richfaces/resource/ResourceFactory.java	                        (rev 0)
+++ root/trunk/core/api/src/main/java/org/richfaces/resource/ResourceFactory.java	2010-08-02 19:36:31 UTC (rev 18325)
@@ -0,0 +1,37 @@
+/*
+ * 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.resource;
+
+import javax.faces.application.Resource;
+import javax.faces.context.FacesContext;
+
+/**
+ * @author Nick Belaevski
+ * 
+ */
+public interface ResourceFactory {
+
+    public abstract Resource createResource(String resourceName, String libraryName, String contentType);
+
+    public abstract Resource createResource(FacesContext context, ResourceCodecData resourceData);
+
+}

Modified: root/trunk/core/api/src/main/java/org/richfaces/skin/SkinFactory.java
===================================================================
--- root/trunk/core/api/src/main/java/org/richfaces/skin/SkinFactory.java	2010-08-02 19:10:54 UTC (rev 18324)
+++ root/trunk/core/api/src/main/java/org/richfaces/skin/SkinFactory.java	2010-08-02 19:36:31 UTC (rev 18325)
@@ -85,5 +85,5 @@
     public abstract Theme getTheme(FacesContext facesContext, String name);
 
     public abstract Skin getSkin(FacesContext context, String name);
-    
+
 }

Modified: root/trunk/core/impl/src/main/java/org/richfaces/VersionBean.java
===================================================================
--- root/trunk/core/impl/src/main/java/org/richfaces/VersionBean.java	2010-08-02 19:10:54 UTC (rev 18324)
+++ root/trunk/core/impl/src/main/java/org/richfaces/VersionBean.java	2010-08-02 19:36:31 UTC (rev 18325)
@@ -111,7 +111,7 @@
 
         private void initializeDerivativeProperties() {
             fullVersionString = MessageFormat.format("v.{0} SVN r.{1}", implementationVersion, scmRevision);
-            resourceVersion = implementationVersion.replace('.', '_') + "_" + scmRevision;
+            resourceVersion = implementationVersion.replace('.', '_');
         }
 
         private Manifest readManifest() {

Modified: root/trunk/core/impl/src/main/java/org/richfaces/renderkit/html/BaseGradient.java
===================================================================
--- root/trunk/core/impl/src/main/java/org/richfaces/renderkit/html/BaseGradient.java	2010-08-02 19:10:54 UTC (rev 18324)
+++ root/trunk/core/impl/src/main/java/org/richfaces/renderkit/html/BaseGradient.java	2010-08-02 19:36:31 UTC (rev 18325)
@@ -36,12 +36,14 @@
 
 import javax.faces.context.FacesContext;
 
+import org.richfaces.VersionBean;
 import org.richfaces.renderkit.html.images.GradientType;
 import org.richfaces.renderkit.html.images.GradientType.BiColor;
 import org.richfaces.resource.DynamicResource;
 import org.richfaces.resource.ImageType;
 import org.richfaces.resource.Java2DUserResource;
 import org.richfaces.resource.StateHolderResource;
+import org.richfaces.resource.VersionedResource;
 import org.richfaces.skin.Skin;
 import org.richfaces.skin.SkinFactory;
 
@@ -50,7 +52,7 @@
  *         created 02.02.2007
  */
 @DynamicResource
-public class BaseGradient implements Java2DUserResource, StateHolderResource {
+public class BaseGradient implements Java2DUserResource, StateHolderResource, VersionedResource {
 
     protected Integer headerBackgroundColor;
     protected Integer headerGradientColor;
@@ -241,6 +243,7 @@
     }
     
     public void writeState(FacesContext context, DataOutput dataOutput) throws IOException {
+        //TODO move this call to another place in this and alike resources
         initialize();
 
         dataOutput.writeInt(this.headerBackgroundColor);
@@ -264,4 +267,8 @@
         return false;
     }
 
+    public String getVersion() {
+        return VersionBean.VERSION.getResourceVersion();
+    }
+
 }

Modified: root/trunk/core/impl/src/main/java/org/richfaces/resource/AbstractBaseResource.java
===================================================================
--- root/trunk/core/impl/src/main/java/org/richfaces/resource/AbstractBaseResource.java	2010-08-02 19:10:54 UTC (rev 18324)
+++ root/trunk/core/impl/src/main/java/org/richfaces/resource/AbstractBaseResource.java	2010-08-02 19:36:31 UTC (rev 18325)
@@ -161,9 +161,9 @@
         String resourceVersion = getResourceVersion();
         String resourceUri = resourceCodec.encodeResourceRequestPath(context, libraryName, resourceName, 
             resourceData, resourceVersion);
+        
+        resourceUri = resourceCodec.encodeJSFMapping(context, resourceUri);
 
-        resourceUri = Util.encodeJSFURL(context, resourceUri);
-
         if (LOGGER.isDebugEnabled()) {
             LOGGER.debug(MessageFormat.format("Request path for {0} resource is: {1}", String.valueOf(resourceName),
                 String.valueOf(resourceUri)));

Modified: root/trunk/core/impl/src/main/java/org/richfaces/resource/DefaultResourceCodec.java
===================================================================
--- root/trunk/core/impl/src/main/java/org/richfaces/resource/DefaultResourceCodec.java	2010-08-02 19:10:54 UTC (rev 18324)
+++ root/trunk/core/impl/src/main/java/org/richfaces/resource/DefaultResourceCodec.java	2010-08-02 19:36:31 UTC (rev 18325)
@@ -29,46 +29,22 @@
 
 public final class DefaultResourceCodec implements ResourceCodec {
 
-    private static final String RESOURCE_VERSION_PARAM = "v";
+    private static final String VERSION_PARAM = "v";
 
-    private static final String RESOURCE_DATA_BYTES_ARRAY_PARAM = "db";
+    private static final String DATA_BYTES_ARRAY_PARAM = "db";
     
-    private static final String RESOURCE_DATA_OBJECT_PARAM = "do";
+    private static final String DATA_OBJECT_PARAM = "do";
 
     private static final String LIBRARY_NAME_PARAM = "ln";
 
-    public String decodeResourceName(FacesContext context, String requestPath) {
-        return requestPath;
+    String encodeResource(DefaultResourceCodecData data) {
+        return encodeResource(data.getLibraryName(), data.getResourceName(), data.getDataString(), 
+            data.isDataSerialized(), data.getVersion());
     }
-
-    public String decodeLibraryName(FacesContext context, String requestPath) {
-        Map<String, String> paramMap = context.getExternalContext().getRequestParameterMap();
-        return paramMap.get(LIBRARY_NAME_PARAM);
-    }
     
-    public Object decodeResourceData(FacesContext context, String requestPath) {
-        Map<String, String> paramMap = context.getExternalContext().getRequestParameterMap();
+    String encodeResource(String libraryName, String resourceName, 
+        String encodedResourceData, boolean dataIsSerialized, String resourceVersion) {
         
-        String encodedData = paramMap.get(RESOURCE_DATA_BYTES_ARRAY_PARAM);
-        if (encodedData != null) {
-            return Util.decodeBytesData(encodedData);
-        } else {
-            encodedData = paramMap.get(RESOURCE_DATA_OBJECT_PARAM);
-            if (encodedData != null) {
-                return Util.decodeObjectData(encodedData);
-            }
-        }
-        
-        return null;
-    }
-
-    public String decodeResourceVersion(FacesContext context, String requestPath) {
-        return context.getExternalContext().getRequestParameterMap().get(RESOURCE_VERSION_PARAM);
-    }
-
-    private String encodeResource(FacesContext context, String libraryName, String resourceName, 
-        String encodedResourceData, boolean dataIsBytesArray, String resourceVersion) {
-        
         boolean parameterAppended = false;
         
         StringBuilder sb = new StringBuilder();
@@ -80,7 +56,7 @@
                 parameterAppended = true;
             }
             
-            sb.append(RESOURCE_VERSION_PARAM);
+            sb.append(VERSION_PARAM);
             sb.append('=');
             sb.append(Util.encodeURIQueryPart(resourceVersion));
         }
@@ -93,7 +69,7 @@
                 sb.append('&');
             }
             
-            sb.append(dataIsBytesArray ? RESOURCE_DATA_BYTES_ARRAY_PARAM : RESOURCE_DATA_OBJECT_PARAM);
+            sb.append(dataIsSerialized ? DATA_OBJECT_PARAM : DATA_BYTES_ARRAY_PARAM);
             sb.append('=');
             sb.append(Util.encodeURIQueryPart(encodedResourceData));
         }
@@ -116,38 +92,38 @@
     
     public String encodeResourceRequestPath(FacesContext context, String libraryName, String resourceName, Object resourceData, String resourceVersion) {
         String encodedDataString = null;
-        boolean isBytesArray = false;
+        boolean dataIsSerialized = false;
         if (resourceData != null) {
             if (resourceData instanceof byte[]) {
-                isBytesArray = true;
                 encodedDataString = Util.encodeBytesData((byte[]) resourceData);
             } else {
                 encodedDataString = Util.encodeObjectData(resourceData);
+                dataIsSerialized = true;
             }
         }
 
         return ResourceHandlerImpl.RICHFACES_RESOURCE_IDENTIFIER
-            + encodeResource(context, libraryName, resourceName, encodedDataString, isBytesArray, resourceVersion);
+            + encodeResource(libraryName, resourceName, encodedDataString, dataIsSerialized, resourceVersion);
     }
     
     public String encodeJSFMapping(FacesContext context, String resourcePath) {
         return Util.encodeJSFURL(context, resourcePath);
     }
     
-    public String getResourceKey(FacesContext context, String requestPath) {
-        Map<String, String> paramMap = context.getExternalContext().getRequestParameterMap();
-        
-        boolean isBytesArray = true;
-        String resourceDataString = paramMap.get(RESOURCE_DATA_BYTES_ARRAY_PARAM);
-        if (resourceDataString == null) {
-            resourceDataString = paramMap.get(RESOURCE_DATA_OBJECT_PARAM);
-            isBytesArray = false;
+    public ResourceCodecData decodeResource(FacesContext context, String requestPath) {
+        Map<String, String> params = context.getExternalContext().getRequestParameterMap();
+        DefaultResourceCodecData data = new DefaultResourceCodecData(this);
+        data.setResourceName(requestPath);
+        data.setLibraryName(params.get(LIBRARY_NAME_PARAM));
+        data.setVersion(params.get(VERSION_PARAM));
+
+        String objectDataString = params.get(DATA_OBJECT_PARAM);
+        if (objectDataString != null) {
+            data.setDataString(objectDataString);
+            data.setDataSerialized(true);
+        } else {
+            data.setDataString(params.get(DATA_BYTES_ARRAY_PARAM));
         }
-        
-        String resourceVersionString = paramMap.get(RESOURCE_VERSION_PARAM);
-        
-        return encodeResource(context, decodeLibraryName(context, requestPath), 
-            decodeResourceName(context, requestPath), 
-            resourceDataString, isBytesArray, resourceVersionString);
+        return data;
     }
 }

Added: root/trunk/core/impl/src/main/java/org/richfaces/resource/DefaultResourceCodecData.java
===================================================================
--- root/trunk/core/impl/src/main/java/org/richfaces/resource/DefaultResourceCodecData.java	                        (rev 0)
+++ root/trunk/core/impl/src/main/java/org/richfaces/resource/DefaultResourceCodecData.java	2010-08-02 19:36:31 UTC (rev 18325)
@@ -0,0 +1,113 @@
+/*
+ * 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.resource;
+
+import org.richfaces.util.Util;
+
+/**
+ * @author Nick Belaevski
+ * 
+ */
+final class DefaultResourceCodecData implements ResourceCodecData {
+
+    private DefaultResourceCodec defaultResourceCodec;
+    
+    public DefaultResourceCodecData(DefaultResourceCodec defaultResourceCodec) {
+        super();
+        this.defaultResourceCodec = defaultResourceCodec;
+    }
+
+    private String resourceName;
+    
+    private String libraryName;
+    
+    private String version;
+    
+    private String dataString;
+    
+    private boolean dataSerialized;
+    
+    //lazy evaluated
+    private String resourceKey = null;
+    
+    //lazy evaluated
+    private Object data = null;
+
+    protected void setResourceName(String resourceName) {
+        this.resourceName = resourceName;
+    }
+
+    public String getResourceName() {
+        return resourceName;
+    }
+    
+    protected void setLibraryName(String libraryName) {
+        this.libraryName = libraryName;
+    }
+
+    public String getLibraryName() {
+        return libraryName;
+    }
+    
+    protected void setVersion(String version) {
+        this.version = version;
+    }
+
+    public String getVersion() {
+        return version;
+    }
+    
+    public String getResourceKey() {
+        if (resourceKey == null) {
+            resourceKey = defaultResourceCodec.encodeResource(this);
+        }
+        return resourceKey;
+    }
+
+    protected String getDataString() {
+        return dataString;
+    }
+    
+    protected void setDataString(String dataString) {
+        this.dataString = dataString;
+    }
+
+    protected void setDataSerialized(boolean dataSerialized) {
+        this.dataSerialized = dataSerialized;
+    }
+    
+    protected boolean isDataSerialized() {
+        return dataSerialized;
+    }
+    
+    public Object getData() {
+        if (data == null && dataString != null) {
+            if (isDataSerialized()) {
+                data = Util.decodeObjectData(dataString);
+            } else {
+                data = Util.decodeBytesData(dataString);
+            }
+        }
+        
+        return data;
+    }
+}

Added: root/trunk/core/impl/src/main/java/org/richfaces/resource/ResourceFactoryImpl.java
===================================================================
--- root/trunk/core/impl/src/main/java/org/richfaces/resource/ResourceFactoryImpl.java	                        (rev 0)
+++ root/trunk/core/impl/src/main/java/org/richfaces/resource/ResourceFactoryImpl.java	2010-08-02 19:36:31 UTC (rev 18325)
@@ -0,0 +1,295 @@
+/*
+ * 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.resource;
+
+import java.net.URL;
+import java.text.MessageFormat;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.Set;
+
+import javax.faces.application.Resource;
+import javax.faces.application.ResourceHandler;
+import javax.faces.context.FacesContext;
+
+import org.richfaces.application.DependencyInjector;
+import org.richfaces.application.ServiceTracker;
+import org.richfaces.skin.SkinFactory;
+import org.richfaces.util.PropertiesUtil;
+import org.richfaces.util.Util;
+
+import com.google.common.collect.Maps;
+
+/**
+ * @author Nick Belaevski
+ * 
+ */
+public class ResourceFactoryImpl implements ResourceFactory {
+
+    private static final String SKINNED_RESOURCE_PREFIX = "%skin%/";
+
+    private static final ResourceLogger LOGGER = ResourceLogger.INSTANCE;
+
+    private static class ResourceLocator {
+        
+        private String resourcePath;
+        
+        public ResourceLocator(String resourcePath) {
+            super();
+            this.resourcePath = resourcePath;
+        }
+
+        public String locateResource(FacesContext facesContext) {
+            return resourcePath;
+        }
+        
+    }
+
+    private static final class SkinResourceLocator extends ResourceLocator {
+        
+        public SkinResourceLocator(String resourcePath) {
+            super(resourcePath);
+        }
+
+        @Override
+        public String locateResource(FacesContext facesContext) {
+            SkinFactory skinFactory = SkinFactory.getInstance(facesContext);
+
+            String skinName = skinFactory.getSkin(facesContext).getName();
+            return skinName + '/' + super.locateResource(facesContext);
+        }
+    }
+    
+    private ResourceHandler defaultHandler;
+    
+    private Map<String, ResourceLocator> resourceLocatorsMap; 
+    
+    public ResourceFactoryImpl(ResourceHandler defaultHandler) {
+        super();
+        this.defaultHandler = defaultHandler;
+        
+        initializeResourceLocatorsMap();
+    }
+
+    private void initializeResourceLocatorsMap() {
+        resourceLocatorsMap = Maps.newHashMap();
+        
+        Properties properties = new Properties();
+        PropertiesUtil.loadProperties(properties, "META-INF/resources/org.richfaces/resource-mappings.properties");
+        
+        Set<Entry<Object, Object>> entries = properties.entrySet();
+        for (Entry<Object, Object> entry : entries) {
+            String resourceKey = (String) entry.getKey();
+            
+            ResourceLocator resourceLocator;
+            String resourcePath = (String) entry.getValue();
+            if (resourcePath.startsWith(SKINNED_RESOURCE_PREFIX)) {
+                resourceLocator = new SkinResourceLocator(resourcePath.substring(SKINNED_RESOURCE_PREFIX.length()));
+            } else {
+                resourceLocator = new ResourceLocator(resourcePath);
+            }
+            
+            resourceLocatorsMap.put(resourceKey, resourceLocator);
+        }
+        
+        resourceLocatorsMap = Collections.unmodifiableMap(resourceLocatorsMap);
+    }
+    
+    private String extractParametersFromResourceName(String resourceName) {
+        if (!(resourceName.lastIndexOf("?") != -1)) {
+            return resourceName;
+        }
+        return resourceName.substring(0, resourceName.lastIndexOf("?"));
+    }
+
+    private Resource createCompiledCSSResource(String resourceName, String libraryName) {
+        Resource sourceResource = defaultHandler.createResource(resourceName, libraryName, "text/plain");
+        if (sourceResource != null) {
+            return new CompiledCSSResource(sourceResource);
+        }
+        
+        return null;
+    }
+    
+    protected void injectProperties(Object resource, Map<String, String> parameters) {
+        FacesContext facesContext = FacesContext.getCurrentInstance();
+
+        Map<Object, Object> attributes = facesContext.getAttributes();
+        try {
+            attributes.put(ResourceParameterELResolver.CONTEXT_ATTRIBUTE_NAME, parameters);
+            ServiceTracker.getService(DependencyInjector.class).inject(facesContext,resource);
+        } finally {
+            attributes.remove(ResourceParameterELResolver.CONTEXT_ATTRIBUTE_NAME);
+        }
+    }
+
+    /**
+     * Should be called only if {@link #isResourceExists(String)} returns <code>true</code>
+     *
+     * @param resourceName
+     * @return
+     */
+    protected Resource createHandlerDependentResource(String resourceName, Map<String, String> parameters) {
+        Resource resource = null;
+        ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
+
+        if (contextClassLoader != null) {
+            try {
+                Class<?> loadedClass = Class.forName(resourceName, false, contextClassLoader);
+
+                boolean legitimateResource = false;
+
+                DynamicResource annotation = loadedClass.getAnnotation(DynamicResource.class);
+                legitimateResource = (annotation != null);
+                if (legitimateResource) {
+                    LOGGER.debug(
+                        MessageFormat.format("Dynamic resource annotation is present on resource class {0}", resourceName));
+                } else {
+                    LOGGER.debug(
+                        MessageFormat.format("Dynamic resource annotation is not present on resource class {0}", resourceName));
+                }
+
+                if (!legitimateResource) {
+                    // TODO resource marker extension name?
+                    URL resourceMarkerUrl = contextClassLoader.getResource("META-INF/" + resourceName + ".resource.properties");
+
+                    legitimateResource = resourceMarkerUrl != null;
+
+                    if (LOGGER.isDebugEnabled()) {
+                        if (legitimateResource) {
+                            LOGGER.debug(
+                                MessageFormat.format("Marker file for {0} resource found in classpath", resourceName));
+                        } else {
+                            LOGGER.debug(
+                                MessageFormat.format("Marker file for {0} resource does not exist", resourceName));
+                        }
+                    }
+                }
+
+                if (legitimateResource) {
+                    Object wrappedResource;
+                    if (Java2DUserResource.class.isAssignableFrom(loadedClass)) {
+                        Java2DUserResource java2DUserResource = (Java2DUserResource) loadedClass.newInstance();
+                        wrappedResource = java2DUserResource;
+                        resource = new Java2DUserResourceWrapperImpl(java2DUserResource);
+                    } else if (UserResource.class.isAssignableFrom(loadedClass)) {
+                        UserResource userResource = (UserResource) loadedClass.newInstance();
+                        wrappedResource = userResource;
+                        resource = new UserResourceWrapperImpl(userResource);
+                    } else {
+                        Class<? extends Resource> resourceClass = loadedClass.asSubclass(Resource.class);
+                        resource = (Resource) resourceClass.newInstance();
+                        wrappedResource = resource;
+                    }
+
+                    if (parameters != null) {
+                        injectProperties(wrappedResource, parameters);
+                    }
+
+                    resource.setResourceName(resourceName);
+                    if (LOGGER.isDebugEnabled()) {
+                        LOGGER.debug(MessageFormat.format("Successfully created instance of {0} resource",
+                            resourceName));
+                    }
+                }
+            } catch (ClassNotFoundException e) {
+                //do nothing
+            } catch (Exception e) {
+                LOGGER.logResourceProblem(FacesContext.getCurrentInstance(), e, "Error creating resource {0}", resourceName);
+            } catch (LinkageError e) {
+                LOGGER.logResourceProblem(FacesContext.getCurrentInstance(), e, "Error creating resource {0}", resourceName);
+            }
+        }
+
+        return resource;
+    }
+    
+    public Resource createResource(FacesContext context, ResourceCodecData resourceData) {
+        String resourceName = resourceData.getResourceName();
+
+        if ((resourceName == null) || (resourceName.length() == 0)) {
+            return null;
+        }
+
+        String libraryName = resourceData.getLibraryName();
+        Resource resource = createResource(resourceName, libraryName, null);
+
+        if (resource == null) {
+            LOGGER.logMissingResource(context, resourceData.getResourceKey());
+            return null;
+        }
+
+        if (resource instanceof VersionedResource) {
+            VersionedResource versionedResource = (VersionedResource) resource;
+            String existingVersion = versionedResource.getVersion();
+            String requestedVersion = resourceData.getVersion();
+
+            if (LOGGER.isDebugEnabled()) {
+                LOGGER.debug(
+                    MessageFormat.format(
+                        "Client requested {0} version of resource, server has {1} version",
+                        String.valueOf(requestedVersion), String.valueOf(existingVersion)));
+            }
+
+            if ((existingVersion != null) && (requestedVersion != null)
+                && !existingVersion.equals(requestedVersion)) {
+                LOGGER.logResourceProblem(context, null, "Resource {0} of version {1} was not found", resourceName,
+                    requestedVersion);
+                return null;
+            }
+        }
+
+        Object decodedData = resourceData.getData();
+
+        if (LOGGER.isDebugEnabled()) {
+            if (decodedData != null) {
+                LOGGER.debug("Resource state data succesfully decoded");
+            } else {
+                LOGGER.debug("Resource state data decoded as null");
+            }
+        }
+        
+        Util.restoreResourceState(context, resource, decodedData);
+        
+        return resource;
+    }
+    
+    public Resource createResource(String resourceName, String libraryName, String contentType) {
+        Resource result = null;
+        Map<String, String> params = Util.parseResourceParameters(resourceName);
+        resourceName = extractParametersFromResourceName(resourceName);
+        if (resourceName.endsWith(".ecss")) {
+            //TODO nick - params?
+            result = createCompiledCSSResource(resourceName, libraryName);
+        } else {
+            //TODO nick - libraryName as package name?
+            if ((resourceName != null) && ((libraryName == null) || (libraryName.length() == 0))) {
+                result = createHandlerDependentResource(resourceName, params);
+            }
+        }
+    
+        return result;
+    }
+    
+}

Modified: root/trunk/core/impl/src/main/java/org/richfaces/resource/ResourceHandlerImpl.java
===================================================================
--- root/trunk/core/impl/src/main/java/org/richfaces/resource/ResourceHandlerImpl.java	2010-08-02 19:10:54 UTC (rev 18324)
+++ root/trunk/core/impl/src/main/java/org/richfaces/resource/ResourceHandlerImpl.java	2010-08-02 19:36:31 UTC (rev 18325)
@@ -24,14 +24,12 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.net.URL;
 import java.text.MessageFormat;
 import java.util.Date;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Map.Entry;
 
-import javax.faces.application.ProjectStage;
 import javax.faces.application.Resource;
 import javax.faces.application.ResourceHandler;
 import javax.faces.application.ResourceHandlerWrapper;
@@ -42,24 +40,24 @@
 import javax.servlet.http.HttpServletResponse;
 
 import org.ajax4jsf.cache.Cache;
-import org.richfaces.application.DependencyInjector;
 import org.richfaces.application.ServiceTracker;
-import org.richfaces.log.RichfacesLogger;
 import org.richfaces.util.RequestStateManager.BooleanRequestStateVariable;
 import org.richfaces.util.Util;
-import org.slf4j.Logger;
 
 /**
  * @author Nick Belaevski
  * @since 4.0
  */
+//TODO extract caching
 public class ResourceHandlerImpl extends ResourceHandlerWrapper {
     public static final String RICHFACES_RESOURCE_IDENTIFIER = "/rfRes/";
     public static final String RESOURCE_CACHE_NAME = "org.richfaces.ResourcesCache";
     public static final String HANDLER_START_TIME_ATTRIBUTE = ResourceHandlerImpl.class.getName() + ":StartTime";
 
-    private static final Logger LOGGER = RichfacesLogger.RESOURCE.getLogger();
+    private static final ResourceLogger LOGGER = ResourceLogger.INSTANCE;
 
+    private ResourceFactory resourceFactory;
+    
     // TODO - review - do we need this?
     static {
 
@@ -72,6 +70,8 @@
 
             thread.setContextClassLoader(systemCL);
             ImageIO.setUseCache(false);
+        } catch (Exception e) {
+            LOGGER.error(e.getMessage(), e);
         } finally {
             thread.setContextClassLoader(initialTCCL);
         }
@@ -81,7 +81,8 @@
 
     public ResourceHandlerImpl(ResourceHandler defaultHandler) {
         this.defaultHandler = defaultHandler;
-
+        this.resourceFactory = new ResourceFactoryImpl(defaultHandler);
+        
         if (LOGGER.isDebugEnabled()) {
             LOGGER.debug(MessageFormat.format("Instance of {0} resource handler created", getClass().getName()));
         }
@@ -148,42 +149,10 @@
         context.getExternalContext().setResponseStatus(HttpServletResponse.SC_NOT_MODIFIED);
     }
 
-    private void logResourceProblem(FacesContext context, Throwable throwable, String messagePattern,
-        Object... arguments) {
-        boolean isProductionStage = context.isProjectStage(ProjectStage.Production);
-
-        if (LOGGER.isWarnEnabled() || (!isProductionStage && LOGGER.isInfoEnabled())) {
-            String formattedMessage = MessageFormat.format(messagePattern, arguments);
-
-            if (throwable != null) {
-                LOGGER.warn(formattedMessage, throwable);
-            } else {
-                if (isProductionStage) {
-                    LOGGER.info(formattedMessage);
-                } else {
-                    LOGGER.warn(formattedMessage);
-                }
-            }
-        }
-    }
-
-    private void logMissingResource(FacesContext context, String resourceData) {
-        logResourceProblem(context, null, "Resource {0} was not found", resourceData);
-    }
-
     private static void sendResourceNotFound(FacesContext context) {
         context.getExternalContext().setResponseStatus(HttpServletResponse.SC_NOT_FOUND);
     }
 
-    private Resource createCompiledCSSResource(String resourceName, String libraryName) {
-        Resource sourceResource = defaultHandler.createResource(resourceName, libraryName, "text/plain");
-        if (sourceResource != null) {
-            return new CompiledCSSResource(sourceResource);
-        }
-        
-        return null;
-    }
-    
     @Override
     public void handleResourceRequest(FacesContext context) throws IOException {
         if (isThisHandlerResourceRequest(context)) {
@@ -193,102 +162,49 @@
 
             assert (resourcePath != null) && (resourcePath.length() != 0);
 
-            String resourceKey = resourceCodec.getResourceKey(context, resourcePath);
+            ResourceCodecData data = resourceCodec.decodeResource(context, resourcePath);
+            assert (data != null);
 
-            assert (resourceKey != null) && (resourceKey.length() != 0);
-
             Cache cache = ServiceTracker.getService(context, Cache.class);
-            Resource resource = lookupInCache(cache, resourceKey);
+            Resource resource = lookupInCache(cache, data.getResourceKey());
 
             if (resource == null) {
-                String resourceName = resourceCodec.decodeResourceName(context, resourcePath);
+                resource = resourceFactory.createResource(context, data);
+            }
+            
+            if (resource == null) {
+                sendResourceNotFound(context);
+                return;
+            }
+            
+            if (resource instanceof CacheableResource) {
+                CacheableResource cacheableResource = (CacheableResource) resource;
 
-                if ((resourceName == null) || (resourceName.length() == 0)) {
-                    logMissingResource(context, resourceKey);
-                    sendResourceNotFound(context);
+                if (cacheableResource.isCacheable(context)) {
 
-                    return;
-                }
+                    // TODO - we could move this part of code to ConcurrentMap so that
+                    // only single thread does resource put
+                    CachedResourceImpl cachedResource = new CachedResourceImpl();
 
-                if (resourceName.lastIndexOf(".ecss") != -1) {
-                    String libraryName = resourceCodec.decodeLibraryName(context, resourcePath);
-                    resource = createCompiledCSSResource(resourceName, libraryName);
-                }
+                    cachedResource.initialize(resource);
 
-                if (resource == null) {
-                    resource = createHandlerDependentResource(resourceName, null);
-                }
+                    // someone may provided this resource for us
+                    // while we were reading it, check once again
+                    resource = lookupInCache(cache, data.getResourceKey());
 
-                if (resource == null) {
-                    logMissingResource(context, resourceName);
-                    sendResourceNotFound(context);
+                    if (resource == null) {
+                        Date cacheExpirationDate = cachedResource.getExpired(context);
 
-                    return;
-                }
+                        if (LOGGER.isDebugEnabled()) {
+                            LOGGER.debug(new MessageFormat(
+                                "Storing {0} resource in cache until {1,date,dd MMM yyyy HH:mm:ss zzz}", Locale.US).
+                                format(new Object[]{data.getResourceKey(), cacheExpirationDate}));
+                        }
 
-                if (resource instanceof VersionedResource) {
-                    VersionedResource versionedResource = (VersionedResource) resource;
-                    String existingVersion = versionedResource.getVersion();
-                    String requestedVersion = resourceCodec.decodeResourceVersion(context, resourcePath);
-
-                    if (LOGGER.isDebugEnabled()) {
-                        LOGGER.debug(
-                            MessageFormat.format(
-                                "Client requested {0} version of resource, server has {1} version",
-                                String.valueOf(requestedVersion), String.valueOf(existingVersion)));
+                        cache.put(data.getResourceKey(), cachedResource, cacheExpirationDate);
+                        resource = cachedResource;
                     }
-
-                    if ((existingVersion != null) && (requestedVersion != null)
-                        && !existingVersion.equals(requestedVersion)) {
-                        logResourceProblem(context, null, "Resource {0} of version {1} was not found", resourceName,
-                            requestedVersion);
-                        sendResourceNotFound(context);
-
-                        return;
-                    }
                 }
-
-                Object decodedData = resourceCodec.decodeResourceData(context, resourcePath);
-
-                if (LOGGER.isDebugEnabled()) {
-                    if (decodedData != null) {
-                        LOGGER.debug("Resource state data succesfully decoded");
-                    } else {
-                        LOGGER.debug("Resource state data decoded as null");
-                    }
-                }
-                
-                Util.restoreResourceState(context, resource, decodedData);
-
-                if (resource instanceof AbstractCacheableResource) {
-                    AbstractCacheableResource cacheableResource = (AbstractCacheableResource) resource;
-
-                    if (cacheableResource.isCacheable(context)) {
-
-                        // TODO - we could move this part of code to ConcurrentMap so that
-                        // only single thread does resource put
-                        CachedResourceImpl cachedResource = new CachedResourceImpl();
-
-                        cachedResource.initialize(resource);
-
-                        // someone may provided this resource for us
-                        // while we were reading it, check once again
-                        resource = lookupInCache(cache, resourceKey);
-
-                        if (resource == null) {
-                            Date cacheExpirationDate = cachedResource.getExpired(context);
-
-                            if (LOGGER.isDebugEnabled()) {
-                                LOGGER.debug(new MessageFormat(
-                                    "Storing {0} resource in cache until {1,date,dd MMM yyyy HH:mm:ss zzz}", Locale.US).
-                                    format(new Object[]{resourceKey, cacheExpirationDate}));
-                            }
-
-                            cache.put(resourceKey, cachedResource, cacheExpirationDate);
-                            resource = cachedResource;
-                        }
-                    }
-                }
             }
 
             if (resource.userAgentNeedsUpdate(context)) {
@@ -366,127 +282,16 @@
         }
     }
 
-    protected void injectProperties(Object resource, Map<String, String> parameters) {
-        FacesContext facesContext = FacesContext.getCurrentInstance();
-
-        Map<Object, Object> attributes = facesContext.getAttributes();
-        try {
-            attributes.put(ResourceParameterELResolver.CONTEXT_ATTRIBUTE_NAME, parameters);
-            ServiceTracker.getService(DependencyInjector.class).inject(facesContext,resource);
-        } finally {
-            attributes.remove(ResourceParameterELResolver.CONTEXT_ATTRIBUTE_NAME);
-        }
-    }
-
-    /**
-     * Should be called only if {@link #isResourceExists(String)} returns <code>true</code>
-     *
-     * @param resourceName
-     * @return
-     */
-    protected Resource createHandlerDependentResource(String resourceName, Map<String, String> parameters) {
-        Resource resource = null;
-        ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
-
-        if (contextClassLoader != null) {
-            try {
-                Class<?> loadedClass = Class.forName(resourceName, false, contextClassLoader);
-
-                boolean legitimateResource = false;
-
-                DynamicResource annotation = loadedClass.getAnnotation(DynamicResource.class);
-                legitimateResource = (annotation != null);
-                if (legitimateResource) {
-                    LOGGER.debug(
-                        MessageFormat.format("Dynamic resource annotation is present on resource class {0}", resourceName));
-                } else {
-                    LOGGER.debug(
-                        MessageFormat.format("Dynamic resource annotation is not present on resource class {0}", resourceName));
-                }
-
-                if (!legitimateResource) {
-                    // TODO resource marker extension name?
-                    URL resourceMarkerUrl = contextClassLoader.getResource("META-INF/" + resourceName + ".resource.properties");
-
-                    legitimateResource = resourceMarkerUrl != null;
-
-                    if (LOGGER.isDebugEnabled()) {
-                        if (legitimateResource) {
-                            LOGGER.debug(
-                                MessageFormat.format("Marker file for {0} resource found in classpath", resourceName));
-                        } else {
-                            LOGGER.debug(
-                                MessageFormat.format("Marker file for {0} resource does not exist", resourceName));
-                        }
-                    }
-                }
-
-                if (legitimateResource) {
-                    Object wrappedResource;
-                    if (Java2DUserResource.class.isAssignableFrom(loadedClass)) {
-                        Java2DUserResource java2DUserResource = (Java2DUserResource) loadedClass.newInstance();
-                        wrappedResource = java2DUserResource;
-                        resource = new Java2DUserResourceWrapperImpl(java2DUserResource);
-                    } else if (UserResource.class.isAssignableFrom(loadedClass)) {
-                        UserResource userResource = (UserResource) loadedClass.newInstance();
-                        wrappedResource = userResource;
-                        resource = new UserResourceWrapperImpl(userResource);
-                    } else {
-                        Class<? extends Resource> resourceClass = loadedClass.asSubclass(Resource.class);
-                        resource = (Resource) resourceClass.newInstance();
-                        wrappedResource = resource;
-                    }
-
-                    if (parameters != null) {
-                        injectProperties(wrappedResource, parameters);
-                    }
-
-                    resource.setResourceName(resourceName);
-                    if (LOGGER.isDebugEnabled()) {
-                        LOGGER.debug(MessageFormat.format("Successfully created instance of {0} resource",
-                            resourceName));
-                    }
-                }
-            } catch (ClassNotFoundException e) {
-                //do nothing
-            } catch (Exception e) {
-                logResourceProblem(FacesContext.getCurrentInstance(), e, "Error creating resource {0}", resourceName);
-            } catch (LinkageError e) {
-                logResourceProblem(FacesContext.getCurrentInstance(), e, "Error creating resource {0}", resourceName);
-            }
-        }
-
-        return resource;
-    }
-
     @Override
     public Resource createResource(String resourceName, String libraryName, String contentType) {
-        Resource result = null;
-        Map<String, String> params = Util.parseResourceParameters(resourceName);
-        resourceName = extractParametersFromResourceName(resourceName);
-        if (resourceName.lastIndexOf(".ecss") != -1) {
-            //TODO nick - params?
-            result = createCompiledCSSResource(resourceName, libraryName);
-        } else {
-            //TODO nick - libraryName as package name?
-            if ((resourceName != null) && ((libraryName == null) || (libraryName.length() == 0))) {
-                result = createHandlerDependentResource(resourceName, params);
-            }
+        Resource resource = resourceFactory.createResource(resourceName, libraryName, contentType);
+        if (resource == null) {
+            resource = defaultHandler.createResource(resourceName, libraryName, contentType);
         }
-        if (result == null) {
-            result = defaultHandler.createResource(resourceName, libraryName, contentType);
-        }
-    
-        return result;
+        
+        return resource;
     }
 
-    private String extractParametersFromResourceName(String resourceName) {
-        if (!(resourceName.lastIndexOf("?") != -1)) {
-            return resourceName;
-        }
-        return resourceName.substring(0, resourceName.lastIndexOf("?"));
-    }
-
     @Override
     public Resource createResource(String resourceName, String libraryName) {
         return createResource(resourceName, libraryName, null);

Added: root/trunk/core/impl/src/main/java/org/richfaces/resource/ResourceLogger.java
===================================================================
--- root/trunk/core/impl/src/main/java/org/richfaces/resource/ResourceLogger.java	                        (rev 0)
+++ root/trunk/core/impl/src/main/java/org/richfaces/resource/ResourceLogger.java	2010-08-02 19:36:31 UTC (rev 18325)
@@ -0,0 +1,313 @@
+/*
+ * 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.resource;
+
+import java.text.MessageFormat;
+
+import javax.faces.application.ProjectStage;
+import javax.faces.context.FacesContext;
+
+import org.richfaces.log.RichfacesLogger;
+import org.slf4j.Logger;
+import org.slf4j.Marker;
+
+/**
+ * @author Nick Belaevski
+ * 
+ */
+final class ResourceLogger implements Logger {
+
+    static final ResourceLogger INSTANCE = new ResourceLogger();
+
+    private static final Logger LOGGER = RichfacesLogger.RESOURCE.getLogger();
+    
+    private ResourceLogger() {}
+
+    void logResourceProblem(FacesContext context, Throwable throwable, String messagePattern,
+        Object... arguments) {
+        boolean isProductionStage = context.isProjectStage(ProjectStage.Production);
+
+        if (LOGGER.isWarnEnabled() || (!isProductionStage && LOGGER.isInfoEnabled())) {
+            String formattedMessage = MessageFormat.format(messagePattern, arguments);
+
+            if (throwable != null) {
+                LOGGER.warn(formattedMessage, throwable);
+            } else {
+                if (isProductionStage) {
+                    LOGGER.info(formattedMessage);
+                } else {
+                    LOGGER.warn(formattedMessage);
+                }
+            }
+        }
+    }
+
+    void logMissingResource(FacesContext context, String resourceData) {
+        logResourceProblem(context, null, "Resource {0} was not found", resourceData);
+    }
+
+    public String getName() {
+        return LOGGER.getName();
+    }
+
+    public boolean isTraceEnabled() {
+        return LOGGER.isTraceEnabled();
+    }
+
+    public void trace(String msg) {
+        LOGGER.trace(msg);
+    }
+
+    public void trace(String format, Object arg) {
+        LOGGER.trace(format, arg);
+    }
+
+    public void trace(String format, Object arg1, Object arg2) {
+        LOGGER.trace(format, arg1, arg2);
+    }
+
+    public void trace(String format, Object[] argArray) {
+        LOGGER.trace(format, argArray);
+    }
+
+    public void trace(String msg, Throwable t) {
+        LOGGER.trace(msg, t);
+    }
+
+    public boolean isTraceEnabled(Marker marker) {
+        return LOGGER.isTraceEnabled(marker);
+    }
+
+    public void trace(Marker marker, String msg) {
+        LOGGER.trace(marker, msg);
+    }
+
+    public void trace(Marker marker, String format, Object arg) {
+        LOGGER.trace(marker, format, arg);
+    }
+
+    public void trace(Marker marker, String format, Object arg1, Object arg2) {
+        LOGGER.trace(marker, format, arg1, arg2);
+    }
+
+    public void trace(Marker marker, String format, Object[] argArray) {
+        LOGGER.trace(marker, format, argArray);
+    }
+
+    public void trace(Marker marker, String msg, Throwable t) {
+        LOGGER.trace(marker, msg, t);
+    }
+
+    public boolean isDebugEnabled() {
+        return LOGGER.isDebugEnabled();
+    }
+
+    public void debug(String msg) {
+        LOGGER.debug(msg);
+    }
+
+    public void debug(String format, Object arg) {
+        LOGGER.debug(format, arg);
+    }
+
+    public void debug(String format, Object arg1, Object arg2) {
+        LOGGER.debug(format, arg1, arg2);
+    }
+
+    public void debug(String format, Object[] argArray) {
+        LOGGER.debug(format, argArray);
+    }
+
+    public void debug(String msg, Throwable t) {
+        LOGGER.debug(msg, t);
+    }
+
+    public boolean isDebugEnabled(Marker marker) {
+        return LOGGER.isDebugEnabled(marker);
+    }
+
+    public void debug(Marker marker, String msg) {
+        LOGGER.debug(marker, msg);
+    }
+
+    public void debug(Marker marker, String format, Object arg) {
+        LOGGER.debug(marker, format, arg);
+    }
+
+    public void debug(Marker marker, String format, Object arg1, Object arg2) {
+        LOGGER.debug(marker, format, arg1, arg2);
+    }
+
+    public void debug(Marker marker, String format, Object[] argArray) {
+        LOGGER.debug(marker, format, argArray);
+    }
+
+    public void debug(Marker marker, String msg, Throwable t) {
+        LOGGER.debug(marker, msg, t);
+    }
+
+    public boolean isInfoEnabled() {
+        return LOGGER.isInfoEnabled();
+    }
+
+    public void info(String msg) {
+        LOGGER.info(msg);
+    }
+
+    public void info(String format, Object arg) {
+        LOGGER.info(format, arg);
+    }
+
+    public void info(String format, Object arg1, Object arg2) {
+        LOGGER.info(format, arg1, arg2);
+    }
+
+    public void info(String format, Object[] argArray) {
+        LOGGER.info(format, argArray);
+    }
+
+    public void info(String msg, Throwable t) {
+        LOGGER.info(msg, t);
+    }
+
+    public boolean isInfoEnabled(Marker marker) {
+        return LOGGER.isInfoEnabled(marker);
+    }
+
+    public void info(Marker marker, String msg) {
+        LOGGER.info(marker, msg);
+    }
+
+    public void info(Marker marker, String format, Object arg) {
+        LOGGER.info(marker, format, arg);
+    }
+
+    public void info(Marker marker, String format, Object arg1, Object arg2) {
+        LOGGER.info(marker, format, arg1, arg2);
+    }
+
+    public void info(Marker marker, String format, Object[] argArray) {
+        LOGGER.info(marker, format, argArray);
+    }
+
+    public void info(Marker marker, String msg, Throwable t) {
+        LOGGER.info(marker, msg, t);
+    }
+
+    public boolean isWarnEnabled() {
+        return LOGGER.isWarnEnabled();
+    }
+
+    public void warn(String msg) {
+        LOGGER.warn(msg);
+    }
+
+    public void warn(String format, Object arg) {
+        LOGGER.warn(format, arg);
+    }
+
+    public void warn(String format, Object[] argArray) {
+        LOGGER.warn(format, argArray);
+    }
+
+    public void warn(String format, Object arg1, Object arg2) {
+        LOGGER.warn(format, arg1, arg2);
+    }
+
+    public void warn(String msg, Throwable t) {
+        LOGGER.warn(msg, t);
+    }
+
+    public boolean isWarnEnabled(Marker marker) {
+        return LOGGER.isWarnEnabled(marker);
+    }
+
+    public void warn(Marker marker, String msg) {
+        LOGGER.warn(marker, msg);
+    }
+
+    public void warn(Marker marker, String format, Object arg) {
+        LOGGER.warn(marker, format, arg);
+    }
+
+    public void warn(Marker marker, String format, Object arg1, Object arg2) {
+        LOGGER.warn(marker, format, arg1, arg2);
+    }
+
+    public void warn(Marker marker, String format, Object[] argArray) {
+        LOGGER.warn(marker, format, argArray);
+    }
+
+    public void warn(Marker marker, String msg, Throwable t) {
+        LOGGER.warn(marker, msg, t);
+    }
+
+    public boolean isErrorEnabled() {
+        return LOGGER.isErrorEnabled();
+    }
+
+    public void error(String msg) {
+        LOGGER.error(msg);
+    }
+
+    public void error(String format, Object arg) {
+        LOGGER.error(format, arg);
+    }
+
+    public void error(String format, Object arg1, Object arg2) {
+        LOGGER.error(format, arg1, arg2);
+    }
+
+    public void error(String format, Object[] argArray) {
+        LOGGER.error(format, argArray);
+    }
+
+    public void error(String msg, Throwable t) {
+        LOGGER.error(msg, t);
+    }
+
+    public boolean isErrorEnabled(Marker marker) {
+        return LOGGER.isErrorEnabled(marker);
+    }
+
+    public void error(Marker marker, String msg) {
+        LOGGER.error(marker, msg);
+    }
+
+    public void error(Marker marker, String format, Object arg) {
+        LOGGER.error(marker, format, arg);
+    }
+
+    public void error(Marker marker, String format, Object arg1, Object arg2) {
+        LOGGER.error(marker, format, arg1, arg2);
+    }
+
+    public void error(Marker marker, String format, Object[] argArray) {
+        LOGGER.error(marker, format, argArray);
+    }
+
+    public void error(Marker marker, String msg, Throwable t) {
+        LOGGER.error(marker, msg, t);
+    }
+
+
+}

Modified: root/trunk/core/impl/src/main/java/org/richfaces/skin/AbstractSkinFactory.java
===================================================================
--- root/trunk/core/impl/src/main/java/org/richfaces/skin/AbstractSkinFactory.java	2010-08-02 19:10:54 UTC (rev 18324)
+++ root/trunk/core/impl/src/main/java/org/richfaces/skin/AbstractSkinFactory.java	2010-08-02 19:36:31 UTC (rev 18325)
@@ -21,10 +21,6 @@
  */
 package org.richfaces.skin;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.Enumeration;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Properties;
@@ -40,10 +36,8 @@
 import javax.faces.context.FacesContext;
 
 import org.ajax4jsf.Messages;
-import org.ajax4jsf.resource.util.URLToStreamHelper;
 import org.ajax4jsf.util.ELUtils;
-import org.richfaces.log.RichfacesLogger;
-import org.slf4j.Logger;
+import org.richfaces.util.PropertiesUtil;
 
 /**
  * @author Nick Belaevski
@@ -80,7 +74,6 @@
      * user-defined.
      */
     private static final String[] SKINS_PATHS = {DEFAULT_SKIN_PATH, USER_SKIN_PATH};
-    private static final Logger LOG = RichfacesLogger.APPLICATION.getLogger();
 
     private ConcurrentMap<String, FutureTask<Skin>> skins = new ConcurrentHashMap<String, FutureTask<Skin>>();
 
@@ -134,8 +127,6 @@
      * @throws SkinNotFoundException
      */
     protected Properties loadProperties(String name, String[] paths) throws SkinNotFoundException {
-        ClassLoader loader = getClassLoader();
-    
         // Get properties for concrete skin.
         Properties skinProperties = new Properties();
         int loadedPropertiesCount = 0;
@@ -143,7 +134,7 @@
         for (int i = 0; i < paths.length; i++) {
             String skinPropertiesLocation = paths[i].replaceAll("%s", name);
     
-            if (loadProperties(loader, skinProperties, skinPropertiesLocation)) {
+            if (PropertiesUtil.loadProperties(skinProperties, skinPropertiesLocation)) {
                 loadedPropertiesCount++;
             }
         }
@@ -155,54 +146,6 @@
         return skinProperties;
     }
 
-    /**
-     * @param loader
-     * @param properties
-     * @param location
-     */
-    protected boolean loadProperties(ClassLoader loader, Properties properties, String location) {
-        boolean loaded = false;
-    
-        try {
-            Enumeration<URL> resources = loader.getResources(location);
-    
-            while (resources.hasMoreElements()) {
-                URL url = (URL) resources.nextElement();
-                InputStream propertyStream = null;
-    
-                try {
-                    propertyStream = URLToStreamHelper.urlToStream(url);
-                    properties.load(propertyStream);
-                    loaded = true;
-                } catch (IOException e) {
-                    LOG.warn(Messages.getMessage(Messages.SKIN_PROPERTIES_IO_ERROR), e);
-    
-                    continue;
-                } finally {
-                    if (null != propertyStream) {
-                        propertyStream.close();
-                    }
-                }
-            }
-        } catch (IOException e) {
-    
-            // Do nothing - we can only log error, and continue to load next
-            // property.
-            if (LOG.isInfoEnabled()) {
-                LOG.info(Messages.getMessage(Messages.SKIN_PROPERTIES_IO_ERROR), e);
-            }
-        }
-    
-        return loaded;
-    }
-
-    /**
-     * @return
-     */
-    protected ClassLoader getClassLoader() {
-        return Thread.currentThread().getContextClassLoader();
-    }
-
     @Override
     public Skin getSkin(FacesContext context, String name) {
         if (null == name) {

Added: root/trunk/core/impl/src/main/java/org/richfaces/util/PropertiesUtil.java
===================================================================
--- root/trunk/core/impl/src/main/java/org/richfaces/util/PropertiesUtil.java	                        (rev 0)
+++ root/trunk/core/impl/src/main/java/org/richfaces/util/PropertiesUtil.java	2010-08-02 19:36:31 UTC (rev 18325)
@@ -0,0 +1,90 @@
+/*
+ * 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.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.text.MessageFormat;
+import java.util.Enumeration;
+import java.util.Properties;
+
+import org.ajax4jsf.resource.util.URLToStreamHelper;
+import org.richfaces.log.RichfacesLogger;
+import org.slf4j.Logger;
+
+/**
+ * @author Nick Belaevski
+ * 
+ */
+public final class PropertiesUtil {
+
+    private static final Logger LOGGER = RichfacesLogger.UTIL.getLogger();
+    
+    private PropertiesUtil() {
+    }
+
+    private static ClassLoader getClassLoader() {
+        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+        if (classLoader == null) {
+            classLoader = PropertiesUtil.class.getClassLoader();
+        }
+        
+        return classLoader;
+    }
+    
+    public static boolean loadProperties(Properties properties, String location) {
+        boolean loaded = false;
+        
+        try {
+            Enumeration<URL> resources = getClassLoader().getResources(location);
+    
+            while (resources.hasMoreElements()) {
+                URL url = (URL) resources.nextElement();
+                InputStream propertyStream = null;
+    
+                try {
+                    propertyStream = URLToStreamHelper.urlToStream(url);
+                    properties.load(propertyStream);
+                    loaded = true;
+                } catch (IOException e) {
+                    LOGGER.warn(MessageFormat.format("Failure loading properties from URL: {0}", url.toExternalForm()), e);
+    
+                    continue;
+                } finally {
+                    if (null != propertyStream) {
+                        propertyStream.close();
+                    }
+                }
+            }
+        } catch (IOException e) {
+    
+            // Do nothing - we can only log error, and continue to load next
+            // property.
+            if (LOGGER.isInfoEnabled()) {
+                LOGGER.warn(MessageFormat.format("Failure loading properties from location: {0}", location), e);
+            }
+        }
+    
+        return loaded;
+    }
+}

Modified: root/trunk/core/impl/src/test/java/org/richfaces/resource/AbstractBaseResourceTest.java
===================================================================
--- root/trunk/core/impl/src/test/java/org/richfaces/resource/AbstractBaseResourceTest.java	2010-08-02 19:10:54 UTC (rev 18324)
+++ root/trunk/core/impl/src/test/java/org/richfaces/resource/AbstractBaseResourceTest.java	2010-08-02 19:36:31 UTC (rev 18325)
@@ -137,14 +137,26 @@
             EasyMock.eq("custom.library"),
             EasyMock.eq("org.richfaces.resource.MockStateAwareResource"),
             EasyMock.aryEq(resourceState.getBytes()), EasyMock.eq("4_0_alpha"))).andReturn("/rfRes/Resource0/4_0_alpha/data?l=custom.library");
+        
+        EasyMock.expect(resourceCodec.encodeJSFMapping(EasyMock.same(facesContext), EasyMock.eq("/rfRes/Resource0/4_0_alpha/data?l=custom.library"))).
+            andReturn("/rfRes/Resource0/4_0_alpha/data.jsf?l=custom.library");
+        
         EasyMock.expect(resourceCodec.encodeResourceRequestPath(EasyMock.same(facesContext), 
             EasyMock.eq("custom.library"),
             EasyMock.eq("org.richfaces.resource.MockStateAwareResource"),
             EasyMock.eq(null), EasyMock.eq("4_0_alpha"))).andReturn("/rfRes/Resource1/4_0_alpha?l=custom.library");
+
+        EasyMock.expect(resourceCodec.encodeJSFMapping(EasyMock.same(facesContext), EasyMock.eq("/rfRes/Resource1/4_0_alpha?l=custom.library"))).
+            andReturn("/rfRes/Resource1/4_0_alpha.jsf?l=custom.library");
+
         EasyMock.expect(resourceCodec.encodeResourceRequestPath(EasyMock.same(facesContext), 
             EasyMock.<String>isNull(),
             EasyMock.eq("org.richfaces.resource.MockResource"),
             EasyMock.eq(null), EasyMock.eq("4_0_alpha"))).andReturn("/rfRes/Resource2/4_0_alpha");
+
+        EasyMock.expect(resourceCodec.encodeJSFMapping(EasyMock.same(facesContext), EasyMock.eq("/rfRes/Resource2/4_0_alpha"))).
+            andReturn("/rfRes/Resource2/4_0_alpha.jsf");
+
         EasyMock.replay(resourceCodec);
         ServicesFactoryImpl injector = new ServicesFactoryImpl();
         injector.init(Collections.<Module>singletonList(new Module(){

Modified: root/trunk/core/impl/src/test/java/org/richfaces/resource/ResourceHandlerImplTest.java
===================================================================
--- root/trunk/core/impl/src/test/java/org/richfaces/resource/ResourceHandlerImplTest.java	2010-08-02 19:10:54 UTC (rev 18324)
+++ root/trunk/core/impl/src/test/java/org/richfaces/resource/ResourceHandlerImplTest.java	2010-08-02 19:36:31 UTC (rev 18325)
@@ -23,6 +23,8 @@
 
 package org.richfaces.resource;
 
+import static org.easymock.EasyMock.expect;
+
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileReader;
@@ -227,15 +229,16 @@
         final ResourceCodec mockedCodec = EasyMock.createNiceMock(ResourceCodec.class);
         final org.ajax4jsf.cache.Cache mockCache = EasyMock.createNiceMock(org.ajax4jsf.cache.Cache.class);
 
-        EasyMock.expect(mockedCodec.decodeResourceName(EasyMock.<FacesContext>notNull(), 
-            EasyMock.eq("StateHolderResource"))).andReturn("org.richfaces.resource.StateHolderResourceImpl");
-        EasyMock.expect(mockedCodec.decodeResourceData(EasyMock.<FacesContext>notNull(), 
-            EasyMock.eq("StateHolderResource"))).andReturn("test text".getBytes());
-        EasyMock.expect(mockedCodec.decodeResourceVersion(EasyMock.<FacesContext>notNull(), 
-            EasyMock.eq("StateHolderResource"))).andReturn(null);
-        EasyMock.expect(mockedCodec.getResourceKey(EasyMock.<FacesContext>notNull(), 
-            EasyMock.eq("StateHolderResource"))).andReturn("StateHolderResource.jsf?db=1");
-        EasyMock.replay(mockedCodec,mockCache);
+        ResourceCodecData resourceCodecData = EasyMock.createMock(ResourceCodecData.class);
+        expect(resourceCodecData.getResourceName()).andStubReturn("org.richfaces.resource.StateHolderResourceImpl");
+        expect(resourceCodecData.getLibraryName()).andStubReturn(null);
+        expect(resourceCodecData.getData()).andStubReturn("test text".getBytes());
+        expect(resourceCodecData.getVersion()).andStubReturn(null);
+        expect(resourceCodecData.getResourceKey()).andStubReturn("StateHolderResource.jsf?db=1");
+        
+        EasyMock.expect(mockedCodec.decodeResource(EasyMock.<FacesContext>notNull(), 
+            EasyMock.eq("StateHolderResource"))).andReturn(resourceCodecData);
+        EasyMock.replay(mockedCodec, resourceCodecData, mockCache);
 
         ServicesFactoryImpl injector = new ServicesFactoryImpl();
         injector.init(Collections.<Module>singletonList(new Module(){
@@ -255,6 +258,8 @@
 
         assertEquals(HttpServletResponse.SC_OK, resourceResponse.getStatusCode());
         assertEquals("test text", resourceResponse.getContentAsString("US-ASCII"));
+        
+        EasyMock.verify(mockedCodec, resourceCodecData, mockCache);
     }
 
     public void testVersionedResource() throws Exception {

Modified: root/trunk/core/impl/src/test/java/org/richfaces/resource/StateHolderResourceImpl.java
===================================================================
--- root/trunk/core/impl/src/test/java/org/richfaces/resource/StateHolderResourceImpl.java	2010-08-02 19:10:54 UTC (rev 18324)
+++ root/trunk/core/impl/src/test/java/org/richfaces/resource/StateHolderResourceImpl.java	2010-08-02 19:36:31 UTC (rev 18325)
@@ -42,6 +42,10 @@
 public class StateHolderResourceImpl extends AbstractCacheableResource implements StateHolderResource {
     private Object state = "";
 
+    public StateHolderResourceImpl() {
+        setResourceName(StateHolderResourceImpl.class.getName());
+    }
+    
     @Override
     public InputStream getInputStream() throws IOException {
         try {



More information about the richfaces-svn-commits mailing list