/*
* #!
* 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.basic.index;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import net.ontopia.topicmaps.core.AssociationIF;
import net.ontopia.topicmaps.core.OccurrenceIF;
import net.ontopia.topicmaps.core.ScopedIF;
import net.ontopia.topicmaps.core.TopicIF;
import net.ontopia.topicmaps.core.TopicNameIF;
import net.ontopia.topicmaps.core.VariantNameIF;
import net.ontopia.topicmaps.impl.utils.IndexManagerIF;
import net.ontopia.topicmaps.core.index.ScopeIndexIF;
import net.ontopia.topicmaps.impl.utils.BasicIndex;
import net.ontopia.topicmaps.impl.utils.EventManagerIF;
import net.ontopia.topicmaps.impl.utils.ObjectTreeManager;
import net.ontopia.utils.CollectionMap;
/**
* INTERNAL: The basic dynamic scope index implementation.
*/
public class ScopeIndex extends BasicIndex implements ScopeIndexIF {
protected CollectionMap basenames;
protected CollectionMap variants;
protected CollectionMap occurs;
protected CollectionMap assocs;
ScopeIndex(IndexManagerIF imanager, EventManagerIF emanager, ObjectTreeManager otree) {
// Initialize index maps
basenames = new CollectionMap();
variants = new CollectionMap();
occurs = new CollectionMap();
assocs = new CollectionMap();
// Initialize object tree event handlers [objects added or removed]
otree.addListener(new ScopedIF_added(basenames, TopicNameIF.EVENT_ADD_THEME), TopicNameIF.EVENT_ADDED);
otree.addListener(new ScopedIF_removed(basenames, TopicNameIF.EVENT_REMOVE_THEME), TopicNameIF.EVENT_REMOVED);
otree.addListener(new ScopedIF_added(variants, VariantNameIF.EVENT_ADD_THEME), VariantNameIF.EVENT_ADDED);
otree.addListener(new ScopedIF_removed(variants, VariantNameIF.EVENT_REMOVE_THEME), VariantNameIF.EVENT_REMOVED);
otree.addListener(new ScopedIF_added(occurs, OccurrenceIF.EVENT_ADD_THEME), OccurrenceIF.EVENT_ADDED);
otree.addListener(new ScopedIF_removed(occurs, OccurrenceIF.EVENT_REMOVE_THEME), OccurrenceIF.EVENT_REMOVED);
otree.addListener(new ScopedIF_added(assocs, AssociationIF.EVENT_ADD_THEME), AssociationIF.EVENT_ADDED);
otree.addListener(new ScopedIF_removed(assocs, AssociationIF.EVENT_REMOVE_THEME), AssociationIF.EVENT_REMOVED);
// Initialize object property event handlers
handlers.put(TopicNameIF.EVENT_ADD_THEME, new ScopedIF_addTheme(basenames));
handlers.put(TopicNameIF.EVENT_REMOVE_THEME, new ScopedIF_removeTheme(basenames));
handlers.put(VariantNameIF.EVENT_ADD_THEME, new ScopedIF_addTheme(variants));
handlers.put(VariantNameIF.EVENT_REMOVE_THEME, new ScopedIF_removeTheme(variants));
handlers.put(OccurrenceIF.EVENT_ADD_THEME, new ScopedIF_addTheme(occurs));
handlers.put(OccurrenceIF.EVENT_REMOVE_THEME, new ScopedIF_removeTheme(occurs));
handlers.put(AssociationIF.EVENT_ADD_THEME, new ScopedIF_addTheme(assocs));
handlers.put(AssociationIF.EVENT_REMOVE_THEME, new ScopedIF_removeTheme(assocs));
// Register dynamic index as event listener
Iterator iter = handlers.keySet().iterator();
while (iter.hasNext()) {
emanager.addListener(this, (String)iter.next());
}
}
// -----------------------------------------------------------------------------
// ScopeIndexIF
// -----------------------------------------------------------------------------
public Collection getTopicNames(TopicIF theme) {
Collection result = (Collection)basenames.get(theme);
if (result == null) return Collections.EMPTY_SET;
// Create new collection
return new ArrayList(result);
}
public Collection getVariants(TopicIF theme) {
Collection result = (Collection)variants.get(theme);
if (result == null) return Collections.EMPTY_SET;
// Create new collection
return new ArrayList(result);
}
public Collection getOccurrences(TopicIF theme) {
Collection result = (Collection)occurs.get(theme);
if (result == null) return Collections.EMPTY_SET;
// Create new collection
return new ArrayList(result);
}
public Collection getAssociations(TopicIF theme) {
Collection result = (Collection)assocs.get(theme);
if (result == null) return Collections.EMPTY_SET;
// Create new collection
return new ArrayList(result);
}
public Collection getTopicNameThemes() {
// Create new collection
Collection result = new ArrayList(basenames.keySet());
result.remove(null);
return result;
}
public Collection getVariantThemes() {
// Create new collection
Collection result = new ArrayList(variants.keySet());
result.remove(null);
return result;
}
public Collection getOccurrenceThemes() {
// Create new collection
Collection result = new ArrayList(occurs.keySet());
result.remove(null);
return result;
}
public Collection getAssociationThemes() {
// Create new collection
Collection result = new ArrayList(assocs.keySet());
result.remove(null);
return result;
}
public boolean usedAsTopicNameTheme(TopicIF topic) {
return basenames.containsKey(topic);
}
public boolean usedAsVariantTheme(TopicIF topic) {
return variants.containsKey(topic);
}
public boolean usedAsOccurrenceTheme(TopicIF topic) {
return occurs.containsKey(topic);
}
public boolean usedAsAssociationTheme(TopicIF topic) {
return assocs.containsKey(topic);
}
public boolean usedAsTheme(TopicIF topic) {
return (basenames.containsKey(topic) ||
variants.containsKey(topic) ||
occurs.containsKey(topic) ||
assocs.containsKey(topic));
}
// -----------------------------------------------------------------------------
// Event handlers
// -----------------------------------------------------------------------------
/**
* EventHandler: ScopedIF.addTheme
*/
class ScopedIF_addTheme extends EventHandler {
protected CollectionMap objects;
ScopedIF_addTheme(CollectionMap objects) {
this.objects = objects;
}
public void processEvent(Object object, String event, Object new_value, Object old_value) {
ScopedIF scoped = (ScopedIF)object;
// Register scope
Collection scope = scoped.getScope();
if (scope.isEmpty())
// Unregister null theme
objects.remove(null, scoped);
// Register theme
objects.add(new_value, scoped);
}
}
/**
* EventHandler: ScopedIF.removeTheme
*/
class ScopedIF_removeTheme extends EventHandler {
protected CollectionMap objects;
ScopedIF_removeTheme(CollectionMap objects) {
this.objects = objects;
}
public void processEvent(Object object, String event, Object new_value, Object old_value) {
ScopedIF scoped = (ScopedIF)object;
// Register themes
Collection scope = scoped.getScope();
if (scope.size() == 1 && scope.contains(old_value))
// Unregister null theme
objects.add(null, scoped);
// Unregister theme
objects.remove(old_value, scoped);
}
}
/**
* EventHandler: ScopedIF.added
*/
class ScopedIF_added extends EventHandler {
protected CollectionMap objects;
protected String child_event;
ScopedIF_added(CollectionMap objects, String child_event) {
this.objects = objects;
this.child_event = child_event;
}
public void processEvent(Object object, String event, Object new_value, Object old_value) {
ScopedIF added = (ScopedIF)new_value;
// Register themes
Collection scope = added.getScope();
if (scope.isEmpty()) {
// Register the null theme
objects.add(null, added);
} else {
Object[] _scope = scope.toArray();
for (int i=0; i < _scope.length; i++)
addEvent(added, child_event, _scope[i]);
}
}
}
/**
* EventHandler: ScopedIF.removed
*/
class ScopedIF_removed extends EventHandler {
protected CollectionMap objects;
protected String child_event;
ScopedIF_removed(CollectionMap objects, String child_event) {
this.objects = objects;
this.child_event = child_event;
}
public void processEvent(Object object, String event, Object new_value, Object old_value) {
ScopedIF removed = (ScopedIF)old_value;
// Unregister themes
Collection scope = removed.getScope();
if (!scope.isEmpty()) {
Object[] _scope = scope.toArray();
for (int i=0; i < _scope.length; i++)
removeEvent(removed, child_event, _scope[i]);
}
// Unregister null theme
objects.remove(null, removed);
}
}
}