001: /* Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com
002:
003: This file is part of the db4o open source object database.
004:
005: db4o is free software; you can redistribute it and/or modify it under
006: the terms of version 2 of the GNU General Public License as published
007: by the Free Software Foundation and as clarified by db4objects' GPL
008: interpretation policy, available at
009: http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
010: Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
011: Suite 350, San Mateo, CA 94403, USA.
012:
013: db4o is distributed in the hope that it will be useful, but WITHOUT ANY
014: WARRANTY; without even the implied warranty of MERCHANTABILITY or
015: FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
016: for more details.
017:
018: You should have received a copy of the GNU General Public License along
019: with this program; if not, write to the Free Software Foundation, Inc.,
020: 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
021: package com.db4o.reflect.core;
022:
023: import java.lang.reflect.Array;
024:
025: import com.db4o.reflect.*;
026:
027: /**
028: * @exclude
029: */
030: public abstract class AbstractReflectArray implements ReflectArray {
031:
032: protected final Reflector _reflector;
033:
034: public AbstractReflectArray(Reflector reflector) {
035: _reflector = reflector;
036: }
037:
038: public abstract Object newInstance(ReflectClass componentType,
039: int[] dimensions);
040:
041: public abstract Object newInstance(ReflectClass componentType,
042: int length);
043:
044: public int[] dimensions(Object arr) {
045: int count = 0;
046: ReflectClass claxx = _reflector.forObject(arr);
047: while (claxx.isArray()) {
048: count++;
049: claxx = claxx.getComponentType();
050: }
051: int dim[] = new int[count];
052: for (int i = 0; i < count; i++) {
053: try {
054: dim[i] = getLength(arr);
055: arr = get(arr, 0);
056: } catch (Exception e) {
057: return dim;
058: }
059: }
060: return dim;
061: }
062:
063: public int flatten(Object a_shaped, int[] a_dimensions,
064: int a_currentDimension, Object[] a_flat, int a_flatElement) {
065: if (a_currentDimension == (a_dimensions.length - 1)) {
066: for (int i = 0; i < a_dimensions[a_currentDimension]; i++) {
067: a_flat[a_flatElement++] = getNoExceptions(a_shaped, i);
068: }
069: } else {
070: for (int i = 0; i < a_dimensions[a_currentDimension]; i++) {
071: a_flatElement = flatten(getNoExceptions(a_shaped, i),
072: a_dimensions, a_currentDimension + 1, a_flat,
073: a_flatElement);
074: }
075: }
076: return a_flatElement;
077: }
078:
079: public Object get(Object onArray, int index) {
080: return Array.get(onArray, index);
081: }
082:
083: public ReflectClass getComponentType(ReflectClass a_class) {
084: while (a_class.isArray()) {
085: a_class = a_class.getComponentType();
086: }
087: return a_class;
088: }
089:
090: public int getLength(Object array) {
091: return Array.getLength(array);
092: }
093:
094: private final Object getNoExceptions(Object onArray, int index) {
095: try {
096: return get(onArray, index);
097: } catch (Exception e) {
098: return null;
099: }
100: }
101:
102: public boolean isNDimensional(ReflectClass a_class) {
103: return a_class.getComponentType().isArray();
104: }
105:
106: public void set(Object onArray, int index, Object element) {
107: if (element == null) {
108: try {
109: Array.set(onArray, index, element);
110: } catch (Exception e) {
111: // This can happen on primitive arrays
112: // and we are fine with ignoring it.
113: // TODO: check if it's a primitive array first and don't ignore exceptions
114: }
115:
116: } else {
117: Array.set(onArray, index, element);
118: }
119: }
120:
121: public int shape(Object[] a_flat, int a_flatElement,
122: Object a_shaped, int[] a_dimensions, int a_currentDimension) {
123: if (a_currentDimension == (a_dimensions.length - 1)) {
124: for (int i = 0; i < a_dimensions[a_currentDimension]; i++) {
125: set(a_shaped, i, a_flat[a_flatElement++]);
126: }
127: } else {
128: for (int i = 0; i < a_dimensions[a_currentDimension]; i++) {
129: a_flatElement = shape(a_flat, a_flatElement, get(
130: a_shaped, i), a_dimensions,
131: a_currentDimension + 1);
132: }
133: }
134: return a_flatElement;
135: }
136:
137: }
|