
org.zoodb.jdo.internal.ZooClassProxy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of parent Show documentation
Show all versions of parent Show documentation
ZooDB Java JDO Object Database.
The newest version!
/*
* Copyright 2009-2013 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 .
*
* See the README and COPYING files for further information.
*/
package org.zoodb.jdo.internal;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.zoodb.api.impl.ZooPCImpl;
import org.zoodb.jdo.api.ZooClass;
import org.zoodb.jdo.api.ZooField;
import org.zoodb.jdo.api.ZooHandle;
import org.zoodb.jdo.internal.client.SchemaManager;
import org.zoodb.jdo.internal.util.ClassCreator;
import org.zoodb.jdo.internal.util.IteratorTypeAdapter;
import org.zoodb.jdo.internal.util.Util;
/**
* Internal Schema class.
*
* This should not throw any JDOxyz-exceptions, because it is not part of the JDO API.
*
* The class serves as a proxy for the latest version of a particular class in the schema version
* tree.
* The proxy's reference to the latest version is updated by SchemaOperations.
*
* @author Tilmann Zaeschke
*/
public class ZooClassProxy implements ZooClass {
private ZooClassDef def;
private final ZooClassProxy superProxy;
//TODO there should be only one proxy for all nodes, I guess...
private final SchemaManager schemaManager;
private final long schemaId;
private ArrayList subClasses = new ArrayList();
private final Session session;
public ZooClassProxy(ZooClassDef def, Session session) {
this.def = def;
this.schemaManager = session.getSchemaManager();
this.schemaId = def.getSchemaId();
this.session = session;
ZooClassDef defSuper = def.getSuperDef();
if (!def.getClassName().equals(ZooPCImpl.class.getName())) {
if (defSuper.getVersionProxy() == null) {
//super-class needs a proxy
this.superProxy = new ZooClassProxy(defSuper, session);
defSuper.associateProxy(superProxy);
} else {
//super class already has a proxy
this.superProxy = defSuper.getVersionProxy();
}
this.superProxy.subClasses.add(this);
//associate previous versions
while ((def = def.getPreviousVersion()) != null) {
def.associateProxy(this);
}
} else {
// this is the root class
superProxy = null;
}
}
@Override
public void remove() {
checkInvalid();
schemaManager.deleteSchema(this, false);
}
@Override
public void removeWithSubClasses() {
checkInvalid();
schemaManager.deleteSchema(this, true);
}
public ZooClassDef getSchemaDef() {
checkInvalid();
return def;
}
protected void checkInvalid() {
if (!session.isOpen()) {
throw new IllegalStateException("This schema belongs to a closed PersistenceManager.");
}
if (def.jdoZooIsDeleted()) {
throw new IllegalStateException("This schema object is invalid, for " +
"example because it has been deleted.");
}
//consistency check
if (def.getNextVersion() != null) {
throw new IllegalStateException();
}
}
@Override
public void createIndex(String fieldName, boolean isUnique) {
checkInvalid();
locateFieldOrFail(fieldName).createIndex(isUnique);
}
@Override
public boolean removeIndex(String fieldName) {
checkInvalid();
return locateFieldOrFail(fieldName).removeIndex();
}
@Override
public boolean hasIndex(String fieldName) {
checkInvalid();
return locateFieldOrFail(fieldName).hasIndex();
}
@Override
public boolean isIndexUnique(String fieldName) {
checkInvalid();
return locateFieldOrFail(fieldName).isIndexUnique();
}
private ZooField locateFieldOrFail(String fieldName) {
ZooField f = getField(fieldName);
if (f == null) {
throw new IllegalArgumentException("Field not found: " + fieldName);
}
return f;
}
@Override
public void dropInstances() {
checkInvalid();
schemaManager.dropInstances(this);
}
@Override
public void rename(String newName) {
checkInvalid();
schemaManager.renameSchema(def, newName);
}
@Override
public String getName() {
checkInvalid();
return def.getClassName();
}
@Override
public ZooClass getSuperClass() {
checkInvalid();
if (def.getSuperDef() == null) {
return null;
}
return def.getSuperDef().getVersionProxy();
}
@Override
public List getAllFields() {
checkInvalid();
ArrayList ret = new ArrayList();
for (ZooFieldDef fd: def.getAllFields()) {
ret.add(fd.getProxy());
}
return ret;
}
@Override
public List getLocalFields() {
checkInvalid();
ArrayList ret = new ArrayList();
for (ZooFieldDef fd: def.getAllFields()) {
if (fd.getDeclaringType() == def) {
ret.add(fd.getProxy());
}
}
return ret;
}
@Override
public ZooField defineField(String fieldName, Class> type) {
checkAddField(fieldName);
ZooFieldDef field = schemaManager.addField(def, fieldName, type);
//Update, in case it changed
def = field.getDeclaringType();
return field.getProxy();
}
@Override
public ZooField defineField(String fieldName, ZooClass type, int arrayDepth) {
checkAddField(fieldName);
ZooClassDef typeDef = ((ZooClassProxy)type).getSchemaDef();
ZooFieldDef field = schemaManager.addField(def, fieldName, typeDef, arrayDepth);
//Update, in case it changed
def = field.getDeclaringType();
return field.getProxy();
}
private void checkAddField(String fieldName) {
checkInvalid();
checkJavaFieldNameConformity(fieldName);
//check existing names
for (ZooFieldDef fd: def.getAllFields()) {
if (fd.getName().equals(fieldName)) {
throw new IllegalArgumentException("Field name already defined: " + fieldName);
}
}
}
static void checkJavaFieldNameConformity(String fieldName) {
if (fieldName == null || fieldName.length() == 0) {
throw new IllegalArgumentException("Field name invalid: '" + fieldName + "'");
}
for (int i = 0; i < fieldName.length(); i++) {
char c = fieldName.charAt(i);
if (i == 0) {
if (!Character.isJavaIdentifierStart(c)) {
throw new IllegalArgumentException("Field name invalid: " + fieldName);
}
} else {
if (!Character.isJavaIdentifierPart(c)) {
throw new IllegalArgumentException("Field name invalid: " + fieldName);
}
}
}
}
@Override
public String toString() {
checkInvalid();
return "Class schema(" + Util.getOidAsString(def) + "): " + def.getClassName();
}
@Override
public Class> getJavaClass() {
Class> cls = def.getJavaClass();
if (cls == null) {
try {
cls = Class.forName(def.getClassName());
} catch (ClassNotFoundException e) {
cls = ClassCreator.createClass(
def.getClassName(), def.getSuperDef().getClassName());
//throw new JDOUserException("Class not found: " + className, e);
}
}
return cls;
}
@Override
public ZooField getField(String fieldName) {
checkInvalid();
for (ZooFieldDef f: def.getAllFields()) {
if (f.getName().equals(fieldName)) {
return f.getProxy();
}
}
return null;
}
@Override
public void removeField(String fieldName) {
checkInvalid();
ZooField f = getField(fieldName);
if (f == null) {
throw new IllegalStateException(
"Field not found: " + def.getClassName() + "." + fieldName);
}
removeField(f);
}
@Override
public void removeField(ZooField field) {
checkInvalid();
ZooFieldDef fieldDef = ((ZooFieldProxy)field).getFieldDef();
def = schemaManager.removeField(fieldDef);
}
public void newVersionRollback(ZooClassDef newDef) {
if (def.getSchemaId() != schemaId) {
//this would indicate a bug
throw new IllegalArgumentException();
}
if (def != newDef
|| newDef.getPreviousVersion() == null
|| newDef.getNextVersion() != null) {
//this would indicate a bug
throw new IllegalStateException();
}
def = newDef.getPreviousVersion();
}
public void newVersion(ZooClassDef newDef) {
if (def.getSchemaId() != schemaId) {
//this would indicate a bug
throw new IllegalArgumentException();
}
if (def == newDef
|| newDef.getPreviousVersion() != def
|| newDef.getNextVersion() != null) {
//this would indicate a bug
throw new IllegalStateException();
}
def = newDef;
}
@Override
public List getSubClasses() {
checkInvalid();
ArrayList subs = new ArrayList();
for (ZooClassProxy sub: subClasses) {
subs.add(sub);
}
return subs;
}
@Override
public Iterator> getInstanceIterator() {
checkInvalid();
//TODO return CloseableIterator instead?
return def.jdoZooGetNode().loadAllInstances(this, true);
}
@Override
public Iterator getHandleIterator(boolean subClasses) {
checkInvalid();
//TODO return CloseableIterator instead?
return new IteratorTypeAdapter(
def.jdoZooGetNode().oidIterator(this, subClasses));
}
public ArrayList getAllVersions() {
ArrayList ret = new ArrayList();
ZooClassDef d = def;
while (d != null) {
ret.add(d);
d = d.getPreviousVersion();
}
return ret;
}
public List getSubProxies() {
return subClasses;
}
/**
*
* @return Schema ID which is independent of the schema version.
*/
public long getSchemaId() {
return schemaId;
}
/**
* Schema operation callback for removing this class definition.
*/
public void socRemoveDef() {
superProxy.subClasses.remove(this);
}
/**
* Schema operation callback for removing this class definition.
*/
public void socRemoveDefRollback() {
superProxy.subClasses.add(this);
}
@Override
public long instanceCount(boolean subClasses) {
checkInvalid();
if (def.jdoZooIsNew() && def.getSchemaVersion() == 0) {
return 0;
}
return def.jdoZooGetNode().countInstances(this, subClasses);
}
@Override
public ZooHandle newInstance() {
GenericObject go = GenericObject.newEmptyInstance(def, session.internalGetCache());
ZooHandleImpl hdl = go.getOrCreateHandle();
return hdl;
}
@Override
public ZooHandle newInstance(long oid) {
if (session.isOidUsed(oid)) {
throw new IllegalArgumentException(
"An object with this OID already exists: " + Util.oidToString(oid));
}
GenericObject go = GenericObject.newEmptyInstance(oid, def, session.internalGetCache());
ZooHandleImpl hdl = go.getOrCreateHandle();
return hdl;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy