1 /*******************************************************************************
\r
2 * Copyright (c) 2010 Association for Decentralized Information Management in
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.databoard.binding.reflection;
14 import java.lang.reflect.Array;
\r
15 import java.util.Iterator;
\r
17 import org.simantics.databoard.Bindings;
\r
18 import org.simantics.databoard.adapter.AdaptException;
\r
19 import org.simantics.databoard.adapter.Adapter;
\r
20 import org.simantics.databoard.adapter.AdapterConstructionException;
\r
21 import org.simantics.databoard.binding.ArrayBinding;
\r
22 import org.simantics.databoard.binding.Binding;
\r
23 import org.simantics.databoard.binding.error.BindingException;
\r
24 import org.simantics.databoard.binding.error.UnsupportedOperationException;
\r
25 import org.simantics.databoard.type.ArrayType;
\r
28 * ReflectionArrayBinding binds T[]
30 * @author Toni Kalajainen <toni.kalajainen@vtt.fi>
32 public class GenericArrayBinding extends ArrayBinding {
35 Class<?> componentClass;
37 public GenericArrayBinding(Class<?> clazz, ArrayType type, Binding componentBinding) {
38 super(type, componentBinding);
41 this.componentClass = clazz.getComponentType();
45 public Object create() {
46 return Array.newInstance(componentClass, 0);
50 public Object create(int length, Iterator<Object> values) {
51 Object result = Array.newInstance(componentClass, length);
52 for (int i=0; i<length; i++)
53 Array.set(result, i, values.next());
58 public Object create(Object[] array) throws BindingException {
59 int length = array.length;
60 Object result = Array.newInstance(componentClass, length);
61 System.arraycopy(array, 0, result, 0, length);
66 public void readFrom(Binding srcBinding, Object src, Object dst)
\r
67 throws BindingException {
\r
69 ArrayBinding sb = (ArrayBinding) srcBinding;
\r
70 Binding scb = sb.getComponentBinding();
\r
71 Binding dcb = getComponentBinding();
\r
72 Adapter cloner = dcb.isImmutable() ? Bindings.adapterFactory.getAdapter(scb, dcb, false, true) : null;
\r
73 int length = Array.getLength(dst);
\r
74 if (length != sb.size(src)) throw new BindingException(clazz.getName()+" is length immutable");
\r
76 for (int i=0; i<length; i++) {
\r
77 if (dcb.isImmutable()) {
\r
78 Object sc = sb.get(src, i);
\r
79 Object dc = cloner.adapt(sc);
\r
82 Object dc = Array.get(dst, i);
\r
83 Object sc = sb.get(src, i);
\r
84 dc = dcb.readFromTry(scb, sc, dc);
\r
85 Array.set(dst, i, dc);
\r
88 } catch (AdaptException e) {
\r
89 throw new BindingException(e);
\r
90 } catch (AdapterConstructionException e) {
\r
91 throw new BindingException(e);
\r
96 public Object readFromTry(Binding srcBinding, Object src, Object dst)
\r
97 throws BindingException {
\r
99 ArrayBinding sb = (ArrayBinding) srcBinding;
\r
100 Binding scb = sb.getComponentBinding();
\r
101 Binding dcb = getComponentBinding();
\r
102 Adapter cloner = Bindings.adapterFactory.getAdapter(scb, dcb, false, true);
\r
103 int length = Array.getLength(dst);
\r
104 int srcSize = sb.size(src);
\r
106 if (length != srcSize || dcb.isImmutable()) {
\r
107 d = Array.newInstance(componentClass, srcSize);
\r
108 if (dcb.isImmutable()) {
\r
109 for (int i=0; i<srcSize; i++) {
\r
110 Object sc = sb.get(src, i);
\r
111 Object dc = cloner.adapt(sc);
\r
115 int X = Math.min(Array.getLength(dst), srcSize);
\r
116 for (int i=0; i<X; i++) {
\r
117 Object dc = Array.get(dst, i);
\r
118 Object sc = sb.get(src, i);
\r
119 dc = dcb.readFromTry(scb, sc, dc);
\r
120 Array.set(d, i, dc);
\r
122 for (int i=X; i<srcSize; i++) {
\r
123 Object sc = sb.get(src, i);
\r
124 Object dc = cloner.adapt(sc);
\r
130 if (dcb.isImmutable()) {
\r
131 for (int i=0; i<length; i++) {
\r
132 Object sc = sb.get(src, i);
\r
133 Object dc = cloner.adapt(sc);
\r
137 for (int i=0; i<length; i++) {
\r
138 Object dc = Array.get(dst, i);
\r
139 Object sc = sb.get(src, i);
\r
140 dc = dcb.readFromTry(scb, sc, dc);
\r
141 Array.set(d, i, dc);
\r
147 } catch (AdaptException e) {
\r
148 throw new BindingException(e);
\r
149 } catch (AdapterConstructionException e) {
\r
150 throw new BindingException(e);
\r
155 public Object get(Object array, int index) throws BindingException {
156 if (!isInstance(array)) throw new BindingException("Unexpected class "+array.getClass().getSimpleName()+", "+clazz.getSimpleName()+" expected");
157 return Array.get(array, index);
161 public void getAll(Object array, Object[] result) throws BindingException {
162 int length = Array.getLength(array);
\r
163 System.arraycopy(array, 0, result, 0, length);
167 public void set(Object array, int index, Object value)
168 throws BindingException {
\r
169 if (index<0 || index>Array.getLength(array))
\r
170 throw new BindingException("Index out of bounds");
171 Array.set(array, index, value);
175 public int size(Object array) throws BindingException {
176 if (!isInstance(array)) {
\r
178 throw new BindingException("Tried to calculate the size of a null array.");
\r
179 throw new BindingException("Unexpected class "+array.getClass().getSimpleName()+", "+clazz.getSimpleName()+" expected");
\r
181 return Array.getLength(array);
184 public boolean isInstance(Object obj) {
185 return clazz.isInstance(obj);
189 public boolean isImmutable() {
194 public void add(Object array, int index, Object element)
195 throws BindingException, IndexOutOfBoundsException {
196 throw new UnsupportedOperationException();
200 public void remove(Object array, int index, int count)
201 throws BindingException, IndexOutOfBoundsException {
202 throw new UnsupportedOperationException();
206 public void setSize(Object array, int newSize) throws BindingException {
\r
207 int oldSize = Array.getLength(array);
\r
208 if (oldSize==newSize) return;
\r
209 throw new BindingException(clazz.getName()+" is length immutable");
\r
213 public boolean isResizable() {
\r
218 protected boolean baseEquals(Object obj) {
\r
219 return super.baseEquals(obj) && ((GenericArrayBinding)obj).clazz.equals(clazz);
\r
223 public int baseHashCode() {
\r
224 return super.baseHashCode() + 13 * clazz.hashCode();
\r