Return-Path: X-Original-To: apmail-myfaces-commits-archive@www.apache.org Delivered-To: apmail-myfaces-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id C337CD78B for ; Thu, 6 Dec 2012 00:56:42 +0000 (UTC) Received: (qmail 40056 invoked by uid 500); 6 Dec 2012 00:56:42 -0000 Delivered-To: apmail-myfaces-commits-archive@myfaces.apache.org Received: (qmail 40005 invoked by uid 500); 6 Dec 2012 00:56:42 -0000 Mailing-List: contact commits-help@myfaces.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "MyFaces Development" Delivered-To: mailing list commits@myfaces.apache.org Received: (qmail 39997 invoked by uid 99); 6 Dec 2012 00:56:42 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 06 Dec 2012 00:56:42 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 06 Dec 2012 00:56:34 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id DF633238890B; Thu, 6 Dec 2012 00:56:11 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1417718 - in /myfaces/core/branches/2.0.x: api/src/main/java/javax/faces/component/ impl/src/main/java/org/apache/myfaces/application/ impl/src/main/java/org/apache/myfaces/view/facelets/ impl/src/main/java/org/apache/myfaces/view/facelets... Date: Thu, 06 Dec 2012 00:56:10 -0000 To: commits@myfaces.apache.org From: lu4242@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20121206005611.DF633238890B@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: lu4242 Date: Thu Dec 6 00:56:08 2012 New Revision: 1417718 URL: http://svn.apache.org/viewvc?rev=1417718&view=rev Log: MYFACES-3660 Component resource added using @ResourceDependency annotation from a facelet component should have an id defined by facelets Added: myfaces/core/branches/2.0.x/api/src/main/java/javax/faces/component/_ViewAttributeMap.java (with props) myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/view/facelets/pss/acid/component/UIRDComponent.java (with props) myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/view/facelets/pss/acid/managed/ComponentBindingBean.java (with props) myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/view/facelets/pss/acid/managed/ResourceDependencyBean.java (with props) myfaces/core/branches/2.0.x/impl/src/test/resources/org/apache/myfaces/view/facelets/pss/acid/componentBinding1.xhtml (with props) myfaces/core/branches/2.0.x/impl/src/test/resources/org/apache/myfaces/view/facelets/pss/acid/resourceDependency1.xhtml (with props) myfaces/core/branches/2.0.x/impl/src/test/resources/org/apache/myfaces/view/facelets/pss/acid/resources/ (with props) myfaces/core/branches/2.0.x/impl/src/test/resources/org/apache/myfaces/view/facelets/pss/acid/resources/custom.css (with props) Modified: myfaces/core/branches/2.0.x/api/src/main/java/javax/faces/component/UIViewRoot.java myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/DefaultFaceletsStateManagementStrategy.java myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ComponentTagHandlerDelegate.java myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesTestCase.java myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/view/facelets/pss/acid/AcidMyFacesRequestTestCase.java myfaces/core/branches/2.0.x/impl/src/test/resources/org/apache/myfaces/view/facelets/pss/acid/WEB-INF/testcomponent.taglib.xml Modified: myfaces/core/branches/2.0.x/api/src/main/java/javax/faces/component/UIViewRoot.java URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/api/src/main/java/javax/faces/component/UIViewRoot.java?rev=1417718&r1=1417717&r2=1417718&view=diff ============================================================================== --- myfaces/core/branches/2.0.x/api/src/main/java/javax/faces/component/UIViewRoot.java (original) +++ myfaces/core/branches/2.0.x/api/src/main/java/javax/faces/component/UIViewRoot.java Thu Dec 6 00:56:08 2012 @@ -116,6 +116,9 @@ public class UIViewRoot extends UICompon private static final String JAVAX_FACES_LOCATION_BODY = "javax_faces_location_body"; private static final String JAVAX_FACES_LOCATION_FORM = "javax_faces_location_form"; + private transient boolean _resourceDependencyUniqueId; + private transient Map _attributesMap; + /** * Construct an instance of the UIViewRoot. */ @@ -343,10 +346,20 @@ public class UIViewRoot extends UICompon // UNIQUE_ID_PREFIX, and will be unique within this UIViewRoot. if(seed==null) { - Long uniqueIdCounter = (Long) getStateHelper().get(PropertyKeys.uniqueIdCounter); - uniqueIdCounter = (uniqueIdCounter == null) ? 0 : uniqueIdCounter; - getStateHelper().put(PropertyKeys.uniqueIdCounter, (uniqueIdCounter+1L)); - return bld.append(UNIQUE_ID_PREFIX).append(uniqueIdCounter).toString(); + if (isResourceDependencyUniqueId()) + { + Long uniqueIdCounter = (Long) getStateHelper().get(PropertyKeys.resourceDependencyUniqueIdCounter); + uniqueIdCounter = (uniqueIdCounter == null) ? 0 : uniqueIdCounter; + getStateHelper().put(PropertyKeys.resourceDependencyUniqueIdCounter, (uniqueIdCounter+1L)); + return bld.append(UNIQUE_ID_PREFIX).append("__rd_").append(uniqueIdCounter).toString(); + } + else + { + Long uniqueIdCounter = (Long) getStateHelper().get(PropertyKeys.uniqueIdCounter); + uniqueIdCounter = (uniqueIdCounter == null) ? 0 : uniqueIdCounter; + getStateHelper().put(PropertyKeys.uniqueIdCounter, (uniqueIdCounter+1L)); + return bld.append(UNIQUE_ID_PREFIX).append(uniqueIdCounter).toString(); + } } // Optionally, a unique seed value can be supplied by component creators which // should be included in the generated unique id. @@ -1234,6 +1247,32 @@ public class UIViewRoot extends UICompon getStateHelper().put(PropertyKeys.afterPhaseListener, afterPhaseListener); } + @Override + public Map getAttributes() + { + if (_attributesMap == null) + { + _attributesMap = new _ViewAttributeMap(this, super.getAttributes()); + } + return _attributesMap; + } + + /** + * Indicates if the component is created when facelets builds the view and + * is caused by the presence of a ResourceDependency annotation. + * + * @return the _resourceDependencyUniqueId + */ + boolean isResourceDependencyUniqueId() + { + return _resourceDependencyUniqueId; + } + + void setResourceDependencyUniqueId(boolean resourceDependencyUniqueId) + { + this._resourceDependencyUniqueId = resourceDependencyUniqueId; + } + enum PropertyKeys { afterPhaseListener @@ -1243,6 +1282,7 @@ public class UIViewRoot extends UICompon , renderKitId , viewId , uniqueIdCounter + , resourceDependencyUniqueIdCounter } @Override Added: myfaces/core/branches/2.0.x/api/src/main/java/javax/faces/component/_ViewAttributeMap.java URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/api/src/main/java/javax/faces/component/_ViewAttributeMap.java?rev=1417718&view=auto ============================================================================== --- myfaces/core/branches/2.0.x/api/src/main/java/javax/faces/component/_ViewAttributeMap.java (added) +++ myfaces/core/branches/2.0.x/api/src/main/java/javax/faces/component/_ViewAttributeMap.java Thu Dec 6 00:56:08 2012 @@ -0,0 +1,181 @@ +/* + * 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 javax.faces.component; + +import java.util.Collection; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +/** + * + * @author Leonardo Uribe + */ +class _ViewAttributeMap implements Map +{ + //private static final String RESET_SAVE_STATE_MODE_KEY = + // "oam.view.resetSaveStateMode"; + + /** + * Key under UIViewRoot to generated unique ids for components added + * by @ResourceDependency effect. + */ + private static final String RESOURCE_DEPENDENCY_UNIQUE_ID_KEY = + "oam.view.resourceDependencyUniqueId"; + private static final String UNIQUE_ID_COUNTER_KEY = + "oam.view.uniqueIdCounter"; + + private Map _delegate; + private UIViewRoot _root; + + public _ViewAttributeMap(UIViewRoot root, Map delegate) + { + this._delegate = delegate; + this._root = root; + } + + public int size() + { + return _delegate.size(); + } + + public boolean isEmpty() + { + return _delegate.isEmpty(); + } + + public boolean containsKey(Object key) + { + return _delegate.containsKey(key); + } + + public boolean containsValue(Object value) + { + return _delegate.containsValue(value); + } + + public Object get(Object key) + { + checkKey(key); + int keyLength = ((String)key).length(); + /* + if (RESET_SAVE_STATE_MODE_KEY.length() == keyLength + && RESET_SAVE_STATE_MODE_KEY.equals(key)) + { + return _root.getResetSaveStateMode(); + }*/ + if (RESOURCE_DEPENDENCY_UNIQUE_ID_KEY.length() == keyLength + && RESOURCE_DEPENDENCY_UNIQUE_ID_KEY.equals(key)) + { + return _root.isResourceDependencyUniqueId(); + } + if (UNIQUE_ID_COUNTER_KEY.length() == keyLength + && UNIQUE_ID_COUNTER_KEY.equals(key)) + { + return _root.getStateHelper().get(UIViewRoot.PropertyKeys.uniqueIdCounter); + } + return _delegate.get(key); + } + + public Object put(String key, Object value) + { + int keyLength = ((String)key).length(); + + /* + if (RESET_SAVE_STATE_MODE_KEY.length() == keyLength + && RESET_SAVE_STATE_MODE_KEY.equals(key)) + { + Integer b = _root.getResetSaveStateMode(); + _root.setResetSaveStateMode(value == null ? 0 : (Integer) value); + return b; + }*/ + if (RESOURCE_DEPENDENCY_UNIQUE_ID_KEY.length() == keyLength + && RESOURCE_DEPENDENCY_UNIQUE_ID_KEY.equals(key)) + { + boolean b = _root.isResourceDependencyUniqueId(); + _root.setResourceDependencyUniqueId(value == null ? false : (Boolean) value); + return b; + } + if (UNIQUE_ID_COUNTER_KEY.length() == keyLength + && UNIQUE_ID_COUNTER_KEY.equals(key)) + { + Long v = (Long) _root.getStateHelper().get(UIViewRoot.PropertyKeys.uniqueIdCounter); + _root.getStateHelper().put(UIViewRoot.PropertyKeys.uniqueIdCounter, value); + return v; + } + return _delegate.put(key, value); + } + + public Object remove(Object key) + { + return _delegate.remove(key); + } + + public void putAll(Map m) + { + _delegate.putAll(m); + } + + public void clear() + { + _delegate.clear(); + } + + public Set keySet() + { + return _delegate.keySet(); + } + + public Collection values() + { + return _delegate.values(); + } + + public Set> entrySet() + { + return _delegate.entrySet(); + } + + public boolean equals(Object o) + { + return _delegate.equals(o); + } + + public int hashCode() + { + return _delegate.hashCode(); + } + + public String toString() + { + return _delegate.toString(); + } + + private void checkKey(Object key) + { + if (key == null) + { + throw new NullPointerException("key"); + } + if (!(key instanceof String)) + { + throw new ClassCastException("key is not a String"); + } + } +} Propchange: myfaces/core/branches/2.0.x/api/src/main/java/javax/faces/component/_ViewAttributeMap.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java?rev=1417718&r1=1417717&r2=1417718&view=diff ============================================================================== --- myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java (original) +++ myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java Thu Dec 6 00:56:08 2012 @@ -104,6 +104,7 @@ import org.apache.myfaces.el.unified.res import org.apache.myfaces.lifecycle.LifecycleImpl; import org.apache.myfaces.shared.config.MyfacesConfig; import org.apache.myfaces.shared.util.ClassUtils; +import org.apache.myfaces.view.facelets.FaceletCompositionContext; import org.apache.myfaces.view.facelets.el.ELText; /** @@ -157,6 +158,14 @@ public class ApplicationImpl extends App private static final boolean LAZY_LOAD_CONFIG_OBJECTS_DEFAULT_VALUE = true; private Boolean _lazyLoadConfigObjects = null; + + /** + * Key under UIViewRoot to generated unique ids for components added + * by @ResourceDependency effect. + */ + private static final String RESOURCE_DEPENDENCY_UNIQUE_ID_KEY = + "oam.view.resourceDependencyUniqueId"; + // ~ Instance fields // -------------------------------------------------------------------------- // -- @@ -1798,6 +1807,50 @@ public class ApplicationImpl extends App rvc.setClassProcessed(inspectedClass); } } + + /** + * If the ResourceDependency component is created under facelets processing, it should receive + * an special unique component id. This method check if there is a FaceletCompositionContext + * and if that so, set the id. Components added by the effect of ResourceDependency are special, + * because they do not have state, but they depends on the view structure, so with PSS, + * each time the view is built they are "recalculated", so they work as if they were transient + * components that needs to be created at each request, but there are some cases were the + * components needs to be saved and restored fully. If a component is created outside facelets + * control (render response phase) it is expected to use the default implementation of + * createUniqueId(), but in that case, note that this happens after markInitialState() is + * called, and the component in this case is saved and restored fully, as expected. + * + * This code cannot be called from facelets component tag handler, because in cases where a + * component subtree is created using binding property, facelets lost control over component + * creation and delegates it to the user, but since the binding code is executed each time the + * view is created, the effect over ResourceDependency persists and the binding code takes into + * account in the recalculation step, even if later the node related to the binding property + * is dropped and recreated from the state fully. + * + * @param facesContext + * @param component + */ + private void setResourceIdOnFaceletsMode(FacesContext facesContext, UIComponent component) + { + if (component.getId() == null) + { + FaceletCompositionContext mctx = FaceletCompositionContext.getCurrentInstance(facesContext); + if (mctx != null) + { + UIViewRoot root = facesContext.getViewRoot(); + root.getAttributes().put(RESOURCE_DEPENDENCY_UNIQUE_ID_KEY, Boolean.TRUE); + try + { + String uid = root.createUniqueId(facesContext, null); + component.setId(uid); + } + finally + { + root.getAttributes().put(RESOURCE_DEPENDENCY_UNIQUE_ID_KEY, Boolean.FALSE); + } + } + } + } private void _handleAttachedResourceDependency(FacesContext context, ResourceDependency annotation) { @@ -1826,6 +1879,10 @@ public class ApplicationImpl extends App // Call setRendererType on the UIOutput instance, passing the renderer-type. output.setRendererType(rendererType); + // If the @ResourceDependency was done inside facelets processing, + // call setId() and set a proper id from facelets + setResourceIdOnFaceletsMode(context, output); + // Obtain the Map of attributes from the UIOutput component by calling UIComponent.getAttributes(). Map attributes = output.getAttributes(); @@ -2301,6 +2358,10 @@ public class ApplicationImpl extends App // Call setRendererType on the UIOutput instance, passing the renderer-type. output.setRendererType(rendererType); + + // If the @ResourceDependency was done inside facelets processing, + // call setId() and set a proper id from facelets + setResourceIdOnFaceletsMode(context, output); // Obtain the Map of attributes from the UIOutput component by calling UIComponent.getAttributes(). Map attributes = output.getAttributes(); Modified: myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/DefaultFaceletsStateManagementStrategy.java URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/DefaultFaceletsStateManagementStrategy.java?rev=1417718&r1=1417717&r2=1417718&view=diff ============================================================================== --- myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/DefaultFaceletsStateManagementStrategy.java (original) +++ myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/DefaultFaceletsStateManagementStrategy.java Thu Dec 6 00:56:08 2012 @@ -166,6 +166,9 @@ public class DefaultFaceletsStateManagem private static final Object[] EMPTY_STATES = new Object[]{null, null}; + private static final String UNIQUE_ID_COUNTER_KEY = + "oam.view.uniqueIdCounter"; + private ViewDeclarationLanguageFactory _vdlFactory; private RenderKitFactory _renderKitFactory = null; @@ -254,8 +257,16 @@ public class DefaultFaceletsStateManagem { view.getAttributes().put(ComponentSupport.FACELET_STATE_INSTANCE, faceletViewState); } + if (state.length == 3) + { + if (view.getId() == null) + { + view.setId(view.createUniqueId(context, null)); + } + //Jump to where the count is + view.getAttributes().put(UNIQUE_ID_COUNTER_KEY, state[2]); + } } - // TODO: Why is necessary enable event processing? // ANS: On RestoreViewExecutor, setProcessingEvents is called first to false // and then to true when postback. Since we need listeners registered to PostAddToViewEvent @@ -286,7 +297,6 @@ public class DefaultFaceletsStateManagem if (state != null && state[1] != null) { states = (Map) state[1]; - // Visit the children and restore their state. boolean emptyState = false; boolean containsFaceletState = states.containsKey( @@ -386,7 +396,6 @@ public class DefaultFaceletsStateManagem context.getAttributes().remove(FaceletViewDeclarationLanguage.REMOVING_COMPONENTS_BUILD); } } - List clientIdsAdded = getClientIdsAdded(view); if (clientIdsAdded != null) { @@ -459,7 +468,6 @@ public class DefaultFaceletsStateManagem } } } - // Restore binding, because UIViewRoot.processRestoreState() is never called //the event processing has to be enabled because of the restore view event triggers //TODO ask the EG the this is a spec violation if we do it that way @@ -573,8 +581,12 @@ public class DefaultFaceletsStateManagem // As required by ResponseStateManager, the return value is an Object array. First // element is the structure object, second is the state map. - - if (states == null) + Long uniqueIdCount = (Long) view.getAttributes().get(UNIQUE_ID_COUNTER_KEY); + if (uniqueIdCount != null && !uniqueIdCount.equals(1L)) + { + serializedView = new Object[] { null, states, uniqueIdCount }; + } + else if (states == null) { serializedView = EMPTY_STATES; } Modified: myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ComponentTagHandlerDelegate.java URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ComponentTagHandlerDelegate.java?rev=1417718&r1=1417717&r2=1417718&view=diff ============================================================================== --- myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ComponentTagHandlerDelegate.java (original) +++ myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ComponentTagHandlerDelegate.java Thu Dec 6 00:56:08 2012 @@ -50,6 +50,8 @@ import javax.faces.view.facelets.Validat import org.apache.myfaces.util.ExternalSpecifications; import org.apache.myfaces.view.facelets.AbstractFaceletContext; +import org.apache.myfaces.view.facelets.ComponentState; +import org.apache.myfaces.view.facelets.DefaultFaceletsStateManagementStrategy; import org.apache.myfaces.view.facelets.FaceletCompositionContext; import org.apache.myfaces.view.facelets.tag.MetaRulesetImpl; import org.apache.myfaces.view.facelets.tag.jsf.core.AjaxHandler; @@ -435,6 +437,18 @@ public class ComponentTagHandlerDelegate ComponentSupport.getViewRoot(ctx, c).getAttributes().put("oam.CALL_PRE_DISPOSE_VIEW", Boolean.TRUE); c.subscribeToEvent(PreDisposeViewEvent.class, new ClearBindingValueExpressionListener()); } + + if (c.getChildCount() > 0 || c.getFacetCount() > 0) + { + // In this case, this component is used to hold a subtree that is generated + // dynamically. In this case, the best is mark this component to be restored + // fully, because this ensures the state is correctly preserved. Note this + // is only necessary when the component has additional children or facets, + // because those components requires an unique id provided by createUniqueId(), + // and this ensures stability of the generated ids. + c.getAttributes().put(DefaultFaceletsStateManagementStrategy.COMPONENT_ADDED_AFTER_BUILD_VIEW, + ComponentState.REMOVE_ADD); + } } } else Modified: myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesTestCase.java URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesTestCase.java?rev=1417718&r1=1417717&r2=1417718&view=diff ============================================================================== --- myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesTestCase.java (original) +++ myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesTestCase.java Thu Dec 6 00:56:08 2012 @@ -34,13 +34,23 @@ import java.util.logging.Logger; import javax.el.ExpressionFactory; import javax.faces.FacesException; import javax.faces.FactoryFinder; +import javax.faces.application.Application; +import javax.faces.application.FacesMessage; +import javax.faces.application.ProjectStage; +import javax.faces.application.ViewHandler; +import javax.faces.component.UIViewRoot; import javax.faces.context.ExternalContext; import javax.faces.context.FacesContext; import javax.faces.context.FacesContextFactory; +import javax.faces.context.Flash; +import javax.faces.event.ExceptionQueuedEvent; +import javax.faces.event.ExceptionQueuedEventContext; import javax.faces.event.PhaseId; import javax.faces.event.PhaseListener; +import javax.faces.event.PreRenderViewEvent; import javax.faces.lifecycle.Lifecycle; import javax.faces.lifecycle.LifecycleFactory; +import javax.faces.view.ViewDeclarationLanguage; import javax.faces.webapp.FacesServlet; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; @@ -52,6 +62,7 @@ import org.apache.myfaces.config.Runtime import org.apache.myfaces.config.element.FacesConfig; import org.apache.myfaces.config.impl.digester.elements.Factory; import org.apache.myfaces.lifecycle.LifecycleImpl; +import org.apache.myfaces.lifecycle.ViewNotFoundException; import org.apache.myfaces.mc.test.core.annotation.DeclareFacesConfig; import org.apache.myfaces.mc.test.core.annotation.ManagedBeans; import org.apache.myfaces.mc.test.core.annotation.PageBean; @@ -62,6 +73,7 @@ import org.apache.myfaces.test.el.MockEx import org.apache.myfaces.test.mock.MockPrintWriter; import org.apache.myfaces.test.mock.MockServletConfig; import org.apache.myfaces.test.mock.MockServletContext; +import org.apache.myfaces.util.DebugUtils; import org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage; import org.apache.myfaces.webapp.AbstractFacesInitializer; import org.apache.myfaces.webapp.StartupServletContextListener; @@ -99,6 +111,13 @@ public abstract class AbstractMyFacesTes public static final String LAST_PHASE_PROCESSED = "oam.LAST_PHASE_PROCESSED"; + public static final String LAST_RENDER_PHASE_STEP = "oam.LAST_RENDER_PHASE_STEP"; + + public static final int BEFORE_RENDER_STEP = 1; + public static final int BUILD_VIEW_CYCLE_STEP = 2; + public static final int VIEWHANDLER_RENDER_STEP = 3; + public static final int AFTER_RENDER_STEP = 4; + // ------------------------------------------------------------ Constructors /** @@ -446,6 +465,7 @@ public abstract class AbstractMyFacesTes processRemainingExecutePhases(facesContext); lifecycle.render(facesContext); facesContext.getAttributes().put(LAST_PHASE_PROCESSED, PhaseId.RENDER_RESPONSE); + facesContext.getAttributes().put(LAST_RENDER_PHASE_STEP, AFTER_RENDER_STEP); } protected void processRemainingExecutePhases(FacesContext facesContext) throws Exception @@ -516,7 +536,29 @@ public abstract class AbstractMyFacesTes } if (continueProcess || PhaseId.INVOKE_APPLICATION.equals(lastPhaseId)) { - processRender(facesContext); + Integer step = (Integer) facesContext.getAttributes().get(LAST_RENDER_PHASE_STEP); + if (step == null) + { + processRender(facesContext); + } + else + { + if (BEFORE_RENDER_STEP == step.intValue()) + { + executeBuildViewCycle(facesContext); + executeViewHandlerRender(facesContext); + executeAfterRender(facesContext); + } + else if (BUILD_VIEW_CYCLE_STEP == step.intValue()) + { + executeViewHandlerRender(facesContext); + executeAfterRender(facesContext); + } + else if (VIEWHANDLER_RENDER_STEP == step.intValue()) + { + executeAfterRender(facesContext); + } + } } } } @@ -532,6 +574,291 @@ public abstract class AbstractMyFacesTes return false; } + protected void executeBeforeRender(FacesContext facesContext) throws Exception + { + if (lifecycle instanceof LifecycleImpl) + { + LifecycleImpl lifecycleImpl = (LifecycleImpl) lifecycle; + + Object phaseExecutor = null; + Field renderExecutorField = lifecycleImpl.getClass().getDeclaredField("renderExecutor"); + if (!renderExecutorField.isAccessible()) + { + renderExecutorField.setAccessible(true); + } + phaseExecutor = renderExecutorField.get(lifecycleImpl); + + if (facesContext.getResponseComplete()) + { + return; + } + + Object phaseManager = facesContext.getAttributes().get(PHASE_MANAGER_INSTANCE); + if (phaseManager == null) + { + Method getPhaseListenersMethod = lifecycleImpl.getClass().getDeclaredMethod("getPhaseListeners"); + if (!getPhaseListenersMethod.isAccessible()) + { + getPhaseListenersMethod.setAccessible(true); + } + + Constructor plmc = PHASE_MANAGER_CLASS.getDeclaredConstructor(new Class[]{Lifecycle.class, FacesContext.class, PhaseListener[].class}); + if (!plmc.isAccessible()) + { + plmc.setAccessible(true); + } + phaseManager = plmc.newInstance(lifecycle, facesContext, getPhaseListenersMethod.invoke(lifecycleImpl, null)); + facesContext.getAttributes().put(PHASE_MANAGER_INSTANCE, phaseManager); + } + + Flash flash = facesContext.getExternalContext().getFlash(); + + try + { + facesContext.setCurrentPhaseId(PhaseId.RENDER_RESPONSE); + + flash.doPrePhaseActions(facesContext); + + // let the PhaseExecutor do some pre-phase actions + + //renderExecutor.doPrePhaseActions(facesContext); + Method doPrePhaseActionsMethod = phaseExecutor.getClass().getMethod("doPrePhaseActions", FacesContext.class); + if(!(doPrePhaseActionsMethod.isAccessible())) + { + doPrePhaseActionsMethod.setAccessible(true); + } + doPrePhaseActionsMethod.invoke(phaseExecutor, facesContext); + + //phaseListenerMgr.informPhaseListenersBefore(PhaseId.RENDER_RESPONSE); + Method informPhaseListenersBeforeMethod = phaseManager.getClass().getDeclaredMethod("informPhaseListenersBefore", PhaseId.class); + if(!(informPhaseListenersBeforeMethod.isAccessible())) + { + informPhaseListenersBeforeMethod.setAccessible(true); + } + informPhaseListenersBeforeMethod.invoke(phaseManager, PhaseId.RENDER_RESPONSE); + + // also possible that one of the listeners completed the response + if (facesContext.getResponseComplete()) + { + return; + } + + //renderExecutor.execute(facesContext); + } + + catch (Throwable e) + { + // JSF 2.0: publish the executor's exception (if any). + ExceptionQueuedEventContext context = new ExceptionQueuedEventContext (facesContext, e, null, PhaseId.RENDER_RESPONSE); + facesContext.getApplication().publishEvent (facesContext, ExceptionQueuedEvent.class, context); + } + + finally + { + /* + phaseListenerMgr.informPhaseListenersAfter(renderExecutor.getPhase()); + flash.doPostPhaseActions(facesContext); + + // publish a field in the application map to indicate + // that the first request has been processed + requestProcessed(facesContext); + */ + } + + facesContext.getExceptionHandler().handle(); + + + facesContext.getAttributes().remove(PHASE_MANAGER_INSTANCE); + + facesContext.getAttributes().put(LAST_RENDER_PHASE_STEP, BEFORE_RENDER_STEP); + } + else + { + throw new UnsupportedOperationException("Cannot execute phase on custom lifecycle instances"); + } + } + + public void executeBuildViewCycle(FacesContext facesContext) throws Exception + { + Application application = facesContext.getApplication(); + ViewHandler viewHandler = application.getViewHandler(); + UIViewRoot root; + UIViewRoot previousRoot; + String viewId; + String newViewId; + boolean isNotSameRoot; + int loops = 0; + int maxLoops = 15; + + if (facesContext.getViewRoot() == null) + { + throw new ViewNotFoundException("A view is required to execute "+facesContext.getCurrentPhaseId()); + } + + try + { + // do-while, because the view might change in PreRenderViewEvent-listeners + do + { + root = facesContext.getViewRoot(); + previousRoot = root; + viewId = root.getViewId(); + + ViewDeclarationLanguage vdl = viewHandler.getViewDeclarationLanguage( + facesContext, viewId); + if (vdl != null) + { + vdl.buildView(facesContext, root); + } + + // publish a PreRenderViewEvent: note that the event listeners + // of this event can change the view, so we have to perform the algorithm + // until the viewId does not change when publishing this event. + application.publishEvent(facesContext, PreRenderViewEvent.class, root); + + // was the response marked as complete by an event listener? + if (facesContext.getResponseComplete()) + { + return; + } + + root = facesContext.getViewRoot(); + + newViewId = root.getViewId(); + + isNotSameRoot = !( (newViewId == null ? newViewId == viewId : newViewId.equals(viewId) ) && + previousRoot.equals(root) ); + + loops++; + } + while ((newViewId == null && viewId != null) + || (newViewId != null && (!newViewId.equals(viewId) || isNotSameRoot ) ) && loops < maxLoops); + + if (loops == maxLoops) + { + // PreRenderView reach maxLoops - probably a infinitive recursion: + boolean production = facesContext.isProjectStage(ProjectStage.Production); + /* + Level level = production ? Level.FINE : Level.WARNING; + if (log.isLoggable(level)) + { + log.log(level, "Cicle over buildView-PreRenderViewEvent on RENDER_RESPONSE phase " + + "reaches maximal limit, please check listeners for infinite recursion."); + }*/ + } + + facesContext.getAttributes().put(LAST_RENDER_PHASE_STEP, BUILD_VIEW_CYCLE_STEP); + } + catch (IOException e) + { + throw new FacesException(e.getMessage(), e); + } + } + + public void executeViewHandlerRender(FacesContext facesContext) + { + Application application = facesContext.getApplication(); + ViewHandler viewHandler = application.getViewHandler(); + + try + { + viewHandler.renderView(facesContext, facesContext.getViewRoot()); + + // log all unhandled FacesMessages, don't swallow them + // perf: org.apache.myfaces.context.servlet.FacesContextImpl.getMessageList() creates + // new Collections.unmodifiableList with every invocation-> call it only once + // and messageList is RandomAccess -> use index based loop + List messageList = facesContext.getMessageList(); + if (!messageList.isEmpty()) + { + StringBuilder builder = new StringBuilder(); + //boolean shouldLog = false; + for (int i = 0, size = messageList.size(); i < size; i++) + { + FacesMessage message = messageList.get(i); + if (!message.isRendered()) + { + builder.append("\n- "); + builder.append(message.getDetail()); + + //shouldLog = true; + } + } + /* + if (shouldLog) + { + log.log(Level.WARNING, "There are some unhandled FacesMessages, " + + "this means not every FacesMessage had a chance to be rendered.\n" + + "These unhandled FacesMessages are: " + builder.toString()); + }*/ + } + facesContext.getAttributes().put(LAST_RENDER_PHASE_STEP, VIEWHANDLER_RENDER_STEP); + } + catch (IOException e) + { + throw new FacesException(e.getMessage(), e); + } + } + + public void executeAfterRender(FacesContext facesContext) throws Exception + { + if (lifecycle instanceof LifecycleImpl) + { + LifecycleImpl lifecycleImpl = (LifecycleImpl) lifecycle; + + Object phaseExecutor = null; + Field renderExecutorField = lifecycleImpl.getClass().getDeclaredField("renderExecutor"); + if (!renderExecutorField.isAccessible()) + { + renderExecutorField.setAccessible(true); + } + phaseExecutor = renderExecutorField.get(lifecycleImpl); + + Object phaseManager = facesContext.getAttributes().get(PHASE_MANAGER_INSTANCE); + if (phaseManager == null) + { + Method getPhaseListenersMethod = lifecycleImpl.getClass().getDeclaredMethod("getPhaseListeners"); + if (!getPhaseListenersMethod.isAccessible()) + { + getPhaseListenersMethod.setAccessible(true); + } + + Constructor plmc = PHASE_MANAGER_CLASS.getDeclaredConstructor(new Class[]{Lifecycle.class, FacesContext.class, PhaseListener[].class}); + if (!plmc.isAccessible()) + { + plmc.setAccessible(true); + } + phaseManager = plmc.newInstance(lifecycle, facesContext, getPhaseListenersMethod.invoke(lifecycleImpl, null)); + facesContext.getAttributes().put(PHASE_MANAGER_INSTANCE, phaseManager); + } + + + Flash flash = facesContext.getExternalContext().getFlash(); + + //phaseListenerMgr.informPhaseListenersAfter(renderExecutor.getPhase()); + Method informPhaseListenersAfterMethod = phaseManager.getClass().getDeclaredMethod("informPhaseListenersAfter", PhaseId.class); + if(!(informPhaseListenersAfterMethod.isAccessible())) + { + informPhaseListenersAfterMethod.setAccessible(true); + } + informPhaseListenersAfterMethod.invoke(phaseManager, PhaseId.RENDER_RESPONSE); + + flash.doPostPhaseActions(facesContext); + + facesContext.getExceptionHandler().handle(); + + facesContext.getAttributes().remove(PHASE_MANAGER_INSTANCE); + + facesContext.getAttributes().put(LAST_RENDER_PHASE_STEP, AFTER_RENDER_STEP); + //End render response phase + facesContext.getAttributes().put(LAST_PHASE_PROCESSED, PhaseId.RENDER_RESPONSE); + } + else + { + throw new UnsupportedOperationException("Cannot execute phase on custom lifecycle instances"); + } + } + /** * Execute an specified phase, doing some reflection over LifecycleImpl. * Modified: myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/view/facelets/pss/acid/AcidMyFacesRequestTestCase.java URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/view/facelets/pss/acid/AcidMyFacesRequestTestCase.java?rev=1417718&r1=1417717&r2=1417718&view=diff ============================================================================== --- myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/view/facelets/pss/acid/AcidMyFacesRequestTestCase.java (original) +++ myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/view/facelets/pss/acid/AcidMyFacesRequestTestCase.java Thu Dec 6 00:56:08 2012 @@ -22,12 +22,14 @@ import javax.faces.application.StateMana import javax.faces.component.UICommand; import javax.faces.component.UIComponent; import javax.faces.component.UIInput; +import javax.faces.component.UIPanel; import javax.faces.component.html.HtmlDataTable; import junit.framework.Assert; import org.apache.myfaces.mc.test.core.AbstractMyFacesRequestTestCase; import org.apache.myfaces.shared.config.MyfacesConfig; +import org.apache.myfaces.view.facelets.pss.acid.managed.ResourceDependencyBean; import org.junit.Test; public class AcidMyFacesRequestTestCase extends AbstractMyFacesRequestTestCase @@ -418,4 +420,92 @@ public class AcidMyFacesRequestTestCase //Check it is restored Assert.assertNotNull(component); } + + /** + * Check if a dynamic subtree can be created from a binding property, and if it + * will be preserved across request. + * + * The idea is just inject a subtree using some code like this: + * <h:panelGroup id="panel" binding="#{componentBindingBean.panel}"> + * + * The solution is if a binding returns a component that has children or facets + * attached, it is not elegible for PSS algorithm because the additional components + * are created outside facelets control, and there is no warrant that the same structure + * will be generated across requests, violating PSS base principle (it is possible to + * restore to the initial state calling vdl.buildView). + * + * This test is here because all state saving modes should support this method. + * + * @throws Exception + */ + @Test + public void testComponentBinding() throws Exception + { + setupRequest("/componentBinding1.xhtml"); + processLifecycleExecuteAndRender(); + + UIComponent comp = facesContext.getViewRoot().findComponent("panel"); + Assert.assertNotNull(comp); + Assert.assertEquals(1, comp.getChildCount()); + + UICommand button = (UICommand) facesContext.getViewRoot().findComponent("mainForm:postback"); + submit(button); + processLifecycleExecuteAndRender(); + + comp = facesContext.getViewRoot().findComponent("panel"); + + Assert.assertEquals("value1", comp.getAttributes().get("attr1")); + Assert.assertEquals("value2", comp.getChildren().get(0).getAttributes().get("attr2")); + + button = (UICommand) facesContext.getViewRoot().findComponent("mainForm:postback"); + submit(button); + processLifecycleExecuteAndRender(); + + comp = facesContext.getViewRoot().findComponent("panel"); + + Assert.assertEquals("value1", comp.getAttributes().get("attr1")); + Assert.assertEquals("value2", comp.getChildren().get(0).getAttributes().get("attr2")); + + tearDownRequest(); + } + + @Test + public void testResourceDependency() throws Exception + { + setupRequest("/resourceDependency1.xhtml"); + processLifecycleExecute(); + + executeBeforeRender(facesContext); + executeBuildViewCycle(facesContext); + + UIPanel headPanel = (UIPanel) facesContext.getViewRoot().getFacet("head"); + Assert.assertNotNull(headPanel); + Assert.assertEquals(1, headPanel.getChildCount()); + + String nextUniqueId = facesContext.getViewRoot().createUniqueId(facesContext, null); + + executeViewHandlerRender(facesContext); + executeAfterRender(facesContext); + + UICommand button = (UICommand) facesContext.getViewRoot().findComponent("mainForm:postback"); + submit(button); + + processLifecycleExecute(); + + ResourceDependencyBean bean = facesContext.getApplication().evaluateExpressionGet( + facesContext, "#{resourceDependencyBean}", ResourceDependencyBean.class); + bean.setIncludeContent(true); + + executeBeforeRender(facesContext); + executeBuildViewCycle(facesContext); + + headPanel = (UIPanel) facesContext.getViewRoot().getFacet("head"); + Assert.assertNotNull(headPanel); + Assert.assertEquals(1, headPanel.getChildCount()); + Assert.assertNotSame(nextUniqueId, headPanel.getChildren().get(0).getId()); + + executeViewHandlerRender(facesContext); + executeAfterRender(facesContext); + } + } Added: myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/view/facelets/pss/acid/component/UIRDComponent.java URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/view/facelets/pss/acid/component/UIRDComponent.java?rev=1417718&view=auto ============================================================================== --- myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/view/facelets/pss/acid/component/UIRDComponent.java (added) +++ myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/view/facelets/pss/acid/component/UIRDComponent.java Thu Dec 6 00:56:08 2012 @@ -0,0 +1,35 @@ +/* + * Copyright 2012 The Apache Software Foundation. + * + * Licensed 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.view.facelets.pss.acid.component; + +import javax.faces.application.ResourceDependency; +import javax.faces.component.FacesComponent; +import javax.faces.component.UIOutput; + +/** + * + * @author lu4242 + */ +@FacesComponent(value = "com.myapp.UIRDComponent") +@ResourceDependency(name = "custom.css", target="head") +public class UIRDComponent extends UIOutput +{ + public UIRDComponent() + { + super(); + } + +} Propchange: myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/view/facelets/pss/acid/component/UIRDComponent.java ------------------------------------------------------------------------------ svn:eol-style = native Added: myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/view/facelets/pss/acid/managed/ComponentBindingBean.java URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/view/facelets/pss/acid/managed/ComponentBindingBean.java?rev=1417718&view=auto ============================================================================== --- myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/view/facelets/pss/acid/managed/ComponentBindingBean.java (added) +++ myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/view/facelets/pss/acid/managed/ComponentBindingBean.java Thu Dec 6 00:56:08 2012 @@ -0,0 +1,75 @@ +/* + * 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.view.facelets.pss.acid.managed; + +import javax.faces.bean.ManagedBean; +import javax.faces.bean.RequestScoped; +import javax.faces.component.UIOutput; +import javax.faces.component.UIPanel; +import javax.faces.component.html.HtmlPanelGroup; +import javax.faces.context.FacesContext; + +/** + * + * @author Leonardo Uribe + */ +@ManagedBean(name="componentBindingBean") +@RequestScoped +public class ComponentBindingBean +{ + private UIPanel panel; + + public UIPanel getPanel() + { + if (panel == null) + { + panel = new HtmlPanelGroup(); + if (FacesContext.getCurrentInstance().isPostback()) + { + // Just try to mess the binding. In theory this does + // not have effect, because the binding with children + // or facets should be restored fully. + UIOutput out2 = new UIOutput(); + out2.setValue("hello2"); + panel.getChildren().add(out2); + } + UIOutput out = new UIOutput(); + out.setValue("hello1"); + panel.getChildren().add(out); + if (!FacesContext.getCurrentInstance().isPostback()) + { + // Store something into the state + panel.getAttributes().put("attr1", "value1"); + panel.getChildren().get(0).getAttributes().put("attr2", "value2"); + } + else + { + //Try to mess the state, in theory it should not have effect + panel.getAttributes().remove("attr1"); + panel.getChildren().get(0).getAttributes().remove("attr2"); + } + } + return panel; + } + + public void setPanel(UIPanel panel) + { + this.panel = panel; + } +} Propchange: myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/view/facelets/pss/acid/managed/ComponentBindingBean.java ------------------------------------------------------------------------------ svn:eol-style = native Added: myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/view/facelets/pss/acid/managed/ResourceDependencyBean.java URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/view/facelets/pss/acid/managed/ResourceDependencyBean.java?rev=1417718&view=auto ============================================================================== --- myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/view/facelets/pss/acid/managed/ResourceDependencyBean.java (added) +++ myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/view/facelets/pss/acid/managed/ResourceDependencyBean.java Thu Dec 6 00:56:08 2012 @@ -0,0 +1,49 @@ +/* + * 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.view.facelets.pss.acid.managed; + +import javax.faces.bean.ManagedBean; +import javax.faces.bean.SessionScoped; + +/** + * + * @author Leonardo Uribe + */ +@ManagedBean(name="resourceDependencyBean") +@SessionScoped +public class ResourceDependencyBean +{ + private boolean includeContent; + + /** + * @return the includeContent + */ + public boolean isIncludeContent() + { + return includeContent; + } + + /** + * @param includeContent the includeContent to set + */ + public void setIncludeContent(boolean includeContent) + { + this.includeContent = includeContent; + } +} Propchange: myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/view/facelets/pss/acid/managed/ResourceDependencyBean.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: myfaces/core/branches/2.0.x/impl/src/test/resources/org/apache/myfaces/view/facelets/pss/acid/WEB-INF/testcomponent.taglib.xml URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/test/resources/org/apache/myfaces/view/facelets/pss/acid/WEB-INF/testcomponent.taglib.xml?rev=1417718&r1=1417717&r2=1417718&view=diff ============================================================================== --- myfaces/core/branches/2.0.x/impl/src/test/resources/org/apache/myfaces/view/facelets/pss/acid/WEB-INF/testcomponent.taglib.xml (original) +++ myfaces/core/branches/2.0.x/impl/src/test/resources/org/apache/myfaces/view/facelets/pss/acid/WEB-INF/testcomponent.taglib.xml Thu Dec 6 00:56:08 2012 @@ -64,5 +64,12 @@ com.myapp.UISelfRenderComponent + + + rdcomponent + + com.myapp.UIRDComponent + + \ No newline at end of file Added: myfaces/core/branches/2.0.x/impl/src/test/resources/org/apache/myfaces/view/facelets/pss/acid/componentBinding1.xhtml URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/test/resources/org/apache/myfaces/view/facelets/pss/acid/componentBinding1.xhtml?rev=1417718&view=auto ============================================================================== --- myfaces/core/branches/2.0.x/impl/src/test/resources/org/apache/myfaces/view/facelets/pss/acid/componentBinding1.xhtml (added) +++ myfaces/core/branches/2.0.x/impl/src/test/resources/org/apache/myfaces/view/facelets/pss/acid/componentBinding1.xhtml Thu Dec 6 00:56:08 2012 @@ -0,0 +1,28 @@ + + + + + + + + + + + + + Propchange: myfaces/core/branches/2.0.x/impl/src/test/resources/org/apache/myfaces/view/facelets/pss/acid/componentBinding1.xhtml ------------------------------------------------------------------------------ svn:eol-style = native Added: myfaces/core/branches/2.0.x/impl/src/test/resources/org/apache/myfaces/view/facelets/pss/acid/resourceDependency1.xhtml URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/test/resources/org/apache/myfaces/view/facelets/pss/acid/resourceDependency1.xhtml?rev=1417718&view=auto ============================================================================== --- myfaces/core/branches/2.0.x/impl/src/test/resources/org/apache/myfaces/view/facelets/pss/acid/resourceDependency1.xhtml (added) +++ myfaces/core/branches/2.0.x/impl/src/test/resources/org/apache/myfaces/view/facelets/pss/acid/resourceDependency1.xhtml Thu Dec 6 00:56:08 2012 @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + Propchange: myfaces/core/branches/2.0.x/impl/src/test/resources/org/apache/myfaces/view/facelets/pss/acid/resourceDependency1.xhtml ------------------------------------------------------------------------------ svn:eol-style = native Propchange: myfaces/core/branches/2.0.x/impl/src/test/resources/org/apache/myfaces/view/facelets/pss/acid/resources/ ------------------------------------------------------------------------------ bugtraq:number = true Added: myfaces/core/branches/2.0.x/impl/src/test/resources/org/apache/myfaces/view/facelets/pss/acid/resources/custom.css URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/test/resources/org/apache/myfaces/view/facelets/pss/acid/resources/custom.css?rev=1417718&view=auto ============================================================================== --- myfaces/core/branches/2.0.x/impl/src/test/resources/org/apache/myfaces/view/facelets/pss/acid/resources/custom.css (added) +++ myfaces/core/branches/2.0.x/impl/src/test/resources/org/apache/myfaces/view/facelets/pss/acid/resources/custom.css Thu Dec 6 00:56:08 2012 @@ -0,0 +1,15 @@ +/* + * Copyright 2012 The Apache Software Foundation. + * + * Licensed 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. + */ Propchange: myfaces/core/branches/2.0.x/impl/src/test/resources/org/apache/myfaces/view/facelets/pss/acid/resources/custom.css ------------------------------------------------------------------------------ svn:eol-style = native