KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jonas_ejb > deployment > api > EjbRelationshipRoleDesc


1 /**
2  * JOnAS: Java(TM) Open Application Server
3  * Copyright (C) 1999-2004 Bull S.A.
4  * Contact: jonas-team@objectweb.org
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19  * USA
20  *
21  * --------------------------------------------------------------------------
22  * $Id: EjbRelationshipRoleDesc.java,v 1.28 2005/04/28 16:52:59 benoitf Exp $
23  * --------------------------------------------------------------------------
24  */

25 package org.objectweb.jonas_ejb.deployment.api;
26
27 import java.util.HashMap JavaDoc;
28 import java.util.Iterator JavaDoc;
29
30 import org.objectweb.jonas_ejb.deployment.xml.EjbRelationshipRole;
31 import org.objectweb.jonas_ejb.deployment.xml.ForeignKeyJdbcMapping;
32 import org.objectweb.jonas_ejb.deployment.xml.JonasEjbRelationshipRole;
33 import org.objectweb.jonas_lib.deployment.api.DeploymentDescException;
34 import org.objectweb.util.monolog.api.BasicLevel;
35 import org.objectweb.util.monolog.api.Logger;
36
37 /**
38  * Class to hold meta-information related to an ejb-relation-role
39  * Created on July 7, 2002
40  * @author Christophe Ney [cney@batisseurs.com] : Initial developer
41  * @author Helene Joanin on May 2003: code cleanup
42  * @author Helene Joanin on May 2003: complement for legacy first version
43  */

