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.foundation.Visitor4;
024: import com.db4o.internal.marshall.*;
025: import com.db4o.internal.query.processor.QConObject;
026: import com.db4o.internal.replication.*;
027: import com.db4o.internal.slots.Slot;
028: import com.db4o.marshall.*;
029: import com.db4o.reflect.*;
030:
031: /**
032: * TODO: refactor for symmetric inheritance - don't inherit from YapField and override,
033: * instead extract an abstract superclass from YapField and let both YapField and this class implement
034: *
035: * @exclude
036: */
037: public abstract class VirtualFieldMetadata extends FieldMetadata {
038:
039: private static final Object ANY_OBJECT = new Object();
040:
041: private final ReflectClass _classReflector;
042:
043: VirtualFieldMetadata(int handlerID, BuiltinTypeHandler handler) {
044: super (handlerID, handler);
045: _classReflector = handler.classReflector();
046: }
047:
048: public abstract void addFieldIndex(MarshallerFamily mf,
049: ClassMetadata yapClass, StatefulBuffer a_writer,
050: Slot oldSlot) throws FieldIndexException;
051:
052: public boolean alive() {
053: return true;
054: }
055:
056: boolean canAddToQuery(String fieldName) {
057: return fieldName.equals(getName());
058: }
059:
060: public boolean canUseNullBitmap() {
061: return false;
062: }
063:
064: public ReflectClass classReflector() {
065: return _classReflector;
066: }
067:
068: void collectConstraints(Transaction a_trans, QConObject a_parent,
069: Object a_template, Visitor4 a_visitor) {
070:
071: // QBE constraint collection call
072: // There isn't anything useful to do here, since virtual fields
073: // are not on the actual object.
074:
075: }
076:
077: void deactivate(Transaction a_trans, Object a_onObject, int a_depth) {
078: // do nothing
079: }
080:
081: public abstract void delete(MarshallerFamily mf,
082: StatefulBuffer a_bytes, boolean isUpdate);
083:
084: public Object getOrCreate(Transaction a_trans, Object a_OnObject) {
085: // This is the first part of marshalling
086: // Virtual fields do it all in #marshall(), the object is never used.
087: // Returning any object here prevents triggering null handling.
088: return ANY_OBJECT;
089: }
090:
091: public boolean needsArrayAndPrimitiveInfo() {
092: return false;
093: }
094:
095: public boolean needsHandlerId() {
096: return false;
097: }
098:
099: public void instantiate(UnmarshallingContext context) {
100: context.reference().produceVirtualAttributes();
101: instantiate1(context.transaction(), context.reference(),
102: context.buffer());
103: }
104:
105: abstract void instantiate1(Transaction a_trans,
106: ObjectReference a_yapObject, Buffer a_bytes);
107:
108: public void loadHandler(ObjectContainerBase a_stream) {
109: // do nothing
110: }
111:
112: public void marshall(MarshallingContext context, Object obj) {
113: context.doNotIndirectWrites();
114: marshall(context.transaction(), context.reference(), context,
115: context.isNew());
116: }
117:
118: private final void marshall(Transaction trans, ObjectReference ref,
119: WriteBuffer buffer, boolean isNew) {
120:
121: if (!trans.supportsVirtualFields()) {
122: marshallIgnore(buffer);
123: return;
124: }
125:
126: ObjectContainerBase stream = trans.container();
127: HandlerRegistry handlers = stream._handlers;
128: boolean migrating = false;
129:
130: if (stream._replicationCallState != Const4.NONE) {
131: if (stream._replicationCallState == Const4.OLD) {
132:
133: // old replication code
134:
135: migrating = true;
136: if (ref.virtualAttributes() == null) {
137: Object obj = ref.getObject();
138: ObjectReference migratingRef = null;
139: MigrationConnection mgc = handlers.i_migration;
140: if (mgc != null) {
141: migratingRef = mgc.referenceFor(obj);
142: if (migratingRef == null) {
143: ObjectContainerBase peer = mgc.peer(stream);
144: migratingRef = peer.transaction()
145: .referenceForObject(obj);
146: }
147: }
148: if (migratingRef != null) {
149: VirtualAttributes migrateAttributes = migratingRef
150: .virtualAttributes();
151: if (migrateAttributes != null
152: && migrateAttributes.i_database != null) {
153: migrating = true;
154: ref
155: .setVirtualAttributes((VirtualAttributes) migrateAttributes
156: .shallowClone());
157: migrateAttributes.i_database.bind(trans);
158: }
159: }
160: }
161: } else {
162:
163: // new dRS replication
164:
165: Db4oReplicationReferenceProvider provider = handlers._replicationReferenceProvider;
166: Object parentObject = ref.getObject();
167: Db4oReplicationReference replicationReference = provider
168: .referenceFor(parentObject);
169: if (replicationReference != null) {
170: migrating = true;
171: VirtualAttributes va = ref
172: .produceVirtualAttributes();
173: va.i_version = replicationReference.version();
174: va.i_uuid = replicationReference.longPart();
175: va.i_database = replicationReference
176: .signaturePart();
177: }
178: }
179: }
180:
181: if (ref.virtualAttributes() == null) {
182: ref.produceVirtualAttributes();
183: migrating = false;
184: }
185: marshall(trans, ref, buffer, migrating, isNew);
186: }
187:
188: abstract void marshall(Transaction trans, ObjectReference ref,
189: WriteBuffer buffer, boolean migrating, boolean isNew);
190:
191: abstract void marshallIgnore(WriteBuffer writer);
192:
193: public void readVirtualAttribute(Transaction trans, Buffer buffer,
194: ObjectReference ref) {
195: if (!trans.supportsVirtualFields()) {
196: incrementOffset(buffer);
197: return;
198: }
199: instantiate1(trans, ref, buffer);
200: }
201:
202: public boolean isVirtual() {
203: return true;
204: }
205:
206: protected Object indexEntryFor(Object indexEntry) {
207: return indexEntry;
208: }
209:
210: protected Indexable4 indexHandler(ObjectContainerBase stream) {
211: return (Indexable4) _handler;
212: }
213: }
|