/*
* #!
* 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.entry;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import net.ontopia.topicmaps.core.TopicMapStoreIF;
import net.ontopia.utils.OntopiaRuntimeException;
/**
* INTERNAL: Class used to manage topic map stores for multiple
* application users.<p>
*
* The class uses transaction user objects and topic map reference
* keys to group topic map stores. Topic map stores are created using
* the containing topic map repository instance.<p>
*
* Note that only a single topic map store can be managed per
* transaction user and reference key combination.
*
* @since 1.3.2
* @deprecated
*/
public class StoreRegistry {
protected TopicMapRepositoryIF repository;
protected Map<Object, Map<String, TopicMapStoreIF>> txnusers = Collections.synchronizedMap(new HashMap<Object, Map<String, TopicMapStoreIF>>());
public StoreRegistry(TopicMapRepositoryIF repository) {
this.repository = repository;
}
/**
* INTERNAL: Returns the topic map repository used.
*/
public TopicMapRepositoryIF getRepository() {
return repository;
}
/**
* INTERNAL: Looks up a topic map store for a given transaction user
* and topic map reference key. A transaction user is the object
* that is used to make sure that you get the right transaction
* among many. The transaction user object can be any object. It is
* just used to look up the right store.
*/
public TopicMapStoreIF getStore(Object txnuser, String refkey) {
synchronized (txnuser) {
if (txnusers.containsKey(txnuser)) {
Map<String, TopicMapStoreIF> stores = txnusers.get(txnuser);
if (stores.containsKey(refkey))
return stores.get(refkey);
}
}
return null;
}
/**
* INTERNAL: Returns the reference key for the given transaction
* user's topic map store. An exception is thrown if the store is
* not registered with the registry.
*/
public synchronized String getReferenceKey(Object txnuser, TopicMapStoreIF store) {
synchronized (txnuser) {
if (txnusers.containsKey(txnuser)) {
Map<String, TopicMapStoreIF> stores = txnusers.get(txnuser);
Iterator<Entry<String, TopicMapStoreIF>> iter = stores.entrySet().iterator();
while (iter.hasNext()) {
Entry<String, TopicMapStoreIF> entry = iter.next();
if (store.equals(entry.getValue()))
return entry.getKey();
}
}
}
throw new OntopiaRuntimeException(store + " is not opened for transaction user: " + txnuser);
}
/**
* INTERNAL: Returns a collection contains all reference keys for
* the given transaction user.
*/
public synchronized Collection<String> getReferenceKeys(Object txnuser) {
Map<String, TopicMapStoreIF> refmap = txnusers.get(txnuser);
if (refmap != null)
return refmap.keySet();
else
return Collections.emptySet();
}
/**
* INTERNAL: Returns a collection contains all stores that is
* registered with the given transaction user.
*/
public synchronized Collection<TopicMapStoreIF> getStores(Object txnuser) {
Map<String, TopicMapStoreIF> refmap = txnusers.get(txnuser);
if (refmap != null)
return refmap.values();
else
return Collections.emptySet();
}
/**
* INTERNAL: Returns true if the topic map store is already opend for
* the given transaction user and reference key.<p>
*
* @return true if the store is open, false otherwise
*
* @since 1.3.4
*/
public boolean isStoreOpen(Object txnuser, String refkey) {
synchronized (txnuser) {
return (getStore(txnuser, refkey) != null);
}
}
/**
* INTERNAL: Open a new topic store for the given transaction user
* and reference key. The store is created from a topic map
* reference that is looked up in the topic map repository using the
* reference key.
*/
public TopicMapStoreIF openStore(Object txnuser, String refkey, boolean readonly) throws IOException {
TopicMapStoreIF store;
synchronized (txnuser) {
store = getStore(txnuser, refkey);
if (store != null)
throw new OntopiaRuntimeException("Store already open for reference key: " + refkey);
// Create new store
TopicMapReferenceIF ref = repository.getReferenceByKey(refkey);
if (ref == null)
throw new OntopiaRuntimeException("Could not find reference with key: " + refkey);
store = ref.createStore(readonly);
putStore(txnuser, refkey, store);
}
return store;
}
protected void putStore(Object txnuser, String refkey, TopicMapStoreIF store) {
if (!txnusers.containsKey(txnuser))
txnusers.put(txnuser, new HashMap<String, TopicMapStoreIF>());
Map<String, TopicMapStoreIF> stores = txnusers.get(txnuser);
stores.put(refkey, store);
}
/**
* INTERNAL: Closes and dereferences the topic map store for the
* given transaction user and reference key.
*/
public void closeStore(Object txnuser, String refkey) {
synchronized (txnuser) {
TopicMapStoreIF store = getStore(txnuser, refkey);
if (store == null)
throw new OntopiaRuntimeException("No store open for reference key: " + refkey);
// Close store and dereference
store.close();
removeStore(txnuser, refkey);
}
}
protected void removeStore(Object txnuser, String refkey) {
Map<String, TopicMapStoreIF> stores = txnusers.get(txnuser);
stores.remove(refkey);
if (stores.isEmpty())
txnusers.remove(txnuser);
}
}