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; } }