KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > ejb > cfg > EjbEntityBean


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.ejb.cfg;
31
32 import com.caucho.amber.manager.AmberPersistenceUnit;
33 import com.caucho.amber.type.EntityType;
34 import com.caucho.bytecode.JClass;
35 import com.caucho.bytecode.JClassLoader;
36 import com.caucho.bytecode.JClassWrapper;
37 import com.caucho.bytecode.JField;
38 import com.caucho.bytecode.JMethod;
39 import com.caucho.config.ConfigException;
40 import com.caucho.config.LineConfigException;
41 import com.caucho.config.types.Period;
42 import com.caucho.ejb.AbstractServer;
43 import com.caucho.ejb.EjbServerManager;
44 import com.caucho.ejb.amber.AmberConfig;
45 import com.caucho.ejb.entity.EntityServer;
46 import com.caucho.ejb.gen.AmberAssembler;
47 import com.caucho.ejb.gen.BeanAssembler;
48 import com.caucho.ejb.gen.EntityAssembler;
49 import com.caucho.ejb.gen.EntityCreateMethod;
50 import com.caucho.ejb.gen.EntityFindMethod;
51 import com.caucho.ejb.gen.EntityHomePoolChain;
52 import com.caucho.java.JavaWriter;
53 import com.caucho.java.gen.BaseClass;
54 import com.caucho.java.gen.BaseMethod;
55 import com.caucho.java.gen.CallChain;
56 import com.caucho.java.gen.JavaClassGenerator;
57 import com.caucho.java.gen.MethodCallChain;
58 import com.caucho.management.j2ee.J2EEManagedObject;
59 import com.caucho.util.L10N;
60
61 import javax.annotation.PostConstruct;
62 import javax.ejb.*;
63 import javax.sql.DataSource JavaDoc;
64 import java.io.IOException JavaDoc;
65 import java.util.ArrayList JavaDoc;
66 import java.util.Collection JavaDoc;
67 import java.util.Enumeration JavaDoc;
68 import java.util.Map JavaDoc;
69
70 /**
71  * Configuration for an ejb entity bean.
72  */

