001: /**********************************************************************
002: Copyright (c) 2007 Erik Bengtson and others. All rights reserved.
003: Licensed under the Apache License, Version 2.0 (the "License");
004: you may not use this file except in compliance with the License.
005: You may obtain a copy of the License at
006:
007: http://www.apache.org/licenses/LICENSE-2.0
008:
009: Unless required by applicable law or agreed to in writing, software
010: distributed under the License is distributed on an "AS IS" BASIS,
011: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: See the License for the specific language governing permissions and
013: limitations under the License.
014:
015:
016: Contributors:
017: ...
018: **********************************************************************/package org.jpox.store;
019:
020: import java.util.Collection;
021: import java.util.Collections;
022: import java.util.HashMap;
023: import java.util.HashSet;
024: import java.util.Iterator;
025: import java.util.Map;
026:
027: import org.jpox.metadata.AbstractMemberMetaData;
028: import org.jpox.metadata.ClassMetaData;
029: import org.jpox.metadata.IdentityType;
030: import org.jpox.util.JPOXLogger;
031: import org.jpox.util.Localiser;
032: import org.jpox.util.MultiMap;
033:
034: /**
035: * StoreData Cache Manager
036: */
037: public class StoreDataManager {
038: protected static final Localiser LOCALISER = Localiser
039: .getInstance("org.jpox.store.Localisation");
040:
041: /** Map of all managed store data, keyed by the class/field name. */
042: protected Map storeDataByClass = new HashMap();
043:
044: /** Map of all managed store data using Application Identity, keyed by the app id PK class */
045: protected MultiMap storeDataByAppIdClass = new MultiMap();
046:
047: /** the memory image of schema data beforing running it **/
048: protected Map savedStoreDataByClass;
049:
050: /** the memory image of schema data beforing running it **/
051: protected MultiMap savedStoreDataByAppIdClass;
052:
053: /**
054: * Clear the cache
055: */
056: public void clear() {
057: if (JPOXLogger.PERSISTENCE.isInfoEnabled()) {
058: JPOXLogger.PERSISTENCE.info(LOCALISER.msg("032002"));
059: }
060:
061: storeDataByClass.clear();
062: storeDataByAppIdClass.clear();
063: }
064:
065: /**
066: * Method to register some data with the store.
067: * This will also register the data with the starter process.
068: * @param data The StoreData to add
069: */
070: protected void registerStoreData(StoreData data) {
071: if (data.isFCO()) {
072: // Index any classes by the class name
073: storeDataByClass.put(data.getName(), data);
074:
075: // If it's a class, using APPLICATION identity and is users own AID then store the PK class.
076: // We don't need SingleFieldIdentity in here since they define the class being used
077: ClassMetaData cmd = (ClassMetaData) data.getMetaData();
078: if (cmd.getIdentityType() == IdentityType.APPLICATION
079: && !cmd.usesSingleFieldIdentityClass()) {
080: storeDataByAppIdClass.put(cmd.getObjectidClass(), data);
081: }
082: } else {
083: // Index any fields by the class name of the field
084: storeDataByClass.put(data.getMetaData(), data);
085: }
086:
087: if (JPOXLogger.PERSISTENCE.isInfoEnabled()) {
088: JPOXLogger.PERSISTENCE.info(LOCALISER.msg("032001", data));
089: }
090: }
091:
092: /**
093: * Utility to return all StoreData for a Datastore Container identifier.
094: * Returns StoreData with this table identifier and where the class is the owner of the table.
095: * @param tableIdentifier Identifier for the table
096: * @return The StoreData for this table (if managed).
097: */
098: public synchronized TableStoreData[] getStoreDataForDatastoreContainerObject(
099: DatastoreIdentifier tableIdentifier) {
100: Collection dataForTable = null;
101: Iterator iterator = storeDataByClass.values().iterator();
102: while (iterator.hasNext()) {
103: StoreData data = (StoreData) iterator.next();
104: if (data instanceof TableStoreData) {
105: TableStoreData tableData = (TableStoreData) data;
106: if (tableData.getDatastoreIdentifier() != null
107: && tableData.getDatastoreIdentifier().equals(
108: tableIdentifier)
109: && tableData.isTableOwner()) {
110: if (dataForTable == null) {
111: dataForTable = new HashSet();
112: }
113: dataForTable.add(data);
114: }
115: }
116: }
117: if (dataForTable != null) {
118: return (TableStoreData[]) dataForTable
119: .toArray(new TableStoreData[dataForTable.size()]);
120: }
121: return null;
122: }
123:
124: /**
125: * Accessor for whether the specified class is managed currently
126: * @param className The name of the class
127: * @return Whether it is managed
128: */
129: public boolean managesClass(String className) {
130: return storeDataByClass.containsKey(className);
131: }
132:
133: /**
134: * Accessor for the StoreData currently managed by this store.
135: * @return Collection of the StoreData being managed
136: */
137: public Collection getManagedStoreData() {
138: return Collections.unmodifiableCollection(storeDataByClass
139: .values());
140: }
141:
142: /**
143: * Get the StoreData by the given className
144: * @param className the fully qualified class name
145: * @return the StoreData
146: */
147: public StoreData get(String className) {
148: return (StoreData) storeDataByClass.get(className);
149: }
150:
151: /**
152: * Get the StoreData by the given field/property
153: * @param apmd the field/property
154: * @return the StoreData
155: */
156: public StoreData get(AbstractMemberMetaData apmd) {
157: return (StoreData) storeDataByClass.get(apmd);
158: }
159:
160: /**
161: * Get the Collection of StoreData that currently uses this primary key class
162: * @param className the primary key class name
163: * @return the Collection of StoreData
164: */
165: public Collection getByPrimaryKeyClass(String className) {
166: return (Collection) storeDataByAppIdClass.get(className);
167: }
168:
169: /**
170: * Acessor to the number of StoreData in cache
171: * @return the number of StoreData in cache
172: */
173: public int size() {
174: return storeDataByClass.size();
175: }
176:
177: /**
178: * Begin a transaction that changes the StoreData cache
179: */
180: public void begin() {
181: savedStoreDataByClass = new HashMap(storeDataByClass);
182: savedStoreDataByAppIdClass = new MultiMap(storeDataByAppIdClass);
183: }
184:
185: /**
186: * Rollbacks the transaction changes to the StoreData cache
187: */
188: public void rollback() {
189: storeDataByClass = savedStoreDataByClass;
190: storeDataByAppIdClass = savedStoreDataByAppIdClass;
191: }
192:
193: /**
194: * Commit the transaction changes to the StoreData cache
195: */
196: public void commit() {
197: savedStoreDataByClass = null;
198: savedStoreDataByAppIdClass = null;
199: }
200: }
|