| /* |
| * 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.extensions.scripting.jsf.dynamicdecorators.implemetations; |
| |
| import org.apache.myfaces.extensions.scripting.api.Decorated; |
| import org.apache.myfaces.extensions.scripting.api.ScriptingConst; |
| import org.apache.myfaces.extensions.scripting.core.util.WeavingContext; |
| import org.apache.myfaces.extensions.scripting.jsf2.annotation.purged.*; |
| |
| import javax.el.*; |
| import javax.faces.FacesException; |
| import javax.faces.application.*; |
| import javax.faces.component.UIComponent; |
| import javax.faces.component.behavior.Behavior; |
| import javax.faces.context.FacesContext; |
| import javax.faces.convert.Converter; |
| import javax.faces.el.*; |
| import javax.faces.event.*; |
| import javax.faces.validator.Validator; |
| import java.util.*; |
| import java.util.concurrent.ConcurrentHashMap; |
| |
| /** |
| * @author Werner Punz |
| * <p/> |
| * our decorating applicstion |
| * which should resolve our bean issues within a central |
| * bean processing interceptor |
| */ |
| public class ApplicationProxy extends Application implements Decorated { |
| |
| Application _delegate = null; |
| |
| /* |
| * separate map needed for the behavior ids, because |
| * the original is immutable |
| * we have to do a double bookkeeping |
| * here |
| */ |
| Map<String, String> _behaviors = new ConcurrentHashMap<String, String>(); |
| |
| /** |
| * special data structure to save our |
| * object -> proxy references |
| */ |
| class EventHandlerProxyEntry { |
| Class event; |
| Decorated proxy; |
| |
| EventHandlerProxyEntry(Class event, Decorated proxy) { |
| this.event = event; |
| this.proxy = proxy; |
| } |
| |
| @SuppressWarnings("unused") |
| public Class getEvent() { |
| return event; |
| } |
| |
| @SuppressWarnings("unused") |
| public void setEvent(Class event) { |
| this.event = event; |
| } |
| |
| public Decorated getProxy() { |
| return proxy; |
| } |
| |
| @SuppressWarnings("unused") |
| public void setProxy(Decorated proxy) { |
| this.proxy = proxy; |
| } |
| |
| @Override |
| public boolean equals(Object o) { |
| if (this == o) return true; |
| if (o == null || getClass() != o.getClass()) return false; |
| |
| EventHandlerProxyEntry that = (EventHandlerProxyEntry) o; |
| |
| return !(event != null ? !event.equals(that.event) : that.event != null) && !(proxy != null ? !proxy.getDelegate().getClass().getName().equals(that.proxy.getDelegate().getClass().getName()) : that.proxy != null); |
| |
| } |
| |
| @Override |
| public int hashCode() { |
| int result = event.hashCode(); |
| result = 31 * result + proxy.getDelegate().getClass().getName().hashCode(); |
| return result; |
| } |
| } |
| |
| /** |
| * now at the first look this looks like a weird construct |
| * but the standard java set imposes this limit since |
| * we have to iterate over the entire set to reach the correct element |
| * the trick is to save the same object in as both key and value |
| * and now if we generate a new key on an object |
| * we can fetch our proxy which might already contain |
| * the same object in a refreshed state from the value |
| * part of the set, in our case |
| * using hash maps should speed things up |
| * <p/> |
| * since we only have few write operations but access |
| * the map multithreaded we use concurrentHashMap here |
| */ |
| Map<EventHandlerProxyEntry, EventHandlerProxyEntry> _eventHandlerIdx = new ConcurrentHashMap<EventHandlerProxyEntry, EventHandlerProxyEntry>(); |
| |
| public ApplicationProxy(Application delegate) { |
| _delegate = delegate; |
| } |
| |
| public void addELResolver(ELResolver elResolver) { |
| weaveDelegate(); |
| //This can be problematic if several libraries add their own proxies |
| // that way then might get get a cyclic stack |
| //under normal circumstances this should not happen |
| //because addElResolver is called once and getElResolver |
| //does not change the stack afterwards in the worst case |
| //we might get 2 of our proxies in the delegate stack |
| |
| //the same goes for the rest of the factory stuff |
| if (!(elResolver instanceof ELResolverProxy)) |
| elResolver = new ELResolverProxy(elResolver); |
| _delegate.addELResolver(elResolver); |
| } |
| |
| private void weaveDelegate() { |
| if (_delegate != null) { |
| _delegate = (Application) WeavingContext.getWeaver().reloadScriptingInstance(_delegate, ScriptingConst.ARTIFACT_TYPE_APPLICATION); |
| } |
| } |
| |
| public ELResolver getELResolver() { |
| weaveDelegate(); |
| ELResolver retVal = _delegate.getELResolver(); |
| if (!(retVal instanceof ELResolverProxy)) { |
| retVal = new ELResolverProxy(retVal); |
| } |
| return retVal; |
| |
| } |
| |
| //TOD add a weaving for resource bundles |
| |
| public ResourceBundle getResourceBundle(FacesContext facesContext, String s) throws FacesException, NullPointerException { |
| weaveDelegate(); |
| return _delegate.getResourceBundle(facesContext, s); |
| } |
| |
| public UIComponent createComponent(ValueExpression valueExpression, FacesContext facesContext, String componentType) throws FacesException, NullPointerException { |
| weaveDelegate(); |
| UIComponent component = _delegate.createComponent(valueExpression, facesContext, componentType); |
| UIComponent oldComponent = component; |
| //We can replace annotated components on the fly via |
| //ApplicationImpl.addComponent(final String componentType, final String componentClassName) |
| |
| /*we are reweaving on the fly because we cannot be sure if |
| * the class is not recycled all the time in the creation |
| * code, in the renderer we do it on method base |
| * due to the fact that our renderers are recycled via |
| * a flyweight pattern |
| * |
| * |
| * Also we cannot proxy here because there is no UIComponent interface |
| * maybe in the long run we can make a decorator here instead |
| * but for now lets try it this way |
| */ |
| component = (UIComponent) reloadInstance(component, ScriptingConst.ARTIFACT_TYPE_COMPONENT); |
| |
| //we now have to check for an annotation change, but only in case a reload has happened |
| if (component.getClass().hashCode() != oldComponent.getClass().hashCode()) { |
| return handleAnnotationChange(component, valueExpression, facesContext, componentType); |
| } |
| |
| return component; |
| |
| } |
| |
| public ExpressionFactory getExpressionFactory() { |
| weaveDelegate(); |
| return _delegate.getExpressionFactory(); |
| } |
| |
| public void addELContextListener(ELContextListener elContextListener) { |
| weaveDelegate(); |
| if (WeavingContext.isDynamic(elContextListener.getClass())) |
| elContextListener = (ELContextListener) WeavingContext.createMethodReloadingProxyFromObject(elContextListener, ELContextListener.class, ScriptingConst.ARTIFACT_TYPE_ELCONTEXTLISTENER); |
| _delegate.addELContextListener(elContextListener); |
| } |
| |
| public void removeELContextListener(ELContextListener elContextListener) { |
| weaveDelegate(); |
| _delegate.removeELContextListener(elContextListener); |
| } |
| |
| public ELContextListener[] getELContextListeners() { |
| weaveDelegate(); |
| return _delegate.getELContextListeners(); |
| } |
| |
| public ActionListener getActionListener() { |
| weaveDelegate(); |
| ActionListener retVal = _delegate.getActionListener(); |
| if (WeavingContext.isDynamic(retVal.getClass())) |
| retVal = (ActionListener) WeavingContext.createMethodReloadingProxyFromObject(retVal, ActionListener.class, ScriptingConst.ARTIFACT_TYPE_ACTIONLISTENER); |
| return retVal; |
| } |
| |
| public void setActionListener(ActionListener actionListener) { |
| weaveDelegate(); |
| if (WeavingContext.isDynamic(actionListener.getClass())) |
| actionListener = (ActionListener) WeavingContext.createMethodReloadingProxyFromObject(actionListener, ActionListener.class, ScriptingConst.ARTIFACT_TYPE_ACTIONLISTENER); |
| _delegate.setActionListener(actionListener); |
| } |
| |
| public Locale getDefaultLocale() { |
| weaveDelegate(); |
| return _delegate.getDefaultLocale(); |
| } |
| |
| public void setDefaultLocale(Locale locale) { |
| weaveDelegate(); |
| _delegate.setDefaultLocale(locale); |
| } |
| |
| public String getDefaultRenderKitId() { |
| weaveDelegate(); |
| return _delegate.getDefaultRenderKitId(); |
| } |
| |
| public void setDefaultRenderKitId(String s) { |
| weaveDelegate(); |
| _delegate.setDefaultRenderKitId(s); |
| } |
| |
| public String getMessageBundle() { |
| weaveDelegate(); |
| return _delegate.getMessageBundle(); |
| } |
| |
| public void setMessageBundle(String s) { |
| weaveDelegate(); |
| _delegate.setMessageBundle(s); |
| } |
| |
| public NavigationHandler getNavigationHandler() { |
| weaveDelegate(); |
| //defined in the setter to speed things up a little |
| NavigationHandler retVal = _delegate.getNavigationHandler(); |
| |
| if (retVal != null && WeavingContext.isDynamic(retVal.getClass())) |
| retVal = new NavigationHandlerProxy(retVal); |
| return retVal; |
| } |
| |
| public void setNavigationHandler(NavigationHandler navigationHandler) { |
| weaveDelegate(); |
| |
| if (navigationHandler != null && WeavingContext.isDynamic(navigationHandler.getClass())) |
| navigationHandler = new NavigationHandlerProxy(navigationHandler); |
| _delegate.setNavigationHandler(navigationHandler); |
| } |
| |
| @SuppressWarnings("deprecation") |
| public PropertyResolver getPropertyResolver() { |
| weaveDelegate(); |
| return _delegate.getPropertyResolver(); |
| } |
| |
| @SuppressWarnings("deprecation") |
| public void setPropertyResolver(PropertyResolver propertyResolver) { |
| weaveDelegate(); |
| _delegate.setPropertyResolver(propertyResolver); |
| } |
| |
| @SuppressWarnings("deprecation") |
| public VariableResolver getVariableResolver() { |
| weaveDelegate(); |
| VariableResolver variableResolver = _delegate.getVariableResolver(); |
| if (!(variableResolver instanceof VariableResolverProxy)) |
| variableResolver = new VariableResolverProxy(variableResolver); |
| return variableResolver; |
| } |
| |
| @SuppressWarnings("deprecation") |
| public void setVariableResolver(VariableResolver variableResolver) { |
| weaveDelegate(); |
| if (!(variableResolver instanceof VariableResolverProxy)) |
| variableResolver = new VariableResolverProxy(variableResolver); |
| |
| _delegate.setVariableResolver(variableResolver); |
| } |
| |
| public ViewHandler getViewHandler() { |
| weaveDelegate(); |
| ViewHandler handler = _delegate.getViewHandler(); |
| |
| /* |
| We proxy here to enable dynamic reloading for |
| methods in the long run, as soon as we hit |
| java all our groovy reloading code is lost |
| hence we have to work with proxies here |
| */ |
| if (WeavingContext.isDynamic(handler.getClass())) |
| handler = new ViewHandlerProxy(handler); |
| return handler; |
| } |
| |
| public void setViewHandler(ViewHandler viewHandler) { |
| weaveDelegate(); |
| /*make sure you have the delegates as well in properties*/ |
| if (WeavingContext.isDynamic(viewHandler.getClass())) |
| viewHandler = new ViewHandlerProxy(viewHandler); |
| |
| _delegate.setViewHandler(viewHandler); |
| } |
| |
| public StateManager getStateManager() { |
| weaveDelegate(); |
| return _delegate.getStateManager(); |
| } |
| |
| public void setStateManager(StateManager stateManager) { |
| weaveDelegate(); |
| _delegate.setStateManager(stateManager); |
| } |
| |
| public void addComponent(String componentType, String componentClass) { |
| weaveDelegate(); |
| _delegate.addComponent(componentType, componentClass); |
| } |
| |
| public UIComponent createComponent(String componentType) throws FacesException { |
| weaveDelegate(); |
| //the components are generated anew very often |
| //we cannot do an on object weaving here |
| UIComponent oldComponent = _delegate.createComponent(componentType); |
| |
| /*we are reweaving on the fly because we cannot be sure if |
| * the class is not recycled all the time in the creation |
| * code, in the renderer we do it on method base |
| * due to the fact that our renderers are recycled via |
| * a flyweight pattern*/ |
| UIComponent component = (UIComponent) reloadInstance(oldComponent, ScriptingConst.ARTIFACT_TYPE_COMPONENT); |
| |
| //we now have to check for an annotation change, but only in case a reload has happened |
| if (component.getClass().hashCode() != oldComponent.getClass().hashCode()) { |
| return handleAnnotationChange(component, componentType); |
| } |
| |
| return component; |
| |
| } |
| |
| @SuppressWarnings("deprecation") |
| public UIComponent createComponent(ValueBinding valueBinding, FacesContext facesContext, String componentType) throws FacesException { |
| weaveDelegate(); |
| UIComponent oldComponent = _delegate.createComponent(valueBinding, facesContext, componentType); |
| |
| /*we are reweaving on the fly because we cannot be sure if |
| * the class is not recycled all the time in the creation |
| * code, in the renderer we do it on method base |
| * due to the fact that our renderers are recycled via |
| * a flyweight pattern*/ |
| UIComponent component = (UIComponent) reloadInstance(oldComponent, ScriptingConst.ARTIFACT_TYPE_COMPONENT); |
| |
| //we now have to check for an annotation change, but only in case a reload has happened |
| if (component.getClass().hashCode() != oldComponent.getClass().hashCode()) { |
| return handleAnnotationChange(component, valueBinding, facesContext, componentType); |
| } |
| |
| return component; |
| } |
| |
| public Iterator<String> getComponentTypes() { |
| weaveDelegate(); |
| return _delegate.getComponentTypes(); |
| } |
| |
| public void addConverter(String converterId, String converterClass) { |
| weaveDelegate(); |
| /* if (converterClass.equals(PurgedConverter.class.getName())) { |
| //purged case we do a full rescan |
| WeavingContext.getWeaver().fullClassScan(); |
| Converter componentToChange = _delegate.createConverter(converterId); |
| if (componentToChange instanceof PurgedConverter) { |
| //Null not allowed here, but we set a purted converter to make |
| //sure that we get errors on the proper level |
| _delegate.addConverter(converterId, PurgedConverter.class.getName()); |
| } |
| return; |
| }*/ |
| |
| _delegate.addConverter(converterId, converterClass); |
| } |
| |
| public void addConverter(Class targetClass, String converterClass) { |
| weaveDelegate(); |
| _delegate.addConverter(targetClass, converterClass); |
| } |
| |
| public Converter createConverter(String converterId) { |
| weaveDelegate(); |
| Converter retVal = _delegate.createConverter(converterId); |
| |
| /** |
| * since createConverter is called only once |
| * we have to work with method reloading proxies |
| * we cannot use this technique extensively for speed reasons |
| * most of the time it is fine just to work with |
| * |
| * reloading objects at their interception points |
| */ |
| Converter newRetVal = (Converter) reloadInstance(retVal, ScriptingConst.ARTIFACT_TYPE_CONVERTER); |
| if (newRetVal != retVal) { |
| return _delegate.createConverter(converterId); |
| } |
| |
| return retVal; |
| } |
| |
| public Converter createConverter(Class aClass) { |
| weaveDelegate(); |
| Converter retVal = _delegate.createConverter(aClass); |
| Converter newRetVal = (Converter) reloadInstance(retVal, ScriptingConst.ARTIFACT_TYPE_CONVERTER); |
| if (newRetVal != retVal) { |
| return _delegate.createConverter(aClass); |
| } |
| |
| return retVal; |
| } |
| |
| public Iterator<String> getConverterIds() { |
| weaveDelegate(); |
| return _delegate.getConverterIds(); |
| } |
| |
| public Iterator<Class<?>> getConverterTypes() { |
| weaveDelegate(); |
| return _delegate.getConverterTypes(); |
| } |
| |
| @SuppressWarnings("deprecation") |
| public MethodBinding createMethodBinding(String s, Class[] classes) throws ReferenceSyntaxException { |
| weaveDelegate(); |
| return _delegate.createMethodBinding(s, classes); |
| } |
| |
| public Iterator<Locale> getSupportedLocales() { |
| weaveDelegate(); |
| return _delegate.getSupportedLocales(); |
| } |
| |
| public void setSupportedLocales(Collection<Locale> locales) { |
| weaveDelegate(); |
| _delegate.setSupportedLocales(locales); |
| } |
| |
| public void addValidator(String validatorId, String validatorClass) { |
| weaveDelegate(); |
| /* if (validatorClass.equals(PurgedValidator.class.getName())) { |
| //purged case we do a full rescane |
| WeavingContext.getWeaver().fullClassScan(); |
| Validator componentToChange = _delegate.createValidator(validatorId); |
| if (componentToChange instanceof PurgedValidator) { |
| //Null not allowed here, but we set a purted validator to make |
| //sure that we get errors on the proper level |
| _delegate.addValidator(validatorId, PurgedValidator.class.getName()); |
| |
| } |
| return; |
| } */ |
| _delegate.addValidator(validatorId, validatorClass); |
| } |
| |
| public Validator createValidator(String validatorId) throws FacesException { |
| weaveDelegate(); |
| |
| Validator retVal = _delegate.createValidator(validatorId); |
| |
| //the validators are recreated every request we do not have to deal with them on method level |
| Validator newRetVal = (Validator) reloadInstance(retVal, ScriptingConst.ARTIFACT_TYPE_VALIDATOR); |
| if (newRetVal != retVal) { |
| _delegate.createValidator(validatorId); |
| } |
| return retVal; |
| } |
| |
| public Iterator<String> getValidatorIds() { |
| weaveDelegate(); |
| return _delegate.getValidatorIds(); |
| } |
| |
| @SuppressWarnings("deprecation") |
| public ValueBinding createValueBinding(String s) throws ReferenceSyntaxException { |
| weaveDelegate(); |
| return _delegate.createValueBinding(s); |
| } |
| |
| @Override |
| public void addBehavior(String behaviorId, String behaviorClass) { |
| weaveDelegate(); |
| |
| if (behaviorClass.equals(PurgedValidator.class.getName())) { |
| //purged case we do a full rescan |
| WeavingContext.getWeaver().fullClassScan(); |
| Behavior behavior = _delegate.createBehavior(behaviorId); |
| _behaviors.put(behaviorId, behaviorClass); |
| if (behavior instanceof PurgedBehavior) { |
| //Null not allowed here, but we set a purged validator to make |
| //sure that we get errors on the proper level |
| _delegate.addBehavior(behaviorId, PurgedBehavior.class.getName()); |
| _behaviors.remove(behaviorId); |
| |
| } |
| return; |
| } |
| |
| _delegate.addBehavior(behaviorId, behaviorClass); |
| } |
| |
| @Override |
| public void addDefaultValidatorId(String validatorId) { |
| weaveDelegate(); |
| _delegate.addDefaultValidatorId(validatorId); |
| } |
| |
| @Override |
| public Behavior createBehavior(String behaviorId) throws FacesException { |
| weaveDelegate(); |
| Behavior retVal = _delegate.createBehavior(behaviorId); |
| |
| //we might have casts here against one of the parents |
| //of this object |
| Behavior newBehavior = (Behavior) reloadInstance(retVal, ScriptingConst.ARTIFACT_TYPE_BEHAVIOR); |
| if (newBehavior != retVal) { |
| return _delegate.createBehavior(behaviorId); |
| } |
| |
| return retVal; |
| } |
| |
| @Override |
| public UIComponent createComponent(FacesContext facesContext, Resource resource) { |
| weaveDelegate(); |
| |
| UIComponent oldComponent = _delegate.createComponent(facesContext, resource); |
| |
| /*we are reweaving on the fly because we cannot be sure if |
| * the class is not recycled all the time in the creation |
| * code, in the renderer we do it on method base |
| * due to the fact that our renderers are recycled via |
| * a flyweight pattern*/ |
| UIComponent component = (UIComponent) reloadInstance(oldComponent, ScriptingConst.ARTIFACT_TYPE_COMPONENT); |
| |
| //we now have to check for an annotation change, but only in case a reload has happened |
| if (component.getClass().hashCode() != oldComponent.getClass().hashCode()) { |
| return handleAnnotationChange(component, facesContext, resource); |
| } |
| |
| return component; |
| |
| } |
| |
| @Override |
| public UIComponent createComponent(FacesContext facesContext, String componentType, String rendererType) { |
| weaveDelegate(); |
| UIComponent oldComponent = _delegate.createComponent(facesContext, componentType, rendererType); |
| |
| /*we are reweaving on the fly because we cannot be sure if |
| * the class is not recycled all the time in the creation |
| * code, in the renderer we do it on method base |
| * due to the fact that our renderers are recycled via |
| * a flyweight pattern*/ |
| UIComponent component = (UIComponent) reloadInstance(oldComponent, ScriptingConst.ARTIFACT_TYPE_COMPONENT); |
| |
| //we now have to check for an annotation change, but only in case a reload has happened |
| if (component.getClass().hashCode() != oldComponent.getClass().hashCode()) { |
| return handleAnnotationChange(component, facesContext, componentType, rendererType); |
| } |
| |
| return component; |
| } |
| |
| @Override |
| public UIComponent createComponent(ValueExpression valueExpression, FacesContext facesContext, String s, String s1) { |
| weaveDelegate(); |
| UIComponent oldComponent = _delegate.createComponent(valueExpression, facesContext, s, s1); |
| |
| /*we are reweaving on the fly because we cannot be sure if |
| * the class is not recycled all the time in the creation |
| * code, in the renderer we do it on method base |
| * due to the fact that our renderers are recycled via |
| * a flyweight pattern*/ |
| UIComponent component = (UIComponent) reloadInstance(oldComponent, ScriptingConst.ARTIFACT_TYPE_COMPONENT); |
| |
| //we now have to check for an annotation change, but only in case a reload has happened |
| if (component.getClass().hashCode() != oldComponent.getClass().hashCode()) { |
| return handleAnnotationChange(component, valueExpression, facesContext, s, s1); |
| } |
| |
| return component; |
| } |
| |
| @Override |
| @SuppressWarnings("unchecked") |
| public <T> T evaluateExpressionGet(FacesContext facesContext, String s, Class<? extends T> aClass) throws ELException { |
| weaveDelegate(); |
| //good place for a dynamic reloading check as well |
| T retVal = _delegate.evaluateExpressionGet(facesContext, s, aClass); |
| if (WeavingContext.isDynamic(retVal.getClass())) |
| retVal = (T) WeavingContext.getWeaver().reloadScriptingInstance(retVal, ScriptingConst.ARTIFACT_TYPE_MANAGEDBEAN); |
| return retVal; |
| } |
| |
| @Override |
| public Iterator<String> getBehaviorIds() { |
| weaveDelegate(); |
| return _behaviors.keySet().iterator(); |
| //return _delegate.getBehaviorIds(); |
| } |
| |
| @Override |
| public Map<String, String> getDefaultValidatorInfo() { |
| weaveDelegate(); |
| return _delegate.getDefaultValidatorInfo(); |
| } |
| |
| @Override |
| public ProjectStage getProjectStage() { |
| weaveDelegate(); |
| return _delegate.getProjectStage(); |
| } |
| |
| @Override |
| public ResourceHandler getResourceHandler() { |
| weaveDelegate(); |
| ResourceHandler retVal = _delegate.getResourceHandler(); |
| if(WeavingContext.isDynamic(retVal.getClass())) { |
| return new ResourceHandlerProxy(retVal); |
| } |
| |
| //ResourceHandler newHandler = (ResourceHandler) reloadInstance(retVal, ScriptingConst.ARTIFACT_TYPE_RESOURCEHANDLER); |
| //if (newHandler != retVal) { |
| // return _delegate.getResourceHandler(); |
| //} |
| return retVal; |
| } |
| |
| @Override |
| public void publishEvent(FacesContext facesContext, Class<? extends SystemEvent> eventClass, Class<?> sourceBaseTye, Object source) { |
| weaveDelegate(); |
| _delegate.publishEvent(facesContext, eventClass, sourceBaseTye, source); |
| } |
| |
| @Override |
| public void publishEvent(FacesContext facesContext, Class<? extends SystemEvent> eventClass, Object source) { |
| weaveDelegate(); |
| _delegate.publishEvent(facesContext, eventClass, source); |
| } |
| |
| @Override |
| public void setResourceHandler(ResourceHandler resourceHandler) { |
| weaveDelegate(); |
| _delegate.setResourceHandler(resourceHandler); |
| ResourceHandler handler = _delegate.getResourceHandler(); |
| if (handler instanceof PurgedResourceHandler) { |
| WeavingContext.getWeaver().fullClassScan(); |
| } |
| } |
| |
| @Override |
| public void subscribeToEvent(Class<? extends SystemEvent> eventClass, Class<?> aClass, SystemEventListener systemEventListener) { |
| weaveDelegate(); |
| systemEventListener = makeEventProxy(eventClass, systemEventListener); |
| _delegate.subscribeToEvent(eventClass, aClass, systemEventListener); |
| } |
| |
| private SystemEventListener makeEventProxy(Class<? extends SystemEvent> eventClass, SystemEventListener systemEventListener) { |
| if (WeavingContext.isDynamic(systemEventListener.getClass())) { |
| systemEventListener = new SystemEventListenerProxy(systemEventListener); |
| EventHandlerProxyEntry entry = new EventHandlerProxyEntry(eventClass, (Decorated) systemEventListener); |
| _eventHandlerIdx.put(entry, entry); |
| } |
| return systemEventListener; |
| } |
| |
| @Override |
| public void subscribeToEvent(Class<? extends SystemEvent> eventClass, SystemEventListener systemEventListener) { |
| weaveDelegate(); |
| systemEventListener = makeEventProxy(eventClass, systemEventListener); |
| _delegate.subscribeToEvent(eventClass, systemEventListener); |
| } |
| |
| @Override |
| public void unsubscribeFromEvent(Class<? extends SystemEvent> eventClass, Class<?> aClass, SystemEventListener systemEventListener) { |
| weaveDelegate(); |
| systemEventListener = resolveEventProxy(eventClass, systemEventListener); |
| _delegate.unsubscribeFromEvent(eventClass, aClass, systemEventListener); |
| } |
| |
| private SystemEventListener resolveEventProxy(Class<? extends SystemEvent> eventClass, SystemEventListener systemEventListener) { |
| if (WeavingContext.isDynamic(systemEventListener.getClass())) { |
| systemEventListener = new SystemEventListenerProxy(systemEventListener); |
| EventHandlerProxyEntry entry = new EventHandlerProxyEntry(eventClass, (Decorated) systemEventListener); |
| entry = _eventHandlerIdx.remove(entry); |
| if (entry != null) { |
| systemEventListener = (SystemEventListener) entry.getProxy().getDelegate(); |
| } |
| } |
| return systemEventListener; |
| } |
| |
| @Override |
| public void unsubscribeFromEvent(Class<? extends SystemEvent> eventClass, SystemEventListener systemEventListener) { |
| weaveDelegate(); |
| systemEventListener = resolveEventProxy(eventClass, systemEventListener); |
| _delegate.unsubscribeFromEvent(eventClass, systemEventListener); |
| } |
| |
| public Object getDelegate() { |
| return _delegate; //To change body of implemented methods use File | Settings | File Templates. |
| } |
| |
| private Object reloadInstance(Object instance, int artifactType) { |
| if (instance == null) { |
| return null; |
| } |
| if (WeavingContext.isDynamic(instance.getClass()) && !alreadyWovenInRequest(instance.getClass().getName())) { |
| instance = WeavingContext.getWeaver().reloadScriptingInstance(instance, artifactType); |
| alreadyWovenInRequest(instance.getClass().getName()); |
| } |
| return instance; |
| } |
| |
| private boolean alreadyWovenInRequest(String clazz) { |
| //portlets now can be enabled thanks to the jsf2 indirections regarding the external context |
| Map<String, Object> req = FacesContext.getCurrentInstance().getExternalContext().getRequestMap(); |
| if (req.get(ScriptingConst.SCRIPTING_REQUSINGLETON + clazz) == null) { |
| req.put(ScriptingConst.SCRIPTING_REQUSINGLETON + clazz, ""); |
| return false; |
| } |
| return true; |
| } |
| |
| private UIComponent handleAnnotationChange(UIComponent oldComponent, ValueExpression valueExpression, FacesContext facesContext, String componentType) { |
| UIComponent componentToChange = _delegate.createComponent(valueExpression, facesContext, componentType); |
| if (componentToChange instanceof PurgedComponent) { |
| WeavingContext.getWeaver().fullClassScan(); |
| //via an additional create component we can check whether a purged component |
| //was registered after the reload because the annotation has been removed |
| componentToChange = _delegate.createComponent(valueExpression, facesContext, componentType); |
| |
| return componentToChange; |
| } |
| return oldComponent; |
| } |
| |
| private UIComponent handleAnnotationChange(UIComponent oldComponent, String componentType) { |
| UIComponent componentToChange = _delegate.createComponent(componentType); |
| if (componentToChange instanceof PurgedComponent) { |
| WeavingContext.getWeaver().fullClassScan(); |
| //via an additional create component we can check whether a purged component |
| //was registered after the reload because the annotation has been removed |
| componentToChange = _delegate.createComponent(componentType); |
| |
| return componentToChange; |
| } |
| return oldComponent; |
| } |
| |
| @SuppressWarnings("deprecation") |
| private UIComponent handleAnnotationChange(UIComponent oldComponent, ValueBinding valueBinding, FacesContext context, String componentType) { |
| UIComponent componentToChange = _delegate.createComponent(valueBinding, context, componentType); |
| if (componentToChange instanceof PurgedComponent) { |
| WeavingContext.getWeaver().fullClassScan(); |
| //via an additional create component we can check whether a purged component |
| //was registered after the reload because the annotation has been removed |
| componentToChange = _delegate.createComponent(valueBinding, context, componentType); |
| |
| return componentToChange; |
| } |
| return oldComponent; |
| } |
| |
| private UIComponent handleAnnotationChange(UIComponent oldComponent, FacesContext context, Resource resource) { |
| UIComponent componentToChange = _delegate.createComponent(context, resource); |
| if (componentToChange instanceof PurgedComponent) { |
| WeavingContext.getWeaver().fullClassScan(); |
| //via an additional create component we can check whether a purged component |
| //was registered after the reload because the annotation has been removed |
| componentToChange = _delegate.createComponent(context, resource); |
| |
| return componentToChange; |
| } |
| return oldComponent; |
| } |
| |
| private UIComponent handleAnnotationChange(UIComponent oldComponent, FacesContext context, String componentType, String rendererType) { |
| UIComponent componentToChange = _delegate.createComponent(context, componentType, rendererType); |
| if (componentToChange instanceof PurgedComponent) { |
| WeavingContext.getWeaver().fullClassScan(); |
| //via an additional create component we can check whether a purged component |
| //was registered after the reload because the annotation has been removed |
| componentToChange = _delegate.createComponent(context, componentType, rendererType); |
| |
| return componentToChange; |
| } |
| return oldComponent; |
| } |
| |
| private UIComponent handleAnnotationChange(UIComponent oldComponent, ValueExpression valueExpression, FacesContext facesContext, String s, String s1) { |
| UIComponent componentToChange = _delegate.createComponent(valueExpression, facesContext, s, s1); |
| if (componentToChange instanceof PurgedComponent) { |
| WeavingContext.getWeaver().fullClassScan(); |
| |
| //via an additional create component we can check whether a purged component |
| //was registered after the reload because the annotation has been removed |
| |
| componentToChange = _delegate.createComponent(valueExpression, facesContext, s, s1); |
| |
| return componentToChange; |
| } |
| return oldComponent; |
| } |
| |
| } |