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: EntityCmpDesc.java 6677 2005-04-29 21:35:54Z ashah $
023: * --------------------------------------------------------------------------
024: */package org.objectweb.jonas_ejb.deployment.api;
025:
026: import java.lang.reflect.Field;
027: import java.lang.reflect.Modifier;
028: import java.util.HashMap;
029: import java.util.Iterator;
030:
031: import org.objectweb.jonas_ejb.deployment.xml.AssemblyDescriptor;
032: import org.objectweb.jonas_ejb.deployment.xml.Entity;
033: import org.objectweb.jonas_ejb.deployment.xml.CmpField;
034: import org.objectweb.jonas_ejb.deployment.xml.JonasEntity;
035: import org.objectweb.jonas_ejb.deployment.xml.JdbcMapping;
036: import org.objectweb.jonas_ejb.lib.BeanNaming;
037: import org.objectweb.jonas_lib.deployment.api.DeploymentDescException;
038: import org.objectweb.jonas_lib.deployment.xml.JLinkedList;
039:
040: /**
041: * Base class to hold meta-information related to an entity of type CMP.
042: * @author Christophe Ney [cney@batisseurs.com] : Initial developer
043: * @author Helene Joanin
044: * @author Jerome Camilleri : automatic PK
045: */
046: public abstract class EntityCmpDesc extends EntityDesc {
047:
048: protected HashMap fieldDesc = new HashMap();
049: protected String primaryKeyField = null;
050: protected String jdbcAutomaticPkFieldName = null;
051:
052: /**
053: * constructor to be used by parent node.
054: * @param classLoader class loader to use to laod bean's classes
055: * @param ent entity in the standard deployment descriptor
056: * @param asd assembly-descriptor in the standard deployment descriptor
057: * @param jEnt jonas-entity in the JOnAS deployment descriptor
058: * @param fileName jar or directory containing ejb
059: * @throws DeploymentDescException in error case.
060: */
061: public EntityCmpDesc(ClassLoader classLoader, Entity ent,
062: AssemblyDescriptor asd, JonasEntity jEnt,
063: JLinkedList jMDRList, String fileName)
064: throws DeploymentDescException {
065:
066: super (classLoader, ent, asd, jEnt, jMDRList, fileName);
067:
068: // field descriptors for persistent fields
069: for (Iterator i = ent.getCmpFieldList().iterator(); i.hasNext();) {
070: String fn = ((CmpField) i.next()).getFieldName();
071: FieldDesc fd = this .newFieldDescInstance();
072: fd.setName(fn);
073: fd.setPrimaryKey(false);
074: fieldDesc.put(fn, fd);
075:
076: }
077:
078: // jdbc pk auto field name
079: JdbcMapping jm = jEnt.getJdbcMapping();
080: if ((jm != null) && (jm.getJdbcAutomaticPkFieldName() != null)) {
081: if (jm.getJdbcAutomaticPkFieldName().length() != 0) {
082: jdbcAutomaticPkFieldName = jm
083: .getJdbcAutomaticPkFieldName();
084: }
085: }
086: if (jdbcAutomaticPkFieldName == null) {
087: // Default value
088: jdbcAutomaticPkFieldName = "JPK_";
089: }
090:
091: if (isUndefinedPK()) { // Automatic PK
092: // If Primary Field is not declared (auto generated key field)
093: primaryKeyField = "JONASAUTOPKFIELD";
094: } else if (ent.getPrimkeyField() != null) {
095: // primary key field
096: primaryKeyField = ent.getPrimkeyField();
097: FieldDesc fd = (FieldDesc) fieldDesc.get(primaryKeyField);
098: if (fd == null) {
099: throw new DeploymentDescException("primkey-field "
100: + primaryKeyField
101: + " is not listed as cmp-field in bean "
102: + this .ejbName);
103: }
104: fd.setPrimaryKey(true);
105: } else {
106: // public fields of primary key class
107: Field[] pcf = primaryKeyClass.getFields();
108: for (int i = 0; i < pcf.length; i++) {
109: if (Modifier.isPublic(pcf[i].getModifiers())) {
110: String pn = pcf[i].getName();
111: // exclude serialVersionUID field for jdk1.2.1 on solaris and
112: // exclude JProbe$ for JProbe using
113: if (!pn.equals("serialVersionUID")
114: && !pn.startsWith("JProbe$")) {
115: FieldDesc fd = (FieldDesc) fieldDesc.get(pn);
116: if (fd == null) {
117: throw new DeploymentDescException(
118: "public field "
119: + pn
120: + " of primkey-class is not listed as cmp-field in bean "
121: + this .ejbName);
122: }
123: fd.setPrimaryKey(true);
124: }
125: }
126: }
127: }
128: String packageName = BeanDesc.GENERATED_PREFIX
129: + BeanNaming.getPackageName(getEjbClass().getName());
130: derivedBeanName = new String("JOnAS" + getIdentifier() + "Bean");
131: fullDerivedBeanName = BeanNaming.getClassName(packageName,
132: derivedBeanName);
133:
134: // automatic-pk
135: // used of specific tag automatic-pk is deprecated so nothing in this code was about jdbc-mapping
136: String primkeytype = ent.getPrimKeyClass();
137: if ((jm != null) && (jm.getAutomaticPk() != null)) {
138: // optional parameter automatic-pk
139: jdbcAutomaticPk = jm.getAutomaticPk().equalsIgnoreCase(
140: "true");
141: if (jdbcAutomaticPk && pkObjectType) {
142: // You can't use specific tag 'automatic-pk' with prim-key-type=java.lang.Object
143: throw new DeploymentDescException(
144: "Don't use specific tag 'automatic-pk' with prim-key-type=java.lang.Object in bean "
145: + ent.getEjbName());
146: }
147: }
148: if (pkObjectType && ent.getPrimkeyField() != null) {
149: throw new DeploymentDescException(
150: "'prim-key-field' must not be set if your prim-key-type was java.lang.Object in bean "
151: + ent.getEjbName());
152: }
153: if (this .isAutomaticPk()) { // Check if prim-key-class type is Integer or java.lang.Object
154: if (!(primkeytype.equalsIgnoreCase("java.lang.Integer") || primkeytype
155: .equalsIgnoreCase("Integer"))) {
156: throw new DeploymentDescException(
157: "You must used java.lang.Integer type for your auto-generate primary key field in bean "
158: + ent.getEjbName());
159: }
160: }
161: }
162:
163: /**
164: * Get descriptor for a given field name
165: * Used by GenIC
166: * @param fieldName Name of the field
167: * @return Descriptor for the given field or null
168: */
169: public FieldDesc getCmpFieldDesc(String fieldName) {
170: return (FieldDesc) fieldDesc.get(fieldName);
171: }
172:
173: /**
174: * Indicate if the primary key field is only one field with a primary-key-field
175: * defined in the DD.
176: * @return true if the primary key field is only one field
177: * with a primary-key-field defined in the DD.
178: */
179: public boolean hasSimplePkField() {
180: return primaryKeyField != null;
181: }
182:
183: // TODO remove this method and keep only the hasSimplePkField method
184: public boolean hasPrimaryKeyField() {
185: return hasSimplePkField();
186: }
187:
188: /**
189: * Get the primary key field for the entity.
190: * @return Field for the primary key
191: */
192: public FieldDesc getSimplePkField() {
193: FieldDesc fd = (FieldDesc) fieldDesc
194: .get(getSimplePkFieldName());
195: return fd;
196: }
197:
198: /**
199: * Get the primary key field name for the entity.
200: * @return Field for the primary key
201: */
202: public String getSimplePkFieldName() {
203: if (primaryKeyField == null) {
204: throw new Error("No primary key field defined for bean "
205: + this .ejbName);
206: }
207: return primaryKeyField;
208: }
209:
210: // TODO remove this method and keep only the getSimplePkFieldName() method
211: public String getPrimaryKeyFieldName() {
212: return getSimplePkFieldName();
213: }
214:
215: /**
216: * Get the associated field for auto genarated pk field specify by user
217: * @return Name of the field where automatic pk bean is stored
218: */
219: public String getJdbcAutomaticPkFieldName() {
220: return jdbcAutomaticPkFieldName;
221: }
222:
223: public Iterator getCmpFieldDescIterator() {
224: return fieldDesc.values().iterator();
225: }
226:
227: /**
228: * String representation of the object for test purpose
229: * @return String representation of this object
230: */
231: public String toString() {
232: StringBuffer ret = new StringBuffer();
233: ret.append(super .toString());
234: for (Iterator i = fieldDesc.keySet().iterator(); i.hasNext();) {
235: String f = (String) i.next();
236: FieldDesc fd = (FieldDesc) fieldDesc.get(f);
237: ret.append("\ngetCmpFieldDesc(" + f + ")="
238: + fd.getClass().getName());
239: ret.append(fd.toString());
240: }
241: if (hasPrimaryKeyField()) {
242: ret.append("\ngetPrimaryKeyField()="
243: + getPrimaryKeyFieldName());
244: }
245: return ret.toString();
246: }
247:
248: /**
249: * factory method for field descriptors
250: * @return a FieldDesc.
251: */
252: protected FieldDesc newFieldDescInstance() {
253: return new FieldJdbcDesc();
254: }
255: }
|