73 public class EjbEntityBean extends EjbBean {
74   private final static L10N L = new L10N(EjbEntityBean.class);
75
76   private JClassWrapper _primKeyClass;
77   private String JavaDoc _primKeyField;
78
79   private JClass _compositeKeyClass;
80
81   private String JavaDoc _cmpVersion = "2.x";
82   private boolean _isCMP = false;
83
84   private DataSource JavaDoc _dataSource;
85
86   private String JavaDoc _abstractSchemaName;
87   private String JavaDoc _sqlTable;
88
89   private long _cacheTimeout = 2000L;
90   private int _cacheSize = -666;
91
92   private boolean _loadLazyOnTransaction = true;
93
94   private boolean _isReadOnly = false;
95   private boolean _isReentrant = true;
96
97   private ArrayList JavaDoc<CmpField> _fields = new ArrayList JavaDoc<CmpField>();
98
99   private ArrayList JavaDoc<CmrRelation> _relations = new ArrayList JavaDoc<CmrRelation>();
100   private ArrayList JavaDoc<JMethod> _stubMethods = new ArrayList JavaDoc<JMethod>();
101
102   /**
103    * Creates a new entity bean configuration.
104    */

105   public EjbEntityBean(EjbConfig ejbConfig, String JavaDoc ejbModuleName)
106   {
107     super(ejbConfig, ejbModuleName);
108
109     EjbServerManager ejbManager = ejbConfig.getEJBManager();
110
111     if (ejbManager != null) {
112       _cacheTimeout = ejbManager.getCacheTimeout();
113       _loadLazyOnTransaction = ejbManager.isEntityLoadLazyOnTransaction();
114     }
115   }
116
117   /**
118    * Returns the kind of bean.
119    */

120   public String JavaDoc getEJBKind()
121   {
122     return "entity";
123   }
124
125   /**
126    * Sets the ejb implementation class.
127    */

128   public void setEJBClass(Class JavaDoc ejbClass)
129     throws ConfigException
130   {
131     super.setEJBClass(ejbClass);
132
133     if (! EntityBean.class.isAssignableFrom(ejbClass) && ! isAllowPOJO())
134       throw error(L.l("`{0}' must implement EntityBean. Entity beans must implement javax.ejb.EntityBean.", ejbClass.getName()));
135
136
137     validateNonFinalMethod("setEntityContext",
138                            new JClass[] { JClassLoader.systemForName(EntityContext.class.getName()) }, isAllowPOJO());
139     validateNonFinalMethod("unsetEntityContext", new JClass[0], isAllowPOJO());
140     validateNonFinalMethod("ejbActivate", new JClass[0], isAllowPOJO());
141     validateNonFinalMethod("ejbPassivate", new JClass[0], isAllowPOJO());
142
143     validateNonFinalMethod("ejbRemove", new JClass[0], isAllowPOJO());
144     // XXX: spec doesn't enforce this
145
// validator.validateException(implMethod, RemoveException.class);
146
validateNonFinalMethod("ejbLoad", new JClass[0], isAllowPOJO());
147     validateNonFinalMethod("ejbStore", new JClass[0], isAllowPOJO());
148   }
149
150   /**
151    * Returns the amber entity-type.
152    */

153   public EntityType getEntityType()
154   {
155     AmberPersistenceUnit amberPersistenceUnit = getConfig().getEJBManager().getAmberManager();
156
157     EntityType type = amberPersistenceUnit.createEntity(getAbstractSchemaName(),
158                                                         getEJBClassWrapper());
159
160     type.setProxyClass(getLocal());
161
162     return type;
163   }
164
165   /**
166    * Returns the primary key class.
167    */

168   public JClass getPrimKeyClass()
169   {
170     return _primKeyClass;
171   }
172
173   /**
174    * Sets the primary key class.
175    */

176   public void setPrimKeyClass(Class JavaDoc cl)
177   {
178     _primKeyClass = new JClassWrapper(cl, _jClassLoader);
179   }
180
181   /**
182    * Returns the primary key class.
183    */

184   public JClass getCompositeKeyClass()
185   {
186     return _compositeKeyClass;
187   }
188
189   /**
190    * Returns the primary key field.
191    */

192   public String JavaDoc getPrimKeyField()
193   {
194     return _primKeyField;
195   }
196
197   /**
198    * Sets the primary key field.
199    */

200   public void setPrimKeyField(String JavaDoc field)
201   {
202     _primKeyField = field;
203   }
204
205   /**
206    * Sets the persistence type.
207    */

208   public void setPersistenceType(String JavaDoc type)
209     throws ConfigException
210   {
211     if ("Bean".equals(type))
212       _isCMP = false;
213     else if ("Container".equals(type)) {
214       _isCMP = true;
215
216       /* ejb/0880
217       if (getConfig().getEJBManager().getDataSource() == null) {
218     throw new ConfigException(L.l("No DataSource found. The EJB server can't find a configured database."));
219       }
220       */

221     }
222     else
223       throw new ConfigException(L.l("`{0}' is an known persistence-type. <persistence-type> must either be `Bean' or `Container'.", type));
224   }
225
226   /**
227    * Returns true if the entity bean is a CMP.
228    */

229   public boolean isCMP()
230   {
231     return _isCMP && "2.x".equals(_cmpVersion);
232   }
233
234   /**
235    * Sets true if the entity bean is CMP.
236    */

237   public void setCMP(boolean isCMP)
238   {
239     _isCMP = isCMP;
240   }
241
242   /**
243    * Returns true if the entity bean is a CMP.
244    */

245   public boolean isCMP1()
246   {
247     return _isCMP && "1.x".equals(_cmpVersion);
248   }
249
250   /**
251    * Gets the implementation class name.
252    */

253   public String JavaDoc getFullImplName()
254   {
255     if (isCMP()) {
256       String JavaDoc name = "_ejb." + getEJBName() + "." + getEJBClassName() + "__Amber";
257       return JavaClassGenerator.cleanClassName(name);
258     }
259     else
260       return super.getFullImplName();
261   }
262
263   /**
264    * Sets the CMP version.
265    */

266   public void setCmpVersion(String JavaDoc version)
267     throws ConfigException
268   {
269     _cmpVersion = version;
270
271     if (! version.equals("1.x") && ! version.equals("2.x"))
272       throw error(L.l("CMP version `{0}' is not currently supported. Only CMP version 1.x and 2.x are supported.", version));
273   }
274
275   /**
276    * Sets true if the bean is reentrant.
277    */

278   public void setReentrant(boolean reentrant)
279     throws ConfigException
280   {
281     _isReentrant = reentrant;
282   }
283
284   /**
285    * Returns the JNDI name for the data-source
286    */

287   public DataSource JavaDoc getDataSource()
288   {
289     return _dataSource;
290   }
291
292   /**
293    * Sets the data-source for the bean.
294    */

295   public void setDataSource(DataSource JavaDoc dataSource)
296   {
297     _dataSource = dataSource;
298   }
299
300   /**
301    * Returns the abstract-schema-name for the bean.
302    */

303   public String JavaDoc getAbstractSchemaName()
304   {
305     if (_abstractSchemaName != null)
306       return _abstractSchemaName;
307     else {
308       String JavaDoc name = getEJBName();
309
310       int p = name.lastIndexOf('/');
311       if (p < 0)
312         return name;
313       else
314         return name.substring(p + 1);
315     }
316   }
317
318   /**
319    * Sets the abstract-schema for the bean.
320    */

321   public void setAbstractSchemaName(String JavaDoc abstractSchema)
322     throws ConfigException
323   {
324     _abstractSchemaName = abstractSchema;
325
326     EjbEntityBean bean = getConfig().findEntityBySchema(abstractSchema);
327
328     if (bean != null && this != bean)
329       throw new ConfigException(L.l("Entity bean '{0}' already has abstract schema '{1}'. abstract-schema-name values must be distinct.",
330                                     bean.getEJBName(), abstractSchema));
331   }
332
333   /**
334    * Returns the sql-table for the bean.
335    */

336   public String JavaDoc getSQLTable()
337   {
338     return _sqlTable;
339   }
340
341   /**
342    * Sets the sql-table for the bean.
343    */

344   public void setSQLTable(String JavaDoc sqlTable)
345   {
346     _sqlTable = sqlTable;
347   }
348
349   /**
350    * Returns the number of items in the entity cache.
351    */

352   public int getCacheSize()
353   {
354     return _cacheSize;
355   }
356
357   /**
358    * Sets the number of items in the entity cache.
359    */

360   public void setCacheSize(int cacheSize)
361   {
362     _cacheSize = cacheSize;
363   }
364
365   /**
366    * Sets the timeout for items in the entity cache.
367    */

368   public void setCacheTimeout(Period cacheTimeout)
369   {
370     _cacheTimeout = cacheTimeout.getPeriod();
371   }
372
373   /**
374    * Gets the timeout for items in the entity cache.
375    */

376   public long getCacheTimeout()
377   {
378     return _cacheTimeout;
379   }
380
381   /**
382    * Returns true if the entity bean is read-only
383    */

384   public boolean isReadOnly()
385   {
386     return _isReadOnly;
387   }
388
389   /**
390    * Sets true if the entity bean is read-only
391    */

392   public void setReadOnly(boolean isReadOnly)
393   {
394     _isReadOnly = isReadOnly;
395   }
396
397   /**
398    * Adds a new cmp-field.
399    */

400   public CmpFieldProxy createCmpField()
401   {
402     return new CmpFieldProxy(this);
403   }
404
405   /**
406    * Gets all the cmp-fields
407    */

408   public ArrayList JavaDoc<CmpField> getCmpFields()
409   {
410     return _fields;
411   }
412
413   /**
414    * Gets the matching cmp-field.
415    */

416   public CmpField getCmpField(String JavaDoc fieldName)
417   {
418     for (int i = 0; i < _fields.size(); i++) {
419       CmpField field = _fields.get(i);
420
421       if (field.getName().equals(fieldName))
422         return field;
423     }
424
425     return null;
426   }
427
428   /**
429    * Add a cmp-field.
430    */

431   public CmpField addField(String JavaDoc fieldName)
432     throws ConfigException
433   {
434     CmpField field = getCmpField(fieldName);
435
436     if (field == null) {
437       field = new CmpField(this);
438       field.setFieldName(fieldName);
439
440       field.init();
441
442       _fields.add(field);
443     }
444
445     return field;
446   }
447
448   /**
449    * Returns the field getter method.
450    */

451   public JMethod getFieldGetter(String JavaDoc fieldName)
452   {
453     if (fieldName == null)
454       return null;
455
456     String JavaDoc methodName = ("get" +
457                          Character.toUpperCase(fieldName.charAt(0)) +
458                          fieldName.substring(1));
459
460     try {
461       return getMethod(getEJBClassWrapper(), methodName, new JClass[0]);
462     } catch (Throwable JavaDoc e) {
463       return null;
464     }
465   }
466
467   /**
468    * Adds a relation role.
469    */

470   public void addRelation(CmrRelation relation)
471     throws ConfigException
472   {
473     String JavaDoc fieldName = relation.getName();
474
475     JMethod method = getMethodField(fieldName);
476
477     if (method == null && ! (relation instanceof CmrMap))
478       throw error(L.l("'{0}' is a missing method", fieldName));
479
480     // relation.setJavaType(method.getReturnType());
481

482     _relations.add(relation);
483   }
484
485   /**
486    * Gets the matching cmp-relation.
487    */

488   public CmrRelation getRelation(String JavaDoc relationName)
489   {
490     for (int i = 0; i < _relations.size(); i++) {
491       CmrRelation relation = _relations.get(i);
492
493       if (relationName.equals(relation.getName()))
494         return relation;
495     }
496
497     return null;
498   }
499
500   /**
501    * Returns the cmp-relations
502    */

503   public ArrayList JavaDoc<CmrRelation> getRelations()
504   {
505     return _relations;
506   }
507
508   /**
509    * Returns the stub methods
510    */

511   public ArrayList JavaDoc<JMethod> getStubMethods()
512   {
513     return _stubMethods;
514   }
515
516   /**
517    * Adds a stub method
518    */

519   public void addStubMethod(JMethod method)
520   {
521     if (! _stubMethods.contains(method))
522       _stubMethods.add(method);
523   }
524
525   /**
526    * Gets the matching cmp-field.
527    */

528   public JClass getFieldType(String JavaDoc fieldName)
529   {
530     JMethod method = getMethodField(fieldName);
531
532     if (method != null)
533       return method.getReturnType();
534     else
535       return null;
536   }
537
538   /**
539    * Creates a query object for addition.
540    */

541   public Query createQuery()
542   {
543     return new Query(this);
544   }
545
546   /**
547    * Adds a query.
548    */

549   public void addQuery(Query query)
550   {
551     MethodSignature sig = query.getSignature();
552
553     EjbMethodPattern method = getMethod(sig);
554
555     if (method == null) {
556       method = new EjbMethodPattern(this, sig);
557       method.setLocation(query.getConfigLocation());
558       _methodList.add(method);
559     }
560
561     method.setQueryLocation(query.getConfigLocation());
562     method.setQuery(query.getEjbQl());
563   }
564
565   public EjbMethodPattern getMethod(MethodSignature sig)
566   {
567     for (int i = 0; i < _methodList.size(); i++) {
568       EjbMethodPattern method = _methodList.get(i);
569
570       if (method.getSignature().equals(sig))
571         return method;
572     }
573
574     return null;
575   }
576
577   /**
578    * Gets the best method.
579    */

580   public EjbMethodPattern getQuery(JMethod method, String JavaDoc intf)
581   {
582     return getMethodPattern(method, intf);
583   }
584
585   /**
586    * returns the method list.
587    */

588   public ArrayList JavaDoc<EjbMethodPattern> getQueryList()
589   {
590     return _methodList;
591   }
592
593   /**
594    * Configure initialization.
595    */

596   @PostConstruct
597   public void init()
598     throws ConfigException
599   {
600     try {
601       if (! isCMP() && getEJBClassWrapper().isAbstract())
602         throw error(L.l("'{0}' must not be abstract. BMP entity beans may not be abstract.",
603                         getEJBClass().getName()));
604
605       super.init();
606
607       if (_primKeyClass == null && ! isAllowPOJO() &&
608           (getRemote() != null || getLocal() != null))
609         throw new ConfigException(L.l("{0}: <entity> has no primary key class. Entity beans must define a prim-key-class.",
610                                       getEJBClass().getName()));
611
612       if (getRemoteHome() != null)
613         validateHome(getRemoteHome());
614       if (getLocalHome() != null)
615         validateHome(getLocalHome());
616       if (getRemote() != null)
617         validateRemote(getRemote());
618       if (getLocal() != null)
619         validateRemote(getLocal());
620
621       validateMethods();
622     } catch (LineConfigException e) {
623       throw e;
624     } catch (ConfigException e) {
625       throw new LineConfigException(getLocation() + e.getMessage(), e);
626     }
627
628     J2EEManagedObject.register(new com.caucho.management.j2ee.EntityBean(this));
629   }
630
631   /**
632    * Configure initialization.
633    */

634   public void introspect()
635     throws ConfigException
636   {
637     if (isCMP()) {
638       introspectCMPFields();
639
640       introspectCMPId();
641
642       validateCMPFields();
643     }
644   }
645
646   /**
647    * Introspects the missing CMP fields.
648    */

649   protected void introspectCMPFields()
650     throws ConfigException
651   {
652     JMethod []methods = getMethods(getEJBClassWrapper());
653
654     for (JMethod method : methods) {
655       if (! method.isAbstract())
656         continue;
657
658       String JavaDoc name = method.getName();
659
660       if (name.startsWith("get") && name.length() > 3 &&
661           method.getParameterTypes().length == 0) {
662         String JavaDoc fieldName = getterToFieldName(name);
663
664         CmrRelation rel = getRelation(fieldName);
665
666         if (rel != null) {
667           continue;
668         }
669
670         JClass type = method.getReturnType();
671
672         if (type.isAssignableTo(Collection JavaDoc.class)) {
673           throw error(L.l("'{0}' needs to be a relation",
674                           fieldName));
675         }
676         else if (type.isAssignableTo(Map JavaDoc.class)) {
677           throw error(L.l("'{0}' needs to be a relation",
678                           fieldName));
679         }
680         else if (type.isAssignableTo(EJBLocalObject.class)) {
681           throw error(L.l("{0}: '{1}' needs to be defined in an ejb-relation for getter method {2}.",
682                           getEJBClass().getName(),
683                           fieldName,
684                           method.getFullName()));
685         }
686         else if (type.isAssignableTo(EJBObject.class)) {
687           throw error(L.l("'{0}' needs to be a relation",
688                           fieldName));
689         }
690         else {
691           CmpField cmpField = addField(fieldName);
692
693           cmpField.setJavaType(method.getReturnType());
694         }
695       }
696     }
697   }
698
699   /**
700    * Introspects the missing CMP fields.
701    */

702   protected void validateCMPFields()
703     throws ConfigException
704   {
705     JMethod []methods = getMethods(getEJBClassWrapper());
706
707     for (JMethod method : methods) {
708       if (! method.isAbstract())
709         continue;
710
711       String JavaDoc name = method.getName();
712
713       if (name.startsWith("ejb")) {
714         continue;
715       }
716       else if (name.startsWith("get") && name.length() > 3 &&
717                method.getParameterTypes().length == 0) {
718         String JavaDoc fieldName = getterToFieldName(name);
719
720         if (getCmpField(fieldName) != null ||
721             getRelation(fieldName) != null)
722           continue;
723       }
724       else if (name.startsWith("get") && name.length() > 3 &&
725                method.getParameterTypes().length == 1) {
726         String JavaDoc fieldName = getterToFieldName(name);
727
728         CmrRelation rel = getRelation(fieldName);
729
730         if (rel instanceof CmrMap) {
731           CmrMap map = (CmrMap) rel;
732
733           if (method.equals(map.getMapMethod()))
734             continue;
735         }
736       }
737       else if (name.startsWith("set") && name.length() > 3 &&
738                method.getParameterTypes().length == 1) {
739         String JavaDoc fieldName = getterToFieldName(name);
740
741         CmpField field = getCmpField(fieldName);
742
743         if (field == null) {
744         }
745         else if (isMatch(method, field.getSetter()))
746           continue;
747         else
748           throw new ConfigException(L.l("{0}: '{1}' does not match the corresponding cmp-field getter '{2}'.",
749                                         getEJBClass().getName(),
750                                         method.getFullName(),
751                                         field.getGetter().getFullName()));
752
753         CmrRelation rel = getRelation(fieldName);
754
755         if (rel == null) {
756         }
757         else if (method.equals(rel.getSetter()))
758           continue;
759         else
760           throw new ConfigException(L.l("{0}: '{1}' does not match the corresponding cmp-field getter '{2}'.",
761                                         getEJBClass().getName(),
762                                         method.getFullName(),
763                                         rel.getGetter().getFullName()));
764       }
765
766       throw error(L.l("{0}: '{1}' must not be abstract. Business methods must be implemented.",
767                       getEJBClass().getName(),
768                       method.getFullName()));
769     }
770   }
771
772   /**
773    * Introspects the CMP id.
774    */

775   protected void introspectCMPId()
776     throws ConfigException
777   {
778
779     if (_primKeyClass != null &&
780         ! _primKeyClass.isPrimitive() &&
781         ! _primKeyClass.getName().startsWith("java.lang.") &&
782         ! _primKeyClass.getName().equals("java.util.Date") &&
783         ! _primKeyClass.getName().equals("java.sql.Date") &&
784         ! _primKeyClass.getName().equals("java.sql.Time") &&
785         ! _primKeyClass.getName().equals("java.sql.Timestamp") &&
786         ! _primKeyClass.isAssignableTo(EJBLocalObject.class)) {
787
788       if (_primKeyField != null)
789         throw error(L.l("{0}: 'primkey-field' must not be defined for a composite primkey-class.",
790                         getEJBClass().getName()));
791
792       _compositeKeyClass = _primKeyClass;
793       introspectCMPCompositeId();
794       return;
795     }
796
797     String JavaDoc id = _primKeyField;
798     if (id == null)
799       id = "id";
800
801     CmpProperty property = getCmpField(id);
802
803     if (property == null)
804       property = getRelation(id);
805
806     if (property == null)
807       throw error(L.l("{0}: primary key field '{1}' is an unknown cmp-field",
808                       getEJBClass().getName(), id));
809
810     property.setId(true);
811   }
812
813   /**
814    * Introspects the CMP id.
815    */

816   protected void introspectCMPCompositeId()
817     throws ConfigException
818   {
819     try {
820       JMethod equals = _primKeyClass.getMethod("equals", new JClass[] { JClass.OBJECT });
821
822       if (equals.getDeclaringClass().equals(JClass.OBJECT))
823         throw error(L.l("{0}: primary key class '{1}' must override the 'equals' method.",
824                         getEJBClass().getName(),
825                         _primKeyClass.getName()));
826     } catch (ConfigException e) {
827       throw e;
828     } catch (Throwable JavaDoc e) {
829     }
830
831     try {
832       JMethod hashCode = _primKeyClass.getMethod("hashCode", new JClass[] { });
833
834       if (hashCode.getDeclaringClass().getName().equals(Object JavaDoc.class.getName()))
835         throw error(L.l("{0}: primary key class '{1}' must override the 'hashCode' method.",
836                         getEJBClass().getName(),
837                         _primKeyClass.getName()));
838     } catch (ConfigException e) {
839       throw e;
840     } catch (Throwable JavaDoc e) {
841     }
842
843     if (_primKeyClass.getFields().length == 0)
844         throw error(L.l("{0}: compound key '{1}' has no public accessible fields. Compound key fields must be public.",
845                         getEJBClass().getName(),
846                         _primKeyClass.getName()));
847
848     for (JField field : _primKeyClass.getFields()) {
849       CmpProperty cmpProperty = getCmpField(field.getName());
850
851       if (cmpProperty == null)
852         cmpProperty = getRelation(field.getName());
853
854       if (cmpProperty == null)
855         throw error(L.l("{0}: primary key field '{1}' is an unknown field.",
856                         getEJBClass().getName(), field.getName()));
857
858       cmpProperty.setId(true);
859     }
860   }
861
862   private static String JavaDoc getterToFieldName(String JavaDoc name)
863   {
864     String JavaDoc fieldName = name.substring(3);
865     char ch = fieldName.charAt(0);
866
867     if (Character.isUpperCase(ch) &&
868         (fieldName.length() == 1 ||
869          Character.isLowerCase(fieldName.charAt(1)))) {
870       fieldName = Character.toLowerCase(ch) + fieldName.substring(1);
871     }
872
873     return fieldName;
874   }
875
876   /**
877    * Configure for amber.
878    */

879   public void configureAmber(AmberConfig config)
880     throws ConfigException
881   {
882     if (isCMP()) {
883       try {
884         config.addBean(this);
885       } catch (LineConfigException e) {
886         throw e;
887       } catch (Exception JavaDoc e) {
888         throw new LineConfigException(getLocation() + e.getMessage(), e);
889       }
890     }
891   }
892
893   /**
894    * Creates the assembler for the bean.
895    */

896   protected BeanAssembler createAssembler(String JavaDoc fullClassName)
897   {
898     if (isCMP())
899       return new AmberAssembler(this, fullClassName);
900     else
901       return new EntityAssembler(this, fullClassName);
902   }
903
904   /**
905    * Adds the assemblers.
906    */

907   protected void addImports(BeanAssembler assembler)
908   {
909     super.addImports(assembler);
910
911     assembler.addImport("com.caucho.ejb.FinderExceptionWrapper");
912
913     assembler.addImport("com.caucho.ejb.entity.EntityServer");
914     assembler.addImport("com.caucho.ejb.entity.QEntityContext");
915     assembler.addImport("com.caucho.ejb.entity.EntityHome");
916     assembler.addImport("com.caucho.ejb.entity.EntityLocalHome");
917     assembler.addImport("com.caucho.ejb.entity.EntityRemoteHome");
918     assembler.addImport("com.caucho.ejb.entity.EntityObject");
919     assembler.addImport("com.caucho.ejb.entity.QEntity");
920   }
921
922   /**
923    * Introspects an ejb method.
924    */

925   protected EjbBaseMethod introspectEJBMethod(JMethod method)
926     throws ConfigException
927   {
928     String JavaDoc methodName = method.getName();
929     JClass []paramTypes = method.getParameterTypes();
930
931     if (methodName.startsWith("ejbSelect") && method.isAbstract()) {
932       validateSelectMethod(method);
933
934       EjbMethodPattern pattern = getMethodPattern(method, "Local");
935
936       if (pattern == null)
937         throw error(L.l("{0}: '{1}' expects an ejb-ql query. ejbSelect methods must have an ejb-ql query in the deployment descriptor.",
938                         getEJBClass().getName(),
939                         method.getFullName()));
940
941       String JavaDoc query = pattern.getQuery();
942
943       EjbAmberSelectMethod select;
944       select = new EjbAmberSelectMethod(this, method, query,
945                                         pattern.getQueryLocation());
946
947       select.setQueryLoadsBean(pattern.getQueryLoadsBean());
948
949       return select;
950     }
951
952     return null;
953   }
954
955   /**
956    * Introspects an ejb method.
957    */

958   protected void validateImplMethod(JMethod method)
959     throws ConfigException
960   {
961     String JavaDoc methodName = method.getName();
962     JClass []paramTypes = method.getParameterTypes();
963
964     if (method.isAbstract() &&
965         methodName.startsWith("get") &&
966         paramTypes.length == 0) {
967     }
968     else if (method.isAbstract() &&
969              methodName.startsWith("get") &&
970              paramTypes.length == 1) {
971     }
972     else if (method.isAbstract() &&
973              methodName.startsWith("set") &&
974              paramTypes.length == 1) {
975     }
976     else if (methodName.startsWith("ejb")) {
977     }
978     else if (method.isAbstract()) {
979       throw error(L.l("{0}: '{1}' must not be abstract. The bean must implement its business methods.",
980                       getEJBClass().getName(),
981                       method.getFullName()));
982     }
983   }
984
985   /**
986    * Check that a method is public.
987    *
988    * @return the matching method
989    */

990   private void validateSelectMethod(JMethod method)
991     throws ConfigException
992   {
993     if (! method.isPublic()) {
994       throw error(L.l("{0}: '{1}' must be public. ejbSelect methods must be public.",
995                       getEJBClass().getName(),
996                       method.getFullName()));
997     }
998     else if (method.isStatic()) {
999       throw error(L.l("{0}: `{1}' must not be static. ejbSelect methods must not be static.",
1000                      getEJBClass().getName(),
1001                      method.getFullName()));
1002    }
1003    else if (! method.isAbstract()) {
1004      throw error(L.l("{0}: `{1}' must be abstract. ejbSelect methods must be abstract.",
1005                      getEJBClass().getName(),
1006                      method.getFullName()));
1007    }
1008  }
1009
1010  /**
1011   * Creates the views.
1012   */

1013  protected EjbHomeView createHomeView(JClass homeClass, String JavaDoc prefix)
1014    throws ConfigException
1015  {
1016    return new EjbEntityHomeView(this, homeClass, prefix);
1017  }
1018
1019  /**
1020   * Creates the views.
1021   */

1022  protected EjbObjectView createObjectView(JClass apiClass, String JavaDoc prefix)
1023    throws ConfigException
1024  {
1025    if (isCMP())
1026      return new EjbCmpView(this, apiClass, prefix);
1027    else
1028      return new EjbEntityView(this, apiClass, prefix);
1029  }
1030
1031  /**
1032   * Deploys the bean.
1033   */

1034  public AbstractServer deployServer(EjbServerManager ejbManager,
1035                                     JavaClassGenerator javaGen)
1036    throws ClassNotFoundException JavaDoc
1037  {
1038    EntityServer server = new EntityServer(ejbManager);
1039
1040    server.setEJBName(getEJBName());
1041    server.setJndiName(getJndiName());
1042
1043    server.setRemoteHomeClass(getRemoteHomeClass());
1044    server.setRemoteObjectClass(getRemoteClass());
1045
1046    Class JavaDoc contextImplClass = javaGen.loadClass(getSkeletonName());
1047
1048    server.setContextImplClass(contextImplClass);
1049
1050    server.setCMP(isCMP());
1051
1052    if (_primKeyClass != null)
1053      server.setPrimaryKeyClass(_primKeyClass.getWrappedClass());
1054
1055    server.setLoadLazyOnTransaction(_loadLazyOnTransaction);
1056
1057    server.setInitProgram(getInitProgram());
1058
1059    if (isCMP()) {
1060      server.setAmberEntityHome(getEntityType().getHome());
1061    }
1062    
1063    Thread JavaDoc thread = Thread.currentThread();
1064    ClassLoader JavaDoc oldLoader = thread.getContextClassLoader();
1065
1066    try {
1067      thread.setContextClassLoader(server.getClassLoader());
1068
1069      try {
1070    // ejb/086d
1071
if (getServerProgram() != null)
1072      getServerProgram().configure(server);
1073      } catch (ConfigException e) {
1074    throw e;
1075      } catch (Throwable JavaDoc e) {
1076    throw new ConfigException(e);
1077      }
1078    } finally {
1079      thread.setContextClassLoader(oldLoader);
1080    }
1081
1082    return server;
1083  }
1084
1085  private void validateMethods()
1086    throws ConfigException
1087  {
1088    JClass primKeyClass = getPrimKeyClass();
1089
1090    JMethod []methods = getMethods(getEJBClassWrapper());
1091
1092    for (JMethod method : methods) {
1093      String JavaDoc name = method.getName();
1094
1095      try {
1096        // XXX: ???
1097
JMethod cleanMethod = getEJBClassWrapper().getMethod(name, method.getParameterTypes());
1098        if (cleanMethod != null)
1099          method = cleanMethod;
1100      } catch (Exception JavaDoc e) {
1101      }
1102
1103      if (method.getReturnType().isAssignableTo(EntityBean.class))
1104        throw error(L.l("{0}: `{1}' must not return entity bean `{2}'. Entity bean methods must always return local or remote interfaces.",
1105                        getEJBClass().getName(),
1106                        method.getFullName(),
1107                        method.getReturnType().getShortName()));
1108
1109      if (name.startsWith("ejbFind")) {
1110        if (! isCMP()) {
1111          validateNonFinalMethod(method.getName(),
1112                                 method.getParameterTypes());
1113        }
1114        else if (true) {
1115          // allow overriding
1116
validateNonFinalMethod(method.getName(), method.getParameterTypes());
1117        }
1118        else {
1119          throw error(L.l("{0}: `{1}' forbidden. CMP entity beans must not implement ejbFind methods.",
1120                          method.getDeclaringClass().getName(),
1121                          method.getFullName()));
1122        }
1123      }
1124      else if (name.startsWith("ejbSelect")) {
1125        if (! method.isAbstract())
1126          throw error(L.l("{0}: `{1}' must be abstract. ejbSelect methods must be abstract.",
1127                          method.getDeclaringClass().getName(),
1128                          method.getFullName()));
1129        if (! method.isPublic())
1130          throw error(L.l("{0}: `{1}' must be public.",
1131                          method.getDeclaringClass().getName(),
1132                          method.getFullName()));
1133        validateException(method, FinderException.class);
1134      }
1135      else if (name.startsWith("ejbCreate")) {
1136        validateNonFinalMethod(method.getName(), method.getParameterTypes());
1137        if (! isPrimaryKeyClass(method.getReturnType()))
1138          throw error(L.l("{0}: `{1}' must return `{2}'. ejbCreate methods must return the primary key.",
1139                          method.getDeclaringClass().getName(),
1140                          method.getFullName(),
1141                          getClassName(primKeyClass)));
1142        if (isCMP())
1143          validateException(method, CreateException.class);
1144      }
1145      else if (name.startsWith("ejbPostCreate")) {
1146        validateNonFinalMethod(method.getName(), method.getParameterTypes());
1147
1148        if (! method.getReturnType().getName().equals("void"))
1149          throw error(L.l("{0}: `{1}' must return void. ejbPostCreate methods must return void.",
1150                          method.getDeclaringClass().getName(),
1151                          method.getFullName()));
1152      }
1153      else if (name.startsWith("create") &&
1154               method.isAbstract()) {
1155        // validated in dependent phase.
1156
}
1157      else if (name.startsWith("ejbHome")) {
1158        validateNonFinalMethod(method.getName(), method.getParameterTypes());
1159      }
1160      else if (name.equals("ejbRemove")) {
1161        if (method.getParameterTypes().length != 0)
1162          throw error(L.l("{0}: `{1}' must have no arguments.",
1163                          method.getDeclaringClass().getName(),
1164                          method.getFullName()));
1165      }
1166      else if (name.equals("ejbTimeout")) {
1167        JClass []types = method.getParameterTypes();
1168
1169        if (types.length != 1 || ! types[0].getName().equals("javax.ejb.Timer"))
1170          throw error(L.l("{0}: `{1}' must have one javax.ejb.Timer argument.",
1171                          method.getDeclaringClass().getName(),
1172                          method.getFullName()));
1173      }
1174      else if (classHasMethod(method, JClassLoader.systemForName(EntityBean.class.getName()))) {
1175      }
1176      else if (name.equals("finalize") &&
1177               method.getParameterTypes().length == 0 &&
1178               ! method.getDeclaringClass().getName().equals("java.lang.Object"))
1179        throw error(L.l("{0}: Entity beans must not define `finalize'.",
1180                        getEJBClass().getClass()));
1181      else if (name.startsWith("ejb")) {
1182        throw error(L.l("{0}: `{1}' must not start with `ejb'. ejbXXX methods are reserved by the EJB spec.",
1183                        method.getDeclaringClass().getName(),
1184                        method.getFullName()));
1185      }
1186      else {
1187        boolean isAbstract = method.isAbstract();
1188        JMethod persist = null;
1189
1190        if (! isAbstract || ! isCMP()) {
1191        }
1192        else if (method.getName().startsWith("get")) {
1193          //validateGetImpl(method); -- in relations
1194
}
1195        else if (method.getName().startsWith("set")) {
1196          //validateSetImpl(method); -- in relations
1197
}
1198        else if (method.getName().startsWith("ejbSelect")) {
1199        }
1200        else {
1201          throw error(L.l("{0}: `{1}' must not be abstract. Only CMP methods may be abstract.",
1202                          method.getDeclaringClass().getName(),
1203                          method.getFullName()));
1204        }
1205
1206        /* XXX: should look for matching cmp/cmr-field */
1207        /*
1208        if (! getBeanManagedPersistence()) {
1209          persist = validator.findPersistentMethod(method.getName(),
1210                                                   method.getParameterTypes());
1211
1212          if (persist != null && ! isAbstract)
1213            throw error(L.l("`{0}' must be abstract in {1}",
1214                            method.getFullName(),
1215                            method.getDeclaringClass().getName()));
1216        }
1217
1218        if (persist == null && isAbstract)
1219          throw error(L.l("`{0}' must not be abstract in {1}",
1220                          method.getFullName(),
1221                          method.getDeclaringClass().getName()));
1222        */

1223      }
1224    }
1225  }
1226
1227  /**
1228   * Validates the home interface.
1229   */

1230  private void validateHome(JClass homeClass)
1231    throws ConfigException
1232  {
1233    JClass beanClass = getEJBClassWrapper();
1234    String JavaDoc beanName = beanClass.getName();
1235
1236    String JavaDoc homeName = homeClass.getName();
1237
1238    JClass objectClass;
1239    if (homeClass.isAssignableTo(EJBHome.class))
1240      objectClass = getRemote();
1241    else
1242      objectClass = getLocal();
1243    String JavaDoc objectName = objectClass != null ? objectClass.getName() : null;
1244
1245    boolean hasFindByPrimaryKey = false;
1246
1247    JClass primKeyClass = getPrimKeyClass();
1248
1249    if (! homeClass.isPublic())
1250      throw error(L.l("`{0}' must be public. Entity beans must be public.", homeName));
1251
1252    if (beanClass.isFinal())
1253      throw error(L.l("`{0}' must not be final. Entity beans must not be final.", beanName));
1254
1255    if (! isCMP() && beanClass.isAbstract())
1256      throw error(L.l("`{0}' must not be abstract. BMP entity beans must not be abstract.", beanName));
1257
1258    if (! homeClass.isInterface())
1259      throw error(L.l("`{0}' must be an interface.", homeName));
1260
1261    JMethod []methods = getMethods(homeClass);
1262    for (int i = 0; i < methods.length; i++) {
1263      JMethod method = methods[i];
1264      String JavaDoc name = method.getName();
1265      JClass []param = method.getParameterTypes();
1266      JClass retType = method.getReturnType();
1267
1268      if (method.getDeclaringClass().isAssignableFrom(EJBHome.class))
1269        continue;
1270
1271      if (method.getDeclaringClass().isAssignableFrom(EJBLocalHome.class))
1272        continue;
1273
1274      if (homeClass.isAssignableTo(EJBHome.class))
1275        validateException(method, java.rmi.RemoteException JavaDoc.class);
1276
1277      if (name.startsWith("create")) {
1278        validateException(method, CreateException.class);
1279
1280        if (! retType.equals(objectClass))
1281          throw error(L.l("{0}: `{1}' must return {2}. Create methods must return the local or remote interface.",
1282                          homeName,
1283                          method.getFullName(),
1284                          objectName));
1285
1286        String JavaDoc createName = "ejbC" + name.substring(1);
1287        JMethod implMethod =
1288          validateNonFinalMethod(createName, param, method, homeClass);
1289
1290        if (! isPrimaryKeyClass(implMethod.getReturnType()))
1291          throw error(L.l("{0}: `{1}' must return `{2}'. ejbCreate methods must return the primary key.",
1292                          beanName,
1293                          getFullMethodName(createName, param),
1294                          getClassName(primKeyClass)));
1295
1296        if (! hasException(implMethod, CreateException.class)) {
1297          throw error(L.l("{0}: `{1}' must throw {2}. ejbCreate methods must throw CreateException.",
1298                          implMethod.getDeclaringClass().getName(),
1299                          implMethod.getFullName(),
1300                          "CreateException"));
1301
1302        }
1303
1304        validateExceptions(method, implMethod);
1305
1306        createName = "ejbPostC" + name.substring(1);
1307        implMethod = validateNonFinalMethod(createName, param,
1308                                            method, homeClass);
1309
1310        if (! implMethod.getReturnType().getName().equals("void"))
1311          throw error(L.l("{0}: `{1}' must return {2}. ejbPostCreate methods must return void.",
1312                          beanName,
1313                          getFullMethodName(createName, param),
1314                          "void"));
1315
1316
1317        validateExceptions(method, implMethod);
1318      }
1319      else if (name.startsWith("find")) {
1320        if (name.equals("findByPrimaryKey")) {
1321          hasFindByPrimaryKey = true;
1322
1323          /*
1324           if (param.length != 1 || ! param[0].equals(primKeyClass))
1325             throw error(L.l("`{0}' expected as only argument of {1} in {2}. findByPrimaryKey must take the primary key as its only argument.",
1326                             getClassName(primKeyClass),
1327                             name, homeName));
1328           */

1329
1330          if (! objectClass.equals(method.getReturnType()))
1331            throw error(L.l("{0}: `{1}' must return `{2}'. Find methods must return the remote or local interface.",
1332                            homeName,
1333                            method.getFullName(),
1334                            objectName));
1335        }
1336
1337        String JavaDoc findName = "ejbF" + name.substring(1);
1338        if (! isCMP() && ! isCMP1()
1339            || getMethod(beanClass, findName, param) != null) {
1340          JMethod impl = validateNonFinalMethod(findName, param, isAllowPOJO());
1341
1342          if (impl != null)
1343            validateExceptions(method, impl);
1344
1345          if (objectClass.equals(method.getReturnType())) {
1346            if (impl != null && ! isPrimaryKeyClass(impl.getReturnType()))
1347              throw error(L.l("{0}: `{1}' must return primary key `{2}'. ejbFind methods must return the primary key",
1348                              beanName,
1349                              impl.getFullName(),
1350                              getClassName(primKeyClass)));
1351          }
1352          else if (method.getReturnType().isAssignableTo(Collection JavaDoc.class)) {
1353            if (impl != null && ! impl.getReturnType().isAssignableTo(Collection JavaDoc.class))
1354              throw error(L.l("{0}: `{1}' must return collection.",
1355                              beanName,
1356                              impl.getFullName()));
1357          }
1358          else if (method.getReturnType().isAssignableTo(Enumeration JavaDoc.class)) {
1359            if (! impl.getReturnType().isAssignableTo(Enumeration JavaDoc.class))
1360              throw error(L.l("{0}: `{1}' must return enumeration.",
1361                              beanName,
1362                              impl.getFullName()));
1363          }
1364          else
1365            throw error(L.l("{0}: `{1}' must return `{2}' or a collection. ejbFind methods must return the primary key or a collection.",
1366                            homeName,
1367                            method.getFullName(),
1368                            objectName));
1369        }
1370        else if (isCMP() && ! name.equals("findByPrimaryKey")) {
1371          String JavaDoc query = findQuery(method);
1372
1373          if (query == null) {
1374            throw error(L.l("{0}: `{1}' expects an ejb-ql query. All find methods need queries defined in the EJB deployment descriptor.",
1375                            homeName,
1376                            method.getFullName()));
1377          }
1378        }
1379
1380        validateException(method, FinderException.class);
1381
1382        if (! retType.equals(objectClass) &&
1383            (! retType.isAssignableTo(Collection JavaDoc.class) &&
1384             ! Enumeration JavaDoc.class.getName().equals(retType.getName()) ||
1385                                                                     name.equals("findByPrimaryKey"))) {
1386          throw error(L.l("{0}: `{1}' must return {2} or a collection. ejbFind methods must return the primary key or a collection.",
1387                          homeName,
1388                          method.getFullName(),
1389                          objectName));
1390        }
1391      }
1392      else if (name.startsWith("ejbSelect")) {
1393        throw error(L.l("{0}: `{1}' forbidden. ejbSelect methods may not be exposed in the remote or local interface.",
1394                        homeName,
1395                        method.getFullName()));
1396      }
1397      else if (name.startsWith("ejb")) {
1398        throw error(L.l("{0}: `{1}' forbidden. Only ejbXXX methods defined by the spec are allowed.",
1399                        homeName,
1400                        method.getFullName()));
1401      }
1402      else if (name.startsWith("remove")) {
1403        throw error(L.l("{0}: `{1}' forbidden. removeXXX methods are reserved by the spec.",
1404                        homeName,
1405                        method.getFullName()));
1406      }
1407      else {
1408        retType = method.getReturnType();
1409
1410        if (homeClass.isAssignableTo(EJBHome.class) &&
1411            (retType.isAssignableTo(EJBLocalObject.class) ||
1412             retType.isAssignableTo(EJBLocalHome.class)))
1413          throw error(L.l("{1}: `{0}' must not return local interface.",
1414                          homeClass.getName(),
1415                          method.getFullName()));
1416
1417        String JavaDoc homeMethodName = ("ejbHome" +
1418                                 Character.toUpperCase(name.charAt(0)) +
1419                                 name.substring(1));
1420        JMethod implMethod = validateMethod(homeMethodName, param,
1421                                            method, homeClass);
1422
1423        if (! retType.equals(implMethod.getReturnType()))
1424          throw error(L.l("{0}: `{1}' must return {2}.",
1425                          beanName,
1426                          implMethod.getFullName(),
1427                          method.getReturnType().getName()));
1428
1429        validateExceptions(method, implMethod.getExceptionTypes());
1430      }
1431    }
1432
1433    // ejb/0588
1434
if (! hasFindByPrimaryKey && ! isAllowPOJO() && objectClass != null)
1435      throw error(L.l("{0}: expected `{1}'. All entity homes must define findByPrimaryKey.",
1436                      homeName,
1437                      getFullMethodName("findByPrimaryKey",
1438                                        new JClass[] {
1439                                          primKeyClass })));
1440  }
1441
1442  protected void assembleHomeMethods(BeanAssembler assembler,
1443                                     BaseClass baseClass,
1444                                     String JavaDoc contextClassName,
1445                                     JClass homeClass,
1446                                     String JavaDoc prefix)
1447    throws NoSuchMethodException JavaDoc
1448  {
1449    JMethod []methods = getMethods(homeClass);
1450
1451    for (int i = 0; i < methods.length; i++) {
1452      String JavaDoc className = methods[i].getDeclaringClass().getName();
1453      String JavaDoc methodName = methods[i].getName();
1454
1455      if (className.startsWith("javax.ejb.")) {
1456      }
1457      else if (isOld(methods, methods[i], i)) {
1458      }
1459      else if (methodName.startsWith("create")) {
1460        assembleCreateMethod(methods[i], baseClass, contextClassName, prefix);
1461      }
1462      else if (methodName.startsWith("find")) {
1463        JMethod beanMethod = null;
1464
1465        String JavaDoc name = ("ejb" + Character.toUpperCase(methodName.charAt(0))
1466                       + methodName.substring(1));
1467
1468        try {
1469          beanMethod = getEJBClassWrapper().getMethod(name,
1470                                                      methods[i].getParameterTypes());
1471        } catch (Throwable JavaDoc e) {
1472        }
1473
1474        if (beanMethod != null) {
1475          EntityFindMethod findMethod;
1476          findMethod = new EntityFindMethod(methods[i],
1477                                            beanMethod,
1478                                            contextClassName,
1479                                            prefix);
1480
1481          CallChain call = findMethod.getCall();
1482          call = new EntityHomePoolChain(call);
1483          // call = getTransactionChain(call, methods[i], prefix);
1484
findMethod.setCall(call);
1485
1486          baseClass.addMethod(findMethod);
1487        }
1488      }
1489      else {
1490        JMethod beanMethod = null;
1491
1492        String JavaDoc name = ("ejbHome" + Character.toUpperCase(methodName.charAt(0))
1493                       + methodName.substring(1));
1494
1495        try {
1496          beanMethod = getEJBClassWrapper().getMethod(name,
1497                                                      methods[i].getParameterTypes());
1498        } catch (Exception JavaDoc e) {
1499          throw new NoSuchMethodException JavaDoc("can't find method " + name);
1500        }
1501
1502        CallChain call = new MethodCallChain(beanMethod);
1503        // call = assembler.createPoolChain(call);
1504
call = getTransactionChain(call, beanMethod, prefix);
1505
1506        baseClass.addMethod(new BaseMethod(methods[i], call));
1507      }
1508    }
1509  }
1510
1511  protected void assembleCreateMethod(JMethod method,
1512                                      BaseClass baseClass,
1513                                      String JavaDoc contextClassName,
1514                                      String JavaDoc prefix)
1515  {
1516    String JavaDoc methodName = method.getName();
1517
1518    JMethod beanCreateMethod = null;
1519    JMethod beanPostCreateMethod = null;
1520
1521    String JavaDoc name = ("ejb" + Character.toUpperCase(methodName.charAt(0))
1522                   + methodName.substring(1));
1523
1524    try {
1525      beanCreateMethod = getEJBClassWrapper().getMethod(name,
1526                                                        method.getParameterTypes());
1527    } catch (Throwable JavaDoc e) {
1528    }
1529
1530    if (beanCreateMethod == null)
1531      throw new IllegalStateException JavaDoc(name);
1532
1533    name = ("ejbPost" + Character.toUpperCase(methodName.charAt(0))
1534            + methodName.substring(1));
1535
1536    try {
1537      beanPostCreateMethod = getEJBClassWrapper().getMethod(name,
1538                                                            method.getParameterTypes());
1539    } catch (Throwable JavaDoc e) {
1540    }
1541
1542    EntityCreateMethod createMethod;
1543
1544    createMethod = new EntityCreateMethod(this, method,
1545                                          beanCreateMethod,
1546                                          beanPostCreateMethod,
1547                                          contextClassName);
1548
1549    createMethod.setCall(getTransactionChain(createMethod.getCall(),
1550                                             method,
1551                                             prefix));
1552
1553    baseClass.addMethod(createMethod);
1554  }
1555
1556  /**
1557   * Return true if the type matches the primary key class.
1558   */

1559  private boolean isPrimaryKeyClass(JClass type)
1560  {
1561    return type.equals(getPrimKeyClass());
1562  }
1563
1564  private JMethod getMethodField(String JavaDoc fieldName)
1565  {
1566    String JavaDoc getter = "get" + Character.toUpperCase(fieldName.charAt(0)) +
1567                    fieldName.substring(1);
1568
1569    JMethod []methods = getMethods(getEJBClassWrapper());
1570
1571    for (int i = 0; i < methods.length; i++) {
1572      if (getter.equals(methods[i].getName()) &&
1573          methods[i].getParameterTypes().length == 0)
1574        return methods[i];
1575    }
1576
1577    return null;
1578  }
1579
1580  /**
1581   * Finds the matching query.
1582   */

1583  private String JavaDoc findQuery(JMethod method)
1584    throws ConfigException
1585  {
1586    EjbMethodPattern ejbMethod = getMethodPattern(method, null);
1587
1588    if (ejbMethod != null && ejbMethod.getQuery() != null)
1589      return ejbMethod.getQuery();
1590
1591    EjbMethodPattern ejbQuery = getQuery(method, null);
1592    if (ejbQuery != null)
1593      return ejbQuery.getQuery();
1594    else
1595      return null;
1596  }
1597
1598  /**
1599   * Compares dependencies for identifying relations.
1600   */

1601  public boolean dependsOn(EjbEntityBean target)
1602  {
1603    for (CmrRelation rel : _relations) {
1604      if (rel.isId()) {
1605        EjbEntityBean targetBean = rel.getTargetBean();
1606
1607        if (target == targetBean ||
1608            targetBean != null && targetBean.dependsOn(target))
1609          return true;
1610      }
1611    }
1612
1613    return false;
1614  }
1615
1616  /**
1617   * Generates the bean prologue.
1618   */

1619  public void generateBeanPrologue(JavaWriter out)
1620    throws IOException JavaDoc
1621  {
1622  }
1623
1624  /**
1625   * Generates the after commit method.
1626   */

1627  public void generateAfterCommit(JavaWriter out)
1628    throws IOException JavaDoc
1629  {
1630    for (CmrRelation rel : _relations) {
1631      rel.generateAfterCommit(out);
1632    }
1633  }
1634
1635  /**
1636   * Generates the destroy method.
1637   */

1638  public void generateDestroy(JavaWriter out)
1639    throws IOException JavaDoc
1640  {
1641    for (CmrRelation rel : _relations) {
1642      rel.generateDestroy(out);
1643    }
1644  }
1645
1646  public String JavaDoc toString()
1647  {
1648    return "EjbEntityBean[" + getEJBName() + "]";
1649  }
1650}
1651
Popular Tags