You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2017/02/03 01:48:37 UTC
svn commit: r1781492 - in /myfaces/core/branches/2.3.x:
api/src/main/java/javax/faces/convert/
api/src/main/java/javax/faces/validator/
impl/src/main/java/org/apache/myfaces/application/
impl/src/main/java/org/apache/myfaces/cdi/behavior/ impl/src/main...
Author: lu4242
Date: Fri Feb 3 01:48:37 2017
New Revision: 1781492
URL: http://svn.apache.org/viewvc?rev=1781492&view=rev
Log:
MYFACES-4079 Implement CDI changes for JSF 2.3 (@FacesConverter and @FacesValidator)
Added:
myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/application/_ApplicationUtils.java
myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/behavior/
myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/converter/
myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/converter/ConverterInfo.java
myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/converter/DynamicConverterProducer.java
myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/converter/FacesConverterAnnotationLiteral.java
myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/converter/FacesConverterCDIWrapper.java
myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/converter/FacesConverterExtension.java
myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/validator/
myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/validator/DynamicValidatorProducer.java
myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/validator/FacesValidatorAnnotationLiteral.java
myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/validator/FacesValidatorCDIWrapper.java
myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/validator/FacesValidatorExtension.java
myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/validator/ValidatorInfo.java
Modified:
myfaces/core/branches/2.3.x/api/src/main/java/javax/faces/convert/FacesConverter.java
myfaces/core/branches/2.3.x/api/src/main/java/javax/faces/validator/FacesValidator.java
myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java
myfaces/core/branches/2.3.x/impl/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
Modified: myfaces/core/branches/2.3.x/api/src/main/java/javax/faces/convert/FacesConverter.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.3.x/api/src/main/java/javax/faces/convert/FacesConverter.java?rev=1781492&r1=1781491&r2=1781492&view=diff
==============================================================================
--- myfaces/core/branches/2.3.x/api/src/main/java/javax/faces/convert/FacesConverter.java (original)
+++ myfaces/core/branches/2.3.x/api/src/main/java/javax/faces/convert/FacesConverter.java Fri Feb 3 01:48:37 2017
@@ -23,13 +23,15 @@ import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
+import javax.inject.Qualifier;
/**
* @since 2.0
*/
@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.TYPE)
+@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
@Inherited
+@Qualifier
public @interface FacesConverter
{
/**
@@ -44,4 +46,6 @@ public @interface FacesConverter
* @return
*/
public String value() default "";
+
+ public boolean managed() default false;
}
Modified: myfaces/core/branches/2.3.x/api/src/main/java/javax/faces/validator/FacesValidator.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.3.x/api/src/main/java/javax/faces/validator/FacesValidator.java?rev=1781492&r1=1781491&r2=1781492&view=diff
==============================================================================
--- myfaces/core/branches/2.3.x/api/src/main/java/javax/faces/validator/FacesValidator.java (original)
+++ myfaces/core/branches/2.3.x/api/src/main/java/javax/faces/validator/FacesValidator.java Fri Feb 3 01:48:37 2017
@@ -23,6 +23,7 @@ import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
+import javax.inject.Qualifier;
/**
* @since 2.0
@@ -30,6 +31,7 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Inherited
+@Qualifier
public @interface FacesValidator
{
/**
@@ -43,4 +45,7 @@ public @interface FacesValidator
* {@link javax.faces.application.Application#addDefaultValidatorId(java.lang.String)}.</
*/
boolean isDefault() default false;
+
+ public boolean managed() default false;
+
}
Modified: myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java?rev=1781492&r1=1781491&r2=1781492&view=diff
==============================================================================
--- myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java (original)
+++ myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java Fri Feb 3 01:48:37 2017
@@ -46,6 +46,7 @@ import javax.el.ExpressionFactory;
import javax.el.MethodExpression;
import javax.el.ValueExpression;
import javax.faces.FacesException;
+import javax.faces.FacesWrapper;
import javax.faces.application.Application;
import javax.faces.application.NavigationHandler;
import javax.faces.application.ProjectStage;
@@ -67,6 +68,7 @@ import javax.faces.component.search.Sear
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.DateTimeConverter;
+import javax.faces.convert.FacesConverter;
import javax.faces.el.MethodBinding;
import javax.faces.el.PropertyResolver;
import javax.faces.el.ReferenceSyntaxException;
@@ -85,6 +87,7 @@ import javax.faces.render.ClientBehavior
import javax.faces.render.RenderKit;
import javax.faces.render.Renderer;
import javax.faces.render.RendererWrapper;
+import javax.faces.validator.FacesValidator;
import javax.faces.validator.Validator;
import javax.faces.view.ViewDeclarationLanguage;
import javax.naming.Context;
@@ -96,6 +99,8 @@ import org.apache.myfaces.application.cd
import org.apache.myfaces.cdi.util.ExternalArtifactResolver;
import org.apache.myfaces.application.cdi.ValidatorWrapper;
import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFWebConfigParam;
+import org.apache.myfaces.cdi.converter.FacesConverterCDIWrapper;
+import org.apache.myfaces.cdi.validator.FacesValidatorCDIWrapper;
import org.apache.myfaces.component.search.AllSearchKeywordResolver;
import org.apache.myfaces.component.search.ChildSearchKeywordResolver;
import org.apache.myfaces.component.search.CompositeComponentParentSearchKeywordResolver;
@@ -244,6 +249,12 @@ public class ApplicationImpl extends App
private List<Class<? extends Converter>> _noArgConstructorConverterClasses
= new CopyOnWriteArrayList<Class<? extends Converter>>();
+ private Map<Class<? extends Converter>, Boolean> _cdiManagedConverterMap
+ = new ConcurrentHashMap<Class<? extends Converter>, Boolean>();
+
+ private Map<Class<? extends Validator>, Boolean> _cdiManagedValidatorMap
+ = new ConcurrentHashMap<Class<? extends Validator>, Boolean>();
+
/** Value of javax.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE parameter */
private boolean _dateTimeConverterDefaultTimeZoneIsSystemTimeZone = false;
@@ -613,7 +624,8 @@ public class ApplicationImpl extends App
// SystemEventListenerHolder.getListenersForEventClass(java.lang.Class) on it, passing the
// systemEventClass
// argument. If the list is not empty, perform algorithm traverseListenerList on the list.
- event = _traverseListenerList(holder.getListenersForEventClass(systemEventClass), systemEventClass,
+ event = _ApplicationUtils._traverseListenerList(
+ holder.getListenersForEventClass(systemEventClass), systemEventClass,
source, event);
}
@@ -621,7 +633,8 @@ public class ApplicationImpl extends App
if (uiViewRoot != null)
{
//Call listeners on view level
- event = _traverseListenerListWithCopy(uiViewRoot.getViewListenersForEventClass(systemEventClass),
+ event = _ApplicationUtils._traverseListenerListWithCopy(
+ uiViewRoot.getViewListenersForEventClass(systemEventClass),
systemEventClass, source, event);
}
@@ -1554,13 +1567,40 @@ public class ApplicationImpl extends App
throw new FacesException("Could not find any registered converter-class by converterId : " + converterId);
}
+ if (!_cdiManagedConverterMap.containsKey(converterClass))
+ {
+ FacesConverter annotation = converterClass.getAnnotation(FacesConverter.class);
+ if (annotation != null && annotation.managed())
+ {
+ _cdiManagedConverterMap.put(converterClass, true);
+ }
+ else
+ {
+ _cdiManagedConverterMap.put(converterClass, false);
+ }
+ }
+
try
{
- final Converter converter = createConverterInstance(converterClass);
-
- setConverterProperties(converterClass, converter);
+ Converter converter = null;
- _handleAttachedResourceDependencyAnnotations(FacesContext.getCurrentInstance(), converter);
+ if (Boolean.TRUE.equals(_cdiManagedConverterMap.get(converterClass)))
+ {
+ converter = new FacesConverterCDIWrapper(converterClass, null, converterId);
+
+ setConverterProperties(converterClass, ((FacesWrapper<Converter>)converter).getWrapped());
+
+ _handleAttachedResourceDependencyAnnotations(FacesContext.getCurrentInstance(),
+ ((FacesWrapper<Converter>)converter).getWrapped());
+ }
+ else
+ {
+ converter = createConverterInstance(converterClass);
+
+ setConverterProperties(converterClass, converter);
+
+ _handleAttachedResourceDependencyAnnotations(FacesContext.getCurrentInstance(), converter);
+ }
return converter;
}
@@ -1650,39 +1690,62 @@ public class ApplicationImpl extends App
_converterTargetClassToConverterClassMap.remove(targetClass);
}
+ boolean managed = false;
+ if (!_cdiManagedConverterMap.containsKey(converterClass))
+ {
+ FacesConverter annotation = converterClass.getAnnotation(FacesConverter.class);
+ if (annotation != null && annotation.managed())
+ {
+ _cdiManagedConverterMap.put(converterClass, true);
+ }
+ else
+ {
+ _cdiManagedConverterMap.put(converterClass, false);
+ }
+ }
+
Converter converter = null;
- // check cached constructor information
- if (!_noArgConstructorConverterClasses.contains(converterClass))
+ if (Boolean.TRUE.equals(_cdiManagedConverterMap.get(converterClass)))
{
- // the converter class either supports the one-arg constructor
- // or has never been processed before
- try
+ converter = new FacesConverterCDIWrapper(converterClass, targetClass, null);
+
+ setConverterProperties(converterClass, ((FacesWrapper<Converter>)converter).getWrapped());
+ }
+ else
+ {
+ // check cached constructor information
+ if (!_noArgConstructorConverterClasses.contains(converterClass))
{
- // look for a constructor that takes a single Class object
- // See JSF 1.2 javadoc for Converter
- Constructor<? extends Converter> constructor = converterClass
- .getConstructor(new Class[] { Class.class });
+ // the converter class either supports the one-arg constructor
+ // or has never been processed before
+ try
+ {
+ // look for a constructor that takes a single Class object
+ // See JSF 1.2 javadoc for Converter
+ Constructor<? extends Converter> constructor = converterClass
+ .getConstructor(new Class[] { Class.class });
+
+ converter = constructor.newInstance(new Object[] { targetClass });
+ }
+ catch (Exception e)
+ {
+ // the constructor does not exist
+ // add the class to the no-arg constructor classes cache
+ _noArgConstructorConverterClasses.add(converterClass);
- converter = constructor.newInstance(new Object[] { targetClass });
+ // use no-arg constructor
+ converter = createConverterInstance(converterClass);
+ }
}
- catch (Exception e)
+ else
{
- // the constructor does not exist
- // add the class to the no-arg constructor classes cache
- _noArgConstructorConverterClasses.add(converterClass);
-
// use no-arg constructor
converter = createConverterInstance(converterClass);
}
+
+ setConverterProperties(converterClass, converter);
}
- else
- {
- // use no-arg constructor
- converter = createConverterInstance(converterClass);
- }
-
- setConverterProperties(converterClass, converter);
return converter;
}
@@ -2044,12 +2107,37 @@ public class ApplicationImpl extends App
log.severe(message);
throw new FacesException(message);
}
+
+ if (!_cdiManagedValidatorMap.containsKey(validatorClass))
+ {
+ FacesValidator annotation = validatorClass.getAnnotation(FacesValidator.class);
+ if (annotation != null && annotation.managed())
+ {
+ _cdiManagedValidatorMap.put(validatorClass, true);
+ }
+ else
+ {
+ _cdiManagedValidatorMap.put(validatorClass, false);
+ }
+ }
try
{
- Validator validator = createValidatorInstance(validatorClass);
+ Validator validator = null;
- _handleAttachedResourceDependencyAnnotations(FacesContext.getCurrentInstance(), validator);
+ if (Boolean.TRUE.equals(_cdiManagedValidatorMap.get(validatorClass)))
+ {
+ validator = new FacesValidatorCDIWrapper(validatorClass, validatorId);
+
+ _handleAttachedResourceDependencyAnnotations(FacesContext.getCurrentInstance(),
+ ((FacesWrapper<Validator>)validator).getWrapped());
+ }
+ else
+ {
+ validator = createValidatorInstance(validatorClass);
+
+ _handleAttachedResourceDependencyAnnotations(FacesContext.getCurrentInstance(), validator);
+ }
return validator;
}
@@ -2173,41 +2261,6 @@ public class ApplicationImpl extends App
}
}
- private static SystemEvent _createEvent(Class<? extends SystemEvent> systemEventClass, Object source,
- SystemEvent event)
- {
- if (event == null)
- {
- try
- {
- Constructor<?>[] constructors = systemEventClass.getConstructors();
- Constructor<? extends SystemEvent> constructor = null;
- for (Constructor<?> c : constructors)
- {
- if (c.getParameterTypes().length == 1)
- {
- // Safe cast, since the constructor belongs
- // to a class of type SystemEvent
- constructor = (Constructor<? extends SystemEvent>) c;
- break;
- }
- }
- if (constructor != null)
- {
- event = constructor.newInstance(source);
- }
-
- }
- catch (Exception e)
- {
- throw new FacesException("Couldn't instanciate system event of type " +
- systemEventClass.getName(), e);
- }
- }
-
- return event;
- }
-
private void _handleAnnotations(FacesContext context, Object inspected, UIComponent component)
{
// determine the ProjectStage setting via the given FacesContext
@@ -2584,136 +2637,6 @@ public class ApplicationImpl extends App
}
}
- private static SystemEvent _traverseListenerList(List<? extends SystemEventListener> listeners,
- Class<? extends SystemEvent> systemEventClass, Object source,
- SystemEvent event)
- {
- if (listeners != null && !listeners.isEmpty())
- {
- // perf: org.apache.myfaces.application.ApplicationImpl.
- // SystemListenerEntry.getSpecificSourceListenersNotNull(Class<?>)
- // or javax.faces.component.UIComponent.subscribeToEvent(
- // Class<? extends SystemEvent>, ComponentSystemEventListener)
- // creates a ArrayList:
- for (int i = 0, size = listeners.size(); i < size; i++)
- {
- SystemEventListener listener = listeners.get(i);
- // Call SystemEventListener.isListenerForSource(java.lang.Object), passing the source argument.
- // If this returns false, take no action on the listener.
- if (listener.isListenerForSource(source))
- {
- // Otherwise, if the event to be passed to the listener instances has not yet been constructed,
- // construct the event, passing source as the argument to the one-argument constructor that takes
- // an Object. This same event instance must be passed to all listener instances.
- event = _createEvent(systemEventClass, source, event);
-
- // Call SystemEvent.isAppropriateListener(javax.faces.event.FacesListener), passing the listener
- // instance as the argument. If this returns false, take no action on the listener.
- if (event.isAppropriateListener(listener))
- {
- // Call SystemEvent.processListener(javax.faces.event.FacesListener), passing the listener
- // instance.
- event.processListener(listener);
- }
- }
- }
- }
-
- return event;
- }
-
- private static SystemEvent _traverseListenerListWithCopy(List<? extends SystemEventListener> listeners,
- Class<? extends SystemEvent> systemEventClass, Object source,
- SystemEvent event)
- {
- if (listeners != null && !listeners.isEmpty())
- {
- List<SystemEventListener> listenersCopy = new ArrayList<SystemEventListener>();
- int processedListenerIndex = 0;
-
- for (int i = 0; i < listeners.size(); i++)
- {
- listenersCopy.add(listeners.get(i));
- }
-
- // If the inner for is succesful, processedListenerIndex == listenersCopy.size()
- // and the loop will be complete.
- while (processedListenerIndex < listenersCopy.size())
- {
- for (; processedListenerIndex < listenersCopy.size(); processedListenerIndex++ )
- {
- SystemEventListener listener = listenersCopy.get(processedListenerIndex);
- // Call SystemEventListener.isListenerForSource(java.lang.Object), passing the source argument.
- // If this returns false, take no action on the listener.
- if (listener.isListenerForSource(source))
- {
- // Otherwise, if the event to be passed to the listener instances has not yet been constructed,
- // construct the event, passing source as the argument
- // to the one-argument constructor that takes
- // an Object. This same event instance must be passed to all listener instances.
- event = _createEvent(systemEventClass, source, event);
-
- // Call SystemEvent.isAppropriateListener(javax.faces.event.FacesListener), passing the listener
- // instance as the argument. If this returns false, take no action on the listener.
- if (event.isAppropriateListener(listener))
- {
- // Call SystemEvent.processListener(javax.faces.event.FacesListener), passing the listener
- // instance.
- event.processListener(listener);
- }
- }
- }
-
- boolean listChanged = false;
- if (listeners.size() == listenersCopy.size())
- {
- for (int i = 0; i < listenersCopy.size(); i++)
- {
- if (listenersCopy.get(i) != listeners.get(i))
- {
- listChanged = true;
- break;
- }
- }
- }
- else
- {
- listChanged = true;
- }
-
- if (listChanged)
- {
- for (int i = 0; i < listeners.size(); i++)
- {
- SystemEventListener listener = listeners.get(i);
-
- // check if listenersCopy.get(i) is valid
- if (i < listenersCopy.size())
- {
- // The normal case is a listener was added,
- // so as heuristic, check first
- // if we can find it at the same location
- if (!listener.equals(listenersCopy.get(i)) &&
- !listenersCopy.contains(listener))
- {
- listenersCopy.add(listener);
- }
- }
- else
- {
- if (!listenersCopy.contains(listener))
- {
- listenersCopy.add(listener);
- }
- }
- }
- }
- }
- }
-
- return event;
- }
-
/**
* Method to handle determining if the first request has
* been handled by the associated LifecycleImpl.
@@ -2799,10 +2722,11 @@ public class ApplicationImpl extends App
{
if (source != null && _sourceClassMap != null)
{
- event = _traverseListenerList(_sourceClassMap.get(classSource), systemEventClass, source, event);
+ event = _ApplicationUtils._traverseListenerList(
+ _sourceClassMap.get(classSource), systemEventClass, source, event);
}
- _traverseListenerList(_lstSystemEventListener, systemEventClass, source, event);
+ _ApplicationUtils._traverseListenerList(_lstSystemEventListener, systemEventClass, source, event);
}
private void addListenerNoDuplicate(List<SystemEventListener> listeners, SystemEventListener listener)
Added: myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/application/_ApplicationUtils.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/application/_ApplicationUtils.java?rev=1781492&view=auto
==============================================================================
--- myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/application/_ApplicationUtils.java (added)
+++ myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/application/_ApplicationUtils.java Fri Feb 3 01:48:37 2017
@@ -0,0 +1,202 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.myfaces.application;
+
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.List;
+import javax.faces.FacesException;
+import javax.faces.event.SystemEvent;
+import javax.faces.event.SystemEventListener;
+
+/**
+ *
+ * lu4242
+ */
+class _ApplicationUtils
+{
+
+ static SystemEvent _createEvent(Class<? extends SystemEvent> systemEventClass, Object source,
+ SystemEvent event)
+ {
+ if (event == null)
+ {
+ try
+ {
+ Constructor<?>[] constructors = systemEventClass.getConstructors();
+ Constructor<? extends SystemEvent> constructor = null;
+ for (Constructor<?> c : constructors)
+ {
+ if (c.getParameterTypes().length == 1)
+ {
+ // Safe cast, since the constructor belongs
+ // to a class of type SystemEvent
+ constructor = (Constructor<? extends SystemEvent>) c;
+ break;
+ }
+ }
+ if (constructor != null)
+ {
+ event = constructor.newInstance(source);
+ }
+
+ }
+ catch (Exception e)
+ {
+ throw new FacesException("Couldn't instanciate system event of type " +
+ systemEventClass.getName(), e);
+ }
+ }
+
+ return event;
+ }
+
+ static SystemEvent _traverseListenerList(List<? extends SystemEventListener> listeners,
+ Class<? extends SystemEvent> systemEventClass, Object source,
+ SystemEvent event)
+ {
+ if (listeners != null && !listeners.isEmpty())
+ {
+ // perf: org.apache.myfaces.application.ApplicationImpl.
+ // SystemListenerEntry.getSpecificSourceListenersNotNull(Class<?>)
+ // or javax.faces.component.UIComponent.subscribeToEvent(
+ // Class<? extends SystemEvent>, ComponentSystemEventListener)
+ // creates a ArrayList:
+ for (int i = 0, size = listeners.size(); i < size; i++)
+ {
+ SystemEventListener listener = listeners.get(i);
+ // Call SystemEventListener.isListenerForSource(java.lang.Object), passing the source argument.
+ // If this returns false, take no action on the listener.
+ if (listener.isListenerForSource(source))
+ {
+ // Otherwise, if the event to be passed to the listener instances has not yet been constructed,
+ // construct the event, passing source as the argument to the one-argument constructor that takes
+ // an Object. This same event instance must be passed to all listener instances.
+ event = _ApplicationUtils._createEvent(systemEventClass, source, event);
+
+ // Call SystemEvent.isAppropriateListener(javax.faces.event.FacesListener), passing the listener
+ // instance as the argument. If this returns false, take no action on the listener.
+ if (event.isAppropriateListener(listener))
+ {
+ // Call SystemEvent.processListener(javax.faces.event.FacesListener), passing the listener
+ // instance.
+ event.processListener(listener);
+ }
+ }
+ }
+ }
+
+ return event;
+ }
+
+ static SystemEvent _traverseListenerListWithCopy(List<? extends SystemEventListener> listeners,
+ Class<? extends SystemEvent> systemEventClass, Object source,
+ SystemEvent event)
+ {
+ if (listeners != null && !listeners.isEmpty())
+ {
+ List<SystemEventListener> listenersCopy = new ArrayList<SystemEventListener>();
+ int processedListenerIndex = 0;
+
+ for (int i = 0; i < listeners.size(); i++)
+ {
+ listenersCopy.add(listeners.get(i));
+ }
+
+ // If the inner for is succesful, processedListenerIndex == listenersCopy.size()
+ // and the loop will be complete.
+ while (processedListenerIndex < listenersCopy.size())
+ {
+ for (; processedListenerIndex < listenersCopy.size(); processedListenerIndex++ )
+ {
+ SystemEventListener listener = listenersCopy.get(processedListenerIndex);
+ // Call SystemEventListener.isListenerForSource(java.lang.Object), passing the source argument.
+ // If this returns false, take no action on the listener.
+ if (listener.isListenerForSource(source))
+ {
+ // Otherwise, if the event to be passed to the listener instances has not yet been constructed,
+ // construct the event, passing source as the argument
+ // to the one-argument constructor that takes
+ // an Object. This same event instance must be passed to all listener instances.
+ event = _ApplicationUtils._createEvent(systemEventClass, source, event);
+
+ // Call SystemEvent.isAppropriateListener(javax.faces.event.FacesListener), passing the listener
+ // instance as the argument. If this returns false, take no action on the listener.
+ if (event.isAppropriateListener(listener))
+ {
+ // Call SystemEvent.processListener(javax.faces.event.FacesListener), passing the listener
+ // instance.
+ event.processListener(listener);
+ }
+ }
+ }
+
+ boolean listChanged = false;
+ if (listeners.size() == listenersCopy.size())
+ {
+ for (int i = 0; i < listenersCopy.size(); i++)
+ {
+ if (listenersCopy.get(i) != listeners.get(i))
+ {
+ listChanged = true;
+ break;
+ }
+ }
+ }
+ else
+ {
+ listChanged = true;
+ }
+
+ if (listChanged)
+ {
+ for (int i = 0; i < listeners.size(); i++)
+ {
+ SystemEventListener listener = listeners.get(i);
+
+ // check if listenersCopy.get(i) is valid
+ if (i < listenersCopy.size())
+ {
+ // The normal case is a listener was added,
+ // so as heuristic, check first
+ // if we can find it at the same location
+ if (!listener.equals(listenersCopy.get(i)) &&
+ !listenersCopy.contains(listener))
+ {
+ listenersCopy.add(listener);
+ }
+ }
+ else
+ {
+ if (!listenersCopy.contains(listener))
+ {
+ listenersCopy.add(listener);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return event;
+ }
+
+
+}
Added: myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/converter/ConverterInfo.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/converter/ConverterInfo.java?rev=1781492&view=auto
==============================================================================
--- myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/converter/ConverterInfo.java (added)
+++ myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/converter/ConverterInfo.java Fri Feb 3 01:48:37 2017
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.myfaces.cdi.converter;
+
+import java.io.Serializable;
+import java.lang.reflect.Type;
+import java.util.Objects;
+
+/**
+ *
+ */
+public class ConverterInfo implements Serializable
+{
+ private Type type;
+
+ private Class forClass;
+
+ private String converterId;
+
+ public ConverterInfo(Type type, Class forClass, String converterId)
+ {
+ this.type = type;
+ this.forClass = forClass;
+ this.converterId = converterId;
+ }
+
+ /**
+ * @return the converterId
+ */
+ public String getConverterId()
+ {
+ return converterId;
+ }
+
+ /**
+ * @param converterId the converterId to set
+ */
+ public void setConverterId(String converterId)
+ {
+ this.converterId = converterId;
+ }
+
+ public Class getForClass()
+ {
+ return forClass;
+ }
+
+ public void setForClass(Class forClass)
+ {
+ this.forClass = forClass;
+ }
+
+ public Type getType()
+ {
+ return type;
+ }
+
+ public void setType(Type type)
+ {
+ this.type = type;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int hash = 7;
+ hash = 53 * hash + Objects.hashCode(this.type);
+ hash = 53 * hash + Objects.hashCode(this.forClass);
+ hash = 53 * hash + Objects.hashCode(this.converterId);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (obj == null)
+ {
+ return false;
+ }
+ if (getClass() != obj.getClass())
+ {
+ return false;
+ }
+ final ConverterInfo other = (ConverterInfo) obj;
+ if (!Objects.equals(this.type, other.type))
+ {
+ return false;
+ }
+ if (!Objects.equals(this.forClass, other.forClass))
+ {
+ return false;
+ }
+ if (!Objects.equals(this.converterId, other.converterId))
+ {
+ return false;
+ }
+ return true;
+ }
+
+
+}
Added: myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/converter/DynamicConverterProducer.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/converter/DynamicConverterProducer.java?rev=1781492&view=auto
==============================================================================
--- myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/converter/DynamicConverterProducer.java (added)
+++ myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/converter/DynamicConverterProducer.java Fri Feb 3 01:48:37 2017
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.myfaces.cdi.converter;
+
+import java.io.Serializable;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import static java.util.Arrays.asList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.enterprise.context.Dependent;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.Typed;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.enterprise.inject.spi.PassivationCapable;
+import javax.faces.FacesException;
+import javax.faces.convert.Converter;
+import org.apache.myfaces.shared.util.ClassUtils;
+
+/**
+ *
+ */
+@Typed
+public class DynamicConverterProducer implements Bean<Converter>, Serializable, PassivationCapable
+{
+ private static final long serialVersionUID = 1L;
+
+ private BeanManager beanManager;
+ private ConverterInfo typeInfo;
+ private Set<Type> types;
+ private Class<?> beanClass;
+
+ public DynamicConverterProducer(BeanManager beanManager, ConverterInfo typeInfo)
+ {
+ this.beanManager = beanManager;
+ this.typeInfo = typeInfo;
+ types = new HashSet<Type>(asList(typeInfo.getType(), Object.class));
+ beanClass = ClassUtils.simpleClassForName(typeInfo.getType().getTypeName());
+ }
+
+ @Override
+ public String getId()
+ {
+ String forClass = typeInfo.getForClass() == null ? "" :
+ ((typeInfo.getForClass() == Object.class) ? "" : typeInfo.getForClass().getName());
+ String converterId = typeInfo.getConverterId() == null ? "" : typeInfo.getConverterId();
+ return ""+typeInfo.getType()+"_"+forClass+"_"+converterId;
+ }
+
+ @Override
+ public Class<?> getBeanClass()
+ {
+ return beanClass;
+ }
+
+ @Override
+ public Set<Type> getTypes()
+ {
+ return types;
+ }
+
+ @Override
+ public Set<Annotation> getQualifiers()
+ {
+ return Collections.singleton(
+ (Annotation) new FacesConverterAnnotationLiteral(
+ typeInfo.getForClass() == null ? Object.class : typeInfo.getForClass(),
+ typeInfo.getConverterId() == null ? "" : typeInfo.getConverterId(), true));
+ }
+
+ @Override
+ public Class<? extends Annotation> getScope()
+ {
+ return Dependent.class;
+ }
+
+ @Override
+ public String getName()
+ {
+ return null;
+ }
+
+
+ @Override
+ public Set<Class<? extends Annotation>> getStereotypes()
+ {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public boolean isAlternative()
+ {
+ return false;
+ }
+
+ @Override
+ public Set<InjectionPoint> getInjectionPoints()
+ {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public boolean isNullable()
+ {
+ return true;
+ }
+
+ @Override
+ public Converter create(CreationalContext<Converter> cc)
+ {
+ Class<? extends Converter> converterClass = (Class<? extends Converter>) beanClass;
+ Converter converter = null;
+ try
+ {
+ converter = converterClass.newInstance();
+ }
+ catch (Exception ex)
+ {
+ Logger.getLogger(DynamicConverterProducer.class.getName()).log(
+ Level.SEVERE, "Could not instantiate converter " + beanClass.getName().toString(), ex);
+ throw new FacesException("Could not instantiate converter: " + beanClass.getName().toString(), ex);
+
+ }
+ return converter;
+ }
+
+ @Override
+ public void destroy(Converter t, CreationalContext<Converter> cc)
+ {
+ }
+}
Added: myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/converter/FacesConverterAnnotationLiteral.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/converter/FacesConverterAnnotationLiteral.java?rev=1781492&view=auto
==============================================================================
--- myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/converter/FacesConverterAnnotationLiteral.java (added)
+++ myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/converter/FacesConverterAnnotationLiteral.java Fri Feb 3 01:48:37 2017
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.cdi.converter;
+
+import java.util.Objects;
+import javax.enterprise.util.AnnotationLiteral;
+import javax.faces.convert.FacesConverter;
+
+/**
+ *
+ */
+public class FacesConverterAnnotationLiteral extends AnnotationLiteral<FacesConverter> implements FacesConverter
+{
+ private static final long serialVersionUID = 1L;
+
+ private String value;
+ private Class forClass;
+ private boolean managed;
+
+ public FacesConverterAnnotationLiteral(Class forClass, String value, boolean managed)
+ {
+ this.forClass = forClass;
+ this.value = value;
+ this.managed = managed;
+ }
+
+ @Override
+ public String value()
+ {
+ return value;
+ }
+
+ @Override
+ public Class forClass()
+ {
+ return forClass;
+ }
+
+ @Override
+ public boolean managed()
+ {
+ return managed;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int hash = 7;
+ hash = 59 * hash + Objects.hashCode(this.value);
+ hash = 59 * hash + Objects.hashCode(this.forClass);
+ hash = 59 * hash + (this.managed ? 1 : 0);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (obj == null)
+ {
+ return false;
+ }
+ if (getClass() != obj.getClass())
+ {
+ return false;
+ }
+ final FacesConverterAnnotationLiteral other = (FacesConverterAnnotationLiteral) obj;
+ if (!Objects.equals(this.value, other.value))
+ {
+ return false;
+ }
+ if (!Objects.equals(this.forClass, other.forClass))
+ {
+ return false;
+ }
+ if (this.managed != other.managed)
+ {
+ return false;
+ }
+ return true;
+ }
+
+}
Added: myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/converter/FacesConverterCDIWrapper.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/converter/FacesConverterCDIWrapper.java?rev=1781492&view=auto
==============================================================================
--- myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/converter/FacesConverterCDIWrapper.java (added)
+++ myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/converter/FacesConverterCDIWrapper.java Fri Feb 3 01:48:37 2017
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.myfaces.cdi.converter;
+
+import javax.faces.FacesWrapper;
+import javax.faces.component.PartialStateHolder;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.convert.Converter;
+import javax.faces.convert.ConverterException;
+import org.apache.myfaces.cdi.util.CDIUtils;
+
+/**
+ *
+ */
+public class FacesConverterCDIWrapper implements PartialStateHolder, Converter, FacesWrapper<Converter>
+{
+ private transient Converter delegate;
+
+ //private Class<? extends Converter> converterClass;
+ private Class<?> forClass;
+ private String converterId;
+ private boolean _transient;
+
+ public FacesConverterCDIWrapper()
+ {
+ }
+
+ public FacesConverterCDIWrapper(Class<? extends Converter> converterClass, Class<?> forClass, String converterId)
+ {
+ //this.converterClass = converterClass;
+ this.forClass = forClass;
+ this.converterId = converterId;
+ }
+
+ @Override
+ public Object getAsObject(FacesContext context, UIComponent component, String value) throws ConverterException
+ {
+ return getWrapped().getAsObject(context, component, value);
+ }
+
+ @Override
+ public String getAsString(FacesContext context, UIComponent component, Object value) throws ConverterException
+ {
+ return getWrapped().getAsString(context, component, value);
+ }
+
+ @Override
+ public Converter getWrapped()
+ {
+ if (delegate == null)
+ {
+ if (converterId != null)
+ {
+ delegate = (Converter) CDIUtils.getInstance(CDIUtils.getBeanManager(
+ FacesContext.getCurrentInstance().getExternalContext()),
+ Converter.class, true, new FacesConverterAnnotationLiteral(Object.class, converterId, true));
+ }
+ else if (forClass != null)
+ {
+ delegate = (Converter) CDIUtils.getInstance(CDIUtils.getBeanManager(
+ FacesContext.getCurrentInstance().getExternalContext()),
+ Converter.class, true, new FacesConverterAnnotationLiteral(forClass, "", true));
+ }
+ }
+ return delegate;
+ }
+
+ @Override
+ public Object saveState(FacesContext context)
+ {
+ if (!initialStateMarked())
+ {
+ Object values[] = new Object[2];
+ //values[0] = converterClass;
+ values[0] = forClass;
+ values[1] = converterId;
+ return values;
+ }
+ return null;
+ }
+
+ @Override
+ public void restoreState(FacesContext context, Object state)
+ {
+ if (state != null)
+ {
+ Object values[] = (Object[])state;
+ //converterClass = (Class)values[0];
+ forClass = (Class)values[0];
+ converterId = (String)values[1];
+ }
+ }
+
+ @Override
+ public boolean isTransient()
+ {
+ return _transient;
+ }
+
+ @Override
+ public void setTransient(boolean newTransientValue)
+ {
+ _transient = newTransientValue;
+ }
+
+ private boolean _initialStateMarked = false;
+
+ public void clearInitialState()
+ {
+ _initialStateMarked = false;
+ }
+
+ public boolean initialStateMarked()
+ {
+ return _initialStateMarked;
+ }
+
+ public void markInitialState()
+ {
+ _initialStateMarked = true;
+ }
+}
Added: myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/converter/FacesConverterExtension.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/converter/FacesConverterExtension.java?rev=1781492&view=auto
==============================================================================
--- myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/converter/FacesConverterExtension.java (added)
+++ myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/converter/FacesConverterExtension.java Fri Feb 3 01:48:37 2017
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.myfaces.cdi.converter;
+
+import java.lang.reflect.Type;
+import java.util.HashSet;
+import java.util.Set;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.AfterBeanDiscovery;
+import javax.enterprise.inject.spi.Annotated;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.ProcessManagedBean;
+import javax.faces.convert.FacesConverter;
+
+/**
+ *
+ */
+public class FacesConverterExtension implements Extension
+{
+ private Set<ConverterInfo> types = new HashSet<ConverterInfo>();
+
+ public <T> void collect(@Observes ProcessManagedBean<T> event)
+ {
+ if (event.getAnnotatedBeanClass().isAnnotationPresent(FacesConverter.class))
+ {
+ Annotated annotated = event.getAnnotatedBeanClass();
+
+ Type type = annotated.getBaseType();
+
+ FacesConverter conv = (FacesConverter) annotated.getAnnotation(FacesConverter.class);
+
+ if (conv.managed())
+ {
+ boolean hasForClass = !Object.class.equals(conv.forClass());
+ boolean hasValue = conv.value().length() > 0;
+ if (hasForClass || hasValue)
+ {
+ if (hasForClass)
+ {
+ types.add(new ConverterInfo(type, conv.forClass(), ""));
+ }
+ if (hasValue)
+ {
+ types.add(new ConverterInfo(type, Object.class, conv.value()));
+ }
+ }
+ }
+ }
+ }
+
+ public void afterBean(@Observes AfterBeanDiscovery afterBeanDiscovery, BeanManager beanManager)
+ {
+ for (ConverterInfo typeInfo : types)
+ {
+ afterBeanDiscovery.addBean(new DynamicConverterProducer(beanManager, typeInfo));
+ }
+ }
+
+}
Added: myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/validator/DynamicValidatorProducer.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/validator/DynamicValidatorProducer.java?rev=1781492&view=auto
==============================================================================
--- myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/validator/DynamicValidatorProducer.java (added)
+++ myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/validator/DynamicValidatorProducer.java Fri Feb 3 01:48:37 2017
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.myfaces.cdi.validator;
+
+import java.io.Serializable;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import static java.util.Arrays.asList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.enterprise.context.Dependent;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.Typed;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.enterprise.inject.spi.PassivationCapable;
+import javax.faces.FacesException;
+import javax.faces.validator.Validator;
+import org.apache.myfaces.shared.util.ClassUtils;
+
+/**
+ *
+ */
+@Typed
+public class DynamicValidatorProducer implements Bean<Validator>, Serializable, PassivationCapable
+{
+ private static final long serialVersionUID = 1L;
+
+ private BeanManager beanManager;
+ private ValidatorInfo typeInfo;
+ private Set<Type> types;
+ private Class<?> beanClass;
+
+ public DynamicValidatorProducer(BeanManager beanManager, ValidatorInfo typeInfo)
+ {
+ this.beanManager = beanManager;
+ this.typeInfo = typeInfo;
+ types = new HashSet<Type>(asList(typeInfo.getType(), Object.class));
+ beanClass = ClassUtils.simpleClassForName(typeInfo.getType().getTypeName());
+ }
+
+ @Override
+ public String getId()
+ {
+ String converterId = typeInfo.getValidatorId() == null ? "" : typeInfo.getValidatorId();
+ return ""+typeInfo.getType()+"_"+converterId;
+ }
+
+ @Override
+ public Class<?> getBeanClass()
+ {
+ return beanClass;
+ }
+
+ @Override
+ public Set<Type> getTypes()
+ {
+ return types;
+ }
+
+ @Override
+ public Set<Annotation> getQualifiers()
+ {
+ return Collections.singleton(
+ (Annotation) new FacesValidatorAnnotationLiteral(
+ typeInfo.getValidatorId() == null ? "" : typeInfo.getValidatorId(), false, true));
+ }
+
+ @Override
+ public Class<? extends Annotation> getScope()
+ {
+ return Dependent.class;
+ }
+
+ @Override
+ public String getName()
+ {
+ return null;
+ }
+
+
+ @Override
+ public Set<Class<? extends Annotation>> getStereotypes()
+ {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public boolean isAlternative()
+ {
+ return false;
+ }
+
+ @Override
+ public Set<InjectionPoint> getInjectionPoints()
+ {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public boolean isNullable()
+ {
+ return true;
+ }
+
+ @Override
+ public Validator create(CreationalContext<Validator> cc)
+ {
+ Class<? extends Validator> converterClass = (Class<? extends Validator>) beanClass;
+ Validator converter = null;
+ try
+ {
+ converter = converterClass.newInstance();
+ }
+ catch (Exception ex)
+ {
+ Logger.getLogger(DynamicValidatorProducer.class.getName()).log(
+ Level.SEVERE, "Could not instantiate converter " + beanClass.getName().toString(), ex);
+ throw new FacesException("Could not instantiate converter: " + beanClass.getName().toString(), ex);
+
+ }
+ return converter;
+ }
+
+ @Override
+ public void destroy(Validator t, CreationalContext<Validator> cc)
+ {
+ }
+}
Added: myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/validator/FacesValidatorAnnotationLiteral.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/validator/FacesValidatorAnnotationLiteral.java?rev=1781492&view=auto
==============================================================================
--- myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/validator/FacesValidatorAnnotationLiteral.java (added)
+++ myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/validator/FacesValidatorAnnotationLiteral.java Fri Feb 3 01:48:37 2017
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.cdi.validator;
+
+import java.util.Objects;
+import javax.enterprise.util.AnnotationLiteral;
+import javax.faces.validator.FacesValidator;
+
+/**
+ *
+ */
+public class FacesValidatorAnnotationLiteral extends AnnotationLiteral<FacesValidator> implements FacesValidator
+{
+ private static final long serialVersionUID = 1L;
+
+ private String value;
+ private boolean defaultValue;
+ private boolean managed;
+
+ public FacesValidatorAnnotationLiteral(String value,boolean defaultValue, boolean managed)
+ {
+ this.value = value;
+ this.defaultValue = defaultValue;
+ this.managed = managed;
+ }
+
+ @Override
+ public String value()
+ {
+ return value;
+ }
+
+ @Override
+ public boolean managed()
+ {
+ return managed;
+ }
+
+ @Override
+ public boolean isDefault()
+ {
+ return defaultValue;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int hash = 5;
+ hash = 79 * hash + Objects.hashCode(this.value);
+ hash = 79 * hash + (this.defaultValue ? 1 : 0);
+ hash = 79 * hash + (this.managed ? 1 : 0);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (obj == null)
+ {
+ return false;
+ }
+ if (getClass() != obj.getClass())
+ {
+ return false;
+ }
+ final FacesValidatorAnnotationLiteral other = (FacesValidatorAnnotationLiteral) obj;
+ if (!Objects.equals(this.value, other.value))
+ {
+ return false;
+ }
+ if (this.defaultValue != other.defaultValue)
+ {
+ return false;
+ }
+ if (this.managed != other.managed)
+ {
+ return false;
+ }
+ return true;
+ }
+
+}
Added: myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/validator/FacesValidatorCDIWrapper.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/validator/FacesValidatorCDIWrapper.java?rev=1781492&view=auto
==============================================================================
--- myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/validator/FacesValidatorCDIWrapper.java (added)
+++ myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/validator/FacesValidatorCDIWrapper.java Fri Feb 3 01:48:37 2017
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.myfaces.cdi.validator;
+
+import javax.faces.FacesWrapper;
+import javax.faces.component.PartialStateHolder;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.validator.Validator;
+import javax.faces.validator.ValidatorException;
+import org.apache.myfaces.cdi.util.CDIUtils;
+
+/**
+ *
+ */
+public class FacesValidatorCDIWrapper implements PartialStateHolder, Validator, FacesWrapper<Validator>
+{
+ private transient Validator delegate;
+
+ private String validatorId;
+ private boolean _transient;
+
+ public FacesValidatorCDIWrapper()
+ {
+ }
+
+ public FacesValidatorCDIWrapper(Class<? extends Validator> validatorClass, String validatorId)
+ {
+ this.validatorId = validatorId;
+ }
+
+ @Override
+ public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException
+ {
+ getWrapped().validate(context, component, value);
+ }
+
+ @Override
+ public Validator getWrapped()
+ {
+ if (delegate == null)
+ {
+ delegate = (Validator) CDIUtils.getInstance(CDIUtils.getBeanManager(
+ FacesContext.getCurrentInstance().getExternalContext()),
+ Validator.class, true, new FacesValidatorAnnotationLiteral(validatorId, false, true));
+ }
+ return delegate;
+ }
+
+ @Override
+ public Object saveState(FacesContext context)
+ {
+ if (!initialStateMarked())
+ {
+ Object values[] = new Object[1];
+ values[0] = validatorId;
+ return values;
+ }
+ return null;
+ }
+
+ @Override
+ public void restoreState(FacesContext context, Object state)
+ {
+ if (state != null)
+ {
+ Object values[] = (Object[])state;
+ validatorId = (String)values[0];
+ }
+ }
+
+ @Override
+ public boolean isTransient()
+ {
+ return _transient;
+ }
+
+ @Override
+ public void setTransient(boolean newTransientValue)
+ {
+ _transient = newTransientValue;
+ }
+
+ private boolean _initialStateMarked = false;
+
+ public void clearInitialState()
+ {
+ _initialStateMarked = false;
+ }
+
+ public boolean initialStateMarked()
+ {
+ return _initialStateMarked;
+ }
+
+ public void markInitialState()
+ {
+ _initialStateMarked = true;
+ }
+
+}
Added: myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/validator/FacesValidatorExtension.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/validator/FacesValidatorExtension.java?rev=1781492&view=auto
==============================================================================
--- myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/validator/FacesValidatorExtension.java (added)
+++ myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/validator/FacesValidatorExtension.java Fri Feb 3 01:48:37 2017
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.myfaces.cdi.validator;
+
+import java.lang.reflect.Type;
+import java.util.HashSet;
+import java.util.Set;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.AfterBeanDiscovery;
+import javax.enterprise.inject.spi.Annotated;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.ProcessManagedBean;
+import javax.faces.validator.FacesValidator;
+
+/**
+ *
+ */
+public class FacesValidatorExtension implements Extension
+{
+ private Set<ValidatorInfo> types = new HashSet<ValidatorInfo>();
+
+ public <T> void collect(@Observes ProcessManagedBean<T> event)
+ {
+ if (event.getAnnotatedBeanClass().isAnnotationPresent(FacesValidator.class))
+ {
+ Annotated annotated = event.getAnnotatedBeanClass();
+
+ Type type = annotated.getBaseType();
+
+ FacesValidator conv = (FacesValidator) annotated.getAnnotation(FacesValidator.class);
+
+ if (conv.managed())
+ {
+ boolean hasValue = conv.value().length() > 0;
+ if (hasValue)
+ {
+ types.add(new ValidatorInfo(type, conv.value()));
+ }
+ }
+ }
+ }
+
+ public void afterBean(@Observes AfterBeanDiscovery afterBeanDiscovery, BeanManager beanManager)
+ {
+ for (ValidatorInfo typeInfo : types)
+ {
+ afterBeanDiscovery.addBean(new DynamicValidatorProducer(beanManager, typeInfo));
+ }
+ }
+
+}
Added: myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/validator/ValidatorInfo.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/validator/ValidatorInfo.java?rev=1781492&view=auto
==============================================================================
--- myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/validator/ValidatorInfo.java (added)
+++ myfaces/core/branches/2.3.x/impl/src/main/java/org/apache/myfaces/cdi/validator/ValidatorInfo.java Fri Feb 3 01:48:37 2017
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.myfaces.cdi.validator;
+
+import java.io.Serializable;
+import java.lang.reflect.Type;
+import java.util.Objects;
+
+/**
+ *
+ */
+public class ValidatorInfo implements Serializable
+{
+ private Type type;
+
+ private String validatorId;
+
+ public ValidatorInfo(Type type, String validatorId)
+ {
+ this.type = type;
+ this.validatorId = validatorId;
+ }
+
+ /**
+ * @return the validatorId
+ */
+ public String getValidatorId()
+ {
+ return validatorId;
+ }
+
+ /**
+ * @param validatorId the validatorId to set
+ */
+ public void setValidatorId(String validatorId)
+ {
+ this.validatorId = validatorId;
+ }
+
+ public Type getType()
+ {
+ return type;
+ }
+
+ public void setType(Type type)
+ {
+ this.type = type;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int hash = 7;
+ hash = 53 * hash + Objects.hashCode(this.type);
+ hash = 53 * hash + Objects.hashCode(this.validatorId);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (obj == null)
+ {
+ return false;
+ }
+ if (getClass() != obj.getClass())
+ {
+ return false;
+ }
+ final ValidatorInfo other = (ValidatorInfo) obj;
+ if (!Objects.equals(this.type, other.type))
+ {
+ return false;
+ }
+ if (!Objects.equals(this.validatorId, other.validatorId))
+ {
+ return false;
+ }
+ return true;
+ }
+
+
+}
Modified: myfaces/core/branches/2.3.x/impl/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.3.x/impl/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension?rev=1781492&r1=1781491&r2=1781492&view=diff
==============================================================================
--- myfaces/core/branches/2.3.x/impl/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension (original)
+++ myfaces/core/branches/2.3.x/impl/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension Fri Feb 3 01:48:37 2017
@@ -8,3 +8,5 @@ org.apache.myfaces.cdi.faces.FacesScopeC
org.apache.myfaces.cdi.viewTransient.ViewTransientScopeContextExtension
org.apache.myfaces.cdi.component.ComponentBindingExtension
org.apache.myfaces.cdi.bean.ManagedPropertyExtension
+org.apache.myfaces.cdi.converter.FacesConverterExtension
+org.apache.myfaces.cdi.validator.FacesValidatorExtension