/* This file is part of the db4o object database http://www.db4o.com
Copyright (C) 2004 - 2011 Versant Corporation http://www.versant.com
db4o is free software; you can redistribute it and/or modify it under
the terms of version 3 of the GNU General Public License as published
by the Free Software Foundation.
db4o is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with this program. If not, see http://www.gnu.org/licenses/. */
package com.db4o.internal;
import com.db4o.config.*;
import com.db4o.internal.marshall.*;
import com.db4o.reflect.*;
import com.db4o.typehandlers.*;
public final class TranslatedAspect extends FieldMetadata {
private ObjectTranslator _translator;
public TranslatedAspect(ClassMetadata containingClass, String name){
this(containingClass);
init(name);
}
public TranslatedAspect(ClassMetadata containingClass, ObjectTranslator translator) {
this(containingClass);
initializeTranslator(translator);
}
private TranslatedAspect(ClassMetadata containingClass) {
super(containingClass);
setAvailable();
}
public void initializeTranslator(ObjectTranslator translator) {
_translator = translator;
initializeFieldName();
initializeFieldType();
}
public boolean alive() {
return true;
}
private void initializeFieldName() {
init(fieldNameFor(_translator));
}
private void initializeFieldType() {
ObjectContainerBase stream = containingClass().container();
ReflectClass storedClass = stream.reflector().forClass(translatorStoredClass(_translator));
configure(storedClass, false);
ReflectClass baseType = Handlers4.baseType(storedClass);
stream.showInternalClasses(true);
try {
_fieldType = stream.produceClassMetadata(baseType);
} finally {
stream.showInternalClasses(false);
}
if (null == _fieldType) {
throw new IllegalStateException("Cannot produce class metadata for " + baseType + "!");
}
}
public static String fieldNameFor(ObjectTranslator translator) {
return translator.getClass().getName();
}
public boolean canUseNullBitmap(){
return false;
}
@Override
public void deactivate(ActivationContext context){
if(context.depth().requiresActivation()){
cascadeActivation(context);
}
setOn(context.transaction(), context.targetObject(), null);
}
public Object getOn(Transaction a_trans, Object a_OnObject) {
try {
return _translator.onStore(a_trans.objectContainer(), a_OnObject);
} catch(ReflectException e) {
throw e;
} catch (RuntimeException e) {
throw new ReflectException(e);
}
}
public Object getOrCreate(Transaction a_trans, Object a_OnObject) {
return getOn(a_trans, a_OnObject);
}
public void activate(UnmarshallingContext context) {
Object obj = read(context);
// Activation of members is necessary on purpose here.
// Classes like Hashtable need fully activated members
// to be able to calculate hashCode()
if (obj != null) {
context.container().activate(context.transaction(), obj, context.activationDepth());
}
setOn(context.transaction(), context.persistentObject(), obj);
}
void refresh() {
// do nothing
}
private void setOn(Transaction trans, Object a_onObject, Object toSet) {
try {
_translator.onActivate(trans.objectContainer(), a_onObject, toSet);
} catch (RuntimeException e) {
throw new ReflectException(e);
}
}
protected Object indexEntryFor(Object indexEntry) {
return indexEntry;
}
protected Indexable4 indexHandler(ObjectContainerBase stream) {
return (Indexable4)getHandler();
}
public boolean equals(Object obj) {
if(obj == this){
return true;
}
if(obj == null || obj.getClass() != getClass()){
return false;
}
TranslatedAspect other = (TranslatedAspect) obj;
return _translator.equals(other._translator);
}
public int hashCode() {
return _translator.hashCode();
}
public AspectType aspectType() {
return AspectType.TRANSLATOR;
}
public boolean isObjectConstructor() {
return _translator instanceof ObjectConstructor;
}
public Object construct(ObjectReferenceContext context) {
ContextState contextState = context.saveState();
boolean fieldHasValue = containingClass().seekToField(context, this);
try {
return ((ObjectConstructor)_translator).onInstantiate(
context.container(),
fieldHasValue ? read(context) : null);
} finally {
context.restoreState(contextState);
}
}
}