001 /*
002 * Copyright 2002-2004 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005 * use this file except in compliance with the License. You may obtain a copy of
006 * the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013 * License for the specific language governing permissions and limitations under
014 * the License.
015 */
016 package org.springframework.binding.value.support;
017
018 import java.lang.reflect.Array;
019 import java.util.Iterator;
020 import java.util.List;
021 import java.util.Set;
022
023 import org.springframework.binding.value.IndexAdapter;
024 import org.springframework.binding.value.ValueModel;
025
026 /**
027 * @author Keith Donald
028 */
029 public class GrowableIndexAdapter extends AbstractIndexAdapter implements IndexAdapter {
030
031 private boolean autoGrow;
032
033 private ValueModel collectionValueModel;
034
035 public GrowableIndexAdapter(boolean autoGrow, ValueModel collectionValueModel) {
036 this.autoGrow = autoGrow;
037 this.collectionValueModel = collectionValueModel;
038 }
039
040 public boolean isAutoGrow() {
041 return autoGrow;
042 }
043
044 public void fireIndexedObjectChanged() {
045 }
046
047 public Object getValue() {
048 return getCollectionValue(getIndex());
049 }
050
051 protected Object getCollectionValue(int index) {
052 Object collection = collectionValueModel.getValue();
053 if (collection.getClass().isArray()) {
054 growArrayIfNeccessary(index);
055 return Array.get(collection, index);
056 }
057 else if (collection instanceof List) {
058 growCollectionIfNeccessary(index);
059 return ((List)collection).get(index);
060 }
061 else if (collection instanceof Set) {
062 growCollectionIfNeccessary(index);
063 Set setValue = (Set)collection;
064 Iterator it = setValue.iterator();
065 for (int j = 0; it.hasNext(); j++) {
066 Object element = it.next();
067 if (j == index) {
068 return element;
069 }
070 }
071 return null;
072 }
073 else {
074 throw new IllegalArgumentException("Value must be a collection " + collection);
075 }
076 }
077
078 public void setValue(Object value) {
079 Object oldValue = setCollectionValue(getIndex(), value);
080 fireValueChange(oldValue, value);
081 }
082
083 protected Object setCollectionValue(int index, Object value) {
084 Object collection = collectionValueModel.getValue();
085 if (collection.getClass().isArray()) {
086 growArrayIfNeccessary(index);
087 Object old = Array.get(value, index);
088 Array.set(collection, index, value);
089 return old;
090 }
091 else if (collection instanceof List) {
092 growCollectionIfNeccessary(index);
093 return ((List)value).set(index, value);
094 }
095 else if (collection instanceof Set) {
096 growCollectionIfNeccessary(index);
097 Set setValue = (Set)value;
098 Iterator it = setValue.iterator();
099 Object old = null;
100 for (int j = 0; it.hasNext(); j++) {
101 Object element = it.next();
102 if (j == index) {
103 old = element;
104 it.remove();
105 }
106 }
107 setValue.add(value);
108 return old;
109 }
110 else {
111 throw new IllegalArgumentException("Value must be a collection " + value);
112 }
113 }
114
115 private void growArrayIfNeccessary(int index) {
116 Object value = collectionValueModel.getValue();
117 if (isAutoGrow()) {
118 if (index >= Array.getLength(value)) {
119 value = Array.newInstance(value.getClass(), index + 1);
120 Object newArray = Array.get(value, index);
121 System.arraycopy(value, 0, newArray, 0, Array.getLength(value));
122 collectionValueModel.setValue(newArray);
123 }
124 }
125 }
126
127 private void growCollectionIfNeccessary(int index) {
128 if (isAutoGrow()) {
129 Object value = collectionValueModel.getValue();
130 if (value instanceof List) {
131 List listValue = (List)value;
132 if (isAutoGrow()) {
133 while (index >= listValue.size()) {
134 listValue.add(null);
135 }
136 }
137 }
138 else if (value instanceof Set) {
139 Set setValue = (Set)value;
140 while (index >= setValue.size()) {
141 setValue.add(null);
142 }
143 }
144 }
145 }
146 }