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.internal;
022:
023: import com.db4o.*;
024: import com.db4o.foundation.*;
025: import com.db4o.internal.handlers.*;
026: import com.db4o.internal.marshall.*;
027: import com.db4o.marshall.*;
028: import com.db4o.reflect.*;
029:
030: /**
031: * @exclude
032: */
033: public class PrimitiveFieldHandler extends ClassMetadata {
034:
035: private final TypeHandler4 _handler;
036:
037: PrimitiveFieldHandler(ObjectContainerBase container,
038: TypeHandler4 handler, int handlerID,
039: ReflectClass classReflector) {
040: super (container, classReflector);
041: i_fields = FieldMetadata.EMPTY_ARRAY;
042: _handler = handler;
043: _id = handlerID;
044: }
045:
046: void activateFields(Transaction trans, Object obj, int depth) {
047: // Override
048: // do nothing
049: }
050:
051: final void addToIndex(LocalObjectContainer container,
052: Transaction trans, int id) {
053: // Override
054: // Primitive Indices will be created later.
055: }
056:
057: boolean allowsQueries() {
058: return false;
059: }
060:
061: void cacheDirty(Collection4 col) {
062: // do nothing
063: }
064:
065: public void deleteEmbedded(MarshallerFamily mf,
066: StatefulBuffer a_bytes) throws Db4oIOException {
067: if (mf._primitive.useNormalClassRead()) {
068: super .deleteEmbedded(mf, a_bytes);
069: return;
070: }
071:
072: // Do nothing here, we should be in the payload area
073: // no action to be taken.
074: }
075:
076: public void deleteEmbedded1(MarshallerFamily mf,
077: StatefulBuffer a_bytes, int a_id) throws Db4oIOException {
078:
079: if (_handler instanceof ArrayHandler) {
080: ArrayHandler ya = (ArrayHandler) _handler;
081:
082: // TODO: the following checks, whether the array stores
083: // primitives. There is one case that is not covered here:
084: // If a primitive array is stored to an untyped array or
085: // to an Object variable, they would need to be deleted
086: // and freed also. However, if they are untyped, every
087: // single one would have to be read an checked and this
088: // would be extremely slow.
089:
090: // Solution: Store information, whether an object is
091: // primitive in our pointers, in the highest bit of the
092: // length int.
093:
094: if (ya._usePrimitiveClassReflector) {
095: ya.deletePrimitiveEmbedded(a_bytes, this );
096: a_bytes.slotDelete();
097: return;
098: }
099: }
100:
101: if (_handler instanceof UntypedFieldHandler) {
102: // Any-In-Any: Ignore delete
103: a_bytes.incrementOffset(linkLength());
104: } else {
105: _handler.deleteEmbedded(mf, a_bytes);
106: }
107:
108: // TODO: Was this freeing call necessary?
109: // free(a_bytes.getTransaction(), a_id, a_bytes.getAddress(), a_bytes.getLength());
110:
111: free(a_bytes, a_id);
112:
113: }
114:
115: void deleteMembers(MarshallerFamily mf,
116: ObjectHeaderAttributes attributes, StatefulBuffer a_bytes,
117: int a_type, boolean isUpdate) {
118: if (a_type == Const4.TYPE_ARRAY) {
119: new ArrayHandler(a_bytes.getStream(), this , true)
120: .deletePrimitiveEmbedded(a_bytes, this );
121: } else if (a_type == Const4.TYPE_NARRAY) {
122: new MultidimensionalArrayHandler(a_bytes.getStream(), this ,
123: true).deletePrimitiveEmbedded(a_bytes, this );
124: }
125: }
126:
127: final void free(StatefulBuffer a_bytes, int a_id) {
128: a_bytes.getTransaction().slotFreePointerOnCommit(a_id,
129: a_bytes.slot());
130: }
131:
132: public boolean hasClassIndex() {
133: return false;
134: }
135:
136: public Object instantiate(UnmarshallingContext context) {
137: Object obj = context.persistentObject();
138: if (obj == null) {
139: obj = context.read(_handler);
140: context.setObjectWeak(obj);
141: }
142: context.setStateClean();
143: return obj;
144: }
145:
146: public Object instantiateTransient(UnmarshallingContext context) {
147: return _handler.read(context);
148: }
149:
150: void instantiateFields(UnmarshallingContext context) {
151: Object obj = context.read(_handler);
152: if (obj != null && (_handler instanceof DateHandler)) {
153: final Object existing = context.persistentObject();
154: context.persistentObject(dateHandler().copyValue(obj,
155: existing));
156: }
157: }
158:
159: private DateHandler dateHandler() {
160: return ((DateHandler) _handler);
161: }
162:
163: public boolean isArray() {
164: return _id == Handlers4.ANY_ARRAY_ID
165: || _id == Handlers4.ANY_ARRAY_N_ID;
166: }
167:
168: public boolean isPrimitive() {
169: return true;
170: }
171:
172: public boolean isStrongTyped() {
173: return false;
174: }
175:
176: public Comparable4 prepareComparison(Object a_constraint) {
177: _handler.prepareComparison(a_constraint);
178: return _handler;
179: }
180:
181: public TypeHandler4 readArrayHandler(Transaction a_trans,
182: MarshallerFamily mf, Buffer[] a_bytes) {
183: if (isArray()) {
184: return _handler;
185: }
186: return null;
187: }
188:
189: public ObjectID readObjectID(InternalReadContext context) {
190: if (_handler instanceof ClassMetadata) {
191: return ((ClassMetadata) _handler).readObjectID(context);
192: }
193: if (_handler instanceof ArrayHandler) {
194: // TODO: Here we should theoretically read through the array and collect candidates.
195: // The respective construct is wild: "Contains query through an array in an array."
196: // Ignore for now.
197: return ObjectID.IGNORE;
198: }
199: return ObjectID.NOT_POSSIBLE;
200: }
201:
202: void removeFromIndex(Transaction ta, int id) {
203: // do nothing
204: }
205:
206: public final boolean writeObjectBegin() {
207: return false;
208: }
209:
210: public String toString() {
211: return "Wraps " + _handler.toString() + " in YapClassPrimitive";
212: }
213:
214: public void defrag(MarshallerFamily mf, BufferPair readers,
215: boolean redirect) {
216: if (mf._primitive.useNormalClassRead()) {
217: super .defrag(mf, readers, redirect);
218: } else {
219: _handler.defrag(mf, readers, false);
220: }
221: }
222:
223: public Object wrapWithTransactionContext(Transaction transaction,
224: Object value) {
225: return value;
226: }
227:
228: public Object read(ReadContext context) {
229: return _handler.read(context);
230: }
231:
232: public void write(WriteContext context, Object obj) {
233: _handler.write(context, obj);
234: }
235:
236: public TypeHandler4 typeHandler() {
237: return _handler;
238: }
239:
240: }
|