package com.idega.data;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import javax.ejb.EntityBean;
import javax.ejb.FinderException;
import com.idega.repository.data.Instantiator;
import com.idega.repository.data.Singleton;
import com.idega.repository.data.SingletonRepository;
import com.idega.util.datastructures.HashtableDoubleKeyed;
/**
* IDOContainer is the central service for the IDO Framework.
* IDO or Idega Data Objects is a Framework for Object/Relational mapping and seamless integration between datastores.<br>
* <br>
* Copyright (c) 2001-2004 idega Software
* @author <a href="tryggvi@idega.is">Tryggvi Larusson</a>
* @version 1.0
*/
public class IDOContainer implements Singleton {
//Static variables:
private static Instantiator instantiator = new Instantiator() { public Object getInstance() {return new IDOContainer();}};
//Instance variables:
private boolean beanCachingActive=false;
private boolean queryCachingActive=false;
private Map emptyBeanInstances;
private Map beanCacheMap;
private Map isBeanCacheActive;
//These variables were moved from GenericEntity:
private Map entityAttributes;
private Map entityStaticInstances;
private HashtableDoubleKeyed relationshipTables = new HashtableDoubleKeyed();
private IDOContainer() {
// unload
}
public static IDOContainer getInstance(){
return (IDOContainer) SingletonRepository.getRepository().getInstance(IDOContainer.class, instantiator);
}
protected Map getBeanMap(){
if(this.emptyBeanInstances==null){
this.emptyBeanInstances = new HashMap();
}
return this.emptyBeanInstances;
}
protected Map getBeanCacheMap(){
if(this.beanCacheMap==null){
this.beanCacheMap = new HashMap();
}
return this.beanCacheMap;
}
protected Map getIsBeanCachActiveMap(){
if(this.isBeanCacheActive==null){
this.isBeanCacheActive=new HashMap();
}
return this.isBeanCacheActive;
}
protected IDOBeanCache getBeanCache(Class entityInterfaceClass){
IDOBeanCache idobc = (IDOBeanCache)getBeanCacheMap().get(entityInterfaceClass);
if(idobc==null){
idobc = new IDOBeanCache(entityInterfaceClass);
getBeanCacheMap().put(entityInterfaceClass,idobc);
}
return idobc;
}
protected List getFreeBeansList(Class entityInterfaceClass){
List l = (List)getBeanMap().get(entityInterfaceClass);
if(l==null){
l = new Vector();
}
getBeanMap().put(entityInterfaceClass,l);
return l;
}
protected IDOEntity getFreeBeanInstance(Class entityInterfaceClass)throws Exception{
IDOEntity entity = null;
/*List l = getFreeBeansList(entityInterfaceClass);
if(!l.isEmpty()){
entity= (IDOEntity)l.get(0);
}*/
if(entity==null){
entity = this.instanciateBean(entityInterfaceClass);
}
return entity;
}
public IDOEntity createEntity(Class entityInterfaceClass)throws javax.ejb.CreateException{
try{
IDOEntity entity = null;
try{
entity = getFreeBeanInstance(entityInterfaceClass);
}
catch(Error e){
System.err.println("[idoContainer] : Error creating bean for "+entityInterfaceClass.getName());
e.printStackTrace();
}
((EntityBean)entity).ejbActivate();
((IDOEntityBean)entity).ejbCreate();
return entity;
}
catch(Exception e){
e.printStackTrace();
throw new IDOCreateException(e);
}
}
protected IDOEntity instanciateBean(Class entityInterfaceClass)throws Exception{
Class beanClass = null;
IDOEntity entity = null;
try{
beanClass = IDOLookup.getBeanClassFor(entityInterfaceClass);
}
catch(Error t){
System.err.println("Error looking up bean class for bean: "+entityInterfaceClass.getName());
t.printStackTrace();
}
try{
entity = (IDOEntity)beanClass.newInstance();
}
catch(Error t){
System.err.println("Error instanciating bean class for bean: "+entityInterfaceClass.getName());
t.printStackTrace();
}
return entity;
}
/**
* To find the data by a primary key (cached if appropriate), usually called by HomeImpl classes
*/
public IDOEntity findByPrimaryKey(Class entityInterfaceClass,Object pk,IDOHome home)throws javax.ejb.FinderException{
return findByPrimaryKey(entityInterfaceClass,pk,null,home);
}
/**
* To find the data by a primary key (cached if appropriate), usually called by HomeImpl classes
*/
IDOEntity findByPrimaryKey(Class entityInterfaceClass,Object pk,IDOHome home,String dataSourceName)throws javax.ejb.FinderException{
return findByPrimaryKey(entityInterfaceClass,pk,null,home,dataSourceName);
}
/**
* Workaround to speed up finders where the ResultSet is already created
*/
IDOEntity findByPrimaryKey(Class entityInterfaceClass,Object pk,java.sql.ResultSet rs,IDOHome home)throws javax.ejb.FinderException{
return findByPrimaryKey(entityInterfaceClass,pk,rs,home,null);
}
/**
* Workaround to speed up finders where the ResultSet is already created
*/
IDOEntity findByPrimaryKey(Class entityInterfaceClass,Object pk,java.sql.ResultSet rs,IDOHome home,String dataSourceName)throws javax.ejb.FinderException{
try{
IDOEntity entity=null;
IDOBeanCache cache = null;
boolean useBeanCaching = (dataSourceName==null) && beanCachingActive(entityInterfaceClass);
if(useBeanCaching){
cache = this.getBeanCache(entityInterfaceClass);
entity = cache.getCachedEntity(pk);
}
if(entity==null){
entity = this.instanciateBean(entityInterfaceClass);
if(dataSourceName!=null){
try{
((GenericEntity)entity).setDatasource(dataSourceName);
}
catch(ClassCastException ce){
ce.printStackTrace();
}
}
/**
*@todo
*/
((IDOEntityBean)entity).ejbFindByPrimaryKey(pk);
if(rs!=null){
((GenericEntity)entity).preEjbLoad(rs);
} else {
((IDOEntityBean)entity).ejbLoad();
}
}
((IDOEntityBean)entity).setEJBLocalHome(home);
if(useBeanCaching){
cache.putCachedEntity(pk,entity);
}
return entity;
}
catch(Exception e){
//e.printStackTrace();
throw new FinderException(e.getMessage());
}
}
public synchronized void setBeanCaching(boolean onOrOff){
if(!onOrOff){
this.flushAllBeanCache();
}
this.beanCachingActive=onOrOff;
}
/**
*
* @param entityInterfaceClass
* @return returns true if bean cashing is active for all entities or if it is active for this entityInterfaceClass
*/
protected boolean beanCachingActive(Class entityInterfaceClass) {
Boolean isActive = (Boolean)getIsBeanCachActiveMap().get(entityInterfaceClass);
if(isActive==null){
try {
IDOEntityDefinition def = IDOLookup.getEntityDefinitionForClass(entityInterfaceClass);
isActive = def.isBeanCachingActive();
} catch (IDOLookupException t) {
System.err.println("Error looking up entity defitition for bean: " + entityInterfaceClass.getName());
t.printStackTrace();
}
if(isActive==null){ // still null, use system-default
isActive = ((this.beanCachingActive)?Boolean.TRUE:Boolean.FALSE);
}
getIsBeanCachActiveMap().put(entityInterfaceClass,isActive);
}
return isActive.booleanValue();
}
public synchronized void setQueryCaching(boolean onOrOff){
if(!onOrOff){
this.flushAllQueryCache();
}
this.isBeanCacheActive=null; //remove at least all elements useing system-default (queryCachingActive)
this.queryCachingActive=onOrOff;
}
protected boolean queryCachingActive(Class entityInterfaceClass){
return this.queryCachingActive;
}
IDOEntity getPooledInstance(Class entityInterfaceClass){
return null;
}
public synchronized void flushAllCache(){
this.flushAllBeanCache();
this.flushAllQueryCache();
}
public synchronized void flushAllBeanCache(){
if(this.beanCachingActive){
Iterator iter = getBeanCacheMap().keySet().iterator();
while (iter.hasNext()) {
Class interfaceClass = (Class)iter.next();
this.getBeanCache(interfaceClass).flushAllBeanCache();
}
System.out.println("[idoContainer] Flushing all Bean Cache");
}
}
public synchronized void flushAllQueryCache(){
if(this.queryCachingActive){
Iterator iter = getBeanCacheMap().keySet().iterator();
while (iter.hasNext()) {
Class interfaceClass = (Class)iter.next();
this.getBeanCache(interfaceClass).flushAllQueryCache();
}
System.out.println("[idoContainer] Flushing all Query Cache");
}
}
/**
* Map Used by the IDO Framework and stores a static instance of a IDOEntityDefinition.
* This map has as a key a Class instance and a value a IDOEntityDefinition instance.
* @return Returns the entityAttributes.
*/
Map getEntityDefinitions() {
if(this.entityAttributes==null){
this.entityAttributes=new HashMap();
}
return this.entityAttributes;
}
/**
* Map Used by the IDO Framework and stores a static instance of a IDOEntity.
* This map has as a key a Class instance and a value a IDOEntity instance.
*/
Map getEntityStaticInstances() {
if(this.entityStaticInstances==null){
this.entityStaticInstances=new HashMap();
}
return this.entityStaticInstances;
}
/**
* Map used to look up relationships (Many-to-many) between tables.<br>
* The keys here are two Strings (the EntityNames or TableNames for the Entity beans that have the relationship)
* and as a value an instance of EntityRelationship.
* @return the relationship Map
*/
HashtableDoubleKeyed getRelationshipTableMap(){
if(this.relationshipTables==null){
this.relationshipTables=new HashtableDoubleKeyed();
}
return this.relationshipTables;
}
private DatastoreInterfaceManager datastoreInterfaceManager;
/**
* @return Returns the datastoreInterfaceManager.
*/
public DatastoreInterfaceManager getDatastoreInterfaceManager() {
if(this.datastoreInterfaceManager==null){
this.datastoreInterfaceManager = new DatastoreInterfaceManager();
}
return this.datastoreInterfaceManager;
}
/**
* @param datastoreInterfaceManager The datastoreInterfaceManager to set.
*/
public void setDatastoreInterfaceManager(DatastoreInterfaceManager datastoreInterfaceManager) {
this.datastoreInterfaceManager = datastoreInterfaceManager;
}
}