/*
* #!
* Ontopia Engine
* #-
* Copyright (C) 2001 - 2013 The Ontopia Project
* #-
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* !#
*/
package net.ontopia.persistence.proxy;
import java.util.Collection;
import java.util.Collections;
import net.ontopia.utils.OntopiaRuntimeException;
/**
* INTERNAL: An abstract PersistentIF implementation that handles most
* of the machinery needed to implement persistent objects. Note that
* other persistent classes should extend this class.
*/
public abstract class AbstractROPersistent implements PersistentIF {
protected IdentityIF id;
protected TransactionIF txn;
public AbstractROPersistent() {
}
public AbstractROPersistent(TransactionIF txn) {
_p_setTransaction(txn);
}
// -----------------------------------------------------------------------------
// PersistentIF implementation
// -----------------------------------------------------------------------------
public IdentityIF _p_getIdentity() {
return id;
}
public Class<?> _p_getType() {
return getClass();
}
public void _p_setIdentity(IdentityIF identity) {
this.id = identity;
}
public TransactionIF _p_getTransaction() {
return txn;
}
public void _p_setTransaction(TransactionIF txn) {
if (this.txn != null)
throw new OntopiaRuntimeException("Cannot change the transaction of a persistent object.");
this.txn = txn;
}
// -----------------------------------------------------------------------------
// PersistentIF machinery
// -----------------------------------------------------------------------------
/**
* INTERNAL: Called when the instance requests the value of the
* specified field value. This call will lead to the value being
* retrieved from the data repository.
*/
protected <F> F loadField(int field) {
// get identity
IdentityIF identity = _p_getIdentity();
if (identity == null) return null;
// load from storage
try {
return txn.<F>loadField(identity, field);
} catch (IdentityNotFoundException e) {
return null;
}
}
// NOTE: method will throw IdentityNotFoundException if value object
// not found
protected <F> F loadFieldNoCheck(int field) throws IdentityNotFoundException {
// get identity
IdentityIF identity = _p_getIdentity();
if (identity == null) return null;
// load from storage
return txn.<F>loadField(identity, field);
}
protected <F> Collection<F> loadCollectionField(int field) {
// get identity
IdentityIF identity = _p_getIdentity();
if (identity == null) return Collections.EMPTY_SET;
// load from storage
Collection<F> coll = null;
try {
coll = txn.<Collection<F>>loadField(identity, field);
} catch (IdentityNotFoundException e) {
// let coll be null
}
if (coll == null) {
return Collections.EMPTY_SET;
} else {
// set value and mark field as loaded
return new ReadOnlySet<F>(txn, coll);
}
}
public void detach() {
throw new UnsupportedOperationException();
}
// -----------------------------------------------------------------------------
// Queries
// -----------------------------------------------------------------------------
protected Object executeQuery(String name, Object[] params) {
return txn.executeQuery(name, params);
}
// -----------------------------------------------------------------------------
// Object data and metadata
// -----------------------------------------------------------------------------
// -- persistent state
public boolean isTransient() {
return false;
}
public boolean isNewObject() {
return false;
}
public void setNewObject(boolean newObject) {
throw new UnsupportedOperationException();
}
public boolean isInDatabase() {
return true;
}
public void setInDatabase(boolean inDatabase) {
throw new UnsupportedOperationException();
}
public boolean isPersistent() {
return true;
}
public void setPersistent(boolean persistent) {
throw new UnsupportedOperationException();
}
public boolean isDeleted() {
return false;
}
public void setDeleted(boolean deleted) {
throw new UnsupportedOperationException();
}
// -- loaded
public boolean isLoaded(int field) {
return false;
}
// -- values
public Object loadValue(FieldInfoIF finfo) {
if (finfo.isCollectionField())
return loadCollectionField(finfo.getIndex());
else
return loadField(finfo.getIndex());
}
// -- dirty (unflushed)
public boolean isDirty() {
return false;
}
public boolean isDirty(int field) {
return false;
}
public int nextDirty(int start) {
return -1;
}
public int nextDirty(int start, int end) {
return -1;
}
public void setDirty(int field, boolean dirty) {
throw new UnsupportedOperationException();
}
// -- dirty (flushed)
public boolean isDirtyFlushed() {
return false;
}
public boolean isDirtyFlushed(int field) {
return false;
}
public int nextDirtyFlushed(int start) {
return -1;
}
public int nextDirtyFlushed(int start, int end) {
return -1;
}
public void setDirtyFlushed(int field, boolean dirty) {
throw new UnsupportedOperationException();
}
// -- misc
public void clearAll() {
//! throw new UnsupportedOperationException();
}
public String _p_toString() {
return "ReadOnly:" + _p_getIdentity();
}
}