You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lo...@apache.org on 2016/11/03 11:28:26 UTC
svn commit: r1767871 [1/3] - in /myfaces/tobago/trunk:
tobago-core/src/main/java/org/apache/myfaces/tobago/component/
tobago-core/src/main/java/org/apache/myfaces/tobago/facelets/
tobago-core/src/main/java/org/apache/myfaces/tobago/internal/behavior/ t...
Author: lofwyr
Date: Thu Nov 3 11:28:25 2016
New Revision: 1767871
URL: http://svn.apache.org/viewvc?rev=1767871&view=rev
Log:
TOBAGO-1617: New tag <tc:event> to be similar to <f:ajax> and to replace <tc:command> in facets
Added:
myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/component/ClientBehaviors.java
myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/facelets/EventHandler.java
myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/behavior/
myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/behavior/AttachedListStateWrapper.java
myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/behavior/AttachedStateWrapper.java
myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/behavior/DeltaStateHelper.java
myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/behavior/EventBehavior.java
myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUICommandBase.java
myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIEvent.java
- copied, changed from r1766668, myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUICommand.java
myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIRow.java
- copied, changed from r1765603, myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIColumnEvent.java
myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/EventTagDeclaration.java
myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/RowTagDeclaration.java
- copied, changed from r1765603, myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/ColumnEventTagDeclaration.java
myfaces/tobago/trunk/tobago-core/src/test/java/org/apache/myfaces/tobago/component/ClientBehaviorsUnitTest.java
- copied, changed from r1767843, myfaces/tobago/trunk/tobago-core/src/test/java/org/apache/myfaces/tobago/component/FacetsUnitTest.java
myfaces/tobago/trunk/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/6000-event/
myfaces/tobago/trunk/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/6000-event/event-input.xhtml
myfaces/tobago/trunk/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/6000-event/event.xhtml
myfaces/tobago/trunk/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/6000-event/progress.xhtml
- copied, changed from r1766842, myfaces/tobago/trunk/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/020-output/50-progress/progress.xhtml
myfaces/tobago/trunk/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/EventRenderer.java
- copied, changed from r1766668, myfaces/tobago/trunk/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/CommandRendererBase.java
Removed:
myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/component/ColumnEvent.java
myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIColumnEvent.java
myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/ColumnEventTagDeclaration.java
Modified:
myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/component/RendererTypes.java
myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUICommand.java
myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIInput.java
myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIPage.java
myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIPanel.java
myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIProgress.java
myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISheet.java
myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SheetTagDeclaration.java
myfaces/tobago/trunk/tobago-example/tobago-example-addressbook/src/main/webapp/addressbook/list.xhtml
myfaces/tobago/trunk/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/ProgressController.java
myfaces/tobago/trunk/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/SheetController.java
myfaces/tobago/trunk/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/080-sheet/30-event/sheet-column-event.xhtml
myfaces/tobago/trunk/tobago-example/tobago-example-demo/src/main/webapp/init.xhtml
myfaces/tobago/trunk/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/AjaxClientBehaviorRenderer.java
myfaces/tobago/trunk/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/Command.java
myfaces/tobago/trunk/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/CommandMap.java
myfaces/tobago/trunk/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/JsonUtils.java
myfaces/tobago/trunk/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/CommandRendererBase.java
myfaces/tobago/trunk/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/InRenderer.java
myfaces/tobago/trunk/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/PageRenderer.java
myfaces/tobago/trunk/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/PanelRenderer.java
myfaces/tobago/trunk/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/ProgressRenderer.java
myfaces/tobago/trunk/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/SelectBooleanCheckboxRenderer.java
myfaces/tobago/trunk/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/SelectManyCheckboxRenderer.java
myfaces/tobago/trunk/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/SelectManyListboxRenderer.java
myfaces/tobago/trunk/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/SelectManyShuttleRenderer.java
myfaces/tobago/trunk/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/SelectOneChoiceRenderer.java
myfaces/tobago/trunk/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/SelectOneListboxRenderer.java
myfaces/tobago/trunk/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/SelectOneRadioRenderer.java
myfaces/tobago/trunk/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/SheetRenderer.java
myfaces/tobago/trunk/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/TextareaRenderer.java
myfaces/tobago/trunk/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/TreeSelectRenderer.java
myfaces/tobago/trunk/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/util/HtmlRendererUtils.java
myfaces/tobago/trunk/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/util/RenderUtils.java
myfaces/tobago/trunk/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/tobago-sheet.js
myfaces/tobago/trunk/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/tobago.js
myfaces/tobago/trunk/tobago-theme/tobago-theme-standard/src/test/java/org/apache/myfaces/tobago/renderkit/html/JsonUtilsUnitTest.java
myfaces/tobago/trunk/tobago-tool/tobago-tool-apt/src/main/java/org/apache/myfaces/tobago/apt/processor/FacesConfigGenerator.java
myfaces/tobago/trunk/tobago-tool/tobago-tool-apt/src/main/resources/org/apache/myfaces/tobago/apt/component.stg
Added: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/component/ClientBehaviors.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/component/ClientBehaviors.java?rev=1767871&view=auto
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/component/ClientBehaviors.java (added)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/component/ClientBehaviors.java Thu Nov 3 11:28:25 2016
@@ -0,0 +1,30 @@
+/*
+ * 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.tobago.component;
+
+public enum ClientBehaviors {
+
+ click,
+ change;
+
+ public static final String CLICK = "click";
+ public static final String CHANGE = "click";
+
+}
Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/component/RendererTypes.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/component/RendererTypes.java?rev=1767871&r1=1767870&r2=1767871&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/component/RendererTypes.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/component/RendererTypes.java Thu Nov 3 11:28:25 2016
@@ -34,6 +34,7 @@ public enum RendererTypes {
Command,
Commands,
Date,
+ Event,
Figure,
File,
FlexLayout,
@@ -100,6 +101,7 @@ public enum RendererTypes {
public static final String COLUMN_SELECTOR = "ColumnSelector";
public static final String COMMAND = "Command";
public static final String COMMANDS = "Commands";
+ public static final String EVENT = "Event";
public static final String DATE = "Date";
public static final String FIGURE = "Figure";
public static final String FILE = "File";
Added: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/facelets/EventHandler.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/facelets/EventHandler.java?rev=1767871&view=auto
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/facelets/EventHandler.java (added)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/facelets/EventHandler.java Thu Nov 3 11:28:25 2016
@@ -0,0 +1,242 @@
+/*
+ * 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.tobago.facelets;
+
+import org.apache.myfaces.tobago.internal.behavior.EventBehavior;
+import org.apache.myfaces.tobago.component.Attributes;
+
+import javax.el.MethodExpression;
+import javax.faces.component.PartialStateHolder;
+import javax.faces.component.UIComponent;
+import javax.faces.component.behavior.AjaxBehavior;
+import javax.faces.component.behavior.ClientBehavior;
+import javax.faces.component.behavior.ClientBehaviorHolder;
+import javax.faces.context.FacesContext;
+import javax.faces.event.AbortProcessingException;
+import javax.faces.event.AjaxBehaviorEvent;
+import javax.faces.event.AjaxBehaviorListener;
+import javax.faces.view.BehaviorHolderAttachedObjectHandler;
+import javax.faces.view.facelets.ComponentConfig;
+import javax.faces.view.facelets.ComponentHandler;
+import javax.faces.view.facelets.FaceletContext;
+import javax.faces.view.facelets.TagAttribute;
+import javax.faces.view.facelets.TagAttributeException;
+import javax.faces.view.facelets.TagException;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * This tag creates an instance of AjaxBehavior, and associates it with the nearest
+ * parent UIComponent that implements ClientBehaviorHolder interface. This tag can
+ * be used on single or composite components.
+ * <p>
+ * Unless otherwise specified, all attributes accept static values or EL expressions.
+ * </p>
+ * <p>
+ * According to the documentation, the tag handler implementing this tag should meet
+ * the following conditions:
+ * </p>
+ * <ul>
+ * <li>Since this tag attach objects to UIComponent instances, and those instances
+ * implements Behavior interface, this component should implement
+ * BehaviorHolderAttachedObjectHandler interface.</li>
+ * <li>f:ajax does not support binding property. In theory we should do something similar
+ * to f:convertDateTime tag does: extends from ConverterHandler and override setAttributes
+ * method, but in this case BehaviorTagHandlerDelegate has binding property defined, so
+ * if we extend from BehaviorHandler we add binding support to f:ajax.</li>
+ * <li>This tag works as a attached object handler, but note on the api there is no component
+ * to define a target for a behavior. See comment inside apply() method.</li>
+ * </ul>
+ *
+ * @author Leonardo Uribe (latest modification by $Author: lu4242 $)
+ * @version $Revision: 1177714 $ $Date: 2011-09-30 15:51:51 +0000 (Fri, 30 Sep 2011) $
+ */
+public class EventHandler extends TobagoComponentHandler implements BehaviorHolderAttachedObjectHandler {
+
+ public final static Class<?>[] AJAX_BEHAVIOR_LISTENER_SIG = new Class<?>[]{AjaxBehaviorEvent.class};
+
+ private final TagAttribute _event;
+
+// todo (see original AjaxHandler impl) private final boolean _wrapMode;
+
+ public EventHandler(ComponentConfig config) {
+ super(config);
+ _event = getAttribute(Attributes.event.getName());
+ }
+
+ public void apply(FaceletContext ctx, UIComponent parent)
+ throws IOException {
+
+ super.apply(ctx, parent);
+
+ //Apply only if we are creating a new component
+ if (!ComponentHandler.isNew(parent)) {
+ return;
+ }
+ if (parent instanceof ClientBehaviorHolder) {
+ //Apply this handler directly over the parent
+ applyAttachedObject(ctx.getFacesContext(), parent);
+//todo } else if (UIComponent.isCompositeComponent(parent)) {
+//todo FaceletCompositionContext mctx = FaceletCompositionContext.getCurrentInstance(ctx);
+ // It is supposed that for composite components, this tag should
+ // add itself as a target, but note that on whole api does not exists
+ // some tag that expose client behaviors as targets for composite
+ // components. In RI, there exists a tag called composite:clientBehavior,
+ // but does not appear on spec or javadoc, maybe because this could be
+ // understand as an implementation detail, after all there exists a key
+ // called AttachedObjectTarget.ATTACHED_OBJECT_TARGETS_KEY that could be
+ // used to create a tag outside jsf implementation to attach targets.
+//todo mctx.addAttachedObjectHandler(parent, this);
+ } else {
+ throw new TagException(this.tag,
+ "Parent is not composite component or of type ClientBehaviorHolder, type is: "
+ + parent);
+ }
+ }
+
+ /**
+ * ViewDeclarationLanguage.retargetAttachedObjects uses it to check
+ * if the the target to be processed is applicable for this handler
+ */
+ public String getEventName() {
+ if (_event == null) {
+ return null;
+ } else {
+ return _event.getValue();
+ }
+ }
+
+ /**
+ * This method should create an AjaxBehavior object and attach it to the
+ * parent component.
+ * <p>
+ * Also, it should check if the parent can apply the selected AjaxBehavior
+ * to the selected component through ClientBehaviorHolder.getEventNames() or
+ * ClientBehaviorHolder.getDefaultEventName()
+ */
+ public void applyAttachedObject(FacesContext context, UIComponent parent) {
+ // Retrieve the current FaceletContext from FacesContext object
+ FaceletContext faceletContext = (FaceletContext) context
+ .getAttributes().get(FaceletContext.FACELET_CONTEXT_KEY);
+
+ // cast to a ClientBehaviorHolder
+ ClientBehaviorHolder cvh = (ClientBehaviorHolder) parent;
+
+ String eventName = getEventName();
+ if (eventName == null) {
+ eventName = cvh.getDefaultEventName();
+ if (eventName == null) {
+ throw new TagAttributeException(_event, "eventName could not be defined for f:ajax tag with no wrap mode.");
+ }
+ } else if (!cvh.getEventNames().contains(eventName)) {
+ throw new TagAttributeException(_event, "event it is not a valid eventName defined for this component");
+ }
+
+ Map<String, List<ClientBehavior>> clientBehaviors = cvh.getClientBehaviors();
+
+ List<ClientBehavior> clientBehaviorList = clientBehaviors.get(eventName);
+ if (clientBehaviorList != null && !clientBehaviorList.isEmpty()) {
+ for (ClientBehavior cb : clientBehaviorList) {
+ if (cb instanceof AjaxBehavior) {
+ // The most inner one has been applied, so according to
+ // jsf 2.0 spec section 10.4.1.1 it is not necessary to apply
+ // this one, because the inner one has precendece over
+ // the outer one.
+ return;
+ }
+ }
+ }
+
+ EventBehavior ajaxBehavior = createBehavior(context);
+
+ cvh.addClientBehavior(eventName, ajaxBehavior);
+ }
+
+ protected EventBehavior createBehavior(FacesContext context) {
+ return (EventBehavior) context.getApplication().createBehavior(EventBehavior.BEHAVIOR_ID);
+ }
+
+ /**
+ * The documentation says this attribute should not be used since it is not
+ * taken into account. Instead, getEventName is used on
+ * ViewDeclarationLanguage.retargetAttachedObjects.
+ */
+ public String getFor() {
+ return null;
+ }
+
+ /**
+ * Wraps a method expression in a AjaxBehaviorListener
+ */
+ public final static class AjaxBehaviorListenerImpl implements
+ AjaxBehaviorListener, PartialStateHolder {
+ private MethodExpression _expr;
+ private boolean _transient;
+ private boolean _initialStateMarked;
+
+ public AjaxBehaviorListenerImpl() {
+ }
+
+ public AjaxBehaviorListenerImpl(MethodExpression expr) {
+ _expr = expr;
+ }
+
+ public void processAjaxBehavior(AjaxBehaviorEvent event)
+ throws AbortProcessingException {
+ _expr.invoke(FacesContext.getCurrentInstance().getELContext(),
+ new Object[]{event});
+ }
+
+ public boolean isTransient() {
+ return _transient;
+ }
+
+ public void restoreState(FacesContext context, Object state) {
+ if (state == null) {
+ return;
+ }
+ _expr = (MethodExpression) state;
+ }
+
+ public Object saveState(FacesContext context) {
+ if (initialStateMarked()) {
+ return null;
+ }
+ return _expr;
+ }
+
+ public void setTransient(boolean newTransientValue) {
+ _transient = newTransientValue;
+ }
+
+ public void clearInitialState() {
+ _initialStateMarked = false;
+ }
+
+ public boolean initialStateMarked() {
+ return _initialStateMarked;
+ }
+
+ public void markInitialState() {
+ _initialStateMarked = true;
+ }
+ }
+}
Added: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/behavior/AttachedListStateWrapper.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/behavior/AttachedListStateWrapper.java?rev=1767871&view=auto
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/behavior/AttachedListStateWrapper.java (added)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/behavior/AttachedListStateWrapper.java Thu Nov 3 11:28:25 2016
@@ -0,0 +1,23 @@
+package org.apache.myfaces.tobago.internal.behavior;
+
+import java.io.Serializable;
+import java.util.List;
+
+// todo: clean up (is a copy of MyFaces, but not all stuff is refactored)
+
+class AttachedListStateWrapper
+ implements Serializable
+{
+ private static final long serialVersionUID = -3958718149793179776L;
+ private List<Object> _wrappedStateList;
+
+ public AttachedListStateWrapper(List<Object> wrappedStateList)
+ {
+ _wrappedStateList = wrappedStateList;
+ }
+
+ public List<Object> getWrappedStateList()
+ {
+ return _wrappedStateList;
+ }
+}
Added: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/behavior/AttachedStateWrapper.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/behavior/AttachedStateWrapper.java?rev=1767871&view=auto
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/behavior/AttachedStateWrapper.java (added)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/behavior/AttachedStateWrapper.java Thu Nov 3 11:28:25 2016
@@ -0,0 +1,38 @@
+package org.apache.myfaces.tobago.internal.behavior;
+
+import java.io.Serializable;
+
+// todo: clean up (is a copy of MyFaces, but not all stuff is refactored)
+
+class AttachedStateWrapper implements Serializable
+{
+ private static final long serialVersionUID = 4948301780259917764L;
+ private Class<?> _class;
+ private Object _wrappedStateObject;
+
+ /**
+ * @param clazz
+ * null means wrappedStateObject is a List of state objects
+ * @param wrappedStateObject
+ */
+ public AttachedStateWrapper(Class<?> clazz, Object wrappedStateObject)
+ {
+ if (wrappedStateObject != null && !(wrappedStateObject instanceof Serializable))
+ {
+ throw new IllegalArgumentException("Attached state for Object of type " + clazz + " (Class "
+ + wrappedStateObject.getClass().getName() + ") is not serializable");
+ }
+ _class = clazz;
+ _wrappedStateObject = wrappedStateObject;
+ }
+
+ public Class<?> getClazz()
+ {
+ return _class;
+ }
+
+ public Object getWrappedStateObject()
+ {
+ return _wrappedStateObject;
+ }
+}
Added: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/behavior/DeltaStateHelper.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/behavior/DeltaStateHelper.java?rev=1767871&view=auto
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/behavior/DeltaStateHelper.java (added)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/behavior/DeltaStateHelper.java Thu Nov 3 11:28:25 2016
@@ -0,0 +1,921 @@
+/*
+ * 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.tobago.internal.behavior;
+
+import javax.el.ValueExpression;
+import javax.faces.component.StateHelper;
+import javax.faces.component.StateHolder;
+import javax.faces.component.UIComponentBase;
+import javax.faces.context.FacesContext;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+// todo: clean up (is a copy of MyFaces, but not all stuff is refactored)
+
+/**
+ * A delta enabled state holder implementing the StateHolder Interface.
+ * <p>
+ * Components implementing the PartalStateHolder interface have an initial state
+ * and delta states, the initial state is the one holding all root values
+ * and deltas store differences to the initial states
+ * </p>
+ * <p>
+ * For components not implementing partial state saving only the initial states are
+ * of importance, everything is stored and restored continously there
+ * </p>
+ * <p>
+ * The state helper seems to have three internal storage mechanisms:
+ * one being a list which stores plain values,
+ * one being a key value pair which stores key values in maps
+ * add serves the plain list type while put serves the
+ * key value type,
+ * the third is the value which has to be stored plainly as is!
+ * </p>
+ * In other words, this map can be seen as a composite map. It has two maps:
+ * initial state map and delta map.
+ * <p>
+ * If delta map is used (method component.initialStateMarked() ),
+ * base or initial state map cannot be changed, since all changes
+ * should be tracked on delta map.
+ * </p>
+ * <p>
+ * The intention of this class is just hold property values
+ * and do a clean separation between initial state and delta.
+ * </p>
+ * <p>
+ * The code from this class comes from a refactor of
+ * org.apache.myfaces.trinidad.bean.util.PropertyHashMap
+ * </p>
+ * <p>
+ * The context from this class comes and that should be taken into account
+ * is this:
+ * </p>
+ * <p>
+ * First request:
+ * </p>
+ * <ul>
+ * <li> A new template is created (using
+ * javax.faces.view.ViewDeclarationLanguage.buildView method)
+ * and component.markInitialState is called from its related TagHandler classes
+ * (see javax.faces.view.facelets.ComponentHandler ).
+ * When this method is executed, the component tree was populated from the values
+ * set in the facelet abstract syntax tree (or in other words composition of
+ * facelets templates). </li>
+ * <li> From this point all updates on the variables are considered "delta". </li>
+ * <li> SaveState, if initialStateMarked is true, only delta is saved. </li>
+ * </ul>
+ * <p>
+ * Second request (and next ones)
+ * </p>
+ * <ul>
+ * <li> A new template is created and component.markInitialState is called from
+ * its related TagHandler classes again. In this way, components like c:forEach
+ * or c:if, that add or remove components could notify about this and handle
+ * them properly (see javax.faces.view.StateManagementStrategy). Note that a
+ * component restored using this method is no different as the same component
+ * at the first request at the same time. </li>
+ * <li> A call for restoreState is done, passing the delta as object value. If no
+ * delta, the state is complete and no call is triggered. </li>
+ * <li> Lifecycle occur, changing the necessary stuff. </li>
+ * <li> SaveState, if initialStateMarked is true, only delta is saved. </li>
+ * </ul>
+ * <p>
+ * From the previous analysis, the following conclusions arise:
+ * <ul>
+ * <li>This class only needs to keep track of delta changes, so when
+ * restoreState/saveState is called, the right objects are passed.</li>
+ * <li>UIComponent.clearInitialState is used to reset the partial
+ * state holder to a non delta state, so the state to be saved by
+ * saveState is no longer a delta instead is a full state. If a call
+ * to clearInitialState occur it is not expected a call for
+ * UIComponent.markInitialState occur on the current request.</li>
+ * <li>The state is handled in the same way on UIData, so components
+ * inside UIData share its state on all rows. There is no way to save
+ * delta per row.</li>
+ * <li>The map backed by method put(Serializable,String,Object) is
+ * a replacement of UIComponentBase.attributesMap and UIComponent.bindings map.
+ * Note that on jsf 1.2, instances saved on attributesMap should not be
+ * StateHolder, but on jsf 2.0 it is possible to have it. PartialStateHolder
+ * instances are not handled in this map, or in other words delta state is not
+ * handled in this classes (markInitialState and clearInitialState is not propagated).</li>
+ * <li>The list backed by method add(Serializable,Object) should be (is not) a
+ * replacement of UIComponentBase.facesListeners, but note that StateHelper
+ * does not implement PartialStateHolder, and facesListener could have instances
+ * of that class that needs to be notified when UIComponent.markInitialState or
+ * UIComponent.clearInitialState is called, or in other words facesListeners
+ * should deal with PartialStateHolder instances.</li>
+ * <li>The list backed by method add(Serializable,Object) is
+ * a replacement of UIViewRoot.phaseListeners list. Note that instances of
+ * PhaseListener are not expected to implement StateHolder or PartialStateHolder.</li>
+ * </ul>
+ * </p>
+ * <p>
+ * NOTE: The current implementation of StateHelper on RI does not handle
+ * stateHolder values internally. To prevent problems when developers create
+ * custom components we should do this too. But anyway, the code that
+ * handle this case should be let here as comment, if some day this feature
+ * is provided. Note than stateHolder aware properties like converter,
+ * validator or listeners should deal with StateHolder or PartialStateHolder
+ * on component classes.
+ *
+ * </p>
+ *
+ * @author Werner Punz
+ * @author Leonardo Uribe (latest modification by $Author: bommel $)
+ * @version $Rev: 1187700 $ $Date: 2011-10-22 12:19:37 +0000 (Sat, 22 Oct 2011) $
+ */
+class DeltaStateHelper<A extends EventBehavior> implements StateHelper
+{
+
+ /**
+ * We need to hold a component instance because:
+ *
+ * - The component is the one who knows if we are on initial or delta mode
+ * - eval assume calls to component.ValueExpression
+ */
+ private A _target;
+
+ /**
+ * This map holds the full current state
+ */
+ private Map<Serializable, Object> _fullState;
+
+ /**
+ * This map only keep track of delta changes to be saved
+ */
+ private Map<Serializable, Object> _deltas;
+
+ /**
+ * This map keep track of StateHolder keys, to be saved when
+ * saveState is called.
+ */
+ //private Set<Serializable> _stateHolderKeys;
+
+ private boolean _transient = false;
+
+ public DeltaStateHelper(A target)
+ {
+ super();
+ this._target = target;
+ _fullState = new HashMap<Serializable, Object>();
+ _deltas = null;
+ //_stateHolderKeys = new HashSet<Serializable>();
+ }
+
+ /**
+ * Used to create delta map on demand
+ *
+ * @return
+ */
+ private boolean _createDeltas()
+ {
+ if (isInitialStateMarked())
+ {
+ if (_deltas == null)
+ {
+ _deltas = new HashMap<Serializable, Object>(2);
+ }
+ return true;
+ }
+
+ return false;
+ }
+
+ protected boolean isInitialStateMarked()
+ {
+ return _target.initialStateMarked();
+ }
+
+ public void add(Serializable key, Object value)
+ {
+ if (_createDeltas())
+ {
+ //Track delta case
+ Map<Object, Boolean> deltaListMapValues = (Map<Object, Boolean>) _deltas
+ .get(key);
+ if (deltaListMapValues == null)
+ {
+ deltaListMapValues = new DeltaStateHelper.InternalDeltaListMap<Object, Boolean>(
+ 3);
+ _deltas.put(key, deltaListMapValues);
+ }
+ deltaListMapValues.put(value, Boolean.TRUE);
+ }
+
+ //Handle change on full map
+ List<Object> fullListValues = (List<Object>) _fullState.get(key);
+ if (fullListValues == null)
+ {
+ fullListValues = new DeltaStateHelper.InternalList<Object>(3);
+ _fullState.put(key, fullListValues);
+ }
+ fullListValues.add(value);
+ }
+
+ public Object eval(Serializable key)
+ {
+ Object returnValue = _fullState.get(key);
+ if (returnValue != null)
+ {
+ return returnValue;
+ }
+ ValueExpression expression = _target.getValueExpression(key
+ .toString());
+ if (expression != null)
+ {
+ return expression.getValue(FacesContext.getCurrentInstance()
+ .getELContext());
+ }
+ return null;
+ }
+
+ public Object eval(Serializable key, Object defaultValue)
+ {
+ Object returnValue = _fullState.get(key);
+ if (returnValue != null)
+ {
+ return returnValue;
+ }
+ ValueExpression expression = _target.getValueExpression(key
+ .toString());
+ if (expression != null)
+ {
+ return expression.getValue(FacesContext.getCurrentInstance()
+ .getELContext());
+ }
+ return defaultValue;
+ }
+
+ public Object get(Serializable key)
+ {
+ return _fullState.get(key);
+ }
+
+ public Object put(Serializable key, Object value)
+ {
+ Object returnValue = null;
+ if (_createDeltas())
+ {
+ if (_deltas.containsKey(key))
+ {
+ returnValue = _deltas.put(key, value);
+ _fullState.put(key, value);
+ }
+ else if (value == null && !_fullState.containsKey(key))
+ {
+ returnValue = null;
+ }
+ else
+ {
+ _deltas.put(key, value);
+ returnValue = _fullState.put(key, value);
+ }
+ }
+ else
+ {
+ /*
+ if (value instanceof StateHolder)
+ {
+ _stateHolderKeys.add(key);
+ }
+ */
+ returnValue = _fullState.put(key, value);
+ }
+ return returnValue;
+ }
+
+ public Object put(Serializable key, String mapKey, Object value)
+ {
+ boolean returnSet = false;
+ Object returnValue = null;
+ if (_createDeltas())
+ {
+ //Track delta case
+ Map<String, Object> mapValues = (Map<String, Object>) _deltas
+ .get(key);
+ if (mapValues == null)
+ {
+ mapValues = new DeltaStateHelper.InternalMap<String, Object>();
+ _deltas.put(key, mapValues);
+ }
+ if (mapValues.containsKey(mapKey))
+ {
+ returnValue = mapValues.put(mapKey, value);
+ returnSet = true;
+ }
+ else
+ {
+ mapValues.put(mapKey, value);
+ }
+ }
+
+ //Handle change on full map
+ Map<String, Object> mapValues = (Map<String, Object>) _fullState
+ .get(key);
+ if (mapValues == null)
+ {
+ mapValues = new DeltaStateHelper.InternalMap<String, Object>();
+ _fullState.put(key, mapValues);
+ }
+ if (returnSet)
+ {
+ mapValues.put(mapKey, value);
+ }
+ else
+ {
+ returnValue = mapValues.put(mapKey, value);
+ }
+ return returnValue;
+ }
+
+ public Object remove(Serializable key)
+ {
+ Object returnValue = null;
+ if (_createDeltas())
+ {
+ if (_deltas.containsKey(key))
+ {
+ // Keep track of the removed values using key/null pair on the delta map
+ returnValue = _deltas.put(key, null);
+ _fullState.remove(key);
+ }
+ else
+ {
+ // Keep track of the removed values using key/null pair on the delta map
+ _deltas.put(key, null);
+ returnValue = _fullState.remove(key);
+ }
+ }
+ else
+ {
+ returnValue = _fullState.remove(key);
+ }
+ return returnValue;
+ }
+
+ public Object remove(Serializable key, Object valueOrKey)
+ {
+ // Comment by lu4242 : The spec javadoc says if it is a Collection
+ // or Map deal with it. But the intention of this method is work
+ // with add(?,?) and put(?,?,?), this ones return instances of
+ // InternalMap and InternalList to prevent mixing, so to be
+ // consistent we'll cast to those classes here.
+
+ Object collectionOrMap = _fullState.get(key);
+ Object returnValue = null;
+ if (collectionOrMap instanceof DeltaStateHelper.InternalMap)
+ {
+ if (_createDeltas())
+ {
+ returnValue = _removeValueOrKeyFromMap(_deltas, key,
+ valueOrKey, true);
+ _removeValueOrKeyFromMap(_fullState, key, valueOrKey, false);
+ }
+ else
+ {
+ returnValue = _removeValueOrKeyFromMap(_fullState, key,
+ valueOrKey, false);
+ }
+ }
+ else if (collectionOrMap instanceof DeltaStateHelper.InternalList)
+ {
+ if (_createDeltas())
+ {
+ returnValue = _removeValueOrKeyFromCollectionDelta(_deltas,
+ key, valueOrKey);
+ _removeValueOrKeyFromCollection(_fullState, key, valueOrKey);
+ }
+ else
+ {
+ returnValue = _removeValueOrKeyFromCollection(_fullState, key,
+ valueOrKey);
+ }
+ }
+ return returnValue;
+ }
+
+ private static Object _removeValueOrKeyFromCollectionDelta(
+ Map<Serializable, Object> stateMap, Serializable key,
+ Object valueOrKey)
+ {
+ Object returnValue = null;
+ Map<Object, Boolean> c = (Map<Object, Boolean>) stateMap.get(key);
+ if (c != null)
+ {
+ if (c.containsKey(valueOrKey))
+ {
+ returnValue = valueOrKey;
+ }
+ c.put(valueOrKey, Boolean.FALSE);
+ }
+ return returnValue;
+ }
+
+ private static Object _removeValueOrKeyFromCollection(
+ Map<Serializable, Object> stateMap, Serializable key,
+ Object valueOrKey)
+ {
+ Object returnValue = null;
+ Collection c = (Collection) stateMap.get(key);
+ if (c != null)
+ {
+ if (c.remove(valueOrKey))
+ {
+ returnValue = valueOrKey;
+ }
+ if (c.isEmpty())
+ {
+ stateMap.remove(key);
+ }
+ }
+ return returnValue;
+ }
+
+ private static Object _removeValueOrKeyFromMap(
+ Map<Serializable, Object> stateMap, Serializable key,
+ Object valueOrKey, boolean delta)
+ {
+ if (valueOrKey == null)
+ {
+ return null;
+ }
+
+ Object returnValue = null;
+ Map<String, Object> map = (Map<String, Object>) stateMap.get(key);
+ if (map != null)
+ {
+ if (delta)
+ {
+ // Keep track of the removed values using key/null pair on the delta map
+ returnValue = map.put((String) valueOrKey, null);
+ }
+ else
+ {
+ returnValue = map.remove(valueOrKey);
+ }
+
+ if (map.isEmpty())
+ {
+ //stateMap.remove(key);
+ stateMap.put(key, null);
+ }
+ }
+ return returnValue;
+ }
+
+ public boolean isTransient()
+ {
+ return _transient;
+ }
+
+ /**
+ * Serializing cod
+ * the serialized data structure consists of key value pairs unless the value itself is an internal array
+ * or a map in case of an internal array or map the value itself is another array with its initial value
+ * myfaces.InternalArray, myfaces.internalMap
+ *
+ * the internal Array is then mapped to another array
+ *
+ * the internal Map again is then mapped to a map with key value pairs
+ *
+ *
+ */
+ public Object saveState(FacesContext context)
+ {
+ Map serializableMap = (isInitialStateMarked()) ? _deltas : _fullState;
+
+ if (serializableMap == null || serializableMap.size() == 0)
+ {
+ return null;
+ }
+
+ /*
+ int stateHolderKeyCount = 0;
+ if (isInitalStateMarked())
+ {
+ for (Iterator<Serializable> it = _stateHolderKeys.iterator(); it.hasNext();)
+ {
+ Serializable key = it.next();
+ if (!_deltas.containsKey(key))
+ {
+ stateHolderKeyCount++;
+ }
+ }
+ }*/
+
+ Map.Entry<Serializable, Object> entry;
+ //entry == key, value, key, value
+ Object[] retArr = new Object[serializableMap.entrySet().size() * 2];
+ //Object[] retArr = new Object[serializableMap.entrySet().size() * 2 + stateHolderKeyCount];
+
+ Iterator<Map.Entry<Serializable, Object>> it = serializableMap
+ .entrySet().iterator();
+ int cnt = 0;
+ while (it.hasNext())
+ {
+ entry = it.next();
+ retArr[cnt] = entry.getKey();
+
+ Object value = entry.getValue();
+
+ // The condition in which the call to saveAttachedState
+ // is to handle List, StateHolder or non Serializable instances.
+ // we check it here, to prevent unnecessary calls.
+ if (value instanceof StateHolder ||
+ value instanceof List ||
+ !(value instanceof Serializable))
+ {
+ Object savedValue = saveAttachedState(context,
+ value);
+ retArr[cnt + 1] = savedValue;
+ }
+ else
+ {
+ retArr[cnt + 1] = value;
+ }
+ cnt += 2;
+ }
+
+ /*
+ if (isInitalStateMarked())
+ {
+ for (Iterator<Serializable> it2 = _stateHolderKeys.iterator(); it.hasNext();)
+ {
+ Serializable key = it2.next();
+ if (!_deltas.containsKey(key))
+ {
+ retArr[cnt] = key;
+ Object value = _fullState.get(key);
+ if (value instanceof PartialStateHolder)
+ {
+ //Could contain delta, save it as _AttachedDeltaState
+ PartialStateHolder holder = (PartialStateHolder) value;
+ if (holder.isTransient())
+ {
+ retArr[cnt + 1] = null;
+ }
+ else
+ {
+ retArr[cnt + 1] = new _AttachedDeltaWrapper(value.getClass(), holder.saveState(context));
+ }
+ }
+ else
+ {
+ //Save everything
+ retArr[cnt + 1] = saveAttachedState(context, _fullState.get(key));
+ }
+ cnt += 2;
+ }
+ }
+ }
+ */
+ return retArr;
+ }
+
+ public void restoreState(FacesContext context, Object state)
+ {
+ if (state == null)
+ return;
+
+ Object[] serializedState = (Object[]) state;
+
+ if (!isInitialStateMarked() && !_fullState.isEmpty())
+ {
+ _fullState.clear();
+ if(_deltas != null)
+ {
+ _deltas.clear();
+ }
+ }
+
+ for (int cnt = 0; cnt < serializedState.length; cnt += 2)
+ {
+ Serializable key = (Serializable) serializedState[cnt];
+ Object savedValue = restoreAttachedState(context,
+ serializedState[cnt + 1]);
+
+ if (isInitialStateMarked())
+ {
+ if (savedValue instanceof DeltaStateHelper.InternalDeltaListMap)
+ {
+ for (Map.Entry<Object, Boolean> mapEntry : ((Map<Object, Boolean>) savedValue)
+ .entrySet())
+ {
+ boolean addOrRemove = mapEntry.getValue();
+ if (addOrRemove)
+ {
+ //add
+ this.add(key, mapEntry.getKey());
+ }
+ else
+ {
+ //remove
+ this.remove(key, mapEntry.getKey());
+ }
+ }
+ }
+ else if (savedValue instanceof DeltaStateHelper.InternalMap)
+ {
+ for (Map.Entry<String, Object> mapEntry : ((Map<String, Object>) savedValue)
+ .entrySet())
+ {
+ this.put(key, mapEntry.getKey(), mapEntry.getValue());
+ }
+ }
+ /*
+ else if (savedValue instanceof _AttachedDeltaWrapper)
+ {
+ AttachedStateWrapper wrapper = (AttachedStateWrapper) savedValue;
+ //Restore delta state
+ ((PartialStateHolder)_fullState.get(key)).restoreState(context, wrapper.getWrappedStateObject());
+ //Add this key as StateHolder key
+ _stateHolderKeys.add(key);
+ }
+ */
+ else
+ {
+ put(key, savedValue);
+ }
+ }
+ else
+ {
+ put(key, savedValue);
+ }
+ }
+ }
+
+ public void setTransient(boolean transientValue)
+ {
+ _transient = transientValue;
+ }
+
+ //We use our own data structures just to make sure
+ //nothing gets mixed up internally
+ static class InternalMap<K, V> extends HashMap<K, V> implements StateHolder
+ {
+ public InternalMap()
+ {
+ super();
+ }
+
+ public InternalMap(int initialCapacity, float loadFactor)
+ {
+ super(initialCapacity, loadFactor);
+ }
+
+ public InternalMap(Map<? extends K, ? extends V> m)
+ {
+ super(m);
+ }
+
+ public InternalMap(int initialSize)
+ {
+ super(initialSize);
+ }
+
+ public boolean isTransient()
+ {
+ return false;
+ }
+
+ public void setTransient(boolean newTransientValue)
+ {
+ // No op
+ }
+
+ public void restoreState(FacesContext context, Object state)
+ {
+ Object[] listAsMap = (Object[]) state;
+ for (int cnt = 0; cnt < listAsMap.length; cnt += 2)
+ {
+ this.put((K) listAsMap[cnt], (V) UIComponentBase
+ .restoreAttachedState(context, listAsMap[cnt + 1]));
+ }
+ }
+
+ public Object saveState(FacesContext context)
+ {
+ int cnt = 0;
+ Object[] mapArr = new Object[this.size() * 2];
+ for (Map.Entry<K, V> entry : this.entrySet())
+ {
+ mapArr[cnt] = entry.getKey();
+ Object value = entry.getValue();
+
+ if (value instanceof StateHolder ||
+ value instanceof List ||
+ !(value instanceof Serializable))
+ {
+ mapArr[cnt + 1] = saveAttachedState(context, value);
+ }
+ else
+ {
+ mapArr[cnt + 1] = value;
+ }
+ cnt += 2;
+ }
+ return mapArr;
+ }
+ }
+
+ /**
+ * Map used to keep track of list changes
+ */
+ static class InternalDeltaListMap<K, V> extends DeltaStateHelper.InternalMap<K, V>
+ {
+
+ public InternalDeltaListMap()
+ {
+ super();
+ }
+
+ public InternalDeltaListMap(int initialCapacity, float loadFactor)
+ {
+ super(initialCapacity, loadFactor);
+ }
+
+ public InternalDeltaListMap(int initialSize)
+ {
+ super(initialSize);
+ }
+
+ public InternalDeltaListMap(Map<? extends K, ? extends V> m)
+ {
+ super(m);
+ }
+ }
+
+ static class InternalList<T> extends ArrayList<T> implements StateHolder
+ {
+ public InternalList()
+ {
+ super();
+ }
+
+ public InternalList(Collection<? extends T> c)
+ {
+ super(c);
+ }
+
+ public InternalList(int initialSize)
+ {
+ super(initialSize);
+ }
+
+ public boolean isTransient()
+ {
+ return false;
+ }
+
+ public void setTransient(boolean newTransientValue)
+ {
+ }
+
+ public void restoreState(FacesContext context, Object state)
+ {
+ Object[] listAsArr = (Object[]) state;
+ //since all other options would mean dual iteration
+ //we have to do it the hard way
+ for (Object elem : listAsArr)
+ {
+ add((T) restoreAttachedState(context, elem));
+ }
+ }
+
+ public Object saveState(FacesContext context)
+ {
+ Object[] values = new Object[size()];
+ for (int i = 0; i < size(); i++)
+ {
+ Object value = get(i);
+
+ if (value instanceof StateHolder ||
+ value instanceof List ||
+ !(value instanceof Serializable))
+ {
+ values[i] = saveAttachedState(context, value);
+ }
+ else
+ {
+ values[i] = value;
+ }
+ }
+ return values;
+ }
+ }
+
+ private static Object saveAttachedState(FacesContext context, Object attachedObject)
+ {
+ if (context == null)
+ {
+ throw new NullPointerException ("context");
+ }
+
+ if (attachedObject == null)
+ return null;
+ // StateHolder interface should take precedence over
+ // List children
+ if (attachedObject instanceof StateHolder)
+ {
+ StateHolder holder = (StateHolder) attachedObject;
+ if (holder.isTransient())
+ {
+ return null;
+ }
+
+ return new AttachedStateWrapper(attachedObject.getClass(), holder.saveState(context));
+ }
+ else if (attachedObject instanceof List)
+ {
+ List<Object> lst = new ArrayList<Object>(((List<?>) attachedObject).size());
+ for (Object item : (List<?>) attachedObject)
+ {
+ if (item != null)
+ {
+ lst.add(saveAttachedState(context, item));
+ }
+ }
+
+ return new AttachedListStateWrapper(lst);
+ }
+ else if (attachedObject instanceof Serializable)
+ {
+ return attachedObject;
+ }
+ else
+ {
+ return new AttachedStateWrapper(attachedObject.getClass(), null);
+ }
+ }
+
+ private static Object restoreAttachedState(FacesContext context, Object stateObj) throws IllegalStateException
+ {
+ if (context == null)
+ throw new NullPointerException("context");
+ if (stateObj == null)
+ return null;
+ if (stateObj instanceof AttachedListStateWrapper)
+ {
+ List<Object> lst = ((AttachedListStateWrapper) stateObj).getWrappedStateList();
+ List<Object> restoredList = new ArrayList<Object>(lst.size());
+ for (Object item : lst)
+ {
+ restoredList.add(restoreAttachedState(context, item));
+ }
+ return restoredList;
+ }
+ else if (stateObj instanceof AttachedStateWrapper)
+ {
+ Class<?> clazz = ((AttachedStateWrapper) stateObj).getClazz();
+ Object restoredObject;
+ try
+ {
+ restoredObject = clazz.newInstance();
+ }
+ catch (InstantiationException e)
+ {
+ throw new RuntimeException("Could not restore StateHolder of type " + clazz.getName()
+ + " (missing no-args constructor?)", e);
+ }
+ catch (IllegalAccessException e)
+ {
+ throw new RuntimeException(e);
+ }
+ if (restoredObject instanceof StateHolder)
+ {
+ AttachedStateWrapper wrapper = (AttachedStateWrapper) stateObj;
+ Object wrappedState = wrapper.getWrappedStateObject();
+
+ StateHolder holder = (StateHolder) restoredObject;
+ holder.restoreState(context, wrappedState);
+ }
+ return restoredObject;
+ }
+ else
+ {
+ return stateObj;
+ }
+ }
+}
Added: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/behavior/EventBehavior.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/behavior/EventBehavior.java?rev=1767871&view=auto
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/behavior/EventBehavior.java (added)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/behavior/EventBehavior.java Thu Nov 3 11:28:25 2016
@@ -0,0 +1,371 @@
+/*
+ * 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.tobago.internal.behavior;
+
+import javax.el.ValueExpression;
+import javax.faces.component.StateHelper;
+import javax.faces.component.behavior.ClientBehaviorBase;
+import javax.faces.component.behavior.ClientBehaviorHint;
+import javax.faces.component.behavior.FacesBehavior;
+import javax.faces.context.FacesContext;
+import javax.faces.event.AjaxBehaviorListener;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Map;
+import java.util.Set;
+
+import static org.apache.myfaces.tobago.internal.behavior.EventBehavior.BEHAVIOR_ID;
+
+// todo: clean up (is a copy of MyFaces, but not all stuff is refactored)
+
+@FacesBehavior(value = BEHAVIOR_ID)
+public class EventBehavior extends ClientBehaviorBase
+{
+
+ /**
+ * not needed anymore but enforced by the spec
+ * theoretically a
+ * @FacesBehavior(value = "javax.faces.behavior.Ajax")
+ * could do it
+ */
+ public static final String BEHAVIOR_ID = "org.apache.myfaces.tobago.behavior.Event";
+
+ private static final String ATTR_EXECUTE = "execute";
+ private static final String ATTR_ON_ERROR = "onerror";
+ private static final String ATTR_ON_EVENT = "onevent";
+ private static final String ATTR_RENDER = "render";
+ private static final String ATTR_DISABLED = "disabled";
+ private static final String ATTR_IMMEDIATE = "immediate";
+
+ /**
+ * special render and execute targets
+ */
+ private static final String VAL_FORM = "@form";
+ private static final String VAL_ALL = "@all";
+ private static final String VAL_THIS = "@this";
+ private static final String VAL_NONE = "@none";
+
+ private static final Collection<String> VAL_FORM_LIST = Collections.singletonList(VAL_FORM);
+ private static final Collection<String> VAL_ALL_LIST = Collections.singletonList(VAL_ALL);
+ private static final Collection<String> VAL_THIS_LIST = Collections.singletonList(VAL_THIS);
+ private static final Collection<String> VAL_NONE_LIST = Collections.singletonList(VAL_NONE);
+
+ //To enable delta state saving we need this one
+ private DeltaStateHelper<EventBehavior> _stateHelper = null;
+
+ //private Map<String, ValueExpression> _valueExpressions
+ // = new HashMap<String, ValueExpression>();
+
+ public EventBehavior()
+ {
+ super();
+ }
+
+ public void addAjaxBehaviorListener(AjaxBehaviorListener listener)
+ {
+ super.addBehaviorListener(listener);
+ }
+
+ public void removeAjaxBehaviorListener(AjaxBehaviorListener listener)
+ {
+ removeBehaviorListener(listener);
+ }
+
+ public Collection<String> getExecute()
+ {
+ // we have to evaluate the real value in this method,
+ // because the value of the ValueExpression might
+ // change (almost sure it does!)
+ return evalForCollection(ATTR_EXECUTE);
+ }
+
+ public void setExecute(Collection<String> execute)
+ {
+ getStateHelper().put(ATTR_EXECUTE, execute);
+ }
+
+ public String getOnerror()
+ {
+ return (String) getStateHelper().eval(ATTR_ON_ERROR);
+ }
+
+ public void setOnerror(String onError)
+ {
+ getStateHelper().put(ATTR_ON_ERROR, onError);
+ }
+
+ public String getOnevent()
+ {
+ return (String) getStateHelper().eval(ATTR_ON_EVENT);
+ }
+
+ public void setOnevent(String onEvent)
+ {
+ getStateHelper().put(ATTR_ON_EVENT, onEvent);
+ }
+
+ public Collection<String> getRender()
+ {
+ // we have to evaluate the real value in this method,
+ // because the value of the ValueExpression might
+ // change (almost sure it does!)
+ return evalForCollection(ATTR_RENDER);
+ }
+
+ public void setRender(Collection<String> render)
+ {
+ getStateHelper().put(ATTR_RENDER, render);
+ }
+
+ @SuppressWarnings("unchecked")
+ public ValueExpression getValueExpression(String name)
+ {
+ //return getValueExpressionMap().get(name);
+ if (name == null)
+ {
+ throw new NullPointerException("name can not be null");
+ }
+
+ Map<String,Object> bindings = (Map<String,Object>) getStateHelper().
+ get(EventBehavior.PropertyKeys.bindings);
+ if (bindings != null)
+ {
+ return (ValueExpression) bindings.get(name);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public void setValueExpression(String name, ValueExpression expression)
+ {
+ /*
+ if (item == null)
+ {
+ getValueExpressionMap().remove(name);
+ getStateHelper().remove(name);
+ }
+ else
+ {
+ getValueExpressionMap().put(name, item);
+ }
+ */
+ if (name == null)
+ {
+ throw new NullPointerException("name");
+ }
+
+ if (expression == null)
+ {
+ getStateHelper().remove(EventBehavior.PropertyKeys.bindings, name);
+ }
+ else
+ {
+ getStateHelper().put(EventBehavior.PropertyKeys.bindings, name, expression);
+ }
+ }
+
+ public boolean isDisabled()
+ {
+ Boolean retVal = (Boolean) getStateHelper().eval(ATTR_DISABLED);
+ retVal = (retVal == null) ? false : retVal;
+ return retVal;
+ }
+
+ public void setDisabled(boolean disabled)
+ {
+ getStateHelper().put(ATTR_DISABLED, disabled);
+ }
+
+ public boolean isImmediate()
+ {
+ Boolean retVal = (Boolean) getStateHelper().eval(ATTR_IMMEDIATE);
+ retVal = (retVal == null) ? false : retVal;
+ return retVal;
+ }
+
+ public void setImmediate(boolean immediate)
+ {
+ getStateHelper().put(ATTR_IMMEDIATE, immediate);
+ }
+
+ public boolean isImmediateSet()
+ {
+ return (getStateHelper().get(ATTR_IMMEDIATE) != null) ||
+ (getValueExpression(ATTR_IMMEDIATE) != null);
+ }
+
+ @Override
+ public Set<ClientBehaviorHint> getHints()
+ {
+ return EnumSet.of(ClientBehaviorHint.SUBMITTING);
+ }
+
+ @Override
+ public String getRendererType()
+ {
+ return BEHAVIOR_ID;
+ }
+
+ @Override
+ public void restoreState(FacesContext facesContext, Object o)
+ {
+ if (o == null)
+ {
+ return;
+ }
+ Object[] values = (Object[]) o;
+ if (values[0] != null)
+ {
+ super.restoreState(facesContext, values[0]);
+ }
+ getStateHelper().restoreState(facesContext, values[1]);
+ }
+
+ private StateHelper getStateHelper()
+ {
+ return getStateHelper(true);
+ }
+
+ /**
+ * returns a delta state saving enabled state helper
+ * for the current component
+ * @param create if true a state helper is created if not already existing
+ * @return an implementation of the StateHelper interface or null if none exists and create is set to false
+ */
+ private StateHelper getStateHelper(boolean create)
+ {
+ if(_stateHelper != null)
+ {
+ return _stateHelper;
+ }
+ if(create)
+ {
+ _stateHelper = new DeltaStateHelper<EventBehavior>(this);
+ }
+ return _stateHelper;
+ }
+
+ @Override
+ public Object saveState(FacesContext facesContext)
+ {
+ if (initialStateMarked())
+ {
+ Object parentSaved = super.saveState(facesContext);
+ Object stateHelperSaved = null;
+ StateHelper stateHelper = getStateHelper(false);
+ if (stateHelper != null)
+ {
+ stateHelperSaved = stateHelper.saveState(facesContext);
+ }
+
+ if (parentSaved == null && stateHelperSaved == null)
+ {
+ //No values
+ return null;
+ }
+ return new Object[]{parentSaved, stateHelperSaved};
+ }
+ else
+ {
+ Object[] values = new Object[2];
+ values[0] = super.saveState(facesContext);
+ StateHelper stateHelper = getStateHelper(false);
+ if (stateHelper != null)
+ {
+ values[1] = stateHelper.saveState(facesContext);
+ }
+ return values;
+ }
+ }
+
+ //private Map<String, ValueExpression> getValueExpressionMap()
+ //{
+ // return _valueExpressions;
+ //}
+
+ /**
+ * Invokes eval on the getStateHelper() and tries to get a
+ * Collection out of the result.
+ * @param attributeName
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ private Collection<String> evalForCollection(String attributeName)
+ {
+ Object value = getStateHelper().eval(attributeName);
+ if (value == null)
+ {
+ return Collections.<String>emptyList();
+ }
+ else if (value instanceof Collection)
+ {
+ return (Collection<String>) value;
+ }
+ else if (value instanceof String)
+ {
+ return getCollectionFromSpaceSplitString((String) value);
+ }
+ else
+ {
+ throw new IllegalArgumentException("Type " + value.getClass()
+ + " not supported for attribute " + attributeName);
+ }
+ }
+
+ /**
+ * Splits the String based on spaces and returns the
+ * resulting Strings as Collection.
+ * @param stringValue
+ * @return
+ */
+ private Collection<String> getCollectionFromSpaceSplitString(String stringValue)
+ {
+ //@special handling for @all, @none, @form and @this
+ if (stringValue.equals(VAL_FORM))
+ {
+ return VAL_FORM_LIST;
+ }
+ else if (stringValue.equals(VAL_ALL))
+ {
+ return VAL_ALL_LIST;
+ }
+ else if (stringValue.equals(VAL_NONE))
+ {
+ return VAL_NONE_LIST;
+ }
+ else if (stringValue.equals(VAL_THIS))
+ {
+ return VAL_THIS_LIST;
+ }
+
+ // not one of the "normal" values - split it and return the Collection
+ String[] arrValue = stringValue.split(" ");
+ return Arrays.asList(arrValue);
+ }
+
+ private enum PropertyKeys
+ {
+ bindings,
+ }
+}
Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUICommand.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUICommand.java?rev=1767871&r1=1767870&r2=1767871&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUICommand.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUICommand.java Thu Nov 3 11:28:25 2016
@@ -21,32 +21,18 @@ package org.apache.myfaces.tobago.intern
import org.apache.myfaces.tobago.component.SupportsAccessKey;
import org.apache.myfaces.tobago.component.Visual;
-import org.apache.myfaces.tobago.event.CollapsibleActionListener;
-import org.apache.myfaces.tobago.internal.util.AuthorizationHelper;
-import org.apache.myfaces.tobago.util.ComponentUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.el.MethodExpression;
import javax.faces.component.UICommand;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.component.behavior.ClientBehaviorHolder;
-import javax.faces.context.FacesContext;
-import javax.faces.event.ComponentSystemEvent;
-import javax.faces.event.ComponentSystemEventListener;
-import javax.faces.event.FacesEvent;
-import javax.faces.event.ListenerFor;
-import javax.faces.event.PhaseId;
-import javax.faces.event.PostAddToViewEvent;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-@ListenerFor(systemEventClass = PostAddToViewEvent.class)
-public abstract class AbstractUICommand extends UICommand
- implements SupportsAccessKey, Visual, ClientBehaviorHolder, ComponentSystemEventListener {
+public abstract class AbstractUICommand extends AbstractUICommandBase
+ implements SupportsAccessKey, Visual, ClientBehaviorHolder {
private static final Logger LOG = LoggerFactory.getLogger(AbstractUICommand.class);
@@ -60,57 +46,6 @@ public abstract class AbstractUICommand
// todo: transient
private Boolean parentOfCommands;
- @Override
- public void processEvent(ComponentSystemEvent event) {
- super.processEvent(event);
-
- if (event instanceof PostAddToViewEvent) {
- final List<AbstractUIOperation> list = ComponentUtils.findDescendantList(this, AbstractUIOperation.class);
- for (AbstractUIOperation operation : list) {
- addActionListener(new CollapsibleActionListener(operation.getFor()));
- }
- }
- }
-
- @Override
- public void processDecodes(final FacesContext context) {
- if (context == null) {
- throw new NullPointerException();
- }
-
- // Skip processing if our rendered flag is false
- if (!isRendered()) {
- return;
- }
-
- // Process this component itself
- try {
- decode(context);
- } catch (final RuntimeException e) {
- context.renderResponse();
- throw e;
- }
-
- final Iterator kids = getFacetsAndChildren();
- while (kids.hasNext()) {
- final UIComponent kid = (UIComponent) kids.next();
- kid.processDecodes(context);
- }
- }
-
- @Override
- public void queueEvent(final FacesEvent facesEvent) {
- // fix for TOBAGO-262
- super.queueEvent(facesEvent);
- if (this == facesEvent.getSource()) {
- if (isImmediate()) {
- facesEvent.setPhaseId(PhaseId.APPLY_REQUEST_VALUES);
- } else {
- facesEvent.setPhaseId(PhaseId.INVOKE_APPLICATION);
- }
- }
- }
-
public boolean isParentOfCommands() {
if (parentOfCommands == null) {
parentOfCommands = false;
@@ -124,37 +59,6 @@ public abstract class AbstractUICommand
return parentOfCommands;
}
- /**
- Flag indicating that this element is disabled.
- <br>Default: <code>false</code>
- */
- public boolean isDisabled() {
-
- final FacesContext facesContext = getFacesContext();
- // todo: get from configuration tobago-config.xml
- if (true) {
- final AuthorizationHelper authorizationHelper = AuthorizationHelper.getInstance(facesContext);
- final MethodExpression actionExpression = getActionExpression();
- if (actionExpression != null) {
- final boolean authorized =
- authorizationHelper.isAuthorized(facesContext, actionExpression.getExpressionString());
- if (!authorized) {
- return true;
- }
- }
- }
-
- Boolean bool = (Boolean) getStateHelper().eval(PropertyKeys.disabled);
- if (bool != null) {
- return bool;
- }
- return false;
- }
-
- public void setDisabled(boolean disabled) {
- getStateHelper().put(PropertyKeys.disabled, disabled);
- }
-
// todo generate
@Override
public String getDefaultEventName() {
@@ -169,18 +73,4 @@ public abstract class AbstractUICommand
@Override
public abstract String getLabel();
-
- public abstract String getLink();
-
- public abstract String getTarget();
-
- public abstract boolean isTransition();
-
- public abstract boolean isOmit();
-
- public abstract void setOmit(boolean omit);
-
- public abstract String getTip();
-
- public abstract String getConfirmation();
}
Added: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUICommandBase.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUICommandBase.java?rev=1767871&view=auto
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUICommandBase.java (added)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUICommandBase.java Thu Nov 3 11:28:25 2016
@@ -0,0 +1,132 @@
+/*
+ * 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.tobago.internal.component;
+
+import org.apache.myfaces.tobago.event.CollapsibleActionListener;
+import org.apache.myfaces.tobago.internal.util.AuthorizationHelper;
+import org.apache.myfaces.tobago.util.ComponentUtils;
+
+import javax.el.MethodExpression;
+import javax.faces.component.UICommand;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.event.ComponentSystemEvent;
+import javax.faces.event.ComponentSystemEventListener;
+import javax.faces.event.FacesEvent;
+import javax.faces.event.ListenerFor;
+import javax.faces.event.PhaseId;
+import javax.faces.event.PostAddToViewEvent;
+import java.util.Iterator;
+import java.util.List;
+
+@ListenerFor(systemEventClass = PostAddToViewEvent.class)
+public abstract class AbstractUICommandBase extends UICommand
+ implements ComponentSystemEventListener {
+
+ @Override
+ public void processEvent(ComponentSystemEvent event) {
+ super.processEvent(event);
+
+ if (event instanceof PostAddToViewEvent) {
+ final List<AbstractUIOperation> list = ComponentUtils.findDescendantList(this, AbstractUIOperation.class);
+ for (AbstractUIOperation operation : list) {
+ addActionListener(new CollapsibleActionListener(operation.getFor()));
+ }
+ }
+ }
+
+ @Override
+ public void processDecodes(final FacesContext context) {
+ // Skip processing if our rendered flag is false
+ if (!isRendered()) {
+ return;
+ }
+
+ // Process this component itself
+ try {
+ decode(context);
+ } catch (final RuntimeException e) {
+ context.renderResponse();
+ throw e;
+ }
+
+ final Iterator kids = getFacetsAndChildren();
+ while (kids.hasNext()) {
+ final UIComponent kid = (UIComponent) kids.next();
+ kid.processDecodes(context);
+ }
+ }
+
+ @Override
+ public void queueEvent(final FacesEvent facesEvent) {
+ // fix for TOBAGO-262
+ super.queueEvent(facesEvent);
+ if (this == facesEvent.getSource()) {
+ if (isImmediate()) {
+ facesEvent.setPhaseId(PhaseId.APPLY_REQUEST_VALUES);
+ } else {
+ facesEvent.setPhaseId(PhaseId.INVOKE_APPLICATION);
+ }
+ }
+ }
+
+ /**
+ Flag indicating that this element is disabled.
+ <br>Default: <code>false</code>
+ */
+ public boolean isDisabled() {
+
+ final FacesContext facesContext = getFacesContext();
+ // todo: get from configuration tobago-config.xml
+ if (true) {
+ final AuthorizationHelper authorizationHelper = AuthorizationHelper.getInstance(facesContext);
+ final MethodExpression actionExpression = getActionExpression();
+ if (actionExpression != null) {
+ final boolean authorized =
+ authorizationHelper.isAuthorized(facesContext, actionExpression.getExpressionString());
+ if (!authorized) {
+ return true;
+ }
+ }
+ }
+
+ Boolean bool = (Boolean) getStateHelper().eval(AbstractUICommand.PropertyKeys.disabled);
+ if (bool != null) {
+ return bool;
+ }
+ return false;
+ }
+
+ public void setDisabled(boolean disabled) {
+ getStateHelper().put(AbstractUICommand.PropertyKeys.disabled, disabled);
+ }
+
+ public abstract String getTarget();
+
+ public abstract boolean isTransition();
+
+ public abstract boolean isOmit();
+
+ public abstract void setOmit(boolean omit);
+
+ public abstract String getConfirmation();
+
+ public abstract String getLink();
+}
Copied: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIEvent.java (from r1766668, myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUICommand.java)
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIEvent.java?p2=myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIEvent.java&p1=myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUICommand.java&r1=1766668&r2=1767871&rev=1767871&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUICommand.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIEvent.java Thu Nov 3 11:28:25 2016
@@ -19,163 +19,10 @@
package org.apache.myfaces.tobago.internal.component;
-import org.apache.myfaces.tobago.component.OnComponentPopulated;
-import org.apache.myfaces.tobago.component.SupportsAccessKey;
-import org.apache.myfaces.tobago.component.Visual;
-import org.apache.myfaces.tobago.event.CollapsibleActionListener;
-import org.apache.myfaces.tobago.internal.util.AuthorizationHelper;
-import org.apache.myfaces.tobago.util.ComponentUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.apache.myfaces.tobago.component.ClientBehaviors;
-import javax.el.MethodExpression;
-import javax.faces.component.UICommand;
-import javax.faces.component.UIComponent;
-import javax.faces.component.UIInput;
-import javax.faces.component.behavior.ClientBehaviorHolder;
-import javax.faces.context.FacesContext;
-import javax.faces.event.FacesEvent;
-import javax.faces.event.PhaseId;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
+public abstract class AbstractUIEvent extends AbstractUICommandBase {
-public abstract class AbstractUICommand extends UICommand
- implements SupportsAccessKey, OnComponentPopulated, Visual, ClientBehaviorHolder {
+ public abstract ClientBehaviors getEvent();
- private static final Logger LOG = LoggerFactory.getLogger(AbstractUICommand.class);
-
- // todo generate
- private static final Collection<String> EVENT_NAMES = Arrays.asList("click", "change");
-
- enum PropertyKeys {
- disabled,
- }
-
- // todo: transient
- private Boolean parentOfCommands;
-
- @Override
- public void onComponentPopulated(final FacesContext facesContext, final UIComponent parent) {
-
- final List<AbstractUIOperation> list = ComponentUtils.findDescendantList(this, AbstractUIOperation.class);
- for (AbstractUIOperation operation : list) {
- addActionListener(new CollapsibleActionListener(operation.getFor()));
- }
- }
-
- @Override
- public void processDecodes(final FacesContext context) {
- if (context == null) {
- throw new NullPointerException();
- }
-
- // Skip processing if our rendered flag is false
- if (!isRendered()) {
- return;
- }
-
- // Process this component itself
- try {
- decode(context);
- } catch (final RuntimeException e) {
- context.renderResponse();
- throw e;
- }
-
- final Iterator kids = getFacetsAndChildren();
- while (kids.hasNext()) {
- final UIComponent kid = (UIComponent) kids.next();
- kid.processDecodes(context);
- }
- }
-
- @Override
- public void queueEvent(final FacesEvent facesEvent) {
- // fix for TOBAGO-262
- super.queueEvent(facesEvent);
- if (this == facesEvent.getSource()) {
- if (isImmediate()) {
- facesEvent.setPhaseId(PhaseId.APPLY_REQUEST_VALUES);
- } else {
- facesEvent.setPhaseId(PhaseId.INVOKE_APPLICATION);
- }
- }
- }
-
- public boolean isParentOfCommands() {
- if (parentOfCommands == null) {
- parentOfCommands = false;
- for (UIComponent child : getChildren()) {
- if (child instanceof UICommand || child instanceof UIInput) {
- parentOfCommands = true;
- break;
- }
- }
- }
- return parentOfCommands;
- }
-
- /**
- Flag indicating that this element is disabled.
- <br>Default: <code>false</code>
- */
- public boolean isDisabled() {
-
- final FacesContext facesContext = getFacesContext();
- // todo: get from configuration tobago-config.xml
- if (true) {
- final AuthorizationHelper authorizationHelper = AuthorizationHelper.getInstance(facesContext);
- final MethodExpression actionExpression = getActionExpression();
- if (actionExpression != null) {
- final boolean authorized =
- authorizationHelper.isAuthorized(facesContext, actionExpression.getExpressionString());
- if (!authorized) {
- return true;
- }
- }
- }
-
- Boolean bool = (Boolean) getStateHelper().eval(PropertyKeys.disabled);
- if (bool != null) {
- return bool;
- }
- return false;
- }
-
- public void setDisabled(boolean disabled) {
- getStateHelper().put(PropertyKeys.disabled, disabled);
- }
-
- // todo generate
- @Override
- public String getDefaultEventName() {
- return "click";
- }
-
- // todo generate
- @Override
- public Collection<String> getEventNames() {
- return EVENT_NAMES;
- }
-
- @Override
- public abstract String getLabel();
-
- public abstract String getLink();
-
- public abstract String getTarget();
-
- public abstract boolean isTransition();
-
- public abstract boolean isOmit();
-
- public abstract void setOmit(boolean omit);
-
- public abstract String getTip();
-
- public abstract String getConfirmation();
-
-// public abstract Integer getTabIndex();
}
Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIInput.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIInput.java?rev=1767871&r1=1767870&r2=1767871&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIInput.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIInput.java Thu Nov 3 11:28:25 2016
@@ -34,7 +34,7 @@ public abstract class AbstractUIInput ex
implements SupportsAccessKey, SupportsLabelLayout, Visual, ClientBehaviorHolder, SupportFieldId {
// todo generate
- private static final Collection<String> EVENT_NAMES = Arrays.asList("change");
+ private static final Collection<String> EVENT_NAMES = Arrays.asList("change", "click");
// todo generate
@Override
Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIPage.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIPage.java?rev=1767871&r1=1767870&r2=1767871&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIPage.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIPage.java Thu Nov 3 11:28:25 2016
@@ -28,11 +28,14 @@ import org.slf4j.LoggerFactory;
import javax.faces.component.UIComponent;
import javax.faces.component.UIViewRoot;
+import javax.faces.component.behavior.ClientBehaviorHolder;
import javax.faces.context.FacesContext;
import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
import java.util.Iterator;
-public abstract class AbstractUIPage extends AbstractUIFormBase implements Visual {
+public abstract class AbstractUIPage extends AbstractUIFormBase implements Visual, ClientBehaviorHolder {
private static final Logger LOG = LoggerFactory.getLogger(AbstractUIPage.class);
@@ -42,6 +45,22 @@ public abstract class AbstractUIPage ext
private String formId;
+ // todo generate
+ private static final Collection<String> EVENT_NAMES = Arrays.asList("click", "resize", "load");
+
+ // todo generate
+ @Override
+ public String getDefaultEventName() {
+ return "click";
+ }
+
+ // todo generate
+ @Override
+ public Collection<String> getEventNames() {
+ return EVENT_NAMES;
+ }
+
+
@Override
public boolean getRendersChildren() {
return true;
Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIPanel.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIPanel.java?rev=1767871&r1=1767870&r2=1767871&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIPanel.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIPanel.java Thu Nov 3 11:28:25 2016
@@ -19,5 +19,25 @@
package org.apache.myfaces.tobago.internal.component;
-public abstract class AbstractUIPanel extends AbstractUICollapsiblePanel {
+import javax.faces.component.behavior.ClientBehaviorHolder;
+import java.util.Arrays;
+import java.util.Collection;
+
+public abstract class AbstractUIPanel extends AbstractUICollapsiblePanel implements ClientBehaviorHolder {
+
+ // todo generate
+ private static final Collection<String> EVENT_NAMES = Arrays.asList("click", "mouseover", "mouseout");
+
+ // todo generate
+ @Override
+ public String getDefaultEventName() {
+ return "click";
+ }
+
+ // todo generate
+ @Override
+ public Collection<String> getEventNames() {
+ return EVENT_NAMES;
+ }
+
}
Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIProgress.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIProgress.java?rev=1767871&r1=1767870&r2=1767871&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIProgress.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIProgress.java Thu Nov 3 11:28:25 2016
@@ -24,18 +24,37 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.faces.component.UIOutput;
+import javax.faces.component.behavior.ClientBehaviorHolder;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ComponentSystemEvent;
import javax.faces.event.ComponentSystemEventListener;
import javax.faces.event.ListenerFor;
import javax.faces.event.PreRenderComponentEvent;
import javax.swing.BoundedRangeModel;
+import java.util.Arrays;
+import java.util.Collection;
@ListenerFor(systemEventClass = PreRenderComponentEvent.class)
-public abstract class AbstractUIProgress extends UIOutput implements Visual, ComponentSystemEventListener {
+public abstract class AbstractUIProgress extends UIOutput
+ implements Visual, ComponentSystemEventListener, ClientBehaviorHolder {
private static final Logger LOG = LoggerFactory.getLogger(AbstractUIProgress.class);
+ // todo generate
+ private static final Collection<String> EVENT_NAMES = Arrays.asList("complete");
+
+ // todo generate
+ @Override
+ public String getDefaultEventName() {
+ return "complete";
+ }
+
+ // todo generate
+ @Override
+ public Collection<String> getEventNames() {
+ return EVENT_NAMES;
+ }
+
private double rangeValue;
private double rangeMax;
Copied: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIRow.java (from r1765603, myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIColumnEvent.java)
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIRow.java?p2=myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIRow.java&p1=myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIColumnEvent.java&r1=1765603&r2=1767871&rev=1767871&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIColumnEvent.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIRow.java Thu Nov 3 11:28:25 2016
@@ -19,5 +19,28 @@
package org.apache.myfaces.tobago.internal.component;
-public class AbstractUIColumnEvent extends AbstractUIColumnBase {
+import javax.faces.component.behavior.ClientBehaviorHolder;
+import java.util.Arrays;
+import java.util.Collection;
+
+public class AbstractUIRow extends AbstractUIColumnBase implements ClientBehaviorHolder {
+
+ // todo generate
+ private static final Collection<String> EVENT_NAMES = Arrays.asList("click", "dblclick");
+
+ // todo generate
+ @Override
+ public String getDefaultEventName() {
+ return "click";
+ }
+
+
+
+
+ // todo generate
+ @Override
+ public Collection<String> getEventNames() {
+ return EVENT_NAMES;
+ }
+
}
Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISheet.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISheet.java?rev=1767871&r1=1767870&r2=1767871&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISheet.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISheet.java Thu Nov 3 11:28:25 2016
@@ -416,7 +416,7 @@ public abstract class AbstractUISheet ex
final LayoutTokens tokens = new LayoutTokens();
final List<AbstractUIColumnBase> columns = getAllColumns();
for (final UIColumn column : columns) {
- if (!(column instanceof AbstractUIColumnEvent)) {
+ if (!(column instanceof AbstractUIRow)) {
tokens.addToken(RelativeLayoutToken.DEFAULT_INSTANCE);
}
}