Merge remote-tracking branch 'origin/master' into wicket-6774
diff --git a/wicket-core/src/main/java/org/apache/wicket/Behaviors.java b/wicket-core/src/main/java/org/apache/wicket/Behaviors.java
deleted file mode 100644
index aceb318..0000000
--- a/wicket-core/src/main/java/org/apache/wicket/Behaviors.java
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- * 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.wicket;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.wicket.behavior.Behavior;
-import org.apache.wicket.behavior.InvalidBehaviorIdException;
-import org.apache.wicket.model.IDetachable;
-import org.apache.wicket.util.lang.Args;
-
-/**
- * Manages behaviors in a {@link Component} instance
- *
- * @author igor
- */
-final class Behaviors implements IDetachable
-{
- private static final long serialVersionUID = 1L;
- private final Component component;
-
- public Behaviors(Component component)
- {
- this.component = component;
- }
-
- public void add(Behavior... behaviors)
- {
- Args.notNull(behaviors, "behaviors");
-
- for (Behavior behavior : behaviors)
- {
- Args.notNull(behavior, "behavior");
-
- internalAdd(behavior);
-
- if (!behavior.isTemporary(component))
- {
- component.addStateChange();
- }
-
- // Give handler the opportunity to bind this component
- behavior.bind(component);
- }
- }
-
- private void internalAdd(final Behavior behavior)
- {
- component.data_add(behavior);
- if (behavior.getStatelessHint(component) == false)
- {
- getBehaviorId(behavior);
- }
- }
-
- @SuppressWarnings("unchecked")
- public <M extends Behavior> List<M> getBehaviors(Class<M> type)
- {
- final int len = component.data_length();
- final int start = component.data_start();
- if (len < start)
- {
- return Collections.emptyList();
- }
-
- List<M> subset = new ArrayList<>(len);
- for (int i = component.data_start(); i < len; i++)
- {
- Object obj = component.data_get(i);
- if (obj != null && obj instanceof Behavior)
- {
- if (type == null || type.isAssignableFrom(obj.getClass()))
- {
- subset.add((M)obj);
- }
- }
- }
- if (subset.isEmpty()) {
- return Collections.emptyList();
- }
- return Collections.unmodifiableList(subset);
- }
-
-
- public void remove(Behavior behavior)
- {
- Args.notNull(behavior, "behavior");
-
- if (internalRemove(behavior))
- {
- if (!behavior.isTemporary(component))
- {
- component.addStateChange();
- }
- behavior.detach(component);
- }
- else
- {
- throw new IllegalStateException(
- "Tried to remove a behavior that was not added to the component. Behavior: " +
- behavior.toString());
- }
- }
-
- /**
- * THIS IS WICKET INTERNAL ONLY. DO NOT USE IT.
- *
- * Traverses all behaviors and calls detachModel() on them. This is needed to cleanup behavior
- * after render. This method is necessary for {@link org.apache.wicket.ajax.AjaxRequestTarget} to be able to cleanup
- * component's behaviors after header contribution has been done (which is separated from
- * component render).
- */
- @Override
- public final void detach()
- {
- int len = component.data_length();
- for (int i = component.data_start(); i < len; i++)
- {
- Object obj = component.data_get(i);
- if (obj != null && obj instanceof Behavior)
- {
- final Behavior behavior = (Behavior)obj;
-
- behavior.detach(component);
-
- if (behavior.isTemporary(component))
- {
- internalRemove(behavior);
- i--;
- len--;
- }
- }
- }
- }
-
- private boolean internalRemove(final Behavior behavior)
- {
- final int len = component.data_length();
- for (int i = component.data_start(); i < len; i++)
- {
- Object o = component.data_get(i);
- if (o != null && o.equals(behavior))
- {
- component.data_remove(i);
- behavior.unbind(component);
-
- // remove behavior from behavior-ids
- ArrayList<Behavior> ids = getBehaviorsIdList(false);
- if (ids != null)
- {
- int idx = ids.indexOf(behavior);
- if (idx == ids.size() - 1)
- {
- ids.remove(idx);
- }
- else if (idx >= 0)
- {
- ids.set(idx, null);
- }
- ids.trimToSize();
-
- if (ids.isEmpty())
- {
- removeBehaviorsIdList();
- }
-
- }
- return true;
- }
- }
- return false;
- }
-
- private void removeBehaviorsIdList()
- {
- for (int i = component.data_start(); i < component.data_length(); i++)
- {
- Object obj = component.data_get(i);
- if (obj != null && obj instanceof BehaviorIdList)
- {
- component.data_remove(i);
- return;
- }
- }
- }
-
- private BehaviorIdList getBehaviorsIdList(boolean createIfNotFound)
- {
- int len = component.data_length();
- for (int i = component.data_start(); i < len; i++)
- {
- Object obj = component.data_get(i);
- if (obj != null && obj instanceof BehaviorIdList)
- {
- return (BehaviorIdList)obj;
- }
- }
- if (createIfNotFound)
- {
- BehaviorIdList list = new BehaviorIdList();
- component.data_add(list);
- return list;
- }
- return null;
- }
-
- /**
- * Called when the component is going to be removed. Notifies all
- * behaviors assigned to this component.
- *
- * @param component
- * the component that will be removed from its parent
- */
- public void onRemove(Component component)
- {
- final int len = component.data_length();
- for (int i = component.data_start(); i < len; i++)
- {
- Object obj = component.data_get(i);
- if (obj != null && obj instanceof Behavior)
- {
- final Behavior behavior = (Behavior)obj;
-
- behavior.onRemove(component);
- }
- }
- }
-
- private static class BehaviorIdList extends ArrayList<Behavior>
- {
- private static final long serialVersionUID = 1L;
-
- public BehaviorIdList()
- {
- super(1);
- }
- }
-
- public final int getBehaviorId(Behavior behavior)
- {
- Args.notNull(behavior, "behavior");
-
- boolean found = false;
- for (int i = component.data_start(); i < component.data_length(); i++)
- {
- if (behavior == component.data_get(i))
- {
- found = true;
- break;
- }
- }
- if (!found)
- {
- throw new IllegalStateException(
- "Behavior must be added to component before its id can be generated. Behavior: " +
- behavior + ", Component: " + this);
- }
-
- ArrayList<Behavior> ids = getBehaviorsIdList(true);
-
- int id = ids.indexOf(behavior);
-
- if (id < 0)
- {
- // try to find an unused slot
- for (int i = 0; i < ids.size(); i++)
- {
- if (ids.get(i) == null)
- {
- ids.set(i, behavior);
- id = i;
- break;
- }
- }
- }
-
- if (id < 0)
- {
- // no unused slots, add to the end
- id = ids.size();
- ids.add(behavior);
- ids.trimToSize();
- }
-
- return id;
- }
-
- public final Behavior getBehaviorById(int id)
- {
- Behavior behavior = null;
-
- ArrayList<Behavior> ids = getBehaviorsIdList(false);
- if (ids != null)
- {
- if (id >= 0 && id < ids.size())
- {
- behavior = ids.get(id);
- }
- }
-
- if (behavior != null)
- {
- return behavior;
- }
- throw new InvalidBehaviorIdException(component, id);
- }
-
-
-}
diff --git a/wicket-core/src/main/java/org/apache/wicket/Component.java b/wicket-core/src/main/java/org/apache/wicket/Component.java
index ef9dc41..6a81617 100644
--- a/wicket-core/src/main/java/org/apache/wicket/Component.java
+++ b/wicket-core/src/main/java/org/apache/wicket/Component.java
@@ -381,12 +381,18 @@
/**
* Flag that determines whether the model is set. This is necessary because of the way we
* represent component state ({@link #data}). We can't distinguish between model and behavior
- * using instanceof, because one object can implement both interfaces. Thus we need this flag -
- * when the flag is set, first object in {@link #data} is always model.
+ * using instanceof, because one object can implement both interfaces.
*/
private static final int FLAG_MODEL_SET = 0x100000;
/**
+ * Flag that is set when {@link #getBehaviorId(Behavior)} is called on this component. Once this
+ * flag is set, the indexes of all behaviors must remain fixed to keep the contract of
+ * {@link #getBehaviorId(Behavior)}.
+ */
+ private static final int FLAG_BEHAVIOR_IDS_FIXED = 0x200000;
+
+ /**
* Flag that restricts visibility of a component when set to true. This is usually used when a
* component wants to restrict visibility of another component. Calling
* {@link #setVisible(boolean)} on a component does not always have the desired effect because
@@ -456,8 +462,7 @@
/**
* Instead of remembering the whole markupId, we just remember the number for this component so
- * we can "reconstruct" the markupId on demand. While this could be part of {@link #data},
- * profiling showed that having it as separate property consumes less memory.
+ * we can "reconstruct" the markupId on demand.
*/
int generatedMarkupId = -1;
@@ -480,170 +485,11 @@
* <li>MetaDataEntry (optionally {@link MetaDataEntry}[] if more metadata entries are present) *
* <li>{@link Behavior}(s) added to component. The behaviors are not stored in separate array,
* they are part of the {@link #data} array (this is in order to save the space of the pointer
- * to an empty array as most components have no behaviours). - FIXME - explain why - is this
- * correct?
+ * to an empty array as most components have no behaviours).
+ * <li>A {@link ComponentState} if a combination of the attributes is set.
* </ul>
- * If there is only one attribute set (i.e. model or MetaDataEntry([]) or one behavior), the
- * #data object points directly to value of that attribute. Otherwise the data is of type
- * Object[] where the attributes are ordered as specified above.
- * <p>
*/
- Object data = null;
-
- final int data_start()
- {
- return getFlag(FLAG_MODEL_SET) ? 1 : 0;
- }
-
- final int data_length()
- {
- if (data == null)
- {
- return 0;
- }
- else if (data instanceof Object[] && !(data instanceof MetaDataEntry<?>[]))
- {
- return ((Object[])data).length;
- }
- else
- {
- return 1;
- }
- }
-
- final Object data_get(int index)
- {
- if (data == null)
- {
- return null;
- }
- else if (data instanceof Object[] && !(data instanceof MetaDataEntry<?>[]))
- {
- Object[] array = (Object[])data;
- return index < array.length ? array[index] : null;
- }
- else if (index == 0)
- {
- return data;
- }
- else
- {
- return null;
- }
- }
-
- final void data_set(int index, Object object)
- {
- if (index > data_length() - 1)
- {
- throw new IndexOutOfBoundsException("can not set data at " + index +
- " when data_length() is " + data_length());
- }
- else if (index == 0 && !(data instanceof Object[] && !(data instanceof MetaDataEntry<?>[])))
- {
- data = object;
- }
- else
- {
- Object[] array = (Object[])data;
- array[index] = object;
- }
- }
-
- final void data_add(Object object)
- {
- data_insert(-1, object);
- }
-
- final void data_insert(int position, Object object)
- {
- int currentLength = data_length();
- if (position == -1)
- {
- position = currentLength;
- }
- if (position > currentLength)
- {
- throw new IndexOutOfBoundsException("can not insert data at " + position +
- " when data_length() is " + currentLength);
- }
- if (currentLength == 0)
- {
- data = object;
- }
- else if (currentLength == 1)
- {
- Object[] array = new Object[2];
- if (position == 0)
- {
- array[0] = object;
- array[1] = data;
- }
- else
- {
- array[0] = data;
- array[1] = object;
- }
- data = array;
- }
- else
- {
- Object[] array = new Object[currentLength + 1];
- Object[] current = (Object[])data;
- int after = currentLength - position;
- if (position > 0)
- {
- System.arraycopy(current, 0, array, 0, position);
- }
- array[position] = object;
- if (after > 0)
- {
- System.arraycopy(current, position, array, position + 1, after);
- }
- data = array;
- }
- }
-
- final void data_remove(int position)
- {
- int currentLength = data_length();
-
- if (position > currentLength - 1)
- {
- throw new IndexOutOfBoundsException();
- }
- else if (currentLength == 1)
- {
- data = null;
- }
- else if (currentLength == 2)
- {
- Object[] current = (Object[])data;
- if (position == 0)
- {
- data = current[1];
- }
- else
- {
- data = current[0];
- }
- }
- else
- {
- Object[] current = (Object[])data;
- data = new Object[currentLength - 1];
-
- if (position > 0)
- {
- System.arraycopy(current, 0, data, 0, position);
- }
- if (position != currentLength - 1)
- {
- final int left = currentLength - position - 1;
- System.arraycopy(current, position + 1, data, position, left);
- }
- }
- }
+ private Object data = null;
/**
* Constructor. All components have names. A component's id cannot be null. This is the minimal
@@ -1090,7 +936,7 @@
getClass().getName() +
" has not called super.onRemove() in the override of onRemove() method");
}
- new Behaviors(this).onRemove(this);
+ ComponentState.onRemoveBehaviors(this, data, getFlag(FLAG_MODEL_SET));
removeChildren();
}
@@ -1119,7 +965,8 @@
detachModels();
// detach any behaviors
- new Behaviors(this).detach();
+ data = ComponentState.detachBehaviors(this, data, getFlag(FLAG_MODEL_SET),
+ getFlag(FLAG_BEHAVIOR_IDS_FIXED));
}
catch (Exception x)
{
@@ -1512,39 +1359,20 @@
* @see MetaDataKey
*/
@Override
+ @SuppressWarnings("unchecked")
public final <M extends Serializable> M getMetaData(final MetaDataKey<M> key)
{
- return key.get(getMetaData());
- }
-
- /**
- * Gets the meta data entries for this component as an array of {@link MetaDataEntry} objects.
- *
- * @return the meta data entries for this component
- */
- private MetaDataEntry<?>[] getMetaData()
- {
- MetaDataEntry<?>[] metaData = null;
-
- // index where we should expect the entry
- int index = getFlag(FLAG_MODEL_SET) ? 1 : 0;
-
- int length = data_length();
-
- if (index < length)
+ Object metaData = ComponentState.getMetaData(data, getFlag(FLAG_MODEL_SET));
+ if (metaData == null)
{
- Object object = data_get(index);
- if (object instanceof MetaDataEntry<?>[])
- {
- metaData = (MetaDataEntry<?>[])object;
- }
- else if (object instanceof MetaDataEntry)
- {
- metaData = new MetaDataEntry[] { (MetaDataEntry<?>)object };
- }
+ return null;
}
-
- return metaData;
+ else if (metaData instanceof MetaDataEntry)
+ {
+ MetaDataEntry< ? > entry = (MetaDataEntry< ? >) metaData;
+ return entry.key.equals(key) ? (M) entry.object : null;
+ }
+ return key.get((MetaDataEntry< ? >[]) metaData);
}
/**
@@ -2872,29 +2700,7 @@
@Override
public final <M extends Serializable> Component setMetaData(final MetaDataKey<M> key, final M object)
{
- MetaDataEntry<?>[] old = getMetaData();
-
- Object metaData = null;
- MetaDataEntry<?>[] metaDataArray = key.set(getMetaData(), object);
- if (metaDataArray != null && metaDataArray.length > 0)
- {
- metaData = (metaDataArray.length > 1) ? metaDataArray : metaDataArray[0];
- }
-
- int index = getFlag(FLAG_MODEL_SET) ? 1 : 0;
-
- if (old == null && metaData != null)
- {
- data_insert(index, metaData);
- }
- else if (old != null && metaData != null)
- {
- data_set(index, metaData);
- }
- else if (old != null && metaData == null)
- {
- data_remove(index);
- }
+ data = ComponentState.setMetaData(data, getFlag(FLAG_MODEL_SET), key, object);
return this;
}
@@ -2944,11 +2750,7 @@
*/
IModel<?> getModelImpl()
{
- if (getFlag(FLAG_MODEL_SET))
- {
- return (IModel<?>)data_get(0);
- }
- return null;
+ return ComponentState.getModel(data, getFlag(FLAG_MODEL_SET));
}
/**
@@ -2957,26 +2759,8 @@
*/
void setModelImpl(IModel<?> model)
{
- if (getFlag(FLAG_MODEL_SET))
- {
- if (model != null)
- {
- data_set(0, model);
- }
- else
- {
- data_remove(0);
- setFlag(FLAG_MODEL_SET, false);
- }
- }
- else
- {
- if (model != null)
- {
- data_insert(0, model);
- setFlag(FLAG_MODEL_SET, true);
- }
- }
+ data = ComponentState.setModel(model, data, getFlag(FLAG_MODEL_SET));
+ setFlag(FLAG_MODEL_SET, model != null);
}
/**
@@ -3620,7 +3404,7 @@
*/
public <M extends Behavior> List<M> getBehaviors(Class<M> type)
{
- return new Behaviors(this).getBehaviors(type);
+ return ComponentState.getBehaviors(type, data, getFlag(FLAG_MODEL_SET));
}
/**
@@ -4429,11 +4213,7 @@
*/
public Component remove(final Behavior... behaviors)
{
- Behaviors helper = new Behaviors(this);
- for (Behavior behavior : behaviors)
- {
- helper.remove(behavior);
- }
+ data = ComponentState.removeBehaviors(this, data, getFlag(FLAG_MODEL_SET), behaviors);
return this;
}
@@ -4441,7 +4221,10 @@
@Override
public final Behavior getBehaviorById(int id)
{
- return new Behaviors(this).getBehaviorById(id);
+ data = ComponentState.compactBehaviors(this, data, getFlag(FLAG_MODEL_SET),
+ getFlag(FLAG_BEHAVIOR_IDS_FIXED));
+ setFlag(FLAG_BEHAVIOR_IDS_FIXED, true);
+ return ComponentState.getBehaviorById(this, id, data, getFlag(FLAG_MODEL_SET));
}
/** {@inheritDoc} */
@@ -4453,7 +4236,10 @@
throw new IllegalArgumentException(
"Cannot get a stable id for temporary behavior " + behavior);
}
- return new Behaviors(this).getBehaviorId(behavior);
+ data = ComponentState.compactBehaviors(this, data, getFlag(FLAG_MODEL_SET),
+ getFlag(FLAG_BEHAVIOR_IDS_FIXED));
+ setFlag(FLAG_BEHAVIOR_IDS_FIXED, true);
+ return ComponentState.getBehaviorId(this, behavior, data, getFlag(FLAG_MODEL_SET));
}
/**
@@ -4465,7 +4251,11 @@
*/
public Component add(final Behavior... behaviors)
{
- new Behaviors(this).add(behaviors);
+ data = ComponentState.addBehaviors(this, data, getFlag(FLAG_MODEL_SET), behaviors);
+ for (Behavior curBehavior : behaviors)
+ {
+ ComponentState.bindBehavior(this, curBehavior);
+ }
return this;
}
diff --git a/wicket-core/src/main/java/org/apache/wicket/ComponentState.java b/wicket-core/src/main/java/org/apache/wicket/ComponentState.java
new file mode 100644
index 0000000..363aa7c
--- /dev/null
+++ b/wicket-core/src/main/java/org/apache/wicket/ComponentState.java
@@ -0,0 +1,1081 @@
+/*
+ * 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.wicket;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.wicket.behavior.Behavior;
+import org.apache.wicket.behavior.InvalidBehaviorIdException;
+import org.apache.wicket.model.IModel;
+
+/**
+ * This class keeps track of the flexible state of a component: model, behaviors and meta data.
+ * These types of state vary per component. Not every component contains these elements or their
+ * numbers differ. The state is stored in the {@code data} field in {@link Component}. To keep the
+ * size of this state as small as possible, the following cases are identified:
+ * <ul>
+ * <li>No state at all: {@code data} is {@code null}
+ * <li>Only a model: {@code data} contains the model
+ * <li>Only one or more behaviors: {@code data} contains the behavior, or an array of behaviors
+ * <li>Only one or more meta data entries: {@code data} contains the entry, or an array of entries
+ * <li>A model and one or more behaviors: {@code data} contains an instance of
+ * {@link ModelBehaviorsComponentState}
+ * <li>A model and one or more meta data entries: {@code data} contains an instance of
+ * {@link ModelMetaDataComponentState}
+ * <li>One or more behaviors and one or more meta data entries: {@code data} contains an instance of
+ * {@link BehaviorsMetaDataComponentState}
+ * <li>A model, one or more behaviors and one or more meta data entries: {@code data} contains an
+ * instance of {@link ModelBehaviorsMetaDataComponentState}
+ * </ul>
+ *
+ * @author papegaaij
+ */
+abstract class ComponentState implements Serializable
+{
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * @return The model stored by this state, or null.
+ */
+ abstract IModel< ? > getModel();
+
+ /**
+ * @param model
+ * the new model or null
+ * @return the new state for the component using the rules defined above
+ */
+ abstract Object setModel(IModel< ? > model);
+
+ /**
+ * @return The behaviors stored by this state: null, a single behavior or an array of behaviors.
+ */
+ abstract Object getBehaviors();
+
+ /**
+ * @param behaviors
+ * the new behaviors (null, one behavior or an array of behaviors)
+ * @return the new state for the component using the rules defined above
+ */
+ abstract Object setBehaviors(Object behaviors);
+
+ /**
+ * @return The meta data entries stored by this state: null, a single entry or an array of
+ * entries.
+ */
+ abstract Object getMetaData();
+
+ /**
+ * @param metaData
+ * the new meta data entries (null, one entry or an array of entries)
+ * @return the new state for the component using the rules defined above
+ */
+ abstract Object setMetaData(Object metaData);
+
+ /**
+ * Combines a model and one or more behaviors.
+ */
+ static class ModelBehaviorsComponentState extends ComponentState
+ {
+ private static final long serialVersionUID = 1L;
+
+ private IModel< ? > model;
+
+ private Object behaviors;
+
+ private ModelBehaviorsComponentState(IModel< ? > model, Object behaviors)
+ {
+ this.model = model;
+ this.behaviors = behaviors;
+ }
+
+ @Override
+ IModel< ? > getModel()
+ {
+ return model;
+ }
+
+ @Override
+ Object setModel(IModel< ? > model)
+ {
+ if (model == null)
+ {
+ return behaviors;
+ }
+ this.model = model;
+ return this;
+ }
+
+ @Override
+ Object getBehaviors()
+ {
+ return behaviors;
+ }
+
+ @Override
+ Object setBehaviors(Object behaviors)
+ {
+ if (behaviors == null)
+ {
+ return model;
+ }
+ this.behaviors = behaviors;
+ return this;
+ }
+
+ @Override
+ Object getMetaData()
+ {
+ return null;
+ }
+
+ @Override
+ Object setMetaData(Object metaData)
+ {
+ if (metaData == null)
+ {
+ return this;
+ }
+ return new ModelBehaviorsMetaDataComponentState(model, behaviors, metaData);
+ }
+ }
+
+ /**
+ * Combines a model and one or more meta data entries.
+ */
+ static class ModelMetaDataComponentState extends ComponentState
+ {
+ private static final long serialVersionUID = 1L;
+
+ private IModel< ? > model;
+
+ private Object metaData;
+
+ private ModelMetaDataComponentState(IModel< ? > model, Object metaData)
+ {
+ this.model = model;
+ this.metaData = metaData;
+ }
+
+ @Override
+ IModel< ? > getModel()
+ {
+ return model;
+ }
+
+ @Override
+ Object setModel(IModel< ? > model)
+ {
+ if (model == null)
+ {
+ return metaData;
+ }
+ this.model = model;
+ return this;
+ }
+
+ @Override
+ Object getBehaviors()
+ {
+ return null;
+ }
+
+ @Override
+ Object setBehaviors(Object behaviors)
+ {
+ if (behaviors == null)
+ {
+ return this;
+ }
+ return new ModelBehaviorsMetaDataComponentState(model, behaviors, metaData);
+ }
+
+ @Override
+ Object getMetaData()
+ {
+ return metaData;
+ }
+
+ @Override
+ Object setMetaData(Object metaData)
+ {
+ if (metaData == null)
+ {
+ return model;
+ }
+ this.metaData = metaData;
+ return this;
+ }
+ }
+
+ /**
+ * Combines one or more behaviors and one ore more meta data entries.
+ */
+ static class BehaviorsMetaDataComponentState extends ComponentState
+ {
+ private static final long serialVersionUID = 1L;
+
+ private Object behaviors;
+
+ private Object metaData;
+
+ private BehaviorsMetaDataComponentState(Object behaviors, Object metaData)
+ {
+ this.behaviors = behaviors;
+ this.metaData = metaData;
+ }
+
+ @Override
+ IModel< ? > getModel()
+ {
+ return null;
+ }
+
+ @Override
+ Object setModel(IModel< ? > model)
+ {
+ if (model == null)
+ {
+ return this;
+ }
+ return new ModelBehaviorsMetaDataComponentState(model, behaviors, metaData);
+ }
+
+ @Override
+ Object getBehaviors()
+ {
+ return behaviors;
+ }
+
+ @Override
+ Object setBehaviors(Object behaviors)
+ {
+ if (behaviors == null)
+ {
+ return metaData;
+ }
+ this.behaviors = behaviors;
+ return this;
+ }
+
+ @Override
+ Object getMetaData()
+ {
+ return metaData;
+ }
+
+ @Override
+ Object setMetaData(Object metaData)
+ {
+ if (metaData == null)
+ {
+ return behaviors;
+ }
+ this.metaData = metaData;
+ return this;
+ }
+ }
+
+ /**
+ * Combines a model, one or more behaviors and one or more meta data entries.
+ */
+ static class ModelBehaviorsMetaDataComponentState extends ComponentState
+ {
+ private static final long serialVersionUID = 1L;
+
+ private IModel< ? > model;
+
+ private Object behaviors;
+
+ private Object metaData;
+
+ private ModelBehaviorsMetaDataComponentState(IModel< ? > model, Object behaviors,
+ Object metaData)
+ {
+ this.model = model;
+ this.behaviors = behaviors;
+ this.metaData = metaData;
+ }
+
+ @Override
+ IModel< ? > getModel()
+ {
+ return model;
+ }
+
+ @Override
+ Object setModel(IModel< ? > model)
+ {
+ if (model == null)
+ {
+ return new BehaviorsMetaDataComponentState(behaviors, metaData);
+ }
+ this.model = model;
+ return this;
+ }
+
+ @Override
+ Object getBehaviors()
+ {
+ return behaviors;
+ }
+
+ @Override
+ Object setBehaviors(Object behaviors)
+ {
+ if (behaviors == null)
+ {
+ return new ModelMetaDataComponentState(model, metaData);
+ }
+ this.behaviors = behaviors;
+ return this;
+ }
+
+ @Override
+ Object getMetaData()
+ {
+ return metaData;
+ }
+
+ @Override
+ Object setMetaData(Object metaData)
+ {
+ if (metaData == null)
+ {
+ return new ModelBehaviorsComponentState(model, behaviors);
+ }
+ this.metaData = metaData;
+ return this;
+ }
+ }
+
+ /**
+ * @param state
+ * the component state
+ * @param modelSet
+ * a boolean indicating if the model is set
+ * @return the model from the given state or null
+ */
+ static IModel< ? > getModel(Object state, boolean modelSet)
+ {
+ if (state instanceof ComponentState)
+ {
+ return ((ComponentState) state).getModel();
+ }
+ return modelSet ? (IModel< ? >) state : null;
+ }
+
+ /**
+ * @param state
+ * the component state
+ * @param modelSet
+ * a boolean indicating if the model is set
+ * @return the behaviors from the given state: null, one behavior or an array of behaviors
+ */
+ static Object getBehaviors(Object state, boolean modelSet)
+ {
+ if (state instanceof ComponentState)
+ {
+ return ((ComponentState) state).getBehaviors();
+ }
+ return modelSet || !(state instanceof Behavior || state instanceof Behavior[]) ? null
+ : state;
+ }
+
+ /**
+ * @param state
+ * the component state
+ * @param modelSet
+ * a boolean indicating if the model is set
+ * @return the meta data entries from the given state: null, one entry or an array of entries
+ */
+ static Object getMetaData(Object state, boolean modelSet)
+ {
+ if (state instanceof ComponentState)
+ {
+ return ((ComponentState) state).getMetaData();
+ }
+ return modelSet || !(state instanceof MetaDataEntry || state instanceof MetaDataEntry[])
+ ? null : state;
+ }
+
+ /**
+ * Construct a new component state with the given model value
+ *
+ * @param model
+ * the new model to set or null to clear
+ * @param state
+ * the current component state
+ * @param modelSet
+ * a boolean indicating if the model is set
+ * @return the new component state
+ */
+ static Object setModel(IModel< ? > model, Object state, boolean modelSet)
+ {
+ if (state instanceof ComponentState)
+ {
+ ComponentState compState = (ComponentState) state;
+ return compState.setModel(model);
+ }
+ else if (modelSet || state == null)
+ {
+ return model;
+ }
+ // state does not have a model, clear is a no-op
+ else if (model == null)
+ {
+ return state;
+ }
+ else if (state instanceof MetaDataEntry || state instanceof MetaDataEntry[])
+ {
+ return new ModelMetaDataComponentState(model, state);
+ }
+ else
+ {
+ return new ModelBehaviorsComponentState(model, state);
+ }
+ }
+
+ /**
+ * Construct a new component state with the given behaviors added
+ *
+ * @param component
+ * the component to add the behaviors to
+ * @param state
+ * the current component state
+ * @param modelSet
+ * a boolean indicating if the model is set
+ * @param behaviorsToAdd
+ * the behaviors to add
+ * @return the new component state
+ */
+ static Object addBehaviors(Component component, Object state, boolean modelSet,
+ Behavior... behaviorsToAdd)
+ {
+ if (behaviorsToAdd.length == 0)
+ {
+ return state;
+ }
+ else if (state instanceof ComponentState)
+ {
+ ComponentState compState = (ComponentState) state;
+ return compState
+ .setBehaviors(addBehaviors(component, compState.getBehaviors(), behaviorsToAdd));
+ }
+ else if (modelSet)
+ {
+ return new ModelBehaviorsComponentState((IModel< ? >) state,
+ addBehaviors(component, null, behaviorsToAdd));
+ }
+ else if (state instanceof MetaDataEntry || state instanceof MetaDataEntry[])
+ {
+ return new BehaviorsMetaDataComponentState(
+ addBehaviors(component, null, behaviorsToAdd), state);
+ }
+ else
+ {
+ return addBehaviors(component, state, behaviorsToAdd);
+ }
+ }
+
+ /**
+ * Construct a new component state with the given behaviors removed
+ *
+ * @param component
+ * the component to remove the behaviors from
+ * @param state
+ * the current component state
+ * @param modelSet
+ * a boolean indicating if the model is set
+ * @param behaviorsToRemove
+ * the behaviors to removed
+ * @return the new component state
+ */
+ static Object removeBehaviors(Component component, Object state, boolean modelSet,
+ Behavior... behaviorsToRemove)
+ {
+ if (behaviorsToRemove.length == 0)
+ {
+ return state;
+ }
+ else if (state instanceof ComponentState)
+ {
+ ComponentState compState = (ComponentState) state;
+ return compState.setBehaviors(
+ removeBehaviors(component, compState.getBehaviors(), behaviorsToRemove));
+ }
+ else if (modelSet)
+ {
+ throw cannotRemove(behaviorsToRemove[0]);
+ }
+ else if (state instanceof MetaDataEntry || state instanceof MetaDataEntry[])
+ {
+ throw cannotRemove(behaviorsToRemove[0]);
+ }
+ else
+ {
+ return removeBehaviors(component, state, behaviorsToRemove);
+ }
+ }
+
+ /**
+ * Construct a new component state with the behaviors replaced
+ *
+ * @param state
+ * the current component state
+ * @param modelSet
+ * a boolean indicating if the model is set
+ * @param behaviors
+ * the new value for the behaviors: null, one behavior or an array of behaviors
+ * @return the new component state
+ */
+ static Object setBehaviors(Object state, boolean modelSet, Object behaviors)
+ {
+ if (state instanceof ComponentState)
+ {
+ ComponentState compState = (ComponentState) state;
+ return compState.setBehaviors(behaviors);
+ }
+ else if (state instanceof Behavior || state instanceof Behavior[] || state == null)
+ {
+ return behaviors;
+ }
+ else if (behaviors == null)
+ {
+ return state;
+ }
+ else if (modelSet)
+ {
+ return new ModelBehaviorsComponentState((IModel< ? >) state, behaviors);
+ }
+ else
+ {
+ return new BehaviorsMetaDataComponentState(behaviors, state);
+ }
+ }
+
+ /**
+ * Construct a new component state with the given meta data entry set or reset
+ *
+ * @param state
+ * the current component state
+ * @param modelSet
+ * a boolean indicating if the model is set
+ * @param key
+ * the key to replace the value for
+ * @param data
+ * the new value for the meta data entry, null to clear
+ * @return the new component state
+ */
+ static <T> Object setMetaData(Object state, boolean modelSet, MetaDataKey<T> key, T data)
+ {
+ if (state instanceof ComponentState)
+ {
+ ComponentState compState = (ComponentState) state;
+ return compState.setMetaData(setMetaData(compState.getMetaData(), key, data));
+ }
+ else if (state instanceof MetaDataEntry || state instanceof MetaDataEntry[]
+ || state == null)
+ {
+ return setMetaData(state, key, data);
+ }
+ else if (data == null)
+ {
+ return state;
+ }
+ else if (modelSet)
+ {
+ return new ModelMetaDataComponentState((IModel< ? >) state,
+ new MetaDataEntry<>(key, data));
+ }
+ else
+ {
+ return new BehaviorsMetaDataComponentState(state, new MetaDataEntry<>(key, data));
+ }
+ }
+
+ /**
+ * Bind a behavior to a component, adding a state change if needed.
+ *
+ * @param component
+ * @param behavior
+ */
+ static void bindBehavior(Component component, Behavior behavior)
+ {
+ if (!behavior.isTemporary(component))
+ {
+ component.addStateChange();
+ }
+ behavior.bind(component);
+ }
+
+ private static Object addBehaviors(Component component, Object behaviors,
+ Behavior... behaviorsToAdd)
+ {
+ // nothing to add
+ if (behaviorsToAdd.length == 0)
+ {
+ return behaviors;
+ }
+
+ // the existing array is compact, adding cannot shrink it
+ int curLength = getBehaviorsLength(behaviors);
+ int newSize = Math.max(curLength, behaviorsToAdd.length + getBehaviorsLength(behaviors)
+ - getEmptyBehaviorsSlots(behaviors));
+
+ // new size is 1, it must be we are adding 1 to 0
+ if (newSize == 1)
+ {
+ return behaviorsToAdd[0];
+ }
+
+ // construct the return array and copy existing behaviors
+ Behavior[] ret = new Behavior[newSize];
+ if (behaviors instanceof Behavior[])
+ {
+ System.arraycopy(behaviors, 0, ret, 0, curLength);
+ }
+ else
+ {
+ ret[0] = (Behavior) behaviors;
+ }
+
+ // fill empty slots with behaviors to add
+ int checkSlot = 0;
+ for (Behavior behaviorToAdd : behaviorsToAdd)
+ {
+ while (ret[checkSlot] != null)
+ {
+ checkSlot++;
+ }
+ ret[checkSlot] = behaviorToAdd;
+ }
+ return ret;
+ }
+
+ private static Object removeBehaviors(Component component, Object behaviors,
+ Behavior... behaviorsToRemove)
+ {
+ // nothing to remove
+ if (behaviorsToRemove.length == 0)
+ {
+ return behaviors;
+ }
+ if (behaviors == null)
+ {
+ throw cannotRemove(behaviorsToRemove[0]);
+ }
+
+ if (behaviors instanceof Behavior)
+ {
+ if (!behaviorsToRemove[0].equals(behaviors))
+ {
+ throw cannotRemove(behaviorsToRemove[0]);
+ }
+ if (behaviorsToRemove.length > 1)
+ {
+ throw cannotRemove(behaviorsToRemove[1]);
+ }
+ unbindBehavior(component, (Behavior) behaviors);
+ return null;
+ }
+
+ Behavior[] behaviorArr = (Behavior[]) behaviors;
+ for (Behavior behaviorToRemove : behaviorsToRemove)
+ {
+ boolean found = false;
+ for (int i = 0; i < behaviorArr.length; i++)
+ {
+ Behavior curBehavior = behaviorArr[i];
+ if (curBehavior != null && behaviorToRemove.equals(curBehavior))
+ {
+ found = true;
+ unbindBehavior(component, curBehavior);
+ behaviorArr[i] = null;
+ break;
+ }
+ }
+ if (!found)
+ {
+ throw cannotRemove(behaviorToRemove);
+ }
+ }
+ return behaviorArr;
+ }
+
+ private static IllegalStateException cannotRemove(Behavior behavior)
+ {
+ return new IllegalStateException(
+ "Tried to remove a behavior that was not added to the component. Behavior: "
+ + behavior.toString());
+ }
+
+ private static void unbindBehavior(Component component, Behavior behavior)
+ {
+ behavior.unbind(component);
+ if (!behavior.isTemporary(component))
+ {
+ component.addStateChange();
+ }
+ behavior.detach(component);
+ }
+
+ private static int getBehaviorsLength(Object behaviors)
+ {
+ if (behaviors == null)
+ {
+ return 0;
+ }
+ return behaviors instanceof Behavior[] ? ((Behavior[]) behaviors).length : 1;
+ }
+
+ private static int getEmptyBehaviorsSlots(Object behaviors)
+ {
+ if (!(behaviors instanceof Behavior[]))
+ {
+ return 0;
+ }
+ Behavior[] arr = (Behavior[]) behaviors;
+ int emptyCount = 0;
+ for (Behavior curBehavior : arr)
+ {
+ if (curBehavior == null)
+ {
+ emptyCount++;
+ }
+ }
+ return emptyCount;
+ }
+
+ private static <T> Object setMetaData(Object metadata, MetaDataKey<T> key, T data)
+ {
+ if (metadata == null)
+ {
+ if (data == null)
+ {
+ return null;
+ }
+ else
+ {
+ return new MetaDataEntry<>(key, data);
+ }
+ }
+ else if (metadata instanceof MetaDataEntry)
+ {
+ MetaDataEntry< ? > curEntry = (MetaDataEntry< ? >) metadata;
+ if (curEntry.key.equals(key))
+ {
+ if (data == null)
+ {
+ return null;
+ }
+ else
+ {
+ curEntry.object = data;
+ return curEntry;
+ }
+ }
+ else
+ {
+ if (data == null)
+ {
+ return metadata;
+ }
+ else
+ {
+ MetaDataEntry< ? >[] ret = new MetaDataEntry< ? >[2];
+ ret[0] = (MetaDataEntry< ? >) metadata;
+ ret[1] = new MetaDataEntry<>(key, data);
+ return ret;
+ }
+ }
+ }
+ else
+ {
+ MetaDataEntry< ? >[] metadataArr = (MetaDataEntry< ? >[]) metadata;
+ for (int i = 0; i < metadataArr.length; i++)
+ {
+ MetaDataEntry< ? > curEntry = metadataArr[i];
+ if (curEntry.key.equals(key))
+ {
+ if (data == null)
+ {
+ if (metadataArr.length == 2)
+ {
+ return metadataArr[i == 0 ? 1 : 0];
+ }
+ else
+ {
+ MetaDataEntry< ? >[] ret =
+ new MetaDataEntry< ? >[metadataArr.length - 1];
+ System.arraycopy(metadataArr, 0, ret, 0, i);
+ System.arraycopy(metadataArr, i + 1, ret, i, ret.length - i);
+ return ret;
+ }
+ }
+ else
+ {
+ curEntry.object = data;
+ return metadataArr;
+ }
+ }
+ }
+ if (data == null)
+ {
+ return metadataArr;
+ }
+ MetaDataEntry< ? >[] ret = new MetaDataEntry< ? >[metadataArr.length + 1];
+ System.arraycopy(metadataArr, 0, ret, 0, metadataArr.length);
+ ret[metadataArr.length] = new MetaDataEntry<>(key, data);
+ return ret;
+ }
+ }
+
+ static Behavior getBehaviorById(Component component, int id, Object state, boolean modelSet)
+ {
+ Object behaviors = getBehaviors(state, modelSet);
+ if (behaviors instanceof Behavior)
+ {
+ if (id == 0)
+ {
+ return (Behavior) behaviors;
+ }
+ }
+ else if (behaviors instanceof Behavior[])
+ {
+ Behavior[] behaviorsArr = (Behavior[]) behaviors;
+ if (behaviorsArr.length > id && behaviorsArr[id] != null)
+ {
+ return behaviorsArr[id];
+ }
+ }
+ throw new InvalidBehaviorIdException(component, id);
+ }
+
+ static int getBehaviorId(Component component, Behavior behavior, Object state, boolean modelSet)
+ {
+ Object behaviors = getBehaviors(state, modelSet);
+ if (behavior.equals(behaviors))
+ {
+ return 0;
+ }
+ else if (behaviors instanceof Behavior[])
+ {
+ Behavior[] behaviorsArr = (Behavior[]) behaviors;
+ for (int i = 0; i < behaviorsArr.length; i++)
+ {
+ if (behavior.equals(behaviorsArr[i]))
+ {
+ return i;
+ }
+ }
+ }
+ throw new IllegalStateException(
+ "Behavior must be added to component before its id can be generated. Behavior: "
+ + behavior + ", Component: " + component);
+ }
+
+ @SuppressWarnings("unchecked")
+ static <M extends Behavior> List<M> getBehaviors(Class<M> type, Object state, boolean modelSet)
+ {
+ Object behaviors = getBehaviors(state, modelSet);
+ if (behaviors == null)
+ {
+ return List.of();
+ }
+
+ if (behaviors instanceof Behavior)
+ {
+ if (type == null || type.isInstance(behaviors))
+ {
+ return List.of((M) behaviors);
+ }
+ return List.of();
+ }
+
+ Behavior[] behaviorsArr = (Behavior[]) behaviors;
+ List<M> subset = new ArrayList<>(behaviorsArr.length);
+ for (Behavior curBehavior : behaviorsArr)
+ {
+ if (curBehavior != null && (type == null || type.isInstance(curBehavior)))
+ {
+ subset.add((M) curBehavior);
+ }
+ }
+ if (subset.isEmpty())
+ {
+ return List.of();
+ }
+ return Collections.unmodifiableList(subset);
+ }
+
+ static void onRemoveBehaviors(Component component, Object state, boolean modelSet)
+ {
+ Object behaviors = getBehaviors(state, modelSet);
+ if (behaviors instanceof Behavior)
+ {
+ ((Behavior) behaviors).onRemove(component);
+ }
+ else if (behaviors instanceof Behavior[])
+ {
+ Behavior[] behaviorsArr = (Behavior[]) behaviors;
+ for (Behavior curBehavior : behaviorsArr)
+ {
+ if (curBehavior != null)
+ {
+ curBehavior.onRemove(component);
+ }
+ }
+ }
+ }
+
+ static Object compactBehaviors(Component component, Object state, boolean modelSet,
+ boolean fixedIds)
+ {
+ if (fixedIds)
+ {
+ return state;
+ }
+ Object behaviors = getBehaviors(state, modelSet);
+ if (!(behaviors instanceof Behavior[]))
+ {
+ return state;
+ }
+
+ Behavior[] behaviorsArr = (Behavior[]) behaviors;
+ int setIndex = 0;
+ int endIndex = behaviorsArr.length - 1;
+ int checkIndex = 0;
+ while (checkIndex <= endIndex)
+ {
+ Behavior curBehavior = behaviorsArr[checkIndex];
+ if (curBehavior == null)
+ {
+ checkIndex++;
+ continue;
+ }
+
+ // move tmp behaviors to the end of the array, swap with what's there
+ if (curBehavior.isTemporary(component))
+ {
+ Behavior tmp = behaviorsArr[endIndex];
+ behaviorsArr[endIndex] = curBehavior;
+ behaviorsArr[checkIndex] = tmp;
+ endIndex--;
+ continue;
+ }
+ behaviorsArr[setIndex] = curBehavior;
+ checkIndex++;
+ setIndex++;
+ }
+
+ // wipe the remainder of the array
+ for (; setIndex <= endIndex; setIndex++)
+ {
+ behaviorsArr[setIndex] = null;
+ }
+ return state;
+ }
+
+ static Object detachBehaviors(Component component, Object state, boolean modelSet,
+ boolean fixedIds)
+ {
+ Object behaviors = getBehaviors(state, modelSet);
+ if (behaviors instanceof Behavior)
+ {
+ Behavior behavior = (Behavior) behaviors;
+ behavior.detach(component);
+ if (behavior.isTemporary(component))
+ {
+ behavior.unbind(component);
+ return setBehaviors(state, modelSet, null);
+ }
+ }
+ else if (behaviors instanceof Behavior[])
+ {
+ // remove temporary behaviors and compact the array
+ int highestId = -1;
+ int filledSlots = 0;
+ Behavior[] behaviorsArr = (Behavior[]) behaviors;
+
+ // iterate over all behaviors, detaching them and removing temporary behaviors
+ // remaining behaviors are counted and for stateful behaviors slots assigned
+ for (int i = 0; i < behaviorsArr.length; i++)
+ {
+ Behavior curBehavior = behaviorsArr[i];
+ if (curBehavior != null)
+ {
+ curBehavior.detach(component);
+ if (curBehavior.isTemporary(component))
+ {
+ curBehavior.unbind(component);
+ behaviorsArr[i] = null;
+ }
+ else
+ {
+ filledSlots++;
+ highestId = i;
+ }
+ }
+ }
+
+ // if at most 1 behavior remains, no array is needed
+ int newSize = fixedIds ? Math.max(highestId + 1, filledSlots) : filledSlots;
+ if (newSize == 0)
+ {
+ return setBehaviors(state, modelSet, null);
+ }
+ if (newSize == 1)
+ {
+ return setBehaviors(state, modelSet, behaviorsArr[highestId]);
+ }
+
+ // the calculated size is equal to the current size, cannot compact
+ if (newSize == behaviorsArr.length)
+ {
+ return state;
+ }
+
+ // multiple behaviors (or one with an id > 0)
+ // construct a new array and compact the behaviors
+ Behavior[] ret = new Behavior[newSize];
+
+ if (fixedIds)
+ {
+ System.arraycopy(behaviorsArr, 0, ret, 0, ret.length);
+ }
+ else
+ {
+ int targetIndex = 0;
+ for (int i = 0; i < behaviorsArr.length; i++)
+ {
+ Behavior curBehavior = behaviorsArr[i];
+ if (curBehavior == null)
+ {
+ continue;
+ }
+ ret[targetIndex] = curBehavior;
+ targetIndex++;
+ }
+ }
+ return setBehaviors(state, modelSet, ret);
+ }
+ return state;
+ }
+}
diff --git a/wicket-core/src/main/java/org/apache/wicket/ajax/AbstractDefaultAjaxBehavior.java b/wicket-core/src/main/java/org/apache/wicket/ajax/AbstractDefaultAjaxBehavior.java
index 291303f..76c4fb4 100644
--- a/wicket-core/src/main/java/org/apache/wicket/ajax/AbstractDefaultAjaxBehavior.java
+++ b/wicket-core/src/main/java/org/apache/wicket/ajax/AbstractDefaultAjaxBehavior.java
@@ -83,12 +83,6 @@
final Component component = getComponent();
component.setOutputMarkupId(true);
-
- if (getStatelessHint(component))
- {
- //generate behavior id
- component.getBehaviorId(this);
- }
}
/**
diff --git a/wicket-core/src/main/java/org/apache/wicket/core/util/lang/WicketObjects.java b/wicket-core/src/main/java/org/apache/wicket/core/util/lang/WicketObjects.java
index 4649150..f3b0b95 100644
--- a/wicket-core/src/main/java/org/apache/wicket/core/util/lang/WicketObjects.java
+++ b/wicket-core/src/main/java/org/apache/wicket/core/util/lang/WicketObjects.java
@@ -17,6 +17,7 @@
package org.apache.wicket.core.util.lang;
import java.io.Serializable;
+import java.nio.file.Files;
import org.apache.wicket.Application;
import org.apache.wicket.Component;
diff --git a/wicket-core/src/test/java/org/apache/wicket/behavior/ImmutableBehaviorIdsTest.java b/wicket-core/src/test/java/org/apache/wicket/behavior/ImmutableBehaviorIdsTest.java
index 4f161ab..98e9a44 100644
--- a/wicket-core/src/test/java/org/apache/wicket/behavior/ImmutableBehaviorIdsTest.java
+++ b/wicket-core/src/test/java/org/apache/wicket/behavior/ImmutableBehaviorIdsTest.java
@@ -75,10 +75,10 @@
assertTrue(output.contains("autocomplete=\"off\""));
assertTrue(output.contains("class2=\"border\""));
assertTrue(output.contains("autocomplete2=\"off\""));
- assertTrue(output.contains(".0"));
- assertTrue(output.contains(".1"));
- assertEquals(link, page.getContainer().getBehaviorById(0));
- assertEquals(link2, page.getContainer().getBehaviorById(1));
+ assertTrue(output.contains(".2"));
+ assertTrue(output.contains(".4"));
+ assertEquals(link, page.getContainer().getBehaviorById(2));
+ assertEquals(link2, page.getContainer().getBehaviorById(4));
// if we remove a behavior that is before the ibehaviorlistener its url index should not
// change
@@ -89,11 +89,11 @@
page.getContainer().remove(auto2);
tester.startPage(page);
output = tester.getLastResponseAsString();
- // System.out.println(output);
- assertTrue(output.contains(".0"));
- assertTrue(output.contains(".1"));
- assertEquals(link, page.getContainer().getBehaviorById(0));
- assertEquals(link2, page.getContainer().getBehaviorById(1));
+// System.out.println(output);
+ assertTrue(output.contains(".2"));
+ assertTrue(output.contains(".4"));
+ assertEquals(link, page.getContainer().getBehaviorById(2));
+ assertEquals(link2, page.getContainer().getBehaviorById(4));
}
/**
diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/html/basic/SimplePageExpectedResult_13.html b/wicket-core/src/test/java/org/apache/wicket/markup/html/basic/SimplePageExpectedResult_13.html
index c0ae3c9..e019755 100644
--- a/wicket-core/src/test/java/org/apache/wicket/markup/html/basic/SimplePageExpectedResult_13.html
+++ b/wicket-core/src/test/java/org/apache/wicket/markup/html/basic/SimplePageExpectedResult_13.html
@@ -18,7 +18,7 @@
<script type="text/javascript">
/*<![CDATA[*/
Wicket.Event.add(window, "domready", function(event) {
-Wicket.Ajax.ajax({"u":"./org.apache.wicket.markup.html.basic.SimplePage_13?0-1.0-html","c":"html1","e":"click","pd":true});;
+Wicket.Ajax.ajax({"u":"./org.apache.wicket.markup.html.basic.SimplePage_13?0-1.1-html","c":"html1","e":"click","pd":true});;
Wicket.Event.publish(Wicket.Event.Topic.AJAX_HANDLERS_BOUND);
;});
/*]]>*/