/**
* Copyright (c) 2006-2011 Floggy Open Source Group. All rights reserved.
*
* 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.sourceforge.floggy.persistence.impl;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import javax.microedition.rms.RecordEnumeration;
import javax.microedition.rms.RecordStore;
import net.sourceforge.floggy.persistence.FloggyException;
/**
* DOCUMENT ME!
*
* @author <a href="mailto:thiago.moreira@floggy.org">Thiago Moreira</a>
* @version $Revision$
*/
public class IndexManager {
private static Hashtable indexes = new Hashtable();
private static boolean storeIndexAfterSave = false;
private IndexManager() {
}
/**
* After object delete the cache of the index could be updated.
*
* @param persistable
*
* @throws Exception
*/
public static void afterDelete(__Persistable persistable)
throws Exception {
PersistableMetadata metadata =
PersistableMetadataManager.getClassBasedMetadata(persistable.getClass()
.getName());
Vector indexMetadatas = metadata.getIndexMetadatas();
if (indexMetadatas != null) {
int size = indexMetadatas.size();
for (int i = 0; i < size; i++) {
IndexMetadata indexMetadata =
(IndexMetadata) indexMetadatas.elementAt(i);
afterDelete(persistable, indexMetadata);
}
}
}
/**
* After object delete the cache of the index could be updated.
*
* @param persistable
* @param indexMetadata DOCUMENT ME!
*
* @throws Exception
* @throws IllegalArgumentException DOCUMENT ME!
*/
public static void afterDelete(__Persistable persistable,
IndexMetadata indexMetadata) throws Exception {
if (persistable.__getId() > 0) {
if (indexes.containsKey(indexMetadata.getId())) {
Object value = persistable.__getIndexValue(indexMetadata.getName());
if (value != null) {
Index index = (Index) indexes.get(indexMetadata.getId());
IndexEntry indexEntry = index.getIndexEntry(value);
if (indexEntry != null) {
index.remove(persistable.__getId());
}
}
}
} else {
throw new IllegalArgumentException(
"The persistable object does not have a reference to the RMS system.");
}
}
/**
* After object save the cache of the index could be updated.
*
* @param persistable
*
* @throws Exception
*/
public static void afterSave(__Persistable persistable)
throws Exception {
PersistableMetadata metadata =
PersistableMetadataManager.getClassBasedMetadata(persistable.getClass()
.getName());
Vector indexMetadatas = metadata.getIndexMetadatas();
if (indexMetadatas != null) {
int size = indexMetadatas.size();
for (int i = 0; i < size; i++) {
IndexMetadata indexMetadata =
(IndexMetadata) indexMetadatas.elementAt(i);
afterSave(persistable, indexMetadata);
}
}
}
/**
* After object delete the cache and recordStore of the index must be
* updated
*
* @param persistable
* @param indexMetadata DOCUMENT ME!
*
* @throws Exception
* @throws IllegalArgumentException DOCUMENT ME!
*/
public static void afterSave(__Persistable persistable,
IndexMetadata indexMetadata) throws Exception {
if (persistable.__getId() > 0) {
Index index = null;
Object value = persistable.__getIndexValue(indexMetadata.getName());
String indexId = indexMetadata.getId();
if (indexes.containsKey(indexId)) {
index = (Index) indexes.get(indexId);
} else {
index = new Index();
indexes.put(indexId, index);
}
if (value == null) {
IndexEntry indexEntry = index.getIndexEntry(persistable.__getId());
if (indexEntry != null) {
index.remove(persistable.__getId());
}
} else {
index.put(persistable.__getId(), value);
}
if (storeIndexAfterSave) {
save(indexId, index);
}
} else {
throw new IllegalArgumentException(
"The persistable object does not have a reference to the RMS system.");
}
}
/**
* DOCUMENT ME!
*
* @param persistableClassName DOCUMENT ME!
*
* @throws Exception DOCUMENT ME!
*/
public static void deleteIndex(String persistableClassName)
throws Exception {
PersistableMetadata metadata =
PersistableMetadataManager.getClassBasedMetadata(persistableClassName);
Vector indexMetadatas = metadata.getIndexMetadatas();
if (indexMetadatas != null) {
int size = indexMetadatas.size();
for (int i = 0; i < size; i++) {
IndexMetadata indexMetadata =
(IndexMetadata) indexMetadatas.elementAt(i);
String id = indexMetadata.getId();
if (indexes.containsKey(id)) {
Index index = (Index) indexes.get(id);
index.clear();
}
RecordStoreManager.deleteRecordStore(id);
}
}
}
/**
* DOCUMENT ME!
*
* @param persistableClass DOCUMENT ME!
* @param indexName DOCUMENT ME!
* @param indexValue DOCUMENT ME!
*
* @return DOCUMENT ME!
*
* @throws Exception DOCUMENT ME!
*/
public static int[] getId(Class persistableClass, String indexName,
Object indexValue) throws Exception {
IndexMetadata indexMetadata = getIndexMetadata(persistableClass, indexName);
Index index = (Index) indexes.get(indexMetadata.getId());
return index.getIds(indexValue);
}
/**
* DOCUMENT ME!
*
* @param persistableClass DOCUMENT ME!
* @param indexName DOCUMENT ME!
*
* @return DOCUMENT ME!
*
* @throws FloggyException DOCUMENT ME!
*/
public static IndexMetadata getIndexMetadata(Class persistableClass,
String indexName) throws FloggyException {
PersistableMetadata metadata =
PersistableMetadataManager.getClassBasedMetadata(persistableClass.getName());
Vector indexMetadatas = metadata.getIndexMetadatas();
int size = indexMetadatas.size();
IndexMetadata indexMetadata = null;
for (int i = 0; i < size; i++) {
indexMetadata = (IndexMetadata) indexMetadatas.elementAt(i);
if (indexMetadata.getName().equals(indexName)) {
return indexMetadata;
}
}
throw new FloggyException("The " + indexName + " index does not exist to "
+ persistableClass.getName() + " persistable.");
}
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public static boolean getStoreIndexAfterSave() {
return IndexManager.storeIndexAfterSave;
}
/**
* DOCUMENT ME!
*
* @throws Exception DOCUMENT ME!
*/
public static void init() throws Exception {
Enumeration metadatas = PersistableMetadataManager.getClassBasedMetadatas();
while (metadatas.hasMoreElements()) {
PersistableMetadata metadata =
(PersistableMetadata) metadatas.nextElement();
Vector indexMetadatas = metadata.getIndexMetadatas();
if (indexMetadatas != null) {
int indexMetadatasSize = indexMetadatas.size();
for (int j = 0; j < indexMetadatasSize; j++) {
IndexMetadata indexMetadata =
(IndexMetadata) indexMetadatas.elementAt(j);
loadIndex(metadata, indexMetadata);
}
}
}
}
/**
* DOCUMENT ME!
*
* @param metadata DOCUMENT ME!
* @param indexMetadata DOCUMENT ME!
*
* @throws Exception DOCUMENT ME!
*/
public static void loadIndex(PersistableMetadata metadata,
IndexMetadata indexMetadata) throws Exception {
if (indexes.containsKey(indexMetadata.getId())) {
return;
}
RecordStore rs = RecordStoreManager.getRecordStore(indexMetadata, metadata);
Index index = new Index();
RecordEnumeration enumeration = rs.enumerateRecords(null, null, true);
while (enumeration.hasNextElement()) {
int id = enumeration.nextRecordId();
byte[] buffer = rs.getRecord(id);
IndexEntry indexEntry = new IndexEntry(id);
indexEntry.deserialize(buffer);
index.put(indexEntry);
}
indexes.put(indexMetadata.getId(), index);
RecordStoreManager.closeRecordStore(rs);
}
/**
* DOCUMENT ME!
*/
public static void reset() {
Enumeration elements = indexes.elements();
while (elements.hasMoreElements()) {
Index index = (Index) elements.nextElement();
index.idValue.clear();
index.valueIds.clear();
}
indexes.clear();
}
/**
* DOCUMENT ME!
*
* @param storeIndexAfterSave DOCUMENT ME!
*/
public static void setStoreIndexAfterSave(boolean storeIndexAfterSave) {
IndexManager.storeIndexAfterSave = storeIndexAfterSave;
}
/**
* DOCUMENT ME!
*
* @throws Exception DOCUMENT ME!
*/
public static void shutdown() throws Exception {
Enumeration indexIds = indexes.keys();
while (indexIds.hasMoreElements()) {
String indexId = (String) indexIds.nextElement();
Index index = (Index) indexes.get(indexId);
save(indexId, index);
}
}
private static void save(String indexId, Index index)
throws Exception {
FloggyOutputStream fos = new FloggyOutputStream();
RecordStore rs = RecordStore.openRecordStore(indexId, true);
Enumeration indexValueEnumeration = index.valueIds.elements();
while (indexValueEnumeration.hasMoreElements()) {
IndexEntry indexEntry = (IndexEntry) indexValueEnumeration.nextElement();
indexEntry.serialize(fos);
int id = indexEntry.getRecordId();
byte[] data = fos.toByteArray();
if (id != -1) {
rs.setRecord(id, data, 0, data.length);
} else {
id = rs.addRecord(data, 0, data.length);
indexEntry.setRecordId(id);
}
fos.reset();
}
rs.closeRecordStore();
}
}