[richfaces-svn-commits] JBoss Rich Faces SVN: r15857 - in root: framework/trunk/api/src/main/java/org/richfaces and 12 other directories.

richfaces-svn-commits at lists.jboss.org richfaces-svn-commits at lists.jboss.org
Mon Nov 9 13:21:58 EST 2009


Author: nbelaevski
Date: 2009-11-09 13:21:57 -0500 (Mon, 09 Nov 2009)
New Revision: 15857

Added:
   root/framework/trunk/api/src/main/java/org/richfaces/application/
   root/framework/trunk/api/src/main/java/org/richfaces/application/ServiceTracker.java
   root/framework/trunk/impl/src/main/java/org/richfaces/application/
   root/framework/trunk/impl/src/main/java/org/richfaces/application/InitializationListener.java
   root/framework/trunk/impl/src/main/resources/META-INF/initialization-listener.faces-config.xml
Removed:
   root/framework/trunk/impl/src/main/java/org/ajax4jsf/event/CacheInitializationListener.java
   root/framework/trunk/impl/src/main/java/org/ajax4jsf/event/InitializationListener.java
   root/framework/trunk/impl/src/main/resources/META-INF/cache.faces-config.xml
Modified:
   root/framework/trunk/api/src/main/java/org/ajax4jsf/component/AjaxClientBehavior.java
   root/framework/trunk/api/src/main/java/org/richfaces/skin/SkinFactory.java
   root/framework/trunk/impl/src/main/java/org/ajax4jsf/renderkit/AJAXDataSerializer.java
   root/framework/trunk/impl/src/main/java/org/ajax4jsf/renderkit/AjaxRendererUtils.java
   root/framework/trunk/impl/src/main/java/org/ajax4jsf/util/ServicesUtils.java
   root/framework/trunk/impl/src/main/java/org/richfaces/context/PartialViewContextImpl.java
   root/framework/trunk/impl/src/main/java/org/richfaces/context/RenderComponentCallback.java
   root/framework/trunk/impl/src/test/java/org/richfaces/skin/SkinTestCase.java
   root/framework/trunk/impl/src/test/resources/javascript/4_0_0.html
   root/ui/trunk/components/core/src/main/java/org/ajax4jsf/component/behavior/AjaxBehavior.java
Log:
https://jira.jboss.org/jira/browse/RF-7823
https://jira.jboss.org/jira/browse/RFPL-12

Modified: root/framework/trunk/api/src/main/java/org/ajax4jsf/component/AjaxClientBehavior.java
===================================================================
--- root/framework/trunk/api/src/main/java/org/ajax4jsf/component/AjaxClientBehavior.java	2009-11-09 14:56:04 UTC (rev 15856)
+++ root/framework/trunk/api/src/main/java/org/ajax4jsf/component/AjaxClientBehavior.java	2009-11-09 18:21:57 UTC (rev 15857)
@@ -57,4 +57,8 @@
     public String getOnbeforedomupdate();
 
     public void setOnbeforedomupdate(String onbeforedomupdate);
+
+    public Object getData();
+    
+    public void setData(Object data);
 }

