/* JayFX - A Fact Extractor Plug-in for Eclipse
* Copyright (C) 2006 McGill University (http://www.cs.mcgill.ca/~swevo/jayfx)
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* $Revision: 1.5 $
*/
package de.ovgu.cide.mining.database;
import java.io.File;
import java.util.HashSet;
import java.util.Set;
import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.Environment;
import com.sleepycat.je.EnvironmentConfig;
import com.sleepycat.persist.EntityIndex;
import com.sleepycat.persist.EntityStore;
import com.sleepycat.persist.PrimaryIndex;
import com.sleepycat.persist.SecondaryIndex;
import com.sleepycat.persist.StoreConfig;
import de.ovgu.cide.mining.database.model.AElement;
import de.ovgu.cide.mining.database.model.ARelationKind;
/**
* A database storing all the relations between different program elements.
*/
class BerkeleyProgramDatabase extends AbstractProgramDatabase {
private static BerkeleyProgramDatabase instance = null;
public static BerkeleyProgramDatabase getInstance() {
if (instance == null)
instance = new BerkeleyProgramDatabase();
return instance;
}
// Maps IElements (unique because of the Flyweight pattern
// to bundles containing modifiers and relations
private EntityStore elementStore;
private PrimaryIndex<String, AElement> elementById;
private PrimaryIndex<Integer, ARelation> relationsByNr;
private SecondaryIndex<String, Integer, ARelation> relationsByElement;
/**
* Creates an empty program database.
*/
private BerkeleyProgramDatabase() {
Environment myDbEnvironment = null;
try {
EnvironmentConfig envConfig = new EnvironmentConfig();
envConfig.setTransactional(false);
envConfig.setAllowCreate(true);
StoreConfig storeConfig = new StoreConfig();
storeConfig.setAllowCreate(true);
myDbEnvironment = new Environment(new File("d:/tmp/dbEnv"),
envConfig);
elementStore = new EntityStore(myDbEnvironment, "Elements",
storeConfig);
elementStore.truncateClass(AElement.class);
elementStore.truncateClass(ARelation.class);
elementById = elementStore.getPrimaryIndex(String.class,
AElement.class);
relationsByNr = elementStore.getPrimaryIndex(Integer.class,
ARelation.class);
relationsByElement = elementStore.getSecondaryIndex(relationsByNr,
String.class, "elementId_from");
// elementInformationById =
// elementStore.getPrimaryIndex(String.class,
// ARelation.class);
} catch (DatabaseException dbe) {
dbe.printStackTrace();
}
}
/*
* (non-Javadoc)
*
* @see de.ovgu.cide.mining.database.IProgramDatabase#getAllElements()
*/
@Override
public Iterable<AElement> getAllElements() {
return elementById.entities();
}
/*
* (non-Javadoc)
*
* @see
* de.ovgu.cide.mining.database.IProgramDatabase#getElement(java.lang.String
* )
*/
@Override
public AElement getElement(String id) {
return elementById.get(id);
}
/*
* (non-Javadoc)
*
* @see
* de.ovgu.cide.mining.database.IProgramDatabase#contains(de.ovgu.cide.mining
* .database.model.AIElement)
*/
@Override
public boolean contains(AElement pElement) {
assert (pElement != null);
return elementById.contains(pElement.getId());
}
/*
* (non-Javadoc)
*
* @see
* de.ovgu.cide.mining.database.IProgramDatabase#addElement(de.ovgu.cide
* .mining.database.model.AIElement)
*/
@Override
public void addElement(AElement pElement) {
assert (pElement != null);
elementById.put(pElement);
}
/*
* (non-Javadoc)
*
* @see
* de.ovgu.cide.mining.database.IProgramDatabase#addRelation(de.ovgu.cide
* .mining.database.model.AIElement,
* de.ovgu.cide.mining.database.model.ARelation,
* de.ovgu.cide.mining.database.model.AIElement)
*/
@Override
public void addRelation(AElement pElement1, ARelationKind pRelation,
AElement pElement2) throws ElementNotFoundException {
assert (pElement1 != null);
assert (pElement2 != null);
assert (pRelation != null);
if (!contains(pElement1))
throw new ElementNotFoundException(pElement1.getId());
if (!contains(pElement2))
throw new ElementNotFoundException(pElement2.getId());
// elementStore.
relationsByNr.put(new ARelation(pElement1.getId(), pRelation, pElement2
.getId()));
}
/*
* (non-Javadoc)
*
* @see
* de.ovgu.cide.mining.database.IProgramDatabase#getRange(de.ovgu.cide.mining
* .database.model.AIElement, de.ovgu.cide.mining.database.model.ARelation)
*/
@Override
public Set<AElement> getRange(AElement pElement, ARelationKind... pKinds)
throws ElementNotFoundException {
assert (pElement != null);
assert (pKinds != null);
if (!contains(pElement))
throw new ElementNotFoundException(pElement.getId());
Set<AElement> lReturn = new HashSet<AElement>();
EntityIndex<Integer, ARelation> relations = relationsByElement
.subIndex(pElement.getId());
for (ARelation relation : relations.entities()) {
if (in(relation.kind, pKinds)) {
AElement element = getElement(relation.elementId_to);
if (element != null)
lReturn.add(element);
}
}
return lReturn;
}
private boolean in(ARelationKind kind, ARelationKind[] kinds) {
for (ARelationKind akind : kinds)
if (akind == kind)
return true;
return false;
}
/*
* (non-Javadoc)
*
* @see
* de.ovgu.cide.mining.database.IProgramDatabase#addRelationAndTranspose
* (de.ovgu.cide.mining.database.model.AIElement,
* de.ovgu.cide.mining.database.model.ARelation,
* de.ovgu.cide.mining.database.model.AIElement)
*/
@Override
public void addRelationAndTranspose(AElement pElement1,
ARelationKind pRelation, AElement pElement2)
throws ElementNotFoundException {
assert (pElement1 != null);
assert (pElement2 != null);
assert (pRelation != null);
// if( !contains( pElement1 ))
// throw new ElementNotFoundException( pElement1.getId() );
// if( !contains( pElement2 ))
// throw new ElementNotFoundException( pElement2.getId() );
if (contains(pElement1) && contains(pElement2)) {
addRelation(pElement1, pRelation, pElement2);
addRelation(pElement2, pRelation.getInverseRelation(), pElement1);
}
}
/*
* (non-Javadoc)
*
* @see
* de.ovgu.cide.mining.database.IProgramDatabase#hasRelations(de.ovgu.cide
* .mining.database.model.AIElement)
*/
@Override
public boolean hasRelations(AElement pElement)
throws ElementNotFoundException {
assert (pElement != null);
if (!contains(pElement))
throw new ElementNotFoundException(pElement.getId());
return relationsByElement.get(pElement.getId()) != null;
}
@Override
public void estimateFootprint() {
// TODO Auto-generated method stub
}
// /*
// * (non-Javadoc)
// *
// * @see
// *
// de.ovgu.cide.mining.database.IProgramDatabase#copyRelations(de.ovgu.cide
// * .mining.database.model.AIElement,
// * de.ovgu.cide.mining.database.model.AIElement)
// */
// @Override
// public void copyRelations(AElement pFrom, AElement pTo)
// throws ElementNotFoundException {
// assert (pFrom != null);
// assert (pTo != null);
//
// if (!contains(pFrom))
// throw new ElementNotFoundException(pFrom.getId());
// if (!contains(pTo))
// throw new ElementNotFoundException(pTo.getId());
//
// Map<ARelationKind, Set<String>> lRelations =
// getElementInfo(pFrom).aRelations;
// for (Iterator<ARelationKind> i = lRelations.keySet().iterator(); i
// .hasNext();) {
// ARelationKind lNext = (ARelationKind) i.next();
// Set<String> lElements = lRelations.get(lNext);
// for (Iterator<String> j = lElements.iterator(); j.hasNext();) {
// addRelationAndTranspose(pTo, lNext, getElement(j.next()));
// }
// }
// }
// /**
// * Removes a relation from an element. Does not automatically remove the
// * transpose relation.
// *
// * @param pElement1
// * The element to remove the relation from. Must not be null and
// * must exist in the program database.
// * @param pRelation
// * The relation linking pElement1 with pElement2. Must not be
// * null.
// * @param pElement2
// * The range element of the relation. Must not be null and must
// * exist in the program database.
// * @throws ElementNotFoundException
// * If either pFrom or pTo is not indexed in the database.
// */
// private void removeRelation(AElement pElement1, ARelationKind pRelation,
// AElement pElement2) throws ElementNotFoundException {
// throw new UnsupportedOperationException();
// }
// /*
// * (non-Javadoc)
// *
// * @see
// *
// de.ovgu.cide.mining.database.IProgramDatabase#removeElement(de.ovgu.cide
// * .mining.database.model.AIElement)
// */
// @Override
// public void removeElement(AElement pElement)
// throws ElementNotFoundException {
// throw new UnsupportedOperationException();
// }
//
// /*
// * (non-Javadoc)
// *
// * @see de.ovgu.cide.mining.database.IProgramDatabase#dump()
// */
// @Override
// public void dump() {
// throw new UnsupportedOperationException();
// //
// // for (Iterator i = aElements.keySet().iterator(); i.hasNext();) {
// // AElement lElement1 = (AElement) i.next();
// // System.out.println(lElement1);
// //
// // Object obj = aElements.get(lElement1);
// //
// // if (obj == null)
// // continue;
// //
// // Bundle bundle = (Bundle) obj;
// //
// // Map lRelations;
// //
// // if ((lRelations = bundle.getRelationMap()) == null)
// // continue;
// //
// // for (Iterator j = lRelations.keySet().iterator(); j.hasNext();) {
// // ARelationKind lRelation = (ARelationKind) j.next();
// // System.out.println(" " + lRelation);
// // for (Iterator k = ((Set) lRelations.get(lRelation)).iterator(); k
// // .hasNext();) {
// // System.out.println(" " + k.next());
// // }
// // }
// // }
// }
// /*
// * (non-Javadoc)
// *
// * @see
// * de.ovgu.cide.mining.database.IProgramDatabase#getModifiers(de.ovgu.cide
// * .mining.database.model.AIElement)
// */
// @Override
// public int getModifiers(AElement pElement) {
// int lReturn = 0;
// if (aElements.containsKey(pElement)) {
// Bundle lBundle = (Bundle) aElements.get(pElement);
// lReturn = lBundle.aModifier;
// }
// return lReturn;
// }
}