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 }