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.Rename;
024: import com.db4o.config.*;
025: import com.db4o.ext.Db4oException;
026: import com.db4o.foundation.DeepClone;
027: import com.db4o.foundation.Hashtable4;
028: import com.db4o.foundation.KeySpec;
029: import com.db4o.foundation.KeySpecHashtable4;
030: import com.db4o.foundation.TernaryBool;
031: import com.db4o.reflect.ReflectClass;
032:
033: /**
034: * @exclude
035: */
036: public class Config4Class extends Config4Abstract implements
037: ObjectClass, DeepClone {
038:
039: private final Config4Impl _configImpl;
040:
041: private final static KeySpec CALL_CONSTRUCTOR = new KeySpec(
042: TernaryBool.UNSPECIFIED);
043:
044: private final static KeySpec CLASS_INDEXED = new KeySpec(true);
045:
046: private final static KeySpec EXCEPTIONAL_FIELDS = new KeySpec(null);
047:
048: private final static KeySpec GENERATE_UUIDS = new KeySpec(false);
049:
050: private final static KeySpec GENERATE_VERSION_NUMBERS = new KeySpec(
051: false);
052:
053: /**
054: * We are running into cyclic dependancies on reading the PBootRecord
055: * object, if we maintain MetaClass information there
056: */
057: private final static KeySpec MAINTAIN_METACLASS = new KeySpec(true);
058:
059: private final static KeySpec MAXIMUM_ACTIVATION_DEPTH = new KeySpec(
060: 0);
061:
062: private final static KeySpec MINIMUM_ACTIVATION_DEPTH = new KeySpec(
063: 0);
064:
065: private final static KeySpec PERSIST_STATIC_FIELD_VALUES = new KeySpec(
066: false);
067:
068: private final static KeySpec QUERY_ATTRIBUTE_PROVIDER = new KeySpec(
069: null);
070:
071: private final static KeySpec STORE_TRANSIENT_FIELDS = new KeySpec(
072: false);
073:
074: private final static KeySpec TRANSLATOR = new KeySpec(null);
075:
076: private final static KeySpec TRANSLATOR_NAME = new KeySpec(
077: (String) null);
078:
079: private final static KeySpec UPDATE_DEPTH = new KeySpec(0);
080:
081: private final static KeySpec WRITE_AS = new KeySpec((String) null);
082:
083: protected Config4Class(Config4Impl configuration,
084: KeySpecHashtable4 config) {
085: super (config);
086: _configImpl = configuration;
087: }
088:
089: Config4Class(Config4Impl a_configuration, String a_name) {
090: _configImpl = a_configuration;
091: setName(a_name);
092: }
093:
094: public int adjustActivationDepth(int depth) {
095: TernaryBool cascadeOnActivate = cascadeOnActivate();
096: if (cascadeOnActivate.definiteYes() && depth < 2) {
097: depth = 2;
098: }
099: if (cascadeOnActivate.definiteNo() && depth > 1) {
100: depth = 1;
101: }
102: if (config().classActivationDepthConfigurable()) {
103: int minimumActivationDepth = minimumActivationDepth();
104: if (minimumActivationDepth != 0
105: && depth < minimumActivationDepth) {
106: depth = minimumActivationDepth;
107: }
108: int maximumActivationDepth = maximumActivationDepth();
109: if (maximumActivationDepth != 0
110: && depth > maximumActivationDepth) {
111: depth = maximumActivationDepth;
112: }
113: }
114: return depth;
115: }
116:
117: public void callConstructor(boolean flag) {
118: putThreeValued(CALL_CONSTRUCTOR, flag);
119: }
120:
121: String className() {
122: return getName();
123: }
124:
125: ReflectClass classReflector() {
126: return config().reflector().forName(getName());
127: }
128:
129: public void compare(ObjectAttribute comparator) {
130: _config.put(QUERY_ATTRIBUTE_PROVIDER, comparator);
131: }
132:
133: Config4Field configField(String fieldName) {
134: Hashtable4 exceptionalFields = exceptionalFieldsOrNull();
135: if (exceptionalFields == null) {
136: return null;
137: }
138: return (Config4Field) exceptionalFields.get(fieldName);
139: }
140:
141: public Object deepClone(Object param) {
142: return new Config4Class((Config4Impl) param, _config);
143: }
144:
145: public void enableReplication(boolean setting) {
146: generateUUIDs(setting);
147: generateVersionNumbers(setting);
148: }
149:
150: public void generateUUIDs(boolean setting) {
151: _config.put(GENERATE_UUIDS, setting);
152: }
153:
154: public void generateVersionNumbers(boolean setting) {
155: _config.put(GENERATE_VERSION_NUMBERS, setting);
156: }
157:
158: public ObjectTranslator getTranslator() {
159: ObjectTranslator translator = (ObjectTranslator) _config
160: .get(TRANSLATOR);
161: if (translator != null) {
162: return translator;
163: }
164:
165: String translatorName = _config.getAsString(TRANSLATOR_NAME);
166: if (translatorName == null) {
167: return null;
168: }
169: try {
170: translator = newTranslatorFromReflector(translatorName);
171: } catch (RuntimeException t) {
172: try {
173: translator = newTranslatorFromPlatform(translatorName);
174: } catch (Exception e) {
175: throw new Db4oException(e);
176: }
177: }
178: translate(translator);
179: return translator;
180: }
181:
182: private ObjectTranslator newTranslatorFromPlatform(
183: String translatorName) throws InstantiationException,
184: IllegalAccessException {
185: return (ObjectTranslator) ReflectPlatform.forName(
186: translatorName).newInstance();
187: }
188:
189: private ObjectTranslator newTranslatorFromReflector(
190: String translatorName) {
191: return (ObjectTranslator) config().reflector().forName(
192: translatorName).newInstance();
193: }
194:
195: public void indexed(boolean flag) {
196: _config.put(CLASS_INDEXED, flag);
197: }
198:
199: public boolean indexed() {
200: return _config.getAsBoolean(CLASS_INDEXED);
201: }
202:
203: Object instantiate(ObjectContainerBase a_stream,
204: Object a_toTranslate) {
205: return ((ObjectConstructor) _config.get(TRANSLATOR))
206: .onInstantiate((InternalObjectContainer) a_stream,
207: a_toTranslate);
208: }
209:
210: boolean instantiates() {
211: return getTranslator() instanceof ObjectConstructor;
212: }
213:
214: public void maximumActivationDepth(int depth) {
215: _config.put(MAXIMUM_ACTIVATION_DEPTH, depth);
216: }
217:
218: int maximumActivationDepth() {
219: return _config.getAsInt(MAXIMUM_ACTIVATION_DEPTH);
220: }
221:
222: public void minimumActivationDepth(int depth) {
223: _config.put(MINIMUM_ACTIVATION_DEPTH, depth);
224: }
225:
226: public int minimumActivationDepth() {
227: return _config.getAsInt(MINIMUM_ACTIVATION_DEPTH);
228: }
229:
230: public TernaryBool callConstructor() {
231: if (_config.get(TRANSLATOR) != null) {
232: return TernaryBool.YES;
233: }
234: return _config.getAsTernaryBool(CALL_CONSTRUCTOR);
235: }
236:
237: private Hashtable4 exceptionalFieldsOrNull() {
238: return (Hashtable4) _config.get(EXCEPTIONAL_FIELDS);
239:
240: }
241:
242: private Hashtable4 exceptionalFields() {
243: Hashtable4 exceptionalFieldsCollection = exceptionalFieldsOrNull();
244: if (exceptionalFieldsCollection == null) {
245: exceptionalFieldsCollection = new Hashtable4(16);
246: _config
247: .put(EXCEPTIONAL_FIELDS,
248: exceptionalFieldsCollection);
249: }
250: return exceptionalFieldsCollection;
251: }
252:
253: public ObjectField objectField(String fieldName) {
254: Hashtable4 exceptionalFieldsCollection = exceptionalFields();
255: Config4Field c4f = (Config4Field) exceptionalFieldsCollection
256: .get(fieldName);
257: if (c4f == null) {
258: c4f = new Config4Field(this , fieldName);
259: exceptionalFieldsCollection.put(fieldName, c4f);
260: }
261: return c4f;
262: }
263:
264: public void persistStaticFieldValues() {
265: _config.put(PERSIST_STATIC_FIELD_VALUES, true);
266: }
267:
268: boolean queryEvaluation(String fieldName) {
269: Hashtable4 exceptionalFields = exceptionalFieldsOrNull();
270: if (exceptionalFields != null) {
271: Config4Field field = (Config4Field) exceptionalFields
272: .get(fieldName);
273: if (field != null) {
274: return field.queryEvaluation();
275: }
276: }
277: return true;
278: }
279:
280: public void readAs(Object clazz) {
281: Config4Impl configRef = config();
282: ReflectClass claxx = configRef.reflectorFor(clazz);
283: if (claxx == null) {
284: return;
285: }
286: _config.put(WRITE_AS, getName());
287: configRef.readAs().put(getName(), claxx.getName());
288: }
289:
290: public void rename(String newName) {
291: config().rename(new Rename("", getName(), newName));
292: setName(newName);
293: }
294:
295: public void storeTransientFields(boolean flag) {
296: _config.put(STORE_TRANSIENT_FIELDS, flag);
297: }
298:
299: public void translate(ObjectTranslator translator) {
300: if (translator == null) {
301: _config.put(TRANSLATOR_NAME, null);
302: }
303: _config.put(TRANSLATOR, translator);
304: }
305:
306: void translateOnDemand(String a_translatorName) {
307: _config.put(TRANSLATOR_NAME, a_translatorName);
308: }
309:
310: public void updateDepth(int depth) {
311: _config.put(UPDATE_DEPTH, depth);
312: }
313:
314: Config4Impl config() {
315: return _configImpl;
316: }
317:
318: boolean generateUUIDs() {
319: return _config.getAsBoolean(GENERATE_UUIDS);
320: }
321:
322: boolean generateVersionNumbers() {
323: return _config.getAsBoolean(GENERATE_VERSION_NUMBERS);
324: }
325:
326: void maintainMetaClass(boolean flag) {
327: _config.put(MAINTAIN_METACLASS, flag);
328: }
329:
330: boolean staticFieldValuesArePersisted() {
331: return _config.getAsBoolean(PERSIST_STATIC_FIELD_VALUES);
332: }
333:
334: public ObjectAttribute queryAttributeProvider() {
335: return (ObjectAttribute) _config.get(QUERY_ATTRIBUTE_PROVIDER);
336: }
337:
338: boolean storeTransientFields() {
339: return _config.getAsBoolean(STORE_TRANSIENT_FIELDS);
340: }
341:
342: int updateDepth() {
343: return _config.getAsInt(UPDATE_DEPTH);
344: }
345:
346: String writeAs() {
347: return _config.getAsString(WRITE_AS);
348: }
349:
350: }
|