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.generic;
022:
023: import com.db4o.foundation.DeepClone;
024: import com.db4o.internal.*;
025: import com.db4o.reflect.ReflectClass;
026: import com.db4o.reflect.ReflectConstructor;
027: import com.db4o.reflect.ReflectField;
028: import com.db4o.reflect.ReflectMethod;
029: import com.db4o.reflect.Reflector;
030:
031: /**
032: * @exclude
033: */
034: public class GenericClass implements ReflectClass, DeepClone {
035:
036: private static final GenericField[] NO_FIELDS = new GenericField[0];
037:
038: private final GenericReflector _reflector;
039: private final ReflectClass _delegate;
040:
041: private final String _name;
042: private GenericClass _super class;
043:
044: private GenericClass _array;
045:
046: private boolean _isSecondClass;
047: private boolean _isPrimitive;
048:
049: private int _isCollection;
050:
051: private GenericConverter _converter;
052:
053: private GenericField[] _fields = NO_FIELDS;
054:
055: private int _declaredFieldCount = -1;
056: private int _fieldCount = -1;
057:
058: private final int _hashCode;
059:
060: public GenericClass(GenericReflector reflector,
061: ReflectClass delegateClass, String name,
062: GenericClass super class) {
063: _reflector = reflector;
064: _delegate = delegateClass;
065: _name = name;
066: _super class = super class;
067: _hashCode = _name.hashCode();
068: }
069:
070: public GenericClass arrayClass() {
071: if (_array != null) {
072: return _array;
073: }
074: _array = new GenericArrayClass(_reflector, this , _name,
075: _super class);
076: _array._isSecondClass = _isSecondClass;
077: return _array;
078: }
079:
080: public Object deepClone(Object obj) {
081: GenericReflector reflector = (GenericReflector) obj;
082: GenericClass super Class = null;
083: if (_super class != null) {
084: _super class = (GenericClass) reflector.forName(_super class
085: .getName());
086: }
087: GenericClass ret = new GenericClass(reflector, _delegate,
088: _name, super Class);
089: ret._isSecondClass = _isSecondClass;
090: GenericField[] fields = new GenericField[_fields.length];
091: for (int i = 0; i < fields.length; i++) {
092: fields[i] = (GenericField) _fields[i].deepClone(reflector);
093: }
094: ret.initFields(fields);
095: return ret;
096: }
097:
098: public boolean equals(Object obj) {
099: if (obj == null) {
100: return false;
101: }
102: if (this == obj) {
103: return true;
104: }
105: if (!(obj instanceof GenericClass)) {
106: return false;
107: }
108: GenericClass otherGC = (GenericClass) obj;
109: if (_hashCode != otherGC.hashCode()) {
110: return false;
111: }
112: return _name.equals(otherGC._name);
113: }
114:
115: public ReflectClass getComponentType() {
116: if (_delegate != null) {
117: return _delegate.getComponentType();
118: }
119: return null;
120: }
121:
122: public ReflectConstructor[] getDeclaredConstructors() {
123: if (_delegate != null) {
124: return _delegate.getDeclaredConstructors();
125: }
126: return null;
127: }
128:
129: // TODO: consider that classes may have two fields of
130: // the same name after refactoring.
131:
132: public ReflectField getDeclaredField(String name) {
133: if (_delegate != null) {
134: return _delegate.getDeclaredField(name);
135: }
136: for (int i = 0; i < _fields.length; i++) {
137: if (_fields[i].getName().equals(name)) {
138: return _fields[i];
139: }
140: }
141: return null;
142: }
143:
144: public ReflectField[] getDeclaredFields() {
145: if (_delegate != null) {
146: return _delegate.getDeclaredFields();
147: }
148: return _fields;
149: }
150:
151: public ReflectClass getDelegate() {
152: if (_delegate != null) {
153: return _delegate;
154: }
155: return this ;
156: }
157:
158: int getFieldCount() {
159: if (_fieldCount != -1) {
160: return _fieldCount;
161: }
162: _fieldCount = 0;
163: if (_super class != null) {
164: _fieldCount = _super class.getFieldCount();
165: }
166: if (_declaredFieldCount == -1) {
167: _declaredFieldCount = getDeclaredFields().length;
168: }
169: _fieldCount += _declaredFieldCount;
170: return _fieldCount;
171: }
172:
173: public ReflectMethod getMethod(String methodName,
174: ReflectClass[] paramClasses) {
175: if (_delegate != null) {
176: return _delegate.getMethod(methodName, paramClasses);
177: }
178: return null;
179: }
180:
181: public String getName() {
182: return _name;
183: }
184:
185: public ReflectClass getSuperclass() {
186: if (_super class != null) {
187: return _super class;
188: }
189: if (_delegate == null) {
190: return _reflector.forClass(Object.class);
191: }
192: ReflectClass delegateSuperclass = _delegate.getSuperclass();
193: if (delegateSuperclass != null) {
194: _super class = _reflector.ensureDelegate(delegateSuperclass);
195: }
196: return _super class;
197: }
198:
199: public int hashCode() {
200: return _hashCode;
201: }
202:
203: public void initFields(GenericField[] fields) {
204: int startIndex = 0;
205: if (_super class != null) {
206: startIndex = _super class.getFieldCount();
207: }
208: _fields = fields;
209: for (int i = 0; i < _fields.length; i++) {
210: _fields[i].setIndex(startIndex + i);
211: }
212: }
213:
214: // TODO: Consider: Will this method still be necessary
215: // once constructor logic is pushed into the reflectors?
216: public boolean isAbstract() {
217: if (_delegate != null) {
218: return _delegate.isAbstract();
219: }
220: return false;
221: }
222:
223: public boolean isArray() {
224: if (_delegate != null) {
225: return _delegate.isArray();
226: }
227: return false;
228: }
229:
230: public boolean isAssignableFrom(ReflectClass subclassCandidate) {
231: if (subclassCandidate == null) {
232: return false;
233: }
234: if (equals(subclassCandidate)) {
235: return true;
236: }
237: if (_delegate != null) {
238: if (subclassCandidate instanceof GenericClass) {
239: subclassCandidate = ((GenericClass) subclassCandidate)
240: .getDelegate();
241: }
242: return _delegate.isAssignableFrom(subclassCandidate);
243: }
244: if (!(subclassCandidate instanceof GenericClass)) {
245: return false;
246: }
247: return isAssignableFrom(subclassCandidate.getSuperclass());
248: }
249:
250: public boolean isCollection() {
251: if (_isCollection == 1) {
252: return true;
253: }
254: if (_isCollection == -1) {
255: return false;
256: }
257: _isCollection = _reflector.isCollection(this ) ? 1 : -1;
258: return isCollection();
259: }
260:
261: public boolean isInstance(Object candidate) {
262: if (_delegate != null) {
263: return _delegate.isInstance(candidate);
264: }
265: if (!(candidate instanceof GenericObject)) {
266: return false;
267: }
268: return isAssignableFrom(((GenericObject) candidate)._class);
269: }
270:
271: public boolean isInterface() {
272: if (_delegate != null) {
273: return _delegate.isInterface();
274: }
275: return false;
276: }
277:
278: public boolean isPrimitive() {
279: if (_delegate != null) {
280: return _delegate.isPrimitive();
281: }
282: return _isPrimitive;
283: }
284:
285: public boolean isSecondClass() {
286: if (isPrimitive()) {
287: return true;
288: }
289: return _isSecondClass;
290: }
291:
292: public Object newInstance() {
293: if (_delegate != null) {
294: return _delegate.newInstance();
295: }
296: return new GenericObject(this );
297: }
298:
299: public Reflector reflector() {
300: if (_delegate != null) {
301: return _delegate.reflector();
302: }
303: return _reflector;
304: }
305:
306: void setConverter(GenericConverter converter) {
307: _converter = converter;
308: }
309:
310: void setDeclaredFieldCount(int count) {
311: _declaredFieldCount = count;
312: }
313:
314: void setPrimitive() {
315: _isPrimitive = true;
316: }
317:
318: void setSecondClass() {
319: _isSecondClass = true;
320: }
321:
322: public boolean skipConstructor(boolean flag, boolean testConstructor) {
323: if (_delegate != null) {
324: return _delegate.skipConstructor(flag, testConstructor);
325: }
326: return false;
327: }
328:
329: public String toString() {
330: return "GenericClass " + _name;
331: }
332:
333: public String toString(GenericObject obj) {
334: if (_converter == null) {
335: return "(G) " + getName();
336: }
337: return _converter.toString(obj);
338: }
339:
340: public void useConstructor(ReflectConstructor constructor,
341: Object[] params) {
342: if (_delegate != null) {
343: _delegate.useConstructor(constructor, params);
344: }
345:
346: // ignore, we always create a generic object
347: }
348:
349: public Object[] toArray(Object obj) {
350: if (!isCollection()) {
351: return new Object[] { obj };
352: }
353: return Platform4.collectionToArray(_reflector.getStream(), obj);
354: }
355:
356: }
|