From cf845a4d2c15935c02fc6c19db571be2502e28af Mon Sep 17 00:00:00 2001 From: rk Date: Mon, 11 Mar 2002 15:28:25 +0000 Subject: [PATCH] object store preparations before being integrated in Database.java --- source/mir/entity/EntityList.java | 65 ++++++++----- source/mir/entity/StorableObjectEntity.java | 42 ++++++++ source/mir/storage/store/ObjectStore.java | 118 +++++++++++++---------- source/mir/storage/store/ServletStoreInfo.java | 5 +- source/mir/storage/store/StoreContainer.java | 50 ++++++++-- source/mir/storage/store/StoreContainerType.java | 16 ++- source/mir/storage/store/StoreIdentifier.java | 18 +++- source/mir/storage/store/StoreUtil.java | 61 ++++++++++++ source/objectstore.properties | 5 + 9 files changed, 289 insertions(+), 91 deletions(-) create mode 100755 source/mir/entity/StorableObjectEntity.java create mode 100755 source/mir/storage/store/StoreUtil.java create mode 100755 source/objectstore.properties diff --git a/source/mir/entity/EntityList.java b/source/mir/entity/EntityList.java index bf41e8ff..9aca5c78 100755 --- a/source/mir/entity/EntityList.java +++ b/source/mir/entity/EntityList.java @@ -7,32 +7,35 @@ package mir.entity; -import java.lang.*; -import java.util.*; +import java.lang.*; +import java.util.*; -import freemarker.template.*; +import freemarker.template.*; -import mir.misc.*; +import mir.misc.*; +import mir.storage.store.*; /** * * Container class for lists of Entities. + * Now implements freemarker.template.TemplateListModel + * and @see mir.storage.store.StorableObject. * * @author - * @version 27.6.1999 + * first version 27.6.1999 + * + * @version 1.0 (freemarker compliant & and storable in ObjectStore) */ -public class EntityList implements TemplateListModel { +public class EntityList implements TemplateListModel, StorableObject { - private static Logfile theLog; - private ArrayList theEntityArrayList; - private String whereClause; - private String orderClause; - private int count; - private int offset; - private int offsetnext = -1; - private int offsetprev = -1; - private int freemarkerListPointer=-1; + private static Logfile theLog; + private ArrayList theEntityArrayList = new ArrayList(); + private String whereClause, orderClause; + private Class theEntityClass; + private int count, offset, limit; + private int offsetnext = -1, offsetprev = -1; + private int freemarkerListPointer=-1; static { @@ -40,12 +43,15 @@ public class EntityList implements TemplateListModel { } /** - * Constructor. Creates an empty EntityList + * Constructor. */ - public EntityList(){ - this.theEntityArrayList = new ArrayList(); - } + public EntityList(){ } + + /* get/set EntityClass of Objects stored in EntityList */ + public void setEntityClass(Class theEntityClass) { this.theEntityClass=theEntityClass; } + public Class getEntityClass() { return theEntityClass; } + public void setLimit(int limit) { this.limit = limit; } /** * Sets the WHERE clause that fetched the Entities of this EntityList from the database. @@ -130,7 +136,7 @@ public class EntityList implements TemplateListModel { /** * Returns whether there is a next batch within the WHERE clause - * @return true if yes, false if no. + * @return true if yes, false if no. */ public boolean hasNextBatch() { return (offsetnext >= 0); @@ -183,7 +189,7 @@ public class EntityList implements TemplateListModel { * Inserts an Entity into the EntityList. * @param anEntity The entity to be inserted. */ - + public void add (Entity anEntity) { if (anEntity!=null) theEntityArrayList.add(anEntity); @@ -195,7 +201,7 @@ public class EntityList implements TemplateListModel { /** * @return The number of Entities in the EntityList. */ - + public int size() { return theEntityArrayList.size(); } @@ -249,4 +255,19 @@ public class EntityList implements TemplateListModel { else return false; } + + // Methods to implement StorableObject + + public Set getNotifyOnReleaseSet() { return null; } + + public StoreIdentifier getStoreIdentifier() { + if ( theEntityClass!=null ) { + return + new StoreIdentifier( this, StoreContainerType.STOC_TYPE_ENTITYLIST, + StoreUtil.getEntityListUniqueIdentifierFor( whereClause, orderClause, offset, limit )); + } + theLog.printWarning("EntityList could not return StoreIdentifier"); + return null; + } + } diff --git a/source/mir/entity/StorableObjectEntity.java b/source/mir/entity/StorableObjectEntity.java new file mode 100755 index 00000000..a886efb6 --- /dev/null +++ b/source/mir/entity/StorableObjectEntity.java @@ -0,0 +1,42 @@ +package mir.entity; + +/** + * Title: StorableObjectEntity + * Description: Basic Container that can be handled by ObjectStore + * Copyright: Copyright (c) 2002 + * Company: indy + * @author rk + * @version 1.0 + */ + +import java.util.*; +import mir.storage.store.*; + + +public class StorableObjectEntity extends Entity + implements StorableObject { + + /** + * Method: getStoreIdentifier + * Description: returns unique StoreIdentifer under which the Entity + * is Stored. Based upon primary key and tablename. + * + * @return StoreIdentifier + */ + public StoreIdentifier getStoreIdentifier() { + String id = getId(); + if ( id!=null && theStorageObject!= null ) + return new StoreIdentifier(this, id+"@"+theStorageObject.getTableName()); + return null; + } + + /** + * Method: getNotifyOnReleaseSet() + * Description: returns empty Set, GenericContainer does not implement + * dependencies. + * + * @return null + */ + public Set getNotifyOnReleaseSet() { return null; } + +} \ No newline at end of file diff --git a/source/mir/storage/store/ObjectStore.java b/source/mir/storage/store/ObjectStore.java index 0bf8dbd2..311c3a9c 100755 --- a/source/mir/storage/store/ObjectStore.java +++ b/source/mir/storage/store/ObjectStore.java @@ -31,17 +31,22 @@ package mir.storage.store; */ import java.util.*; +import javax.servlet.http.*; +import javax.servlet.*; import mir.misc.Logfile; public class ObjectStore { private final static ObjectStore INSTANCE=new ObjectStore(); private final static HashMap containerMap=new HashMap(); // StoreContainerType/StoreContainer - private final static Class storableObjectInterface=StorableObject.class; private static Logfile storeLog; private static long storeHit=0,storeMiss=0; + private ResourceBundle ostoreConf; private ObjectStore() { + ostoreConf = ResourceBundle.getBundle("objectstore"); + if ( ostoreConf == null ) + System.err.println("FATAL: could not find objectstore.properties"); } public static ObjectStore getInstance() { return INSTANCE; } @@ -60,8 +65,10 @@ public class ObjectStore { StoreContainer stoc = getStoreContainerForSid( sid ); if (stoc!=null) storeObject=stoc.use(sid); else System.out.println("Warning: container not found for: " + sid.toString()); - if (storeObject!=null) storeHit++; - return storeObject; + if (storeObject!=null) { + storeHit++; + return storeObject; + } } storeMiss++; return null; @@ -87,37 +94,6 @@ public class ObjectStore { } /** - * Method: toString() - * Description: Displays statistical information about the ObjectStore. - * Further information is gathered from all @see StoreContainer - * - * @return String - */ - public String toString() { - - float hitRatio=0; - long divisor=storeHit+storeMiss; - if (divisor>0) hitRatio=(float)storeHit/(float)divisor; - hitRatio*=100; - - StringBuffer sb = new StringBuffer("Mir-ObjectStore v_"); - sb.append(version()).append("\n"); - sb.append("ObjectStore overall hits/misses/ratio: ").append(storeHit); - sb.append("/").append(storeMiss).append("/").append(hitRatio); - sb.append("%\nCurrently ").append(containerMap.size()); - sb.append(" StoreContainer in use - listing information:\n"); - - // ask container for information - StoreContainer currentStoc; - for(Iterator it=containerMap.keySet().iterator();it.hasNext();) { - currentStoc=(StoreContainer)containerMap.get(it.next()); - sb.append(currentStoc.toString()); - } - - return sb.toString(); - } - - /** * Method: invalidate(StorableObject sto) * Description: ObjectStore is notified of change of a @see StorableObject * sto and invalidates all relevant cache entries. @@ -170,37 +146,73 @@ public class ObjectStore { return null; } + private boolean has(StoreIdentifier sid) { + StoreContainer stoc = getStoreContainerForSid( sid ); + return ( stoc != null && stoc.has(sid) ) ? true:false; + } + + public String getConfProperty(String name) { + if (name!=null ) { + String returnValue=""; + try { + return ostoreConf.getString(name); + } + catch (MissingResourceException e) { + System.err.println("ObjectStore: " + e.toString()); + } + } + return null; + } + /** - * Method: implementsStorableObject - * Description: internall helper method to find out if a class implements - * interface StorableObject. + * Method: toString() + * Description: Displays statistical information about the ObjectStore. + * Further information is gathered from all @see StoreContainer * - * @return true if yes, otherwise no. + * @return String */ - private final static boolean implementsStorableObject(Class aClass) { - if (aClass!=null) { - Class[] interfaces = aClass.getInterfaces(); - if (interfaces.length>0) { - for (int i=0;i0) hitRatio=(float)storeHit/(float)divisor; + hitRatio*=100; - private boolean has(StoreIdentifier sid) { - StoreContainer stoc = getStoreContainerForSid( sid ); - return ( stoc != null && stoc.has(sid) ) ? true:false; + StringBuffer sb = new StringBuffer("Mir-ObjectStore "); + sb.append( ((req!=null) ? html_version():version()) ).append("\n"); + sb.append("ObjectStore overall hits/misses/ratio: ").append(storeHit); + sb.append("/").append(storeMiss).append("/").append(hitRatio); + sb.append("%\nCurrently ").append(containerMap.size()); + sb.append(" StoreContainer in use - listing information:\n"); + + // ask container for information + StoreContainer currentStoc; + for(Iterator it=containerMap.keySet().iterator();it.hasNext();) { + currentStoc=(StoreContainer)containerMap.get(it.next()); + sb.append(currentStoc.toHtml(req)); + } + + return sb.toString(); } + /** + * Method: html_version() + * Description: returns ObjectStore version as String for HTML representation + * + * @return String + */ + private String html_version() { return ""+version()+""; } + /** * Method: version() * Description: returns ObjectStore version as String * * @return String */ - private String version() { return "00.d5";} + private String version() { return "v_sstart3__1.0"; } + } \ No newline at end of file diff --git a/source/mir/storage/store/ServletStoreInfo.java b/source/mir/storage/store/ServletStoreInfo.java index a74e81e6..8a6c0dfb 100755 --- a/source/mir/storage/store/ServletStoreInfo.java +++ b/source/mir/storage/store/ServletStoreInfo.java @@ -33,8 +33,9 @@ public class ServletStoreInfo extends HttpServlet { throws ServletException, UnavailableException, IOException { PrintWriter out = res.getWriter(); - out.println("ObjectStore>
\n");
-      out.println(ostore.toString());
+      res.setContentType("text/html");
+      out.println("ObjectStore
\n");
+      out.println(ostore.toHtml(req));
       out.println("\n
"); out.close(); } diff --git a/source/mir/storage/store/StoreContainer.java b/source/mir/storage/store/StoreContainer.java index 53256d7c..e5c79c51 100755 --- a/source/mir/storage/store/StoreContainer.java +++ b/source/mir/storage/store/StoreContainer.java @@ -16,7 +16,8 @@ package mir.storage.store; */ import java.util.*; -import mir.misc.Logfile; +import javax.servlet.http.*; +import mir.misc.*; public class StoreContainer { @@ -26,17 +27,24 @@ public class StoreContainer { private LinkedList container; private StoreContainerType stocType; - private int maxSize=DEFAULT_SIZE; - private int uniqueId; + private int maxSize=DEFAULT_SIZE, uniqueId; private int addCount=0,removeCount=0,storeOutCount; private int hitCount=0,missCount=0; + private static ObjectStore o_store = ObjectStore.getInstance(); - private StoreContainer() {}; + // avoid construction without parameters + private StoreContainer() {}; public StoreContainer(StoreContainerType stoc_type) { this.uniqueId=++uniqueCounter; this.stocType=stoc_type; this.container=new LinkedList(); + int defaultSize = stoc_type.getDefaultSize(); + String confProperty = stoc_type.getConfPrefix()+".DefaultSize"; + String confedSize = o_store.getConfProperty(confProperty); + if ( confedSize!=null ) { + this.maxSize = StringUtil.parseInt (confedSize, defaultSize); + } } public StoreContainer(StoreContainerType stoc_type, int maxSize) { @@ -44,9 +52,11 @@ public class StoreContainer { this.maxSize=maxSize; } + + public synchronized StorableObject use(StoreIdentifier sid) { int hit = container.indexOf(sid); - if (hit>0) { + if (hit>=0) { StoreIdentifier hitSid = (StoreIdentifier)container.get(hit); if ( hitSid!=null ) { hitCount++; @@ -143,6 +153,11 @@ public class StoreContainer { * @return String */ public String toString() { + return toHtml(null); + } + + public String toHtml(HttpServletRequest req) { + boolean showingContent=false; float hitRatio=0; long divisor=hitCount+missCount; if (divisor>0) hitRatio=(float)hitCount/(float)divisor; @@ -150,14 +165,35 @@ public class StoreContainer { StringBuffer sb = new StringBuffer("StoreContainer id: "); sb.append(uniqueId).append(" for "); - sb.append(stocType.toString()).append("\n [current/maximum size: "); + sb.append(stocType.toString()); + if ( req!=null ) { + String show = req.getParameter("stoc_show"); + if ( show!=null && show.equals(""+uniqueId) ) { + // show all entries in container + sb.append(" [showing]"); + showingContent=true; + } + else + sb.append(" [show]"); + } + sb.append("\n [current/maximum size: "); sb.append(container.size()).append("/").append(maxSize); sb.append("]\n [added/stored out/removed: ").append(addCount).append("/"); sb.append(storeOutCount).append("/").append(removeCount).append("]\n [hit/miss/ratio: "); sb.append(hitCount).append("/").append(missCount).append("/"); sb.append(hitRatio).append("%]\n"); - /** @todo list members ? */ + if (showingContent) { + sb.append(" Container contains following references:\n "); + ListIterator it = container.listIterator(); + while ( it.hasNext() ) { + StoreIdentifier sid = (StoreIdentifier)it.next(); + sb.append(sid.toString()).append("\n "); + } + sb.append("End of List\n\n"); + + } + return sb.toString(); } diff --git a/source/mir/storage/store/StoreContainerType.java b/source/mir/storage/store/StoreContainerType.java index 3cb33835..b3441faf 100755 --- a/source/mir/storage/store/StoreContainerType.java +++ b/source/mir/storage/store/StoreContainerType.java @@ -16,7 +16,7 @@ package mir.storage.store; */ import java.util.HashMap; -import mir.misc.Logfile; +import mir.misc.*; public class StoreContainerType { @@ -26,6 +26,7 @@ public class StoreContainerType { public final static int STOC_TYPE_MAX=STOC_TYPE_ENTITYLIST; private static HashMap[] uniqueTypes=new HashMap[STOC_TYPE_MAX+1]; + private static ObjectStore o_store=ObjectStore.getInstance(); private static Logfile storeLog; private Class stocClass=null; private int stocType=STOC_TYPE_UNKNOWN; @@ -33,7 +34,6 @@ public class StoreContainerType { static { uniqueTypes[STOC_TYPE_ENTITY]= new HashMap(); uniqueTypes[STOC_TYPE_ENTITYLIST]=new HashMap(); - } private StoreContainerType() {} @@ -59,6 +59,14 @@ public class StoreContainerType { public int getStocType() { return stocType; } public Class getStocClass() { return stocClass; } + public String getConfPrefix() { + return StoreUtil.getPropNameFor(stocClass)+"."+stringForStoreType(stocType); + } + public int getDefaultSize() { + String confProperty= "StoreContainer."+stringForStoreType(stocType)+".DefaultSize"; + return + StringUtil.parseInt( o_store.getConfProperty(confProperty),10 ); + } public String toString() { StringBuffer sb = new StringBuffer(this.stocClass.toString()); @@ -68,8 +76,8 @@ public class StoreContainerType { private static String stringForStoreType(int stocType) { switch(stocType) { - case STOC_TYPE_ENTITY: return "ENTITY"; - case STOC_TYPE_ENTITYLIST: return "ENTITYLIST"; + case STOC_TYPE_ENTITY: return "Entity"; + case STOC_TYPE_ENTITYLIST: return "EntityList"; default: return "UNKNOWN"; } } diff --git a/source/mir/storage/store/StoreIdentifier.java b/source/mir/storage/store/StoreIdentifier.java index 92ae95ca..6c8969bd 100755 --- a/source/mir/storage/store/StoreIdentifier.java +++ b/source/mir/storage/store/StoreIdentifier.java @@ -14,6 +14,7 @@ package mir.storage.store; */ import java.util.*; import mir.misc.Logfile; +import mir.entity.*; public class StoreIdentifier { @@ -34,10 +35,20 @@ public class StoreIdentifier { private StoreIdentifier() {} public StoreIdentifier(StorableObject reference, int storeType, String uniqueIdentifier) { - this(reference.getClass(), uniqueIdentifier); + Class theClass; + if (reference instanceof EntityList) + theClass=((EntityList)reference).getEntityClass(); + else + theClass=reference.getClass(); + this.uniqueIdentifier=uniqueIdentifier; + this.stocType = StoreContainerType.valueOf(theClass, storeType); this.reference=reference; } + public StoreIdentifier(StorableObject reference, String uniqueIdentifier) { + this(reference, StoreContainerType.STOC_TYPE_ENTITY, uniqueIdentifier); + } + public StoreIdentifier(Class theClass, String uniqueIdentifier) { this(theClass, StoreContainerType.STOC_TYPE_ENTITY,uniqueIdentifier); } @@ -109,8 +120,9 @@ public class StoreIdentifier { public boolean equals(Object sid) { if ( !(sid instanceof StoreIdentifier) ) return false; if ( ((StoreIdentifier)sid).getStoreContainerType()==stocType && - ((StoreIdentifier)sid).getUniqueIdentifier().equals(uniqueIdentifier) ) - return true; + ((StoreIdentifier)sid).getUniqueIdentifier().equals(uniqueIdentifier) ) { + return true; + } return false; } diff --git a/source/mir/storage/store/StoreUtil.java b/source/mir/storage/store/StoreUtil.java new file mode 100755 index 00000000..fdebb895 --- /dev/null +++ b/source/mir/storage/store/StoreUtil.java @@ -0,0 +1,61 @@ +package mir.storage.store; + +/** + * Title: + * Description: + * Copyright: Copyright (c) 2002 + * Company: + * @author + * @version 1.0 + */ + +public final class StoreUtil { + + private final static Class storableObjectInterface=StorableObject.class; + + // avoid construction + private StoreUtil() { } + + + public static final String getPropNameFor(Class aClass) { + if ( aClass!=null ) { + String className=aClass.toString(); + return className.substring(className.lastIndexOf(".")+1); + } + return null; + } + + public static final String getEntityListUniqueIdentifierFor(String where, String order, + int offset, int limit) + { + StringBuffer sb = new StringBuffer("@"); + if ( where!=null ) sb.append(where); + sb.append("@"); + if ( order!=null ) sb.append(order); + sb.append("@").append(offset); + sb.append("@").append(limit); + return sb.toString(); + } + + /** + * Method: implementsStorableObject + * Description: internall helper method to find out if a class implements + * interface StorableObject. + * + * @return true if yes, otherwise no. + */ + public final static boolean implementsStorableObject(Class aClass) { + if (aClass!=null) { + Class[] interfaces = aClass.getInterfaces(); + if (interfaces.length>0) { + for (int i=0;i