00001
00026 package org.objectweb.jonas_ejb.container.jorm;
00027
00028 import org.objectweb.jonas_ejb.container.JContainer;
00029 import org.objectweb.jonas_ejb.container.JEntityFactory;
00030 import org.objectweb.jonas_ejb.container.JEntitySwitch;
00031 import org.objectweb.jonas_ejb.container.TraceEjb;
00032 import org.objectweb.jonas_ejb.deployment.api.EjbRelationshipRoleDesc;
00033 import org.objectweb.jonas_ejb.deployment.api.EntityCmp2Desc;
00034 import org.objectweb.jonas_ejb.deployment.api.EntityDesc;
00035 import org.objectweb.jonas_ejb.lib.JormType;
00036 import org.objectweb.jorm.api.PBinding;
00037 import org.objectweb.jorm.api.PClassMapping;
00038 import org.objectweb.jorm.api.PClassMappingCtrl;
00039 import org.objectweb.jorm.api.PException;
00040 import org.objectweb.jorm.api.PMapCluster;
00041 import org.objectweb.jorm.api.PMapper;
00042 import org.objectweb.jorm.api.PMappingCallback;
00043 import org.objectweb.jorm.facility.naming.basidir.BasidBinder;
00044 import org.objectweb.jorm.naming.api.PBinder;
00045 import org.objectweb.jorm.naming.api.PExceptionNaming;
00046 import org.objectweb.jorm.naming.api.PName;
00047 import org.objectweb.jorm.naming.api.PNameCoder;
00048 import org.objectweb.jorm.naming.api.PNamingContext;
00049 import org.objectweb.util.monolog.api.BasicLevel;
00050
00051 import javax.ejb.EJBException;
00052 import javax.ejb.EntityBean;
00053
00054 import java.io.Serializable;
00055 import java.util.Iterator;
00056
00064 public abstract class JormFactory extends JEntityFactory implements PClassMapping, PClassMappingCtrl {
00065
00066 protected int relNonInit;
00067 protected boolean mapped;
00068 protected PMapper mapper = null;
00069 protected EntityCmp2Desc ecd = null;
00070
00074 public JormFactory() {
00075 super();
00076 }
00077
00078 protected abstract void setMapper(String mapperName) throws PException;
00079 public abstract Object getConnection(Object hints) throws PException;
00080 public abstract void releaseConnection(Object conn) throws PException;
00081
00086 public void init(EntityDesc ed, JContainer c, String mapperName) {
00087 TraceEjb.factory.log(BasicLevel.DEBUG, ed.getEjbName());
00088
00089
00090
00091 super.init(ed, c);
00092 ecd = (EntityCmp2Desc) ed;
00093 try {
00094 setMapper(mapperName);
00095 } catch (PException e) {
00096 throw new EJBException("JormFactory cannot create the mapper", e);
00097 }
00098
00099
00100 TraceEjb.factory.log(BasicLevel.DEBUG, "Jorm initialisation");
00101 PBinder binder = null;
00102 Class binderClass = null;
00103 int binderCT = 0;
00104 try {
00105
00106
00107 binderClass = c.getClassLoader().loadClass(ecd.getJormBinderClassName());
00108 binder = (PBinder) binderClass.newInstance();
00109 if (ecd.hasPrimaryKeyField()) {
00110 binderCT = JormType.getCodingType(ecd.getCmpFieldDesc(ecd.getPrimaryKeyFieldName()).getFieldType(), true);
00111 ((BasidBinder) binder).setCodingType(binderCT);
00112 } else {
00113
00114
00115
00116 }
00117 TraceEjb.factory.log(BasicLevel.DEBUG, "binder " + ecd.getJormBinderClassName() + "instanciated");
00118
00119
00120 binder.setPClassMapping(this);
00121 setPBinder(binder);
00122 TraceEjb.factory.log(BasicLevel.DEBUG, "binder linked to the mapping");
00123
00124 } catch (Exception e) {
00125 TraceEjb.factory.log(BasicLevel.ERROR, "Impossible to create the binder", e);
00126 throw new EJBException("Impossible to create the binder: bean:" + ecd.getEjbName(), e);
00127 }
00128
00129
00130 relNonInit = 0;
00131 try {
00132 for (Iterator it = ecd.getEjbRelationshipRoleDescIterator(); it.hasNext();) {
00133 EjbRelationshipRoleDesc rsr = (EjbRelationshipRoleDesc) it.next();
00134 String source = rsr.getSourceBean().getEjbName();
00135 String target = rsr.getTargetBean().getEjbName();
00136 JormFactory pcm2 = source.equals(target) ? this : (JormFactory) c.getBeanFactory(target);
00137 TraceEjb.factory.log(BasicLevel.DEBUG,
00138 "treatement of the relation " + rsr.getRelation().getName()
00139 + ": current-bean=" + ecd.getEjbName()
00140 + ", source-bean=" + source
00141 + ", dest-bean=" + target
00142 + ", cmr-field=" + rsr.getCmrFieldName());
00143
00144 if (rsr.hasCmrField()) {
00145 PClassMapping gcm = null;
00146
00147 if (rsr.isTargetMultiple()) {
00148
00149 gcm = newGCMInstance(mapperName);
00150 gcm.init((PMappingCallback) mapper, null);
00151 setGenClassMapping(rsr.getCmrFieldName(), gcm);
00152 TraceEjb.factory.log(BasicLevel.DEBUG,
00153 "assign a GenClassMapping for the CMR "
00154 + rsr.getCmrFieldName() + " / gcm=" + gcm);
00155
00156 PBinder gcmBinder = null;
00157 try {
00158 gcmBinder = (PBinder) binderClass.newInstance();
00159 } catch (Exception e) {
00160 TraceEjb.factory.log(BasicLevel.ERROR,
00161 "Impossible to create the binder of the GCM bean: "
00162 + ecd.getEjbName() + " / CMR: "
00163 + rsr.getCmrFieldName(), e);
00164 throw new EJBException(
00165 "Impossible to create the binder of the GCM bean: "
00166 + ecd.getEjbName() + " / CMR: "
00167 + rsr.getCmrFieldName(), e);
00168 }
00169 if (ecd.hasPrimaryKeyField()) {
00170 ((BasidBinder) gcmBinder).setCodingType(binderCT);
00171 } else {
00172
00173
00174
00175 }
00176 gcm.setPBinder(gcmBinder);
00177 gcmBinder.setPClassMapping(gcm);
00178 setPNameCoder(rsr.getCmrFieldName(), (PNameCoder) gcmBinder);
00179 }
00180
00181
00182
00183 if (pcm2 != null) {
00184 TraceEjb.factory.log(BasicLevel.DEBUG, "Pnc Assignement");
00185 if (rsr.isTargetMultiple()) {
00186 ((PClassMappingCtrl)gcm).setPNameCoder((PNameCoder) pcm2.getPBinder());
00187 } else {
00188 setPNameCoder(rsr.getCmrFieldName(), (PNameCoder) pcm2.getPBinder());
00189 }
00190 } else {
00191 relNonInit++;
00192 TraceEjb.factory.log(BasicLevel.DEBUG, "the Pnc is not reachable currently. relNonInit=" + relNonInit);
00193
00194 }
00195 }
00196 EjbRelationshipRoleDesc rsr2 = rsr.getOppositeRelationshipRole();
00197 if (pcm2 != null && rsr2.hasCmrField() && pcm2 != this) {
00198
00199
00200
00201
00202
00203 TraceEjb.factory.log(BasicLevel.DEBUG,
00204 "later Pnc assignement of the opposite CMR field: "
00205 + rsr2.getCmrFieldName());
00206 pcm2.configurePnc(rsr2.getCmrFieldName(), (PNamingContext) getPBinder(), rsr2.isTargetMultiple());
00207 }
00208 }
00209 } catch (EJBException e) {
00210 throw e;
00211 } catch (Exception e) {
00212 TraceEjb.factory.log(BasicLevel.ERROR,
00213 "Impossible to assign the naming context to the PClassMapping", e);
00214 throw new EJBException("Impossible to assign the naming context to the PClassMapping", e);
00215 }
00216 mapped = false;
00217 if (relNonInit == 0) {
00218 mapClass();
00219 }
00220 }
00221
00225 public PMapper getMapper() {
00226 return mapper;
00227 }
00228
00235 public void configurePnc(String n, PNamingContext pnc, boolean isMultiple) throws PException {
00236 if (isMultiple) {
00237 PClassMappingCtrl gcm = (PClassMappingCtrl) getGenClassMapping(n);
00238 gcm.setPNameCoder(pnc);
00239 } else {
00240 setPNameCoder(n, pnc);
00241 }
00242 relNonInit--;
00243 TraceEjb.factory.log(BasicLevel.DEBUG, "PNamingContext assigned, relNonInit=" + relNonInit);
00244 if (relNonInit == 0) {
00245 mapClass();
00246 }
00247 }
00248
00249 private void mapClass() {
00250 if (mapped) {
00251 throw new EJBException("The class is already mapped");
00252 }
00253
00254 try {
00255
00256 mapper.map(this);
00257
00258 PMapCluster pmapclust = mapper.getPMapCluster(getClassName());
00259 if (pmapclust.isDefined()) {
00260 switch (ecd.getCleanupPolicy()) {
00261 case EntityDesc.CLEANUP_REMOVEDATA:
00262 pmapclust.createMappingStructures(false);
00263 pmapclust.deleteData();
00264 break;
00265 case EntityDesc.CLEANUP_REMOVEALL:
00266 pmapclust.deleteMappingStructures();
00267 pmapclust.createMappingStructures(true);
00268 break;
00269 case EntityDesc.CLEANUP_NONE:
00270 break;
00271 case EntityDesc.CLEANUP_CREATE:
00272 pmapclust.createMappingStructures(false);
00273 break;
00274 default:
00275 throw new EJBException("Unknown cleanup policy: " + ecd.getCleanupPolicy());
00276 }
00277 } else {
00278
00279
00280
00281 }
00282 mapped = true;
00283 TraceEjb.factory.log(BasicLevel.DEBUG, getClassName() + " is mapped");
00284 } catch (PException pe) {
00285 Exception e = pe;
00286 while ((e instanceof PException) && ((PException) e).getNestedException() != null) {
00287 e = ((PException) e).getNestedException();
00288 }
00289 TraceEjb.factory.log(BasicLevel.ERROR, "Impossible to map the class on the rdb mapper", e);
00290 throw new EJBException("Impossible to map the class on the rdb mapper", e);
00291 }
00292 }
00293
00294 public void stop() {
00295 super.stop();
00296 try {
00297 mapper.unmap(getClassName());
00298 mapped = false;
00299 } catch (PException e) {
00300 TraceEjb.factory.log(BasicLevel.ERROR,
00301 "Impossible to unmap the class " + getClassName(), e);
00302 }
00303 }
00304
00311 protected org.objectweb.jonas_ejb.container.JEntityContext createNewContext(EntityBean bean) {
00312 return new org.objectweb.jonas_ejb.container.jorm.JEntityContext(this, bean);
00313 }
00314
00315 public JEntitySwitch getJEntitySwitch() {
00316 Object result = null;
00317 String cn = ((EntityCmp2Desc) dd).getJormBindingClassName();
00318 try {
00319 result = getContainer().getClassLoader().loadClass(cn).newInstance();
00320 } catch (ClassNotFoundException e1) {
00321 TraceEjb.factory.log(BasicLevel.ERROR, "Impossible to create a new JEntitySwitch as specified in BeanNaming: " + cn, e1);
00322 return null;
00323 } catch (Exception e) {
00324 TraceEjb.factory.log(BasicLevel.ERROR, "Impossible to create a new JEntitySwitch as specifief in BeanNaming: " + cn, e);
00325 return super.getJEntitySwitch();
00326 }
00327 try {
00328 ((PBinding) result).init(this);
00329 } catch (PException e) {
00330 TraceEjb.factory.log(BasicLevel.ERROR, "Impossible to initialized the new JEntitySwitch as specifief in BeanNaming: " + cn, e);
00331 }
00332 return (JEntitySwitch) result;
00333 }
00334
00339 protected PClassMapping newGCMInstance(String mapperName) throws Exception {
00340 int idx = mapperName.indexOf(".");
00341 String mn = (idx != -1) ? mapperName.substring(0, idx) : mapperName;
00342 return (PClassMapping) Class.forName("org.objectweb.jorm.mapper." + mn + ".genclass."
00343 + Character.toUpperCase(mn.charAt(0))
00344 + mn.substring(1, mn.length()) + "GenClassMapping"
00345 ).newInstance();
00346 }
00347
00352 public Serializable encodePK(Serializable pk) {
00353 try {
00354 return (Serializable) ((PName) pk).encodeString();
00355 } catch (PExceptionNaming e) {
00356 TraceEjb.factory.log(BasicLevel.ERROR, "impossible to serialize PK" + e);
00357 return pk;
00358 }
00359 }
00360
00365 public Serializable decodePK(Serializable strpk) {
00366 try {
00367 return getPBinder().decodeString((String) strpk);
00368 } catch (PExceptionNaming e) {
00369 TraceEjb.factory.log(BasicLevel.ERROR, "impossible to deserialize PK" + e);
00370 return strpk;
00371 }
00372 }
00373 }