/* * #! * 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.util.Collection; import java.util.Iterator; import net.ontopia.persistence.proxy.IdentityIF; import net.ontopia.persistence.proxy.TransactionIF; import net.ontopia.topicmaps.core.ConstraintViolationException; import net.ontopia.topicmaps.core.CrossTopicMapException; import net.ontopia.topicmaps.core.DuplicateReificationException; import net.ontopia.topicmaps.core.ReifiableIF; import net.ontopia.topicmaps.core.TopicIF; import net.ontopia.topicmaps.core.TopicMapIF; import net.ontopia.topicmaps.core.TopicNameIF; import net.ontopia.topicmaps.core.VariantNameIF; import net.ontopia.topicmaps.impl.utils.DeletionUtils; import net.ontopia.topicmaps.impl.utils.ObjectStrings; import net.ontopia.topicmaps.utils.PSI; /** * INTERNAL: The rdbms topic name implementation. */ public class TopicName extends TMObject implements TopicNameIF { // --------------------------------------------------------------------------- // Persistent property declarations // --------------------------------------------------------------------------- protected static final int LF_topic = 2; protected static final int LF_scope = 3; protected static final int LF_type = 4; protected static final int LF_value = 5; protected static final int LF_variants = 6; protected static final int LF_reifier = 7; protected static final String[] fields = {"sources", "topicmap", "topic", "scope", "type", "value", "variants", "reifier"}; public void detach() { detachCollectionField(LF_sources); detachField(LF_topicmap); detachField(LF_topic); detachField(LF_reifier); detachCollectionField(LF_scope); detachField(LF_type); detachField(LF_value); detachCollectionField(LF_variants); } // --------------------------------------------------------------------------- // Data members // --------------------------------------------------------------------------- public static final String CLASS_INDICATOR = "B"; public TopicName() { } public TopicName(TransactionIF txn) { super(txn); } // --------------------------------------------------------------------------- // PersistentIF implementation // --------------------------------------------------------------------------- public int _p_getFieldCount() { return fields.length; } // --------------------------------------------------------------------------- // TMObjectIF implementation // --------------------------------------------------------------------------- public String getClassIndicator() { return CLASS_INDICATOR; } public String getObjectId() { return (id == null ? null : CLASS_INDICATOR + id.getKey(0)); } // --------------------------------------------------------------------------- // NameIF implementation // --------------------------------------------------------------------------- public TopicIF getTopic() { return this.<TopicIF>loadField(LF_topic); } /** * INTERNAL: Set the topic that the topic name belongs to. [parent] */ void setTopic(TopicIF topic) { // Set parent topic map setTopicMap((topic == null ? null : (TopicMap) topic.getTopicMap())); // Notify transaction valueChanged(LF_topic, topic, true); } void setTopicMap(TopicMap topicmap) { // Notify transaction transactionChanged(topicmap); valueChanged(LF_topicmap, topicmap, true); // Inform variants for (VariantName variantname : this.<VariantName>loadCollectionField(LF_variants)) { variantname.setTopicMap(topicmap); } } public String getValue() { return this.<String>loadField(LF_value); } public void setValue(String value) { if (value == null) throw new NullPointerException("Topic name value must not be null."); // Notify listeners fireEvent(TopicNameIF.EVENT_SET_VALUE, value, getValue()); // Notify transaction valueChanged(LF_value, value, true); } public Collection<VariantNameIF> getVariants() { return this.<VariantNameIF>loadCollectionField(LF_variants); } void addVariant(VariantNameIF variant) { if (variant == null) throw new NullPointerException("null is not a valid argument."); // Check to see if variant is already a member of this topic name if (variant.getTopicName() == this) return; // Check if used elsewhere. if (variant.getTopicName() != null) throw new ConstraintViolationException("Moving objects is not allowed."); // Notify listeners fireEvent(TopicNameIF.EVENT_ADD_VARIANT, variant, null); // Set parent name property ((VariantName) variant).setTopicName(this); // Notify transaction valueAdded(LF_variants, variant, false); // Add inherited themes to variant name for (TopicIF theme : getScope()) ((VariantName)variant)._addTheme(theme, false); } void removeVariant(VariantNameIF variant) { if (variant == null) throw new NullPointerException("null is not a valid argument."); // Check to see if variant is not a member of this topic name if (variant.getTopicName() != this) return; // Notify listeners fireEvent(TopicNameIF.EVENT_REMOVE_VARIANT, null, variant); // Remove inherited themes from variant name for (TopicIF theme : getScope()) ((VariantName)variant)._removeTheme(theme, false); // Unset parent name property ((VariantName) variant).setTopicName(null); // Notify transaction valueRemoved(LF_variants, variant, false); } public void remove() { Topic parent = (Topic) getTopic(); if (parent != null) { DeletionUtils.removeDependencies(this); parent.removeTopicName(this); } } // --------------------------------------------------------------------------- // ScopedIF implementation // --------------------------------------------------------------------------- public Collection<TopicIF> getScope() { return this.<TopicIF>loadCollectionField(LF_scope); } public void addTheme(TopicIF theme) { if (theme == null) throw new NullPointerException("null is not a valid argument."); CrossTopicMapException.check(theme, this); // Notify listeners fireEvent(TopicNameIF.EVENT_ADD_THEME, theme, null); // Notify transaction valueAdded(LF_scope, theme, true); // add theme to variants Collection variants = getVariants(); if (!variants.isEmpty()) { Iterator iter = variants.iterator(); while (iter.hasNext()) { VariantName v = (VariantName) iter.next(); v._addTheme(theme, false); } } } public void removeTheme(TopicIF theme) { if (theme == null) throw new NullPointerException("null is not a valid argument."); CrossTopicMapException.check(theme, this); // Notify listeners fireEvent(TopicNameIF.EVENT_REMOVE_THEME, null, theme); // remove theme from variants Collection variants = getVariants(); if (!variants.isEmpty()) { Iterator iter = variants.iterator(); while (iter.hasNext()) { VariantName v = (VariantName) iter.next(); v._removeTheme(theme, false); } } // Notify transaction valueRemoved(LF_scope, theme, true); } // --------------------------------------------------------------------------- // TypedIF implementation // --------------------------------------------------------------------------- public TopicIF getType() { return this.<TopicIF>loadField(LF_type); } public void setType(TopicIF type) { if (type == null) { type = getDefaultNameType(); } else { CrossTopicMapException.check(type, this); } // Notify listeners fireEvent(TopicNameIF.EVENT_SET_TYPE, type, getType()); // Notify transaction valueChanged(LF_type, type, true); } private TopicIF getDefaultNameType() { TopicMapIF tm = getTopicMap(); TopicIF nameType = tm.getTopicBySubjectIdentifier(PSI.getSAMNameType()); if (nameType == null) { nameType = tm.getBuilder().makeTopic(); nameType.addSubjectIdentifier(PSI.getSAMNameType()); } return nameType; } // --------------------------------------------------------------------------- // ReifiableIF implementation // --------------------------------------------------------------------------- public TopicIF getReifier() { return this.<TopicIF>loadField(LF_reifier); } public void setReifier(TopicIF _reifier) { if (_reifier != null) CrossTopicMapException.check(_reifier, this); if (DuplicateReificationException.check(this, _reifier)) { return; } // Notify listeners Topic reifier = (Topic) _reifier; Topic oldReifier = (Topic) getReifier(); fireEvent(ReifiableIF.EVENT_SET_REIFIER, reifier, oldReifier); valueChanged(LF_reifier, reifier, true); if (oldReifier != null) oldReifier.setReified(null); if (reifier != null) reifier.setReified(this); } // --------------------------------------------------------------------------- // Misc. methods // --------------------------------------------------------------------------- public String toString() { return ObjectStrings.toString("rdbms.TopicName", (TopicNameIF) this); } @Override public void syncAfterMerge(IdentityIF source, IdentityIF target) { syncFieldsAfterMerge(source, target, LF_topic, LF_type, LF_reifier, LF_scope); } }