Added: root/framework/trunk/api/src/main/java/org/richfaces/application/ServiceTracker.java
===================================================================
--- root/framework/trunk/api/src/main/java/org/richfaces/application/ServiceTracker.java	                        (rev 0)
+++ root/framework/trunk/api/src/main/java/org/richfaces/application/ServiceTracker.java	2009-11-09 18:21:57 UTC (rev 15857)
@@ -0,0 +1,121 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, 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.application;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.faces.context.FacesContext;
+
+import org.richfaces.skin.SkinFactory;
+
+/**
+ * <p>Tracker class to provide access to various framework implementation services.
+ * Examples of such services are: {@link SkinFactory}, TBD</p>
+ * 
+ * <p><b>Note:</b> this class is not synchronized and presumes that all modification operations 
+ * should be done in a single-thread (e.g. in initialization listener)</p>
+ * 
+ * @author Nick Belaevski
+ * @since 4.0
+ */
+public final class ServiceTracker {
+
+	private static final String SERVICES_MAP_ATTRIBUTE = ServiceTracker.class.getName();
+	
+	private ServiceTracker() {
+		//utility class private constructor
+	}
+	
+	public static Collection<Class<?>> getRegisteredServiceClasses(FacesContext context) {
+		Map<Class<?>, Object> servicesMap = getServicesMap(context, false);
+		if (servicesMap != null) {
+			return Collections.unmodifiableCollection(servicesMap.keySet());
+		} else {
+			return Collections.emptySet();
+		}
+	}
+	
+	@SuppressWarnings("unchecked")
+	public static <T> T getService(FacesContext context, Class<T> serviceInterfaceClass) {
+		if (context == null) {
+			throw new NullPointerException("context");
+		}
+		
+		if (serviceInterfaceClass == null) {
+			throw new NullPointerException("serviceInterfaceClass");
+		}
+
+		T serviceImplementation = null;
+		
+		Map<Class<?>, Object> servicesMap = getServicesMap(context, false);
+		if (servicesMap != null) {
+			serviceImplementation = (T) servicesMap.get(serviceInterfaceClass);
+		}
+		
+		//TODO - null?
+		return serviceImplementation;
+	}
+
+	public static <T> void setService(FacesContext context, 
+			Class<T> serviceInterfaceClass, 
+			T serviceImplementation) {
+		
+		if (context == null) {
+			throw new NullPointerException("context");
+		}
+		
+		if (serviceInterfaceClass == null) {
+			throw new NullPointerException("serviceInterfaceClass");
+		}
+		
+		if (serviceImplementation == null) {
+			throw new NullPointerException("serviceImplementation");
+		}
+		
+		Map<Class<?>, Object> servicesMap = getServicesMap(context, true);
+		servicesMap.put(serviceInterfaceClass, serviceImplementation);
+	}
+	
+	public static void release(FacesContext context) {
+		clearServicesMap(context);
+	}
+	
+	private static Map<Class<?>, Object> getServicesMap(FacesContext facesContext, boolean createIfNull) {
+		Map<String, Object> applicationMap = facesContext.getExternalContext().getApplicationMap();
+		@SuppressWarnings("unchecked")
+		Map<Class<?>, Object> servicesMap = (Map<Class<?>, Object>) applicationMap.get(SERVICES_MAP_ATTRIBUTE);
+		if (servicesMap == null && createIfNull) {
+			servicesMap = new HashMap<Class<?>, Object>();
+			applicationMap.put(SERVICES_MAP_ATTRIBUTE, servicesMap);
+		}
+		
+		return servicesMap;
+	}
+
+	private static void clearServicesMap(FacesContext facesContext) {
+		Map<String, Object> applicationMap = facesContext.getExternalContext().getApplicationMap();
+		applicationMap.remove(SERVICES_MAP_ATTRIBUTE);
+	}
+}

Modified: root/framework/trunk/api/src/main/java/org/richfaces/skin/SkinFactory.java
===================================================================
--- root/framework/trunk/api/src/main/java/org/richfaces/skin/SkinFactory.java	2009-11-09 14:56:04 UTC (rev 15856)
+++ root/framework/trunk/api/src/main/java/org/richfaces/skin/SkinFactory.java	2009-11-09 18:21:57 UTC (rev 15857)
@@ -23,28 +23,10 @@
 
 package org.richfaces.skin;
 
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.faces.FacesException;
 import javax.faces.context.FacesContext;
 
-import org.ajax4jsf.Messages;
-import org.ajax4jsf.resource.util.URLToStreamHelper;
+import org.richfaces.application.ServiceTracker;
 
