Author: nbelaevski
Date: 2007-11-07 16:30:06 -0500 (Wed, 07 Nov 2007)
New Revision: 3813
Added:
trunk/sandbox/ui/orderingList/src/main/java/org/richfaces/component/TranslatedSequenceDataModel.java
Modified:
trunk/sandbox/ui/orderingList/src/main/java/org/richfaces/component/UIOrderingList.java
trunk/sandbox/ui/orderingList/src/main/java/org/richfaces/renderkit/OrderingListRendererBase.java
trunk/sandbox/ui/orderingList/src/main/resources/org/richfaces/renderkit/html/scripts/OrderingList.js
trunk/sandbox/ui/orderingList/src/main/templates/org/richfaces/htmlOrderingList.jspx
Log:
OrderingList development boost - server-side code implemented
Added:
trunk/sandbox/ui/orderingList/src/main/java/org/richfaces/component/TranslatedSequenceDataModel.java
===================================================================
---
trunk/sandbox/ui/orderingList/src/main/java/org/richfaces/component/TranslatedSequenceDataModel.java
(rev 0)
+++
trunk/sandbox/ui/orderingList/src/main/java/org/richfaces/component/TranslatedSequenceDataModel.java 2007-11-07
21:30:06 UTC (rev 3813)
@@ -0,0 +1,105 @@
+/**
+ *
+ */
+package org.richfaces.component;
+
+import java.io.IOException;
+
+import javax.faces.context.FacesContext;
+import javax.faces.model.DataModel;
+
+import org.ajax4jsf.model.DataVisitor;
+import org.ajax4jsf.model.Range;
+import org.ajax4jsf.model.SequenceDataModel;
+
+/**
+ * @author Nick Belaevski
+ * mailto:nbelaevski@exadel.com
+ * created 07.11.2007
+ *
+ */
+public class TranslatedSequenceDataModel extends SequenceDataModel {
+
+ protected static final class TranslatedRowKey {
+ private Integer key;
+ private String asString;
+
+ public TranslatedRowKey(Integer key, String asString) {
+ super();
+ this.key = key;
+ this.asString = asString;
+ }
+
+ public Integer getKey() {
+ return key;
+ }
+
+ public String getAsString() {
+ return asString;
+ }
+
+ public String toString() {
+ return getAsString();
+ }
+ };
+
+ private int[] translationTable;
+ private boolean translatedModel;
+
+ private Object rowKey;
+
+ public TranslatedSequenceDataModel(DataModel wrapped,
+ boolean translatedModel, int[] translationTable) {
+ super(wrapped);
+ this.translatedModel = translatedModel;
+ this.translationTable = translationTable;
+ }
+
+ public TranslatedSequenceDataModel(DataModel wrapped) {
+ super(wrapped);
+ }
+
+ private int translate(int i) {
+ if (translationTable != null) {
+ return translationTable[i];
+ } else {
+ return i;
+ }
+ }
+
+ public Object getRowKey() {
+ return rowKey;
+ }
+
+ public void setRowKey(Object key) {
+ this.rowKey = key;
+
+ if (key instanceof TranslatedRowKey) {
+ super.setRowKey(((TranslatedRowKey) key).getKey());
+ } else {
+ if (this.translatedModel) {
+ if (rowKey != null) {
+ int iKey = ((Integer) key).intValue();
+ super.setRowKey(new Integer(translate(iKey)));
+ } else {
+ super.setRowKey(null);
+ }
+ } else {
+ super.setRowKey(key);
+ }
+ }
+ }
+
+ public void walk(FacesContext context, DataVisitor visitor, Range range,
+ Object argument) throws IOException {
+
+ for (int i = 0; i < getRowCount(); i++) {
+ if (this.translatedModel) {
+ visitor.process(context, new TranslatedRowKey(
+ new Integer(i), String.valueOf(translate(i))), argument);
+ } else {
+ visitor.process(context, new Integer(translate(i)), argument);
+ }
+ }
+ }
+}
Modified:
trunk/sandbox/ui/orderingList/src/main/java/org/richfaces/component/UIOrderingList.java
===================================================================
---
trunk/sandbox/ui/orderingList/src/main/java/org/richfaces/component/UIOrderingList.java 2007-11-07
17:05:59 UTC (rev 3812)
+++
trunk/sandbox/ui/orderingList/src/main/java/org/richfaces/component/UIOrderingList.java 2007-11-07
21:30:06 UTC (rev 3813)
@@ -3,8 +3,10 @@
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -26,21 +28,93 @@
import javax.faces.event.FacesEvent;
import javax.faces.event.ValueChangeEvent;
import javax.faces.event.ValueChangeListener;
+import javax.faces.model.ArrayDataModel;
import javax.faces.model.DataModel;
+import javax.faces.model.ListDataModel;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;
import org.ajax4jsf.component.UIDataAdaptor;
+import org.ajax4jsf.javascript.ScriptUtils;
import org.ajax4jsf.model.DataComponentState;
import org.ajax4jsf.model.ExtendedDataModel;
import org.ajax4jsf.model.RepeatState;
-import org.ajax4jsf.model.SequenceDataModel;
import org.apache.commons.collections.Predicate;
import org.apache.commons.collections.iterators.EmptyIterator;
import org.apache.commons.collections.iterators.FilterIterator;
public abstract class UIOrderingList extends UIDataAdaptor implements EditableValueHolder
{
+ protected static class EditableState {
+ private boolean isTranslated = false;
+
+ //setting this flag to true means we should reorder elements
+ private boolean translatedRendering = false;
+ }
+
+ public static final class SubmittedValue {
+ private int[] permutationOrder;
+ private Set selectedItems = new HashSet();
+ private int activeItem;
+
+ public SubmittedValue(String submittedString) {
+ super();
+ fromString(submittedString);
+ }
+
+ private void fromString(String string) {
+ String[] valueOrder = string.split(",");
+ permutationOrder = new int[valueOrder.length];
+ for (int i = 0; i < valueOrder.length; i++) {
+ Matcher matcher =
Pattern.compile("(\\d+)(s?a?)").matcher(valueOrder[i]);
+ matcher.matches();
+
+ try {
+ permutationOrder[i] = Integer.valueOf(matcher.group(1)).intValue();
+ String group = matcher.group(2);
+ for (int j = 0; j < group.length(); j++) {
+ char c = group.charAt(j);
+ if ('s' == c) {
+ selectedItems.add(new Integer(i));
+ } else if ('a' == c) {
+ activeItem = i;
+ } else {
+ break ;
+ }
+
+ }
+ } catch (NumberFormatException e) {
+ // TODO: handle exception
+ }
+ }
+ }
+
+ public String toString() {
+ StringBuffer result = new StringBuffer();
+ for (int i = 0; i < permutationOrder.length; i++) {
+ result.append(permutationOrder[i]);
+
+ if (selectedItems.contains(new Integer(i))) {
+ result.append('s');
+ }
+
+ if (activeItem == i) {
+ result.append('a');
+ }
+
+ if (i < permutationOrder.length - 1) {
+ result.append(',');
+ }
+ }
+ return result.toString();
+ }
+
+ public int[] getPermutationOrder() {
+ return permutationOrder;
+ }
+
+ }
+
public static final Predicate isColumn = new ColumnPredicate();
private static final class ColumnPredicate implements Predicate {
@@ -53,100 +127,24 @@
return new RepeatState();
}
+ protected DataModel getDataModel(Object current) {
+ if (current == null) {
+ return new ListDataModel(Collections.EMPTY_LIST);
+ } else if (current instanceof List) {
+ return new ListDataModel((List) current);
+ } else if (Object[].class.isAssignableFrom(current.getClass())) {
+ //TODO scalar
+ return new ArrayDataModel((Object[]) current);
+ }
+ throw new IllegalArgumentException();
+ }
+
protected ExtendedDataModel createDataModel() {
- try {
- insideCreateDataModel = true;
-
- return new SequenceDataModel(super.getDataModel());
- } finally {
- insideCreateDataModel = false;
- }
- }
-
- private boolean insideCreateDataModel;
-
- private DataModel getPermutatedDataModel(final DataModel dataModel) {
-
- if (submittedValue == null) {
- return dataModel;
+ DataModel dataModel = super.getDataModel();
+ if (editableState.translatedRendering || editableState.isTranslated) {
+ return new TranslatedSequenceDataModel(dataModel, editableState.isTranslated,
submittedValueHolder != null ? submittedValueHolder.permutationOrder : null);
} else {
- return new DataModel() {
-
- private int rowIndex = -1;
- private int[] indexes;
-
- {
- String[] valueOrder = ((String) submittedValue).split(",");
- for (int i = 0; i < valueOrder.length; i++) {
- String[] currentOrder = valueOrder[i].split("d+");
-
- try {
- indexes[i] = Integer.valueOf(currentOrder[0]).intValue();
- } catch (NumberFormatException e) {
- // TODO: handle exception
- }
-
-// Object currentItem = oldValues.get(itemIndex.intValue());
-// synchronizedList.add(currentItem);
-//
-// if (currentOrder.length > 1) {
-// Iterator it = Arrays.asList(currentOrder[1].toCharArray()).iterator();
-// while (it.hasNext()) {
-// Character marker = (Character) it.next();
-// if (ACTIVITY_MARKER.equals(marker)) {
-// activeItem = currentItem;
-// } else if (SELECTION_MARKER.equals(marker)) {
-// selectedItems.add(currentItem);
-// }
-// }
-// }
- }
- }
-
- @Override
- public int getRowCount() {
- return dataModel.getRowCount();
- }
-
- @Override
- public Object getRowData() {
- return dataModel.getRowData();
- }
-
- @Override
- public int getRowIndex() {
- return rowIndex;
- }
-
- @Override
- public Object getWrappedData() {
- return dataModel.getWrappedData();
- }
-
- @Override
- public boolean isRowAvailable() {
- return dataModel.isRowAvailable();
- }
-
- @Override
- public void setRowIndex(int rowIndex) {
- if (rowIndex < -1) {
- throw new IllegalArgumentException();
- }
-
- if (rowIndex < indexes.length) {
- dataModel.setRowIndex(indexes[rowIndex]);
- }
-
- this.rowIndex = rowIndex;
- }
-
- @Override
- public void setWrappedData(Object data) {
- dataModel.setWrappedData(data);
- }
-
- };
+ return new TranslatedSequenceDataModel(dataModel, false, null);
}
}
@@ -176,7 +174,8 @@
private Object value;
private boolean localValueSet;
- private Object submittedValue;
+ private SubmittedValue submittedValueHolder = null;
+ private EditableState editableState = new EditableState();
public void restoreState(FacesContext faces, Object object) {
Object[] state = (Object[]) object;
@@ -256,12 +255,29 @@
removeFacesListener(listener);
}
+
+ public Object getSubmittedValueAsString() {
+ return submittedValueHolder;
+ }
+
public Object getSubmittedValue() {
- return submittedValue;
+ return new Object[] { submittedValueHolder, editableState };
}
+ public void setSubmittedString(String submittedString) {
+ this.submittedValueHolder = new SubmittedValue(submittedString);
+ }
+
public void setSubmittedValue(Object submittedValue) {
- this.submittedValue = submittedValue;
+ if (submittedValue != null) {
+ Object[] values = (Object[]) submittedValue;
+
+ this.submittedValueHolder = (SubmittedValue) values[0];
+ this.editableState = (EditableState) values[1];
+ } else {
+ this.submittedValueHolder = null;
+ this.editableState = null;
+ }
}
public abstract void setImmediate(boolean immediate);
@@ -286,11 +302,12 @@
}
public void setValue(Object value) {
+ super.setValue(value);
this.value = value;
setLocalValueSet(true);
}
- private Object getComponentValue() {
+ public Object getValue() {
if (this.value != null) {
return (this.value);
}
@@ -301,16 +318,6 @@
return (null);
}
}
-
- public Object getValue() {
- if (insideCreateDataModel) {
- if (submittedValue != null) {
- return getConvertedValue();
- }
- }
-
- return getComponentValue();
- }
/**
@@ -606,7 +613,9 @@
if (isValid()) {
Object previous = getValue();
setValue(newValue);
- setSubmittedValue(null);
+ this.submittedValueHolder = null;
+ this.editableState.isTranslated = true;
+ //setSubmittedValue(null);
if (compareValues(previous, newValue)) {
queueEvent(new ValueChangeEvent(this, previous, newValue));
}
@@ -615,59 +624,46 @@
}
protected Object getConvertedValue() throws ConverterException {
- if (submittedValue instanceof String) {
- Object componentValue = getComponentValue();
- if (componentValue == null) {
- return Collections.EMPTY_LIST;
- }
+ Object convertedValue = getValue();
+ if (convertedValue == null) {
+ convertedValue = Collections.EMPTY_LIST;
+ }
+
+ if (submittedValueHolder != null) {
+ Object savedValue = convertedValue;
- String[] valueOrder = ((String) submittedValue).split(",");
- int[] indexes = new int[valueOrder.length];
- for (int i = 0; i < valueOrder.length; i++) {
- Matcher matcher =
Pattern.compile("(\\d+)(s)?(a)?").matcher(valueOrder[i]);
- matcher.matches();
-
- try {
- indexes[i] = Integer.valueOf(matcher.group(1)).intValue();
- } catch (NumberFormatException e) {
- // TODO: handle exception
- }
-
-// Object currentItem = oldValues.get(itemIndex.intValue());
-// synchronizedList.add(currentItem);
-//
-// if (currentOrder.length > 1) {
-// Iterator it = Arrays.asList(currentOrder[1].toCharArray()).iterator();
-// while (it.hasNext()) {
-// Character marker = (Character) it.next();
-// if (ACTIVITY_MARKER.equals(marker)) {
-// activeItem = currentItem;
-// } else if (SELECTION_MARKER.equals(marker)) {
-// selectedItems.add(currentItem);
-// }
-// }
-// }
- }
-
- if (componentValue instanceof List) {
- List list = (List) componentValue;
+ int[] indexes = submittedValueHolder.permutationOrder;
+
+ if (savedValue instanceof List) {
+ List list = (List) savedValue;
ArrayList arrayList = new ArrayList(list.size());
for (int i = 0; i < indexes.length; i++) {
int j = indexes[i];
arrayList.add(list.get(j));
}
- submittedValue = arrayList;
+ convertedValue = arrayList;
} else {
- submittedValue = Array.newInstance(componentValue.getClass().getComponentType(),
- Array.getLength(componentValue));
- ArrayUtil.copy(submittedValue,
- componentValue, indexes);
+ convertedValue = Array.newInstance(savedValue.getClass().getComponentType(),
+ Array.getLength(savedValue));
+ ArrayUtil.copy(convertedValue,
+ savedValue, indexes);
}
+
+ //submittedValueHolder.newValue = convertedValue;
}
- return submittedValue;
+ return convertedValue;
}
+ @Override
+ protected void resetDataModel() {
+ super.resetDataModel();
+
+ if (this.submittedValueHolder != null) {
+ this.editableState.translatedRendering = true;
+ }
+ }
+
/**
*
* <p>Set the "valid" property according to the below
algorithm.</p>
@@ -861,4 +857,16 @@
message.setSeverity(FacesMessage.SEVERITY_ERROR);
context.addMessage(getClientId(context), message);
}
+
+ public String getElementsOrder() {
+ Object order = null;
+
+ if (this.editableState.translatedRendering) {
+ if (this.submittedValueHolder != null) {
+ order = this.submittedValueHolder.permutationOrder;
+ }
+ }
+
+ return ScriptUtils.toScript(order);
+ }
}
Modified:
trunk/sandbox/ui/orderingList/src/main/java/org/richfaces/renderkit/OrderingListRendererBase.java
===================================================================
---
trunk/sandbox/ui/orderingList/src/main/java/org/richfaces/renderkit/OrderingListRendererBase.java 2007-11-07
17:05:59 UTC (rev 3812)
+++
trunk/sandbox/ui/orderingList/src/main/java/org/richfaces/renderkit/OrderingListRendererBase.java 2007-11-07
21:30:06 UTC (rev 3813)
@@ -145,7 +145,7 @@
String valueOrder = (String) requestParameterMap.get(clientId);
if (valueOrder != null && valueOrder.length() != 0) {
- orderingList.setSubmittedValue(valueOrder);
+ orderingList.setSubmittedString(valueOrder);
}
}
@@ -182,4 +182,5 @@
}
}
}
+
}
Modified:
trunk/sandbox/ui/orderingList/src/main/resources/org/richfaces/renderkit/html/scripts/OrderingList.js
===================================================================
---
trunk/sandbox/ui/orderingList/src/main/resources/org/richfaces/renderkit/html/scripts/OrderingList.js 2007-11-07
17:05:59 UTC (rev 3812)
+++
trunk/sandbox/ui/orderingList/src/main/resources/org/richfaces/renderkit/html/scripts/OrderingList.js 2007-11-07
21:30:06 UTC (rev 3813)
@@ -18,14 +18,14 @@
}
Shuttle = function(containerId, contentTableId, headerTableId, focusKeeperId,
valueKeeperId,
- upControlId, downControlId, firstControlId, lastControlId, onclickControlId) {
+ upControlId, downControlId, firstControlId, lastControlId, onclickControlId,
ordering) {
this.container = document.getElementById(containerId);
this.shuttleTable = document.getElementById(contentTableId);
this.shuttleTbody = this.shuttleTable.tBodies[0];
this.items = null;
this.selectedItems = new Array();
- this.retrieveShuttleItems();
+ this.retrieveShuttleItems(ordering);
this.shuttle = null;
this.sortOrder = Shuttle.ASC;
@@ -72,13 +72,13 @@
this.shuttleTop = LayoutManager.getElemXY(this.shuttleTable).top;
}
-Shuttle.prototype.retrieveShuttleItems = function() {
+Shuttle.prototype.retrieveShuttleItems = function(ordering) {
var rows = this.shuttleTbody.rows;
this.shuttleItems = new Array();
var obj = this;
for (var i = 0; i < rows.length; i++) {
var row = rows[i];
- this.shuttleItems[i] = new SelectItem(null, i, false, row);
+ this.shuttleItems[i] = new SelectItem(null, ordering ? ordering[i] : i, false, row);
}
}
Modified:
trunk/sandbox/ui/orderingList/src/main/templates/org/richfaces/htmlOrderingList.jspx
===================================================================
---
trunk/sandbox/ui/orderingList/src/main/templates/org/richfaces/htmlOrderingList.jspx 2007-11-07
17:05:59 UTC (rev 3812)
+++
trunk/sandbox/ui/orderingList/src/main/templates/org/richfaces/htmlOrderingList.jspx 2007-11-07
21:30:06 UTC (rev 3813)
@@ -16,9 +16,9 @@
</h:scripts>
<f:clientId var="clientId"/>
- <div id="#{clientId}"
onclick="Shuttle.setFocus('#{clientId}focusKeeper')">
+ <div id="#{clientId}"
onclick="Shuttle.setFocus('#{clientId}focusKeeper')"
x:passThruWithExclusions="id,onclick">
<input id="#{clientId}focusKeeper" type="button"
value="" style="position: absolute; left: -32767;"
name="focusKeeper"/>
- <input id="#{clientId}valueKeeper" type="hidden"
name="#{clientId}" value=""/>
+ <input id="#{clientId}valueKeeper" type="hidden"
name="#{clientId}" value="#{component.submittedValueAsString}"/>
<table id="#{clientId}table" cellpadding="0"
cellspacing="0" class="ol_body">
<tr>
@@ -61,7 +61,7 @@
document.body.className = "body";
function init() {
- var shuttle = new Shuttle('#{cId}', '#{cId}internal_tab',
'#{cId}internal_header_tab', '#{cId}focusKeeper',
'#{cId}valueKeeper','#{cId}up', '#{cId}down',
'#{cId}first', '#{cId}last', '#{cId}sortLabel');
+ var shuttle = new Shuttle('#{cId}', '#{cId}internal_tab',
'#{cId}internal_header_tab', '#{cId}focusKeeper',
'#{cId}valueKeeper','#{cId}up', '#{cId}down',
'#{cId}first', '#{cId}last', '#{cId}sortLabel',
#{component.elementsOrder});
var layoutManager = new LayoutManager('#{clientId}internal_header_tab',
'#{clientId}internal_tab');
layoutManager.widthSynchronization();
}