001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019: package org.apache.openjpa.util;
020:
021: import java.util.Map;
022:
023: import org.apache.openjpa.kernel.StoreManager;
024: import org.apache.openjpa.lib.util.concurrent.ConcurrentHashMap;
025:
026: /**
027: * Repository of store-specific facade classes. This is used by facade
028: * implementations to wrap store-specific components without knowing
029: * about all possible back-ends.
030: */
031: public class StoreFacadeTypeRegistry {
032:
033: private Map _impls = new ConcurrentHashMap();
034:
035: /**
036: * Register a facade implementation.
037: *
038: * @param facadeType the facade interface
039: * @param storeType the store's
040: * {@link org.apache.openjpa.kernel.StoreManager} type, or null for generic
041: * @param implType the class implementing the facade
042: */
043: public void registerImplementation(Class facadeType,
044: Class storeType, Class implType) {
045: Object key = (storeType == null) ? (Object) facadeType
046: : new Key(facadeType, storeType);
047: _impls.put(key, implType);
048: }
049:
050: /**
051: * Return the implementation for the given facade and store.
052: *
053: * @param facadeType the facade interface
054: * @param storeType the store's
055: * {@link org.apache.openjpa.kernel.StoreManager} type, or null for generic
056: * @param implType the registered implementor
057: */
058: public Class getImplementation(Class facadeType, Class storeType) {
059: // traverse store type hierarchy to store manager to find most specific
060: // store avaialble
061: Class impl;
062: for (; storeType != null && storeType != StoreManager.class; storeType = storeType
063: .getSuperclass()) {
064: impl = (Class) _impls.get(new Key(facadeType, storeType));
065: if (impl != null)
066: return impl;
067: }
068: return (Class) _impls.get(facadeType);
069: }
070:
071: /**
072: * Return the implementation for the given facade and store. If no
073: * registered implementation is found then returns the given default type
074: * provided it the facade type is assignable from the deafult type.
075: *
076: * @param facadeType the facade interface
077: * @param storeType the store's
078: * {@link org.apache.openjpa.kernel.StoreManager} type, or null for generic
079: * @param implType the registered implementor
080: * @param defaultType class if no registered implementation is available.
081: */
082: public Class getImplementation(Class facadeType, Class storeType,
083: Class defaultType) {
084: Class result = getImplementation(facadeType, storeType);
085: if (result == null)
086: result = defaultType;
087: if (facadeType == null || !facadeType.isAssignableFrom(result))
088: throw new InternalException();
089: return result;
090: }
091:
092: /**
093: * Lookup key for facade+store hash.
094: */
095: private static class Key {
096: public final Class _facadeType;
097: public final Class _storeType;
098:
099: public Key(Class facadeType, Class storeType) {
100: _facadeType = facadeType;
101: _storeType = storeType;
102: }
103:
104: public int hashCode() {
105: return _facadeType.hashCode() ^ _storeType.hashCode();
106: }
107:
108: public boolean equals(Object other) {
109: if (other == this )
110: return true;
111: Key k = (Key) other;
112: return _facadeType == k._facadeType
113: && _storeType == k._storeType;
114: }
115: }
116: }
|