/*
* Copyright 2009-2016 Tilmann Zaeschke. All rights reserved.
*
* This file is part of ZooDB.
*
* ZooDB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ZooDB 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 ZooDB. If not, see <http://www.gnu.org/licenses/>.
*
* See the README and COPYING files for further information.
*/
package org.zoodb.tools.internal;
import java.util.IdentityHashMap;
import org.zoodb.api.impl.ZooPC;
import org.zoodb.internal.GenericObject;
import org.zoodb.internal.Session;
import org.zoodb.internal.ZooClassDef;
import org.zoodb.internal.ZooClassProxy;
import org.zoodb.internal.ZooHandleImpl;
import org.zoodb.internal.util.ClassCreator;
import org.zoodb.internal.util.PrimLongMapLI;
import org.zoodb.jdo.spi.PersistenceCapableImpl;
import org.zoodb.schema.ZooClass;
public class ObjectCache {
private final Session session;
private final IdentityHashMap<Class<?>, ZooClassDef> sMapC =
new IdentityHashMap<Class<?>, ZooClassDef>();
private final PrimLongMapLI<ZooClassDef> sMapI = new PrimLongMapLI<ZooClassDef>();
private final PrimLongMapLI<GOProxy> goMap = new PrimLongMapLI<GOProxy>();
private final PrimLongMapLI<Class<?>> goClsMap = new PrimLongMapLI<Class<?>>();
public ObjectCache(Session session) {
this.session = session;
}
public ZooClassDef getSchema(long clsOid) {
if (!sMapI.containsKey(clsOid)) {
throw new IllegalStateException("soid=" + clsOid);
}
return sMapI.get(clsOid);
}
public ZooClassDef getSchema(Class<?> cls) {
return sMapC.get(cls);
}
public void addSchema(long sOid, ZooClassDef schemaDef) {
sMapI.put(sOid, schemaDef);
// if (schemaDef.getJavaClass() == null) {
// throw new IllegalStateException();
// }
sMapC.put(schemaDef.getJavaClass(), schemaDef);
addGoClass(schemaDef.getVersionProxy());
}
/**
* The only reason why this class exists is that I was to lazy to create a dynamic sub-class
* of GenericObject, which would have required generating a constructor-method that passes
* the ZooClassDef argument to the ZooClassDef constructor of GenericObject.
*/
public static class GOProxy {
public GenericObject go;
public GenericObject getGenericObject() {
return go;
}
}
public GOProxy findOrCreateGo(long oid, ZooClass def) {
GOProxy gop = goMap.get(oid);
if (gop == null) {
GenericObject go;
if (session.isOidUsed(oid)) {
ZooHandleImpl hdl = session.getHandle(oid);
go = ((ZooHandleImpl)hdl).getGenericObject();
} else {
go = ((ZooHandleImpl) def.newInstance(oid)).getGenericObject();
}
Class<?> goCls = addGoClass((ZooClassProxy)def);
try {
gop = (GOProxy) goCls.newInstance();
gop.go = go;
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
goMap.put(oid, gop);
}
return gop;
}
private Class<?> addGoClass(ZooClassProxy def) {
long sOid = def.getSchemaDef().getOid();
Class<?> goCls = goClsMap.get(sOid);
if (goCls == null) {
Class<?> sup;
if (def.getSuperClass().getName().equals(PersistenceCapableImpl.class.getName()) ||
def.getSuperClass().getName().equals(ZooPC.class.getName())) {
sup = GOProxy.class;
} else {
sup = addGoClass((ZooClassProxy) def.getSuperClass());
}
goCls = ClassCreator.createClass(def.getName(), sup.getName());
goClsMap.put(sOid, goCls);
sMapC.put(goCls, def.getSchemaDef());
}
return goCls;
}
public Class<?> getGopClass(long soid) {
return goClsMap.get(soid);
}
public ZooClassDef getClass(long soid) {
return sMapI.get(soid);
}
public GOProxy findOrCreateGo(long oid, Class<?> cls) {
if (!GOProxy.class.isAssignableFrom(cls)) {
throw new IllegalStateException("" + cls.getName());
}
ZooClassDef def = sMapC.get(cls);
return findOrCreateGo(oid, def.getVersionProxy());
}
}