001: /**
002: * JOnAS: Java(TM) Open Application Server
003: * Copyright (C) 1999-2004 Bull S.A.
004: * Contact: jonas-team@objectweb.org
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
019: * USA
020: *
021: * --------------------------------------------------------------------------
022: * $Id: EjbRelationDesc.java 5509 2004-09-27 14:50:09Z joaninh $
023: * --------------------------------------------------------------------------
024: */package org.objectweb.jonas_ejb.deployment.api;
025:
026: import java.util.HashMap;
027: import java.util.Iterator;
028:
029: import org.objectweb.jonas_ejb.deployment.xml.EjbRelation;
030: import org.objectweb.jonas_ejb.deployment.xml.EjbRelationshipRole;
031: import org.objectweb.jonas_ejb.deployment.xml.JonasEjbRelation;
032: import org.objectweb.jonas_ejb.deployment.xml.JonasEjbRelationshipRole;
033: import org.objectweb.jonas_lib.deployment.api.DeploymentDescException;
034: import org.objectweb.util.monolog.api.Logger;
035:
036: /**
037: * Class to hold meta-information related to an ejb-relation.
038: * @author Christophe Ney [cney@batisseurs.com] : Initial developer
039: * @author Helene Joanin on May 2003: code cleanup
040: * @author Helene Joanin on May 2003: complement for legacy first version
041: * @author Ph Durieux (may 2004): default names for relations and roles.
042: */
043:
044: public class EjbRelationDesc {
045:
046: private Logger logger = null;
047: private String name; // name of the relation
048: private String name1; // name of the relation role 1
049: private String name2; // name of the relation role 2
050: private EjbRelationshipRoleDesc relationshipRoleDesc1;
051: private EjbRelationshipRoleDesc relationshipRoleDesc2;
052: private String jdbcTableName = null;
053:
054: // Zeus objects for the associated mapping information (needed in fillMappingInfo);
055: private EjbRelationshipRole role1;
056: private EjbRelationshipRole role2;
057: JonasEjbRelation jRel = null;
058: JonasEjbRelationshipRole jRsRole1 = null;
059: JonasEjbRelationshipRole jRsRole2 = null;
060:
061: /**
062: * constructor to be used by parent node.
063: * @param er The described object EjbRelation
064: * @param logger The logger
065: * @throws DeploymentDescException thrown in error case.
066: */
067: public EjbRelationDesc(EjbRelation er, Logger logger)
068: throws DeploymentDescException {
069:
070: this .logger = logger;
071:
072: role1 = er.getEjbRelationshipRole();
073: role2 = er.getEjbRelationshipRole2();
074:
075: String cmr1 = "";
076: if (role1.getCmrField() != null) {
077: cmr1 = role1.getCmrField().getCmrFieldName();
078: }
079: String cmr2 = "";
080: if (role2.getCmrField() != null) {
081: cmr2 = role2.getCmrField().getCmrFieldName();
082: }
083:
084: // first role. A name is mandatory.
085: // If not set: choose the cmr name of the opposite role, if it exists.
086: name1 = role1.getEjbRelationshipRoleName();
087: if (name1 == null || name1.length() == 0) {
088: if (role2.getCmrField() != null) {
089: name1 = cmr2;
090: } else {
091: name1 = "role1"; // a default value
092: }
093: // We have changed the name, keep the new one.
094: role1.setEjbRelationshipRoleName(name1);
095: }
096:
097: // second role. A name is mandatory.
098: // If not set: choose the cmr name of the opposite role, if it exists.
099: name2 = role2.getEjbRelationshipRoleName();
100: if (name2 == null || name2.length() == 0) {
101: if (role1.getCmrField() != null) {
102: name2 = cmr1;
103: } else {
104: name2 = "role2"; // a default value
105: }
106: // We have changed the name, keep the new one.
107: role2.setEjbRelationshipRoleName(name2);
108: }
109:
110: // the two roles must have different names
111: if (name1.equals(name2)) {
112: throw new DeploymentDescException("Relation " + name
113: + " have 2 roles with same name: " + name1);
114: }
115:
116: // name of the relation. If not set, choose a combination of the 2 cmr names.
117: String ern = er.getEjbRelationName();
118: if (ern == null || ern.length() == 0) {
119: name = cmr2 + "-" + cmr1;
120: } else {
121: name = ern;
122: }
123: }
124:
125: /**
126: * Finish initialisation
127: * @param jer The described object JonasEjbRelation. This param may be null.
128: * @throws DeploymentDescException in error case
129: */
130: public void setJonasInfo(JonasEjbRelation jer)
131: throws DeploymentDescException {
132: // search the associated JonasEjbRelationshipRole of EjbRelationshipRole.
133: // They may not exist.
134: jRel = jer;
135: HashMap table = new HashMap();
136: if (jRel != null) {
137: for (Iterator i = jRel.getJonasEjbRelationshipRoleList()
138: .iterator(); i.hasNext();) {
139: JonasEjbRelationshipRole jersr = (JonasEjbRelationshipRole) i
140: .next();
141: String rname = jersr.getEjbRelationshipRoleName();
142: if (!rname.equals(name1) && !rname.equals(name2)) {
143: throw new DeploymentDescException(
144: "Invalid relationship-role-name \"" + rname
145: + "\" for relation \"" + name
146: + "\" in jonas-ejb-jar.xml");
147: }
148: table.put(rname, jersr);
149: }
150: }
151: jRsRole1 = (JonasEjbRelationshipRole) table.get(name1);
152: jRsRole2 = (JonasEjbRelationshipRole) table.get(name2);
153:
154: relationshipRoleDesc1 = new EjbRelationshipRoleDesc(this ,
155: name1, role1, jRsRole1, role2, true, logger);
156: relationshipRoleDesc2 = new EjbRelationshipRoleDesc(this ,
157: name2, role2, jRsRole2, role1, false, logger);
158:
159: // Add the opposite CMR field for the relation XXu
160: // in order to implement the coherence.
161: boolean r1hf = relationshipRoleDesc1.hasCmrField();
162: boolean r2hf = relationshipRoleDesc2.hasCmrField();
163: EjbRelationshipRoleDesc nocmr = null;
164: EjbRelationshipRoleDesc cmr = null;
165: if (r1hf && !r2hf) {
166: nocmr = relationshipRoleDesc2;
167: cmr = relationshipRoleDesc1;
168: } else if (!r1hf && r2hf) {
169: nocmr = relationshipRoleDesc1;
170: cmr = relationshipRoleDesc2;
171: }
172: if (nocmr != null) {
173: // The relation is OXu, the role 'role' does not have cmr field
174: String cmrName = name;
175: // calculate a cmr field name with the relation name. The bad
176: // character are replaced by the character '_'.
177: for (int i = 0; i < cmrName.length(); i++) {
178: char c = cmrName.charAt(i);
179: if (!Character.isJavaIdentifierPart(c)) {
180: cmrName = cmrName.replace(c, '_');
181: }
182: }
183: cmrName = "jonasCMR" + cmrName;
184: // Add the cmr, no type is specified because the added cmr field
185: // is mono valued.
186: nocmr.setCmrFieldName(cmrName);
187: nocmr.setIsJOnASCmrField();
188: if (nocmr.isTargetMultiple()) {
189: if (cmr.isTargetMultiple()) {
190: nocmr.setCmrFieldType(cmr.cmrFieldType.getName());
191: } else {
192: nocmr.setCmrFieldType("java.util.Collection");
193: }
194: }
195: }
196: }
197:
198: /**
199: * Fills the mapping information of this relation with the values defined in jonas DD.
200: * @throws DeploymentDescException thrown in error case.
201: */
202: protected void fillMappingInfo() throws DeploymentDescException {
203: if (jRel != null) {
204: if (jRel.getJdbcTableName() != null) {
205: if (jRel.getJdbcTableName().length() != 0) {
206: jdbcTableName = jRel.getJdbcTableName();
207: }
208: }
209: relationshipRoleDesc1.fillMappingInfo();
210: relationshipRoleDesc2.fillMappingInfo();
211: }
212: }
213:
214: /**
215: * Fills the mapping information of this relation with default values,
216: * if the mapping information is not already initialized.
217: */
218: protected void fillMappingInfoWithDefault() {
219: if (!hasJdbcTable()) {
220: if (getRelationshipRole1().isTargetMultiple()
221: && getRelationshipRole2().isTargetMultiple()) {
222: // Many-Many: join table needed for the relation
223: jdbcTableName = getRelationshipRole1().getSourceBean()
224: .getAbstractSchemaName().toUpperCase()
225: + "_"
226: + getRelationshipRole2().getSourceBean()
227: .getAbstractSchemaName().toUpperCase();
228: }
229: }
230: if (!getRelationshipRole1().isSourceMultiple()
231: && !getRelationshipRole2().isSourceMultiple()) {
232: // One-One
233: if (!getRelationshipRole1().hasJdbcMapping()
234: && !getRelationshipRole2().hasJdbcMapping()) {
235: if (!getRelationshipRole1().isJOnASCmrField()
236: && !getRelationshipRole2().isJOnASCmrField()) {
237: // One <-> One: foreign keys in the source bean of the first RsRole defined
238: getRelationshipRole1().fillMappingInfoWithDefault();
239: } else {
240: if (!getRelationshipRole1().isJOnASCmrField()) {
241: // One -> One: foreign keys in the source bean of RsRole1
242: getRelationshipRole1()
243: .fillMappingInfoWithDefault();
244: } else {
245: // One <- One: foreign keys in the target bean of RsRole1
246: getRelationshipRole2()
247: .fillMappingInfoWithDefault();
248: }
249: }
250: }
251: } else if (getRelationshipRole1().isSourceMultiple()
252: && getRelationshipRole2().isSourceMultiple()) {
253: // Many-Many
254: getRelationshipRole1().fillMappingInfoWithDefault();
255: getRelationshipRole2().fillMappingInfoWithDefault();
256: } else {
257: // One-Many or Many-One
258: if (getRelationshipRole1().isSourceMultiple()) {
259: // Many-One
260: getRelationshipRole1().fillMappingInfoWithDefault();
261: } else {
262: // One-Many
263: getRelationshipRole2().fillMappingInfoWithDefault();
264: }
265: }
266: }
267:
268: /**
269: * get the name of the relationship.
270: * @return the String name of the relationship.
271: */
272: public String getName() {
273: return name;
274: }
275:
276: /**
277: * get the meta-information for the first relation-ship-role
278: * @return the EjbRelationshipRoleDesc for the first relation-ship-role
279: */
280: public EjbRelationshipRoleDesc getRelationshipRole1() {
281: return relationshipRoleDesc1;
282: }
283:
284: /**
285: * get the meta-information for the second relation-ship-role
286: * @return the EjbRelationshipRoleDesc for the second relation-ship-role
287: */
288: public EjbRelationshipRoleDesc getRelationshipRole2() {
289: return relationshipRoleDesc2;
290: }
291:
292: /**
293: * Is a table in the database is defined for this relation ?
294: * @return true if table name in the database is defined for this relation.
295: */
296: public boolean hasJdbcTable() {
297: return (jdbcTableName != null);
298: }
299:
300: /**
301: * Return the table name in the database associated to this relation.
302: * @return the String name of the table associated to this relation.
303: */
304: public String getJdbcTableName() {
305: return jdbcTableName;
306: }
307:
308: /**
309: * String representation of the object for test purpose
310: * @return String representation of this object
311: */
312: public String toString() {
313: StringBuffer ret = new StringBuffer();
314: ret.append("\ngetName()=" + getName());
315: if (hasJdbcTable()) {
316: ret.append("\ngetJdbcTableName() = " + getJdbcTableName());
317: }
318: ret.append("\ngetRelationshipRole1() = "
319: + getRelationshipRole1());
320: ret.append("\ngetRelationshipRole2() = "
321: + getRelationshipRole2());
322: return ret.toString();
323: }
324: }
|