44 public class EjbRelationshipRoleDesc {
45
46     private Logger logger = null;
47
48     /**
49      * This constant can be used to represent an index of a gen class.
50      */

51     public static final byte INDEX = 1;
52
53     /**
54      * This constant can be used to represent the source of the relation, ie the
55      * element which references the other.
56      */

57     public static final byte SOURCE = 2;
58
59     /**
60      * This constant can be used to represent the target of the relation, ie the
61      * element which is referenced by the other.
62      */

63     public static final byte TARGET = 4;
64
65     /**
66      * Don't change these values without looking at getRelationType() !
67      */

68     public static final byte OOU = 0;
69
70     public static final byte OOB = 1;
71
72     public static final byte OMU = 2;
73
74     public static final byte OMB = OMU + OOB;
75
76     public static final byte MOU = 4;
77
78     public static final byte MOB = MOU + OOB;
79
80     public static final byte MMU = OMU + MOU;
81
82     public static final byte MMB = MMU + OOB;
83
84     private String JavaDoc rsrName;
85
86     private String JavaDoc ejbSourceName;
87
88     private EjbRelationDesc ejbRelationDesc;
89
90     private EntityCmp2Desc sourceEntityCmp2Desc;
91
92     private boolean isSourceMultiple;
93
94     private EntityCmp2Desc targetEntityCmp2Desc;
95
96     private boolean isTargetMultiple;
97
98     private boolean isSlave;
99
100     protected String JavaDoc cmrFieldName = null;
101
102     protected Class JavaDoc cmrFieldType = null;
103
104     protected boolean isJOnASCMR = false;
105
106     private byte relationType = -1;
107
108     private boolean mustCascade;
109
110     // Zeus objects for the associated mapping information (needed in
111
// fillMappingInfo);
112
// They may be null.
113
private JonasEjbRelationshipRole jSourceRsRole = null;
114
115     // mapping information build by fillMappingInfo and
116
// fillMappingInfoWithDefault
117
private HashMap JavaDoc foreignKeyMap = new HashMap JavaDoc();
118
119     private boolean hasJdbcMapping = false;
120
121     /**
122      * constructor to be used by parent node
123      * @param rd parent node = EjbRelationDesc
124      * @param role this role (standard EjbRelationshipRole)
125      * @param jrole this Jonas role (JonasEjbRelationshipRole). This param may
126      * be null.
127      * @param opposite opposite role in the relation (standard
128      * EjbRelationshipRole)
129      * @throws DeploymentDescException in error case.
130      */

131     public EjbRelationshipRoleDesc(EjbRelationDesc rd, String JavaDoc name, EjbRelationshipRole role,
132             JonasEjbRelationshipRole jrole, EjbRelationshipRole opposite, boolean isSlave, Logger logger)
133             throws DeploymentDescException {
134
135         this.logger = logger;
136         ejbRelationDesc = rd;
137         this.isSlave = isSlave;
138         rsrName = name;
139         mustCascade = opposite.isCascadeDelete();
140         ejbSourceName = role.getRelationshipRoleSource().getEjbName();
141
142         // mutiplicity is One or Many
143
if (opposite.getMultiplicity().equalsIgnoreCase("Many")) {
144             isTargetMultiple = true;
145             if (role.isCascadeDelete()) {
146                 throw new DeploymentDescException("Cascade delete not allowed for relationshipRole for relationship '"
147                         + rd.getName() + "(because opposite role has a multiplicity of Many)");
148             }
149         } else if (opposite.getMultiplicity().equalsIgnoreCase("One")) {
150             isTargetMultiple = false;
151         } else {
152             throw new DeploymentDescException("Invalid multiplicity value for relationshipRole for relationship '"
153                     + rd.getName() + "'(must be One or Many)");
154         }
155         if (role.getMultiplicity().equalsIgnoreCase("Many")) {
156             isSourceMultiple = true;
157         } else if (role.getMultiplicity().equalsIgnoreCase("One")) {
158             isSourceMultiple = false;
159         } else {
160             throw new DeploymentDescException("Invalid multiplicity value for relationshipRole for relationship '"
161                     + rd.getName() + "'(must be One or Many)");
162         }
163
164         // store cmr field if any
165
if (role.getCmrField() != null) {
166             setCmrFieldName(role.getCmrField().getCmrFieldName());
167             if (isTargetMultiple) {
168                 String JavaDoc type = role.getCmrField().getCmrFieldType();
169                 if (type == null) {
170                     throw new DeploymentDescException(
171                             "You must specify a cmr-field-type in case where the relation is 'Many' in the cmr-field '"
172                                     + cmrFieldName + "' of bean " + ejbSourceName);
173                 }
174                 setCmrFieldType(type);
175             }
176         }
177
178         // store the JonasEjbRelationshipRole
179
jSourceRsRole = jrole;
180     }
181
182     /**
183      * Fills the mapping information of this relation-ship role with the values
184      * defined in jonas DD.
185      * @throws DeploymentDescException in error case.
186      */

187     protected void fillMappingInfo() throws DeploymentDescException {
188         if (logger.isLoggable(BasicLevel.DEBUG)) {
189             logger.log(BasicLevel.DEBUG, "" + (jSourceRsRole != null) + " for " + rsrName);
190         }
191         if (jSourceRsRole != null) {
192             for (Iterator JavaDoc i = jSourceRsRole.getForeignKeyJdbcMappingList().iterator(); i.hasNext();) {
193                 ForeignKeyJdbcMapping fkMapping = (ForeignKeyJdbcMapping) i.next();
194                 String JavaDoc fkc = fkMapping.getForeignKeyJdbcName();
195                 String JavaDoc kc = null;
196                 if (fkMapping.getKeyJdbcName() != null) {
197                     kc = fkMapping.getKeyJdbcName();
198                 }
199                 if (kc == null) {
200                     // if the target bean has a primary-key-field, this value
201
// may not be defined
202
// in this case, this is the column name of the
203
// primary-key-field
204
if (targetEntityCmp2Desc.hasSimplePkField()) {
205                         kc = ((FieldJdbcDesc) targetEntityCmp2Desc.getSimplePkField()).getJdbcFieldName();
206                     } else {
207                         // error
208
throw new DeploymentDescException(
209                                 "key-jdbc-name must be provided for foreign-key-jdbc-mapping " + fkc
210                                         + " of relation-ship role " + rsrName + "of relation "
211                                         + ejbRelationDesc.getName());
212                     }
213                 }
214                 if (logger.isLoggable(BasicLevel.DEBUG)) {
215                     logger.log(BasicLevel.DEBUG, "explicit fk mapping = " + fkc + " for " + kc);
216                 }
217                 foreignKeyMap.put(kc, fkc);
218             }
219             hasJdbcMapping = true;
220         }
221     }
222
223     /**
224      * Fills the mapping information of this relation-ship role with default
225      * values if the mapping information is not already initialized.
226      */

227     protected void fillMappingInfoWithDefault() {
228         if (logger.isLoggable(BasicLevel.DEBUG)) {
229             logger.log(BasicLevel.DEBUG, "" + hasJdbcMapping);
230         }
231         if (!hasJdbcMapping) {
232             if (targetEntityCmp2Desc.hasSimplePkField()) {
233                 // target entity has a simple pk (primary-key-field)
234
String JavaDoc fn = targetEntityCmp2Desc.getSimplePkFieldName();
235                 FieldJdbcDesc fd = (FieldJdbcDesc) targetEntityCmp2Desc.getCmpFieldDesc(fn);
236                 String JavaDoc kc = fd.getJdbcFieldName();
237                 String JavaDoc fkc = targetEntityCmp2Desc.getAbstractSchemaName() + "_" + kc;
238                 if (logger.isLoggable(BasicLevel.DEBUG)) {
239                     logger.log(BasicLevel.DEBUG, "default fk mapping = " + fkc + " for " + kc);
240                 }
241                 foreignKeyMap.put(kc, fkc);
242             } else {
243                 // target entity has a composite pk
244
for (Iterator JavaDoc i = targetEntityCmp2Desc.getCmpFieldDescIterator(); i.hasNext();) {
245                     FieldJdbcDesc fd = (FieldJdbcDesc) i.next();
246                     String JavaDoc kc = fd.getJdbcFieldName();
247                     String JavaDoc fkc = targetEntityCmp2Desc.getAbstractSchemaName() + "_" + kc;
248                     if (logger.isLoggable(BasicLevel.DEBUG)) {
249                         logger.log(BasicLevel.DEBUG, "default fk mapping = " + fkc + " for " + kc);
250                     }
251                     foreignKeyMap.put(kc, fkc);
252                 }
253             }
254             hasJdbcMapping = true;
255         }
256     }
257
258     /**
259      * return the name of this relationship role.
260      * @return the String name of this relationship role.
261      */

262     public String JavaDoc getName() {
263         return rsrName;
264     }
265
266     protected void setCmrFieldName(String JavaDoc name) throws DeploymentDescException {
267         cmrFieldName = name;
268     }
269
270     protected void setCmrFieldType(String JavaDoc type) throws DeploymentDescException {
271         try {
272             cmrFieldType = Class.forName(type);
273         } catch (ClassNotFoundException JavaDoc e) {
274             throw new DeploymentDescException("class name not found for cmr-field " + cmrFieldName + " of bean "
275                     + ejbSourceName, e);
276         }
277         if (!(cmrFieldType.getName().equals("java.util.Collection") || cmrFieldType.getName().equals("java.util.Set"))) {
278             throw new DeploymentDescException("value of cmr-field-type " + cmrFieldName + " of bean " + ejbSourceName
279                     + " should be java.util.Set or java.util.Collection if set");
280         }
281     }
282
283     /**
284      * mark the cmr as added by JOnAS
285      */

286     protected void setIsJOnASCmrField() {
287         isJOnASCMR = true;
288     }
289
290     /**
291      * set the source bean of this relation-ship role.
292      * @param led EntityCmp2Desc for the source bean of this relation-ship role.
293      */

294     protected void setSourceBean(EntityCmp2Desc led) {
295         sourceEntityCmp2Desc = led;
296     }
297
298     /**
299      * set the target bean of this relation-ship role.
300      * @param led EntityCmp2Desc for the target bean of this relation-ship role.
301      */

302     protected void setTargetBean(EntityCmp2Desc led) {
303         targetEntityCmp2Desc = led;
304         if (cmrFieldType == null) {
305             cmrFieldType = led.getLocalClass();
306         }
307     }
308
309     /**
310      * get the parent ejb relation of this relation-ship-role.
311      * @return the EjbRelationDesc of this relation-ship-role.
312      */

313     public EjbRelationDesc getRelation() {
314         return ejbRelationDesc;
315     }
316
317     /**
318      * get the opposite relation-ship-role of this relation-ship-role.
319      * @return the opposite EjbRelationshipRoleDesc of this relation-ship-role.
320      */

321     public EjbRelationshipRoleDesc getOppositeRelationshipRole() {
322         EjbRelationshipRoleDesc res = ejbRelationDesc.getRelationshipRole1();
323         if (res == this) {
324             return ejbRelationDesc.getRelationshipRole2();
325         } else {
326             return res;
327         }
328     }
329
330     /**
331      * Get the name of the ejb involved in this relation-ship-role. This is the
332      * source bean name of this relation.
333      * @return the String ejb-name of the source bean.
334      */

335     public String JavaDoc getSourceBeanName() {
336         return ejbSourceName;
337     }
338
339     /**
340      * Get the ejb involved in this relation-ship-role. this is the source bean
341      * of this relation.
342      * @return the EntityCmp2Desc of the source bean.
343      */

344     public EntityCmp2Desc getSourceBean() {
345         return sourceEntityCmp2Desc;
346     }
347
348     /**
349      * It retrieves the EntityCmp2Desc which is linked to the EntityCmp2Desc
350      * associated to this EjbRelationshipRoleDesc. This is the target bean of
351      * this relationship role
352      * @return the EntityCmp2Desc of the target bean.
353      */

354     public EntityCmp2Desc getTargetBean() {
355         return targetEntityCmp2Desc;
356     }
357
358     /**
359      * Get state of opposite relationship-role is relation multiple.
360      * @return true if the opposite relationship-role is relation multiple.
361      */

362     public boolean isSourceMultiple() {
363         return isSourceMultiple;
364     }
365
366     /**
367      * Get state of this relationship-role is relation multiple. (get state of
368      * field is relation multiple).
369      * @return true if the relationship-role is relation multiple.
370      */

371     public boolean isTargetMultiple() {
372         return isTargetMultiple;
373     }
374
375     /**
376      * @return true if this bean must cascade delete the other bean in this
377      * relation.
378      */

379     public boolean mustCascade() {
380         return mustCascade;
381     }
382
383     /**
384      * It returns a boolean value which indicates if the cmr has been added by
385      * JOnAS (true) or if the user has specified a cmr field in the descriptor.
386      * A CMR field is be added to manage the coherence of the relation OXu
387      * @return true if the CMR field is not a bean's programmer CMR field.
388      */

389     public boolean isJOnASCmrField() {
390         return isJOnASCMR;
391     }
392
393     /**
394      * It retrieves true if the EntityCmp2Desc associated to this
395      * EjbRelationshipRoleDesc has a cmr field to the linked EntityCmp2Desc
396      * @return true if the relation-ship-role has a CMR field.
397      */

398     // TODO: is this method really needed (return always true??)
399
public boolean hasCmrField() {
400         return cmrFieldName != null;
401     }
402
403     /**
404      * get the name of the cmr-field.
405      * @return the String name of the cmr-field.
406      */

407     public String JavaDoc getCmrFieldName() {
408         return cmrFieldName;
409     }
410
411     /**
412      * get the type of the cmr-field when set in the deployment descriptor.
413      * @return Collection or Set for multiple rel. and null for non multiple
414      * rel.
415      */

416     public Class JavaDoc getCmrFieldType() {
417         return cmrFieldType;
418     }
419
420     /**
421      * This method depends on static values OOB,OOU,... defined upper !
422      * @return the type of the relation: OO-u, OO-b, OM-u, ....
423      */

424     public byte getRelationType() {
425         if (relationType == -1) {
426             relationType = OOU;
427             EjbRelationshipRoleDesc rsr2 = getOppositeRelationshipRole();
428             if (rsr2.hasCmrField() && hasCmrField()) {
429                 relationType += OOB;
430             }
431             if (isTargetMultiple()) {
432                 relationType += OMU;
433             }
434             if (rsr2.isTargetMultiple()) {
435                 relationType += MOU;
436             }
437         }
438         return relationType;
439     }
440
441     /**
442      * Is a jdbc mapping is defined for this relationship role ?
443      * @return true if a jdbc mapping is defined for this relationship role.
444      */

445     public boolean hasJdbcMapping() {
446         return hasJdbcMapping;
447     }
448
449     /**
450      * In M-N relationships, only 1 role will write data on DB.
451      * @return true if role will not write MN relations on database
452      */

453     public boolean isSlave() {
454         return isSlave;
455     }
456
457     /**
458      * @param jdbcFieldName a primary key column name of the table associated to
459      * the target bean.
460      * @return the foreign key column name associated to the given primary key
461      * column name.
462      */

463     public String JavaDoc getForeignKeyJdbcName(String JavaDoc jdbcFieldName) {
464         return (String JavaDoc) foreignKeyMap.get(jdbcFieldName);
465     }
466
467     /**
468      * String representation of the object for test purpose
469      * @return String representation of this object
470      */

471     public String JavaDoc toString() {
472         StringBuffer JavaDoc ret = new StringBuffer JavaDoc();
473         ret.append("\ngetName() = " + getName());
474         ret.append("\ngetRelation().getName() = " + getRelation().getName());
475         ret.append("\ngetOppositeRelationshipRole().getName() = " + getOppositeRelationshipRole().getName());
476         ret.append("\ngetSourceBeanName() = " + getSourceBeanName());
477         ret.append("\ngetTargetBean().getName() = " + getTargetBean().getEjbName());
478         ret.append("\nisSourceMultiple() = " + isSourceMultiple());
479         ret.append("\nisTargetMultiple() = " + isTargetMultiple());
480         ret.append("\nmustCascade() = " + mustCascade());
481         ret.append("\nisJOnASCmrField() = " + isJOnASCmrField());
482         ret.append("\ngetCmrFieldName() = " + getCmrFieldName());
483         ret.append("\ngetCmrFieldType() = " + getCmrFieldType());
484         ret.append("\ngetRelationType() = " + getRelationType());
485         if (hasJdbcMapping()) {
486             for (Iterator JavaDoc i = foreignKeyMap.keySet().iterator(); i.hasNext();) {
487                 String JavaDoc key = (String JavaDoc) i.next();
488                 String JavaDoc fkey = (String JavaDoc) foreignKeyMap.get(key);
489                 ret.append("\ngetForeignKeyJdbcName(" + key + ")=" + fkey);
490             }
491         }
492         return ret.toString();
493     }
494
495 }
Popular Tags