/*
* #!
* 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.topicmaps.impl.rdbms;
import java.net.MalformedURLException;
import java.util.Collection;
import net.ontopia.infoset.core.LocatorIF;
import net.ontopia.infoset.impl.basic.URILocator;
import net.ontopia.persistence.proxy.QueryCollection;
import net.ontopia.topicmaps.core.AssociationIF;
import net.ontopia.topicmaps.core.OccurrenceIF;
import net.ontopia.topicmaps.core.TMObjectIF;
import net.ontopia.topicmaps.core.TopicIF;
import net.ontopia.topicmaps.core.TopicMapIF;
import net.ontopia.topicmaps.core.TopicMapBuilderIF;
import net.ontopia.topicmaps.core.TopicMapStoreIF;
import net.ontopia.topicmaps.impl.utils.TopicMapTransactionIF;
import net.ontopia.topicmaps.core.ReadOnlyException;
import net.ontopia.topicmaps.core.TopicNameIF;
import net.ontopia.topicmaps.impl.utils.ObjectStrings;
import net.ontopia.utils.OntopiaRuntimeException;
/**
* INTERNAL: The read-only rdbms topic map implementation.
*/
public class ReadOnlyTopicMap extends ReadOnlyTMObject implements TopicMapIF {
// ---------------------------------------------------------------------------
// Data members
// ---------------------------------------------------------------------------
protected transient RDBMSTopicMapTransaction transaction;
public ReadOnlyTopicMap() {
}
public LocatorIF getBaseAddress() {
String base_address = this.<String>loadField(TopicMap.LF_base_address);
if (base_address == null) return null;
try {
return new URILocator(base_address);
} catch (MalformedURLException e) {
throw new OntopiaRuntimeException(e);
}
}
public void setBaseAddress(LocatorIF baseAddress) {
throw new ReadOnlyException();
}
public String getTitle() {
return this.<String>loadField(TopicMap.LF_title);
}
public void setTitle(String title) {
throw new ReadOnlyException();
}
// ---------------------------------------------------------------------------
// PersistentIF implementation
// ---------------------------------------------------------------------------
public int _p_getFieldCount() {
return TopicMap.fields.length;
}
// ---------------------------------------------------------------------------
// TMObjectIF implementation
// ---------------------------------------------------------------------------
public String getClassIndicator() {
return TopicMap.CLASS_INDICATOR;
}
public String getObjectId() {
return (id == null ? null : TopicMap.CLASS_INDICATOR + id.getKey(0));
}
public TopicMapIF getTopicMap() {
return this;
}
// ---------------------------------------------------------------------------
// TopicMapIF implementation
// ---------------------------------------------------------------------------
public TopicMapStoreIF getStore() {
return transaction.getStore();
}
public TopicMapTransactionIF getTransaction() {
return transaction;
}
public TopicMapBuilderIF getBuilder() {
return getTransaction().getBuilder();
}
public Object getIndex(String name) {
return getTransaction().getIndexManager().getIndex(name);
}
public void setTransaction(RDBMSTopicMapTransaction transaction) {
// The transaction property can only be set once
if (this.transaction != null)
throw new OntopiaRuntimeException("Transaction can only be set once.");
this.transaction = transaction;
}
public Collection<TopicIF> getTopics() {
Object[] params = new Object[] { getTopicMap() };
return new QueryCollection(txn, "TopicMap.getTopics_size", params,
"TopicMap.getTopics_iterator", params);
}
/**
* Adds a topic to the set of topics.
*/
void addTopic(TopicIF topic) {
throw new ReadOnlyException();
}
/**
* Removes a topic from the set of topics.
*/
void removeTopic(TopicIF topic) {
throw new ReadOnlyException();
}
public Collection getAssociations() {
Object[] params = new Object[] { getTopicMap() };
return new QueryCollection(txn, "TopicMap.getAssociations_size", params,
"TopicMap.getAssociations_iterator", params);
}
/**
* Adds an association to the set of associations.
*/
void addAssociation(AssociationIF association) {
throw new ReadOnlyException();
}
/**
* Removes an associations from the set of associations.
*/
void removeAssociation(AssociationIF association) {
throw new ReadOnlyException();
}
public TMObjectIF getObjectById(String object_id) {
if (object_id == null) throw new NullPointerException("null is not a valid argument.");
// Cut off the indicator character and lookup identity in the database.
try {
long numid;
try {
numid = Long.parseLong(object_id.substring(1), 10);
} catch (NumberFormatException e) {
return null; // if not a valid ID no object will have it... :)
}
TMObjectIF result = null;
switch ( object_id.charAt(0) ) {
case 'T': {
// Lookup topic
result = (TMObjectIF)txn.getObject(txn.getAccessRegistrar().createIdentity(Topic.class, numid));
break;
}
case 'A': {
// Lookup association
result = (TMObjectIF)txn.getObject(txn.getAccessRegistrar().createIdentity(Association.class, numid));
break;
}
case 'O': {
// Lookup occurrence
result = (TMObjectIF)txn.getObject(txn.getAccessRegistrar().createIdentity(Occurrence.class, numid));
break;
}
case 'B': {
// Lookup base
result = (TMObjectIF)txn.getObject(txn.getAccessRegistrar().createIdentity(TopicName.class, numid));
break;
}
case 'N': {
// Lookup variant name
result = (TMObjectIF)txn.getObject(txn.getAccessRegistrar().createIdentity(VariantName.class, numid));
break;
}
case 'R': {
// Lookup association role
result = (TMObjectIF)txn.getObject(txn.getAccessRegistrar().createIdentity(AssociationRole.class, numid));
break;
}
case 'M': {
// Lookup topic map (only this one can match)
if (object_id.equals(getObjectId()))
return this;
}
default:
// No object was found
return null;
}
// return object if it is part of this topic map
return ((result == null || result.getTopicMap() != this) ? null : result);
} catch (IndexOutOfBoundsException e) {
return null;
} catch (OntopiaRuntimeException e) {
return null;
}
}
public void clear() {
throw new ReadOnlyException();
}
// ---------------------------------------------------------------------------
// Misc. methods
// ---------------------------------------------------------------------------
public String toString() {
return ObjectStrings.toString("rdbms.ReadOnlyTopicMap", (TopicMapIF)this);
}
// ---------------------------------------------------------------------------
// Subject identity cache
// ---------------------------------------------------------------------------
public TMObjectIF getObjectByItemIdentifier(LocatorIF locator) {
return transaction.getObjectByItemIdentifier(locator);
}
public TopicIF getTopicBySubjectLocator(LocatorIF locator) {
return transaction.getTopicBySubjectLocator(locator);
}
public TopicIF getTopicBySubjectIdentifier(LocatorIF locator) {
return transaction.getTopicBySubjectIdentifier(locator);
}
// ---------------------------------------------------------------------------
// Role type cache
// ---------------------------------------------------------------------------
public Collection getRolesByType(TopicIF player, TopicIF rtype) {
return transaction.getRolesByType(player, rtype);
}
// ---------------------------------------------------------------------------
// Role type and association type cache
// ---------------------------------------------------------------------------
public Collection getRolesByType(TopicIF player, TopicIF rtype, TopicIF atype) {
return transaction.getRolesByType(player, rtype, atype);
}
// ---------------------------------------------------------------------------
// Optimized shortcuts
// ---------------------------------------------------------------------------
public Collection<OccurrenceIF> getOccurrencesByType(TopicIF topic, TopicIF type) {
return transaction.getOccurrencesByType(topic, type);
}
public Collection<TopicNameIF> getTopicNamesByType(TopicIF topic, TopicIF type) {
return transaction.getTopicNamesByType(topic, type);
}
public Collection<AssociationIF> getAssocations(TopicIF topic) {
return transaction.getAssocations(topic);
}
public Collection<AssociationIF> getAssociationsByType(TopicIF topic, TopicIF type) {
return transaction.getAssociationsByType(topic, type);
}
// ---------------------------------------------------------------------------
// ReifiableIF implementation
// ---------------------------------------------------------------------------
public TopicIF getReifier() {
return this.<TopicIF>loadField(TopicMap.LF_reifier);
}
public void setReifier(TopicIF reifier) {
throw new ReadOnlyException();
}
}