-import org.richfaces.log.RichfacesLogger;
-
-import org.slf4j.Logger;
-
 /**
  * Base factory class ( implement Singleton design pattern ). Produce self
  * instance to build current skin configuration. At present, realised as lazy
@@ -55,12 +37,8 @@
  *
  */
 public abstract class SkinFactory {
-    public static final String BASE_SKIN_PARAMETER = "org.richfaces.BASE_SKIN";
 
-    /**
-     * Full class name of default implementation of the SkinFactory class
-     */
-    public static final String DEFAULT_SKIN_FACTORY_IMPL_CLASS = "org.richfaces.skin.SkinFactoryImpl";
+	public static final String BASE_SKIN_PARAMETER = "org.richfaces.BASE_SKIN";
 
     /**
      * Name of web application init parameter for current skin . Can be simple
@@ -72,24 +50,6 @@
     public static final String SKIN_PARAMETER = "org.richfaces.SKIN";
 
     /**
-     * Resource Uri for file with name of class for application-wide SkinFactory same as SPI definitions for
-     * common Java SAX, Jsf etc. factories
-     */
-    public static final String SERVICE_RESOURCE = "META-INF/services/" + SkinFactory.class.getName();
-
-    /**
-     * static instance variable.
-     */
-    private static Map<ClassLoader, SkinFactory> instances = Collections.synchronizedMap(new HashMap<ClassLoader,
-                                                                 SkinFactory>());
-    private static final Logger LOG = RichfacesLogger.APPLICATION.getLogger();
-
-//  public abstract SkinConfiguration getSkinConfiguration(FacesContext context);
-    public static void reset() {
-        instances = Collections.synchronizedMap(new HashMap<ClassLoader, SkinFactory>());
-    }
-
-    /**
      * Initialize skin factory. TODO - make call from init() method of any
      * servlet or custom faces element method ??? If exist resource
      * META-INF/services/org.richfaces.skin.SkinFactory , create
@@ -99,102 +59,10 @@
      * instantiate custom factory, return default.
      */
     public static final SkinFactory getInstance() {
-        ClassLoader loader = Thread.currentThread().getContextClassLoader();
-        SkinFactory instance = (SkinFactory) instances.get(loader);
-
-        if (instance == null) {
-
-            // Pluggable factories.
-            InputStream input = null; // loader.getResourceAsStream(SERVICE_RESOURCE);
-
-            input = URLToStreamHelper.urlToStreamSafe(loader.getResource(SERVICE_RESOURCE));
-
-            // have services file.
-            if (input != null) {
-                try {
-                    BufferedReader reader = new BufferedReader(new InputStreamReader(input));
-                    String factoryClassName = reader.readLine();
-
-                    if (LOG.isDebugEnabled()) {
-                        LOG.debug(Messages.getMessage(Messages.SET_SKIN_FACTORY_INFO, factoryClassName));
-                    }
-
-                    instance = instantiateSkinFactory(factoryClassName, loader);
-                } catch (Exception e) {
-                    LOG.warn(Messages.getMessage(Messages.CREATING_SKIN_FACTORY_ERROR), e);
-                } finally {
-                    try {
-                        input.close();
-                    } catch (IOException e) {
-
-                        // can be ignored
-                    }
-                }
-            }
-
-            if (instance == null) {
-
-                // instantiate default implementation of SkinFactory - org.richfaces.skin.SkinFactoryImpl,
-                // placed in the richfaces-impl.jar
-                instance = instantiateSkinFactory(DEFAULT_SKIN_FACTORY_IMPL_CLASS, loader);
-            }
-
-            instances.put(loader, instance);
-        }
-
-        return instance;
+    	return ServiceTracker.getService(FacesContext.getCurrentInstance(), SkinFactory.class);
     }
 
     /**
-     * Create new instance of class with given name with the help of given <code>ClassLoader</code>.
-     * Instantiated class should extend <code>SkinFactory</code> base class.
-     * @param factoryClassName - class name of SkinFactory
-     * @param classLoader - class loader
-     * @return - instantiated <code>SkinFactory</code>
-     * @throws FacesException - FacesException is thrown when instantiation fails;
-     *                          causing exception is wrapped into <code>FacesException</code>
-     */
-    private static SkinFactory instantiateSkinFactory(String factoryClassName, ClassLoader classLoader)
-        throws FacesException {
-        
-        SkinFactory instance = null;
-
-        try {
-            Class<?> clazz = Class.forName(factoryClassName, false, classLoader);
-
-            try {
-
-                // try construct factory chain.
-                Constructor<?> factoryConstructor = clazz.getConstructor(new Class[] {SkinFactory.class});
-
-                instance = (SkinFactory) factoryConstructor.newInstance(new Object[] {instance});
-            } catch (NoSuchMethodException e) {
-
-                // no chain constructor - attempt default.
-                instance = (SkinFactory) clazz.newInstance();
-            }
-        } catch (InvocationTargetException ite) {
-            LOG.error(Messages.getMessage(Messages.CREATING_SKIN_FACTORY_ERROR), ite);
-
-            throw new FacesException("Exception when creating instance of [" + SkinFactory.class.getName() + "]", ite);
-        } catch (InstantiationException ie) {
-            LOG.error(Messages.getMessage(Messages.CREATING_SKIN_FACTORY_ERROR), ie);
-
-            throw new FacesException("Exception when creating instance of [" + SkinFactory.class.getName() + "]", ie);
-        } catch (IllegalAccessException iae) {
-            LOG.error(Messages.getMessage(Messages.CREATING_SKIN_FACTORY_ERROR), iae);
-
-            throw new FacesException("Exception when creating instance of [" + SkinFactory.class.getName() + "]", iae);
-        } catch (ClassNotFoundException cnfe) {
-            LOG.error(Messages.getMessage(Messages.CREATING_SKIN_FACTORY_ERROR), cnfe);
-
-            throw new FacesException("Exception when creating instance of [" + SkinFactory.class.getName() + "]", cnfe);
-        }
-
-        return instance;
-    }
-
-    /**
      * Get default {@link Skin} implementation.
      *
      * @param context

Deleted: root/framework/trunk/impl/src/main/java/org/ajax4jsf/event/CacheInitializationListener.java
===================================================================
--- root/framework/trunk/impl/src/main/java/org/ajax4jsf/event/CacheInitializationListener.java	2009-11-09 14:56:04 UTC (rev 15856)
+++ root/framework/trunk/impl/src/main/java/org/ajax4jsf/event/CacheInitializationListener.java	2009-11-09 18:21:57 UTC (rev 15857)
@@ -1,26 +0,0 @@
-package org.ajax4jsf.event;
-
-import org.ajax4jsf.cache.CacheManager;
-
-import javax.faces.event.SystemEvent;
-
-/**
- * @author Anton Belevich
- *
- */
-public class CacheInitializationListener extends InitializationListener {
-    @Override
-    public void init(SystemEvent event) {
-
-        // TODO read configuration ??
-    }
-
-    @Override
-    public void destroy(SystemEvent event) {
-        try {
-            CacheManager.getInstance().destroy();
-        } catch (Exception e) {
-            LOG.error("Error during stop caches.", e);
-        }
-    }
-}

Deleted: root/framework/trunk/impl/src/main/java/org/ajax4jsf/event/InitializationListener.java
===================================================================
--- root/framework/trunk/impl/src/main/java/org/ajax4jsf/event/InitializationListener.java	2009-11-09 14:56:04 UTC (rev 15856)
+++ root/framework/trunk/impl/src/main/java/org/ajax4jsf/event/InitializationListener.java	2009-11-09 18:21:57 UTC (rev 15857)
@@ -1,36 +0,0 @@
-package org.ajax4jsf.event;
-
-import org.richfaces.log.RichfacesLogger;
-
-import org.slf4j.Logger;
-
-import javax.faces.application.Application;
-import javax.faces.event.PostConstructApplicationEvent;
-import javax.faces.event.PreDestroyApplicationEvent;
-import javax.faces.event.SystemEvent;
-import javax.faces.event.SystemEventListener;
-
-/**
- * framework initialization listener
- * @author Anton Belevich
- *
- */
-public abstract class InitializationListener implements SystemEventListener {
-    protected static final Logger LOG = RichfacesLogger.CACHE.getLogger();
-
-    public boolean isListenerForSource(Object source) {
-        return source instanceof Application;
-    }
-
-    public void processEvent(SystemEvent event) {
-        if (event instanceof PostConstructApplicationEvent) {
-            init(event);
-        } else if (event instanceof PreDestroyApplicationEvent) {
-            destroy(event);
-        }
-    }
-
-    public abstract void init(SystemEvent event);
-
-    public abstract void destroy(SystemEvent event);
-}

Modified: root/framework/trunk/impl/src/main/java/org/ajax4jsf/renderkit/AJAXDataSerializer.java
===================================================================
--- root/framework/trunk/impl/src/main/java/org/ajax4jsf/renderkit/AJAXDataSerializer.java	2009-11-09 14:56:04 UTC (rev 15856)
+++ root/framework/trunk/impl/src/main/java/org/ajax4jsf/renderkit/AJAXDataSerializer.java	2009-11-09 18:21:57 UTC (rev 15857)
@@ -30,17 +30,8 @@
  *
  */
 public class AJAXDataSerializer {
-    public static final String SERVICE = AJAXDataSerializer.class.getName();
 
     public String asString(Object data) {
-        StringBuffer result = new StringBuffer();
-
-        if (null != data) {
-            result.append("<![CDATA[ ");
-            result.append(ScriptUtils.toScript(data));
-            result.append(" ]]>");
-        }
-
-        return result.toString();
+    	return ScriptUtils.toScript(data);
     }
 }

Modified: root/framework/trunk/impl/src/main/java/org/ajax4jsf/renderkit/AjaxRendererUtils.java
===================================================================
--- root/framework/trunk/impl/src/main/java/org/ajax4jsf/renderkit/AjaxRendererUtils.java	2009-11-09 14:56:04 UTC (rev 15856)
+++ root/framework/trunk/impl/src/main/java/org/ajax4jsf/renderkit/AjaxRendererUtils.java	2009-11-09 18:21:57 UTC (rev 15857)
@@ -53,9 +53,8 @@
 import org.ajax4jsf.javascript.JSFunction;
 import org.ajax4jsf.javascript.JSFunctionDefinition;
 import org.ajax4jsf.javascript.JSReference;
-import org.ajax4jsf.javascript.ScriptUtils;
 import org.ajax4jsf.renderkit.RendererUtils.HTML;
-import org.ajax4jsf.util.ServicesUtils;
+import org.richfaces.application.ServiceTracker;
 import org.richfaces.log.RichfacesLogger;
 import org.slf4j.Logger;
 
@@ -110,6 +109,8 @@
      */
     public static final String ONCOMPLETE_ATTR_NAME = "oncomplete";
 
+    public static final String DATA_ATTR_NAME = "data";
+
     /**
      * Attribute for keep JavaScript function name for call after complete
      * request.
@@ -781,7 +782,20 @@
 
         return (String) component.getAttributes().get(ONBEGIN_ATTR_NAME);
     }
+    
+    /**
+     * @param component
+     * @return
+     * @since 4.0
+     */
+    public static Object getAjaxData(UIComponent component) {
+        if (component instanceof AjaxComponent) {
+            return ((AjaxComponent) component).getData();
+        }
 
+        return component.getAttributes().get(DATA_ATTR_NAME);
+    }
+
     /**
      * Calculate, must be component render only given areas, or all sended from
      * server.
@@ -969,8 +983,7 @@
         Map<String, Object> responseDataMap = ajaxContext.getResponseDataMap();
 
         // Get data serializer instance
-        AJAXDataSerializer serializer =
-            (AJAXDataSerializer) ServicesUtils.getServiceInstance(AJAXDataSerializer.SERVICE);
+        AJAXDataSerializer serializer = ServiceTracker.getService(context, AJAXDataSerializer.class);
 
         // Put data to JavaScript handlers, inside <span> elements.
         for (Map.Entry<String, Object> entry : responseDataMap.entrySet()) {
@@ -1179,7 +1192,11 @@
 		if (responseData != null) {
 			startExtensionElementIfNecessary(writer, attributes, writingState);
 			writer.startElement(DATA_ELEMENT_NAME, component);
-			writer.writeText(ScriptUtils.toScript(responseData), null);
+	        
+			//TODO - encode response data map
+			AJAXDataSerializer serializer = ServiceTracker.getService(facesContext, AJAXDataSerializer.class);
+			writer.writeText(serializer.asString(responseData), null);
+			
 			writer.endElement(DATA_ELEMENT_NAME);
 		}
 		

Modified: root/framework/trunk/impl/src/main/java/org/ajax4jsf/util/ServicesUtils.java
===================================================================
--- root/framework/trunk/impl/src/main/java/org/ajax4jsf/util/ServicesUtils.java	2009-11-09 14:56:04 UTC (rev 15856)
+++ root/framework/trunk/impl/src/main/java/org/ajax4jsf/util/ServicesUtils.java	2009-11-09 18:21:57 UTC (rev 15857)
@@ -43,6 +43,7 @@
  * @author shura
  *
  */
+ at Deprecated
 public final class ServicesUtils {
     private static final Logger LOG = RichfacesLogger.APPLICATION.getLogger();
     private static Map<String, Map<ClassLoader, Class<?>>> services = Collections.synchronizedMap(new HashMap<String,

Added: root/framework/trunk/impl/src/main/java/org/richfaces/application/InitializationListener.java
===================================================================
--- root/framework/trunk/impl/src/main/java/org/richfaces/application/InitializationListener.java	                        (rev 0)
+++ root/framework/trunk/impl/src/main/java/org/richfaces/application/InitializationListener.java	2009-11-09 18:21:57 UTC (rev 15857)
@@ -0,0 +1,176 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, 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.application;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.text.MessageFormat;
+
+import javax.faces.FacesException;
+import javax.faces.context.FacesContext;
+import javax.faces.event.AbortProcessingException;
+import javax.faces.event.PostConstructApplicationEvent;
+import javax.faces.event.PreDestroyApplicationEvent;
+import javax.faces.event.SystemEvent;
+import javax.faces.event.SystemEventListener;
+
+import org.ajax4jsf.cache.CacheManager;
+import org.ajax4jsf.renderkit.AJAXDataSerializer;
+import org.ajax4jsf.resource.util.URLToStreamHelper;
+import org.richfaces.log.RichfacesLogger;
+import org.richfaces.skin.SkinFactory;
+import org.richfaces.skin.SkinFactoryImpl;
+import org.slf4j.Logger;
+
+/**
+ * @author Nick Belaevski
+ * @since 4.0
+ */
+public class InitializationListener implements SystemEventListener {
+
+	private static final String META_INF_SERVICES = "META-INF/services/";
+	
+	private static final Logger LOG = RichfacesLogger.APPLICATION.getLogger();
+	
+	/* (non-Javadoc)
+	 * @see javax.faces.event.SystemEventListener#isListenerForSource(java.lang.Object)
+	 */
+	public boolean isListenerForSource(Object source) {
+		return true;
+	}
+
+	private static <T> T instantiate(Class<T> interfaceClass, 
+			Class<? extends T> implementationClass, 
+			Class<? extends T> defaultImplementationClass) {
+
+		Constructor<? extends T> constructor = null;
+		Object[] constructorArguments = null;
+
+		if (implementationClass != null) {
+			if (defaultImplementationClass != null && !defaultImplementationClass.equals(implementationClass)) {
+				try {
+					constructor = implementationClass.getConstructor(interfaceClass);
+					T defaultImplementation = instantiate(interfaceClass, defaultImplementationClass, null);
+					constructorArguments = new Object[]{defaultImplementation};
+				} catch (NoSuchMethodException e) {
+					/* ignore */ 
+				}
+			}
+
+			if (constructor == null) {
+				try {
+					constructor = implementationClass.getConstructor();
+				} catch (NoSuchMethodException e) {
+					throw new FacesException(MessageFormat.format("Class {0} has no public no-arg constructor", implementationClass.getName()), e);
+				}
+			}
+
+		} else {
+			try {
+				constructor = defaultImplementationClass.getConstructor();
+			} catch (NoSuchMethodException e) {
+				throw new FacesException(MessageFormat.format("Class {0} has no public no-arg constructor", 
+						defaultImplementationClass.getName()), e);
+			}
+		}
+
+		try {
+			return constructor.newInstance(constructorArguments);
+		} catch (IllegalArgumentException e) {
+			throw new FacesException(MessageFormat.format("Cannot instantiate {0} class, error was: {1}", constructor.getDeclaringClass(), e.getMessage()), e);
+		} catch (InstantiationException e) {
+			throw new FacesException(MessageFormat.format("Cannot instantiate {0} class, error was: {1}", constructor.getDeclaringClass(), e.getMessage()), e);
+		} catch (IllegalAccessException e) {
+			throw new FacesException(MessageFormat.format("Cannot instantiate {0} class, error was: {1}", constructor.getDeclaringClass(), e.getMessage()), e);
+		} catch (InvocationTargetException e) {
+			Throwable cause = e.getCause();
+			if (cause == null) {
+				cause = e;
+			}
+			throw new FacesException(MessageFormat.format("Cannot instantiate {0} class, error was: {1}", constructor.getDeclaringClass(), cause.getMessage()), cause);
+		}
+	}
+	
+    private static final <T> T createServiceInstance(Class<T> interfaceClass, Class<? extends T> defaultImplementationClass) {
+    	ClassLoader loader = Thread.currentThread().getContextClassLoader();
+        InputStream input = URLToStreamHelper.urlToStreamSafe(loader.getResource(META_INF_SERVICES + interfaceClass.getName()));
+
+    	Class<? extends T> implementationClass = null;
+
+        // have services file.
+        if (input != null) {
+            try {
+                BufferedReader reader = new BufferedReader(new InputStreamReader(input));
+                String factoryClassName = reader.readLine();
+
+                implementationClass = Class.forName(factoryClassName, false, loader).asSubclass(interfaceClass);
+            } catch (Exception e) {
+    			LOG.warn(MessageFormat.format("Error loading class for {0} service: {1} ", 
+    					interfaceClass.getName(), e.getMessage()), e);
+			} finally {
+            	try {
+                    input.close();
+                } catch (IOException e) {
+                    // can be ignored
+                }
+            }
+        }
+
+        return instantiate(interfaceClass, implementationClass, defaultImplementationClass);
+    }
+
+    protected void onStart() {
+		FacesContext facesContext = FacesContext.getCurrentInstance();
+
+		SkinFactory skinFactory = createServiceInstance(SkinFactory.class, SkinFactoryImpl.class);
+		ServiceTracker.setService(facesContext, SkinFactory.class, skinFactory);
+		
+		AJAXDataSerializer dataSerializer = createServiceInstance(AJAXDataSerializer.class, AJAXDataSerializer.class);
+		ServiceTracker.setService(facesContext, AJAXDataSerializer.class, dataSerializer);
+    }
+    
+    protected void onStop() {
+		FacesContext facesContext = FacesContext.getCurrentInstance();
+
+		ServiceTracker.release(facesContext);
+        CacheManager.getInstance().destroy();
+    }
+    
+	
+	/* (non-Javadoc)
+	 * @see javax.faces.event.SystemEventListener#processEvent(javax.faces.event.SystemEvent)
+	 */
+	public void processEvent(SystemEvent event) throws AbortProcessingException {
+		if (event instanceof PostConstructApplicationEvent) {
+			onStart();
+		} else if (event instanceof PreDestroyApplicationEvent) {
+			onStop();
+		} else {
+			throw new IllegalArgumentException(MessageFormat.format("Event {0} is not supported!", event));
+		}
+	}
+
+}

Modified: root/framework/trunk/impl/src/main/java/org/richfaces/context/PartialViewContextImpl.java
===================================================================
--- root/framework/trunk/impl/src/main/java/org/richfaces/context/PartialViewContextImpl.java	2009-11-09 14:56:04 UTC (rev 15856)
+++ root/framework/trunk/impl/src/main/java/org/richfaces/context/PartialViewContextImpl.java	2009-11-09 18:21:57 UTC (rev 15857)
@@ -47,6 +47,7 @@
 import javax.faces.event.PhaseId;
 
 import org.ajax4jsf.component.AjaxOutput;
+import org.ajax4jsf.context.AjaxContext;
 import org.ajax4jsf.renderkit.AjaxRendererUtils;
 import org.richfaces.log.RichfacesLogger;
 import org.slf4j.Logger;
@@ -288,6 +289,12 @@
 
 				if (!Boolean.TRUE.equals(renderAll) && !ids.contains(ALL)) {
 					addImplicitRenderIds(ids, callback.isLimitRender());
+					
+					//TODO - review
+					AjaxContext ajaxContext = AjaxContext.getCurrentInstance();
+					ajaxContext.setOnbeforedomupdate(callback.getOnbeforedomupdate());
+					ajaxContext.setOncomplete(callback.getOncomplete());
+					ajaxContext.setResponseData(callback.getData());
 				}
 			} else {
 				//TODO - the same as for "execute"

Modified: root/framework/trunk/impl/src/main/java/org/richfaces/context/RenderComponentCallback.java
===================================================================
--- root/framework/trunk/impl/src/main/java/org/richfaces/context/RenderComponentCallback.java	2009-11-09 14:56:04 UTC (rev 15856)
+++ root/framework/trunk/impl/src/main/java/org/richfaces/context/RenderComponentCallback.java	2009-11-09 18:21:57 UTC (rev 15857)
@@ -37,7 +37,13 @@
     
 	private boolean limitRender = false;
 
-    RenderComponentCallback(String behaviorEvent) {
+	private String oncomplete;
+	
+	private String onbeforedomupdate;
+
+	private Object data;
+	
+	RenderComponentCallback(String behaviorEvent) {
         super(behaviorEvent, null);
     }
 
@@ -45,13 +51,32 @@
         return limitRender;
     }
 
-    @Override
+	public String getOnbeforedomupdate() {
+		return onbeforedomupdate;
+	}
+	
+	public String getOncomplete() {
+		return oncomplete;
+	}
+	
+	public Object getData() {
+		return data;
+	}
+
+	@Override
     protected void doVisit(FacesContext context, UIComponent target, AjaxClientBehavior behavior) {
         super.doVisit(context, target, behavior);
+        
         limitRender = AjaxRendererUtils.isAjaxLimitRender(target);
-
+        onbeforedomupdate = AjaxRendererUtils.getAjaxOnBeforeDomUpdate(target);
+        oncomplete = AjaxRendererUtils.getAjaxOncomplete(target);
+        data = AjaxRendererUtils.getAjaxData(target);
+        
         if (behavior != null) {
             limitRender = behavior.isLimitRender();
+            onbeforedomupdate = behavior.getOnbeforedomupdate();
+            oncomplete = behavior.getOncomplete();
+            data = behavior.getData();
         }
     }
 
@@ -64,4 +89,5 @@
     protected Object getBehaviorAttributeValue(AjaxClientBehavior behavior) {
         return behavior.getRender();
     }
+    
 }

Deleted: root/framework/trunk/impl/src/main/resources/META-INF/cache.faces-config.xml
===================================================================
--- root/framework/trunk/impl/src/main/resources/META-INF/cache.faces-config.xml	2009-11-09 14:56:04 UTC (rev 15856)
+++ root/framework/trunk/impl/src/main/resources/META-INF/cache.faces-config.xml	2009-11-09 18:21:57 UTC (rev 15857)
@@ -1,14 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<faces-config xmlns="http://java.sun.com/xml/ns/javaee" version="2.0">	
-	<application>
-		<system-event-listener>
-			<system-event-listener-class>org.ajax4jsf.event.CacheInitializationListener</system-event-listener-class>
-			<system-event-class>javax.faces.event.PreDestroyApplicationEvent</system-event-class>
-		</system-event-listener>
-		<system-event-listener>
-			<system-event-listener-class>org.ajax4jsf.event.CacheInitializationListener</system-event-listener-class>
-			<system-event-class>javax.faces.event.PostConstructApplicationEvent</system-event-class>
-		</system-event-listener>
-	</application>
-	
-</faces-config>		
\ No newline at end of file

Added: root/framework/trunk/impl/src/main/resources/META-INF/initialization-listener.faces-config.xml
===================================================================
--- root/framework/trunk/impl/src/main/resources/META-INF/initialization-listener.faces-config.xml	                        (rev 0)
+++ root/framework/trunk/impl/src/main/resources/META-INF/initialization-listener.faces-config.xml	2009-11-09 18:21:57 UTC (rev 15857)
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faces-config xmlns="http://java.sun.com/xml/ns/javaee" version="2.0">	
+	<name>richfaces</name>
+	<application>
+		<system-event-listener>
+			<system-event-listener-class>org.richfaces.application.InitializationListener</system-event-listener-class>
+			<system-event-class>javax.faces.event.PreDestroyApplicationEvent</system-event-class>
+		</system-event-listener>
+		<system-event-listener>
+			<system-event-listener-class>org.richfaces.application.InitializationListener</system-event-listener-class>
+			<system-event-class>javax.faces.event.PostConstructApplicationEvent</system-event-class>
+		</system-event-listener>
+	</application>
+	
+</faces-config>		
\ No newline at end of file

Modified: root/framework/trunk/impl/src/test/java/org/richfaces/skin/SkinTestCase.java
===================================================================
--- root/framework/trunk/impl/src/test/java/org/richfaces/skin/SkinTestCase.java	2009-11-09 14:56:04 UTC (rev 15856)
+++ root/framework/trunk/impl/src/test/java/org/richfaces/skin/SkinTestCase.java	2009-11-09 18:21:57 UTC (rev 15857)
@@ -49,7 +49,6 @@
 
     @Override
     public void tearDown() throws Exception {
-        SkinFactory.reset();
         super.tearDown();
     }
 

Modified: root/framework/trunk/impl/src/test/resources/javascript/4_0_0.html
===================================================================
--- root/framework/trunk/impl/src/test/resources/javascript/4_0_0.html	2009-11-09 14:56:04 UTC (rev 15856)
+++ root/framework/trunk/impl/src/test/resources/javascript/4_0_0.html	2009-11-09 18:21:57 UTC (rev 15857)
@@ -138,7 +138,7 @@
 			});
 			
 			test("RichFaces.ajax test", function() {
-				expect(3);
+				expect(7);
 				var ajaxSource = "source";
 				var ajaxEvent = "event";
 				var ajaxOptions = {parameters: {'param': 'value'}};
@@ -146,13 +146,11 @@
 					request : function(source, event, options) {
 						equals(source, ajaxSource);
 						equals(event, ajaxEvent);
-						same(options, {
-							'execute': '@component', 
-							'render': '@component', 
-							'param': 'value', 
-							'org.richfaces.ajax.component': 'source', 
-							'source': 'source'
-						});
+						equals(options['execute'], '@component');
+						equals(options['render'], '@component');
+						equals(options['param'], 'value');
+						equals(options['org.richfaces.ajax.component'], 'source');
+						equals(options['source'], 'source');
 					}
 				}
 				RichFaces.ajax(ajaxSource, ajaxEvent, ajaxOptions);

Modified: root/ui/trunk/components/core/src/main/java/org/ajax4jsf/component/behavior/AjaxBehavior.java
===================================================================
--- root/ui/trunk/components/core/src/main/java/org/ajax4jsf/component/behavior/AjaxBehavior.java	2009-11-09 14:56:04 UTC (rev 15856)
+++ root/ui/trunk/components/core/src/main/java/org/ajax4jsf/component/behavior/AjaxBehavior.java	2009-11-09 18:21:57 UTC (rev 15857)
@@ -6,6 +6,7 @@
 import javax.el.ELContext;
 import javax.el.ValueExpression;
 
+import javax.faces.component.UIComponentBase;
 import javax.faces.component.behavior.FacesBehavior;
 import javax.faces.context.FacesContext;
 
@@ -23,6 +24,7 @@
     private String onbeforedomupdate;
     private String onbegin;
     private String oncomplete;
+    private Object data;
     private String queueId;
     private Set<String> render;
     private String similarityGroupingId;
@@ -30,7 +32,7 @@
 
     private static enum Attributes {
         limitRender, queueId, status, render, execute, similarityGroupingId, oncomplete, onbegin, onbeforedomupdate,
-        other;
+        other, data;
 
         public static Attributes toAttribute(String name) {
             try {
@@ -108,6 +110,27 @@
         return this.oncomplete;
     }
 
+    public void setData(Object data) {
+    	this.data = data;
+    	clearInitialState();
+    }
+    
+    public Object getData() {
+    	if (this.data != null) {
+    		return this.data;
+    	}
+    	
+    	ValueExpression ve = getValueExpression(Attributes.data.toString());
+    	
+    	if (ve != null) {
+            ELContext elContext = FacesContext.getCurrentInstance().getELContext();
+
+            return ve.getValue(elContext);
+    	}
+    	
+    	return this.data;
+    }
+    
     @Override
     public void setRender(Collection<String> render) {
         this.render = asSet(render);
@@ -288,6 +311,11 @@
 
                     break;
 
+                case data:
+                    this.data = value != null ? value : null;
+
+                    break;
+
                 default :
                     break;
             }
@@ -312,7 +340,7 @@
                 values = new Object[] {superState};
             }
         } else {
-            values = new Object[10];
+            values = new Object[11];
             values[0] = superState;
             values[1] = limitRender;
             values[2] = execute;
@@ -323,6 +351,7 @@
             values[7] = onbeforedomupdate;
             values[8] = onbegin;
             values[9] = oncomplete;
+            values[10] = UIComponentBase.saveAttachedState(context, data);
         }
 
         return values;
@@ -345,6 +374,7 @@
                 this.onbeforedomupdate = (String) values[7];
                 this.onbegin = (String) values[8];
                 this.oncomplete = (String) values[9];
+                this.data = UIComponentBase.restoreAttachedState(context, values[10]);
                 clearInitialState();
             }
         }



More information about the richfaces-svn-commits mailing list