001: /*
002: * Created on 09-Jan-2006
003: */
004: package uk.org.ponder.rsf.hibernate3;
005:
006: import java.util.ArrayList;
007: import java.util.HashMap;
008: import java.util.Iterator;
009: import java.util.List;
010: import java.util.Map;
011:
012: import org.hibernate.EntityMode;
013: import org.hibernate.SessionFactory;
014: import org.hibernate.cfg.Configuration;
015: import org.hibernate.mapping.PersistentClass;
016: import org.hibernate.metadata.ClassMetadata;
017: import org.springframework.orm.hibernate3.LocalSessionFactoryBean;
018:
019: import uk.org.ponder.reflect.ClassGetter;
020: import uk.org.ponder.rsf.state.entity.EntityNameInferrer;
021: import uk.org.ponder.saxalizer.SAXalizerMappingContext;
022: import uk.org.ponder.stringutil.StringList;
023: import uk.org.ponder.util.Logger;
024:
025: /**
026: * The central point of Hibernate dependency. Inspects the Hibernate
027: * Configuration, and manages the construction of individual
028: * HibernateEntityBeanLocators to provide mapping for each Hibernate-managed
029: * entity class. As much as possible application-scope state is centralised in
030: * this class, with request-scope state in HibernateEntityBeanManager and
031: * HibernateEntityBeanLocators.
032: *
033: * @author Antranig Basman (amb26@ponder.org.uk)
034: *
035: */
036:
037: public class StaticHibernateEBM implements EntityNameInferrer {
038: // List of class names to be mapped
039: private StringList classnames = new StringList();
040: // comma-separated list of entity names from Spring config
041: private String entitynames;
042: // map of entity names to class names
043: private Map nametoclass = new HashMap();
044: // map of classes to entity names - for Hibernate3 we support "renaming"
045: private Map classtoname = new HashMap();
046: // A list of the Class objects to be mapped - this is used at runtime
047: private List classes = new ArrayList();
048:
049: public void setMappedClasses(String[] classes) {
050: for (int i = 0; i < classes.length; ++i) {
051: this .classnames.add(classes[i]);
052: }
053: }
054:
055: public void setEntityNames(String entitynames) {
056: this .entitynames = entitynames;
057: }
058:
059: private SessionFactory sessionfactory;
060: private SAXalizerMappingContext mappingcontext;
061: private Configuration config;
062:
063: // If THIS property is set, we assume that we will expose ALL mapped
064: //classes
065: public void setLocalSessionFactoryBean(LocalSessionFactoryBean lsfb) {
066: config = lsfb.getConfiguration();
067: setSessionFactory((SessionFactory) lsfb.getObject());
068: }
069:
070: // If we only get a SessionFactory, the class names will have to be
071: // supplied manually via MappedClasses.
072: public void setSessionFactory(SessionFactory sessionfactory) {
073: this .sessionfactory = sessionfactory;
074: }
075:
076: public void setMappingContext(SAXalizerMappingContext mappingcontext) {
077: this .mappingcontext = mappingcontext;
078: }
079:
080: public static String stripEntityName(String entityname) {
081: int lastdotpos = entityname.lastIndexOf('.');
082: if (lastdotpos != -1) {
083: return entityname.substring(lastdotpos + 1);
084: } else
085: return entityname;
086: }
087:
088: // For Hibernate 3 we allow the entity name to differ from class name,
089: // as configured under entity-name in the .hbm file
090: public String getEntityName(Class clazz) {
091: return (String) classtoname.get(clazz);
092: }
093:
094: public void init() {
095: boolean gotclassnames = false;
096: // if no classnames supplied, user would HAVE to have supplied config
097: if (classnames.size() != 0) {
098: gotclassnames = true;
099: }
100: Map classmap = sessionfactory.getAllClassMetadata();
101: for (Iterator it = classmap.keySet().iterator(); it.hasNext();) {
102: String entityname = (String) it.next();
103: ClassMetadata classmeta = (ClassMetadata) classmap
104: .get(entityname);
105: String shortentityname = stripEntityName(entityname);
106: classtoname.put(classmeta.getMappedClass(EntityMode.POJO),
107: shortentityname);
108: }
109:
110: if (!gotclassnames) {
111: if (config == null) {
112: throw new IllegalArgumentException(
113: "Must supply EITHER mappedClasses OR a LocalSessionFactoryBean to StaticHibernateEBM");
114: }
115: for (Iterator pcit = config.getClassMappings(); pcit
116: .hasNext();) {
117: PersistentClass pc = (PersistentClass) pcit.next();
118: Class clazz = pc.getMappedClass();
119: String entityname = pc.getEntityName();
120: nametoclass.put(stripEntityName(entityname), clazz);
121: classes.add(clazz);
122: }
123: } else {
124: for (int i = 0; i < classnames.size(); ++i) {
125: // trim is needed for crummy Spring property conversion
126: String classname = classnames.stringAt(i).trim();
127: Class clazz = ClassGetter.forName(classname);
128: if (clazz == null) {
129: throw new IllegalArgumentException(
130: "Cannot look up name " + classname
131: + " to a class");
132: }
133: nametoclass.put(getEntityName(clazz), clazz);
134: classes.add(clazz);
135: }
136: }
137: // If entitynames supplied, look them up in the just built table.
138: if (entitynames != null) {
139: classes.clear();
140: StringList names = StringList.fromString(entitynames);
141: for (int i = 0; i < names.size(); ++i) {
142: String entityname = names.stringAt(i);
143: Class entityclazz = (Class) nametoclass.get(entityname);
144: if (entityclazz == null) {
145: Logger.log
146: .error("Unable to find mapped class for name "
147: + entityname);
148: } else {
149: classes.add(entityclazz);
150: }
151: }
152: }
153:
154: }
155:
156: public void populateRequestMap(Map locators) {
157: // Create a locator for each determined mapped class
158: for (int i = 0; i < classes.size(); ++i) {
159: Class entityclazz = (Class) classes.get(i);
160: HibernateEntityBeanLocator hebl = new HibernateEntityBeanLocator();
161: hebl.setEntityNameInferrer(this );
162: hebl.setSessionFactory(sessionfactory);
163: hebl.setMappingContext(mappingcontext);
164: hebl.setEntityClass(entityclazz);
165:
166: String entityname = getEntityName(entityclazz);
167:
168: locators.put(entityname, hebl);
169: }
170: }
171:
172: public StringList getEntityNames() {
173: StringList togo = new StringList();
174: for (int i = 0; i < classes.size(); ++i) {
175: Class entityclazz = (Class) classes.get(i);
176: String entityname = getEntityName(entityclazz);
177: togo.add(entityname);
178: }
179: return togo;
180: }
181:
182: //
183: // public void postParse(EntityID toadjust) {
184: // try {
185: // ClassMetadata classmetadata =
186: // sessionfactory.getClassMetadata(toadjust.clazz);
187: // Class IDclazz = classmetadata.getIdentifierType().getReturnedClass();
188: //
189: // toadjust.id = (Serializable) leafparser
190: // .parse(IDclazz, (String) toadjust.id);
191: // }
192: // catch (Exception e) {
193: // throw UniversalRuntimeException.accumulate("Error parsing ID for " +
194: // entityID);
195: // }
196: // }
197: //
198: // public void preRender(EntityID toadjust) {
199: // toadjust.id = leafparser.render(toadjust.id);
200: //
201: // }
202:
203: }
|