001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.metadata;
023:
024: import java.util.ArrayList;
025: import java.util.HashMap;
026: import java.util.Iterator;
027:
028: import org.w3c.dom.Element;
029: import org.jboss.deployment.DeploymentException;
030: import org.jboss.logging.Logger;
031: import org.jboss.util.Strings;
032:
033: /**
034: * The meta data information specific to entity beans.
035: *
036: * @author <a href="mailto:sebastien.alborini@m4x.org">Sebastien Alborini</a>
037: * @author <a href="mailto:scott.stark@jboss.org">Scott Stark</a>
038: * @author <a href="mailto:dain@daingroup.com">Dain Sundstrom</a>
039: * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
040: * @author <a href="mailto:criege@riege.com">Christian Riege</a>
041: *
042: * @version $Revision: 59641 $
043: *
044: * <p><b>Revisions:</b><br>
045: * <p><b>2001/10/16: billb</b>
046: * <ol>
047: * <li>Added clustering tags
048: * </ol>
049: */
050: public class EntityMetaData extends BeanMetaData {
051: // Constants -----------------------------------------------------
052: public final static int CMP_VERSION_1 = 1;
053: public final static int CMP_VERSION_2 = 2;
054: public static final String DEFAULT_ENTITY_INVOKER_PROXY_BINDING = "entity-unified-invoker";
055: public static final String DEFAULT_CLUSTERED_ENTITY_INVOKER_PROXY_BINDING = "clustered-entity-unified-invoker";
056:
057: // Attributes ----------------------------------------------------
058: private boolean cmp;
059: private String primaryKeyClass;
060: private boolean reentrant;
061: private int cmpVersion;
062: private String abstractSchemaName;
063: private ArrayList cmpFields = new ArrayList();
064: private String primKeyField;
065: private ArrayList queries = new ArrayList();
066: private boolean readOnly = false;
067: private boolean doDistCachInvalidations = false;
068: private CacheInvalidationConfigMetaData cacheInvalidConfig = null;
069:
070: // Static --------------------------------------------------------
071: private static Logger log = Logger.getLogger(EntityMetaData.class);
072:
073: // Constructors --------------------------------------------------
074: public EntityMetaData(ApplicationMetaData app) {
075: super (app, BeanMetaData.ENTITY_TYPE);
076: }
077:
078: // Public --------------------------------------------------------
079: public boolean isCMP() {
080: return cmp;
081: }
082:
083: public boolean isCMP1x() {
084: return cmp && (cmpVersion == 1);
085: }
086:
087: public boolean isCMP2x() {
088: return cmp && (cmpVersion == 2);
089: }
090:
091: public boolean isBMP() {
092: return !cmp;
093: }
094:
095: public String getPrimaryKeyClass() {
096: return primaryKeyClass;
097: }
098:
099: public boolean isReentrant() {
100: return reentrant;
101: }
102:
103: public String getAbstractSchemaName() {
104: return abstractSchemaName;
105: }
106:
107: public boolean isReadOnly() {
108: return readOnly;
109: }
110:
111: /**
112: * Gets the container managed fields.
113: * @returns iterator over Strings containing names of the fields
114: */
115: public Iterator getCMPFields() {
116: return cmpFields.iterator();
117: }
118:
119: public String getPrimKeyField() {
120: return primKeyField;
121: }
122:
123: public Iterator getQueries() {
124: return queries.iterator();
125: }
126:
127: public String getDefaultConfigurationName() {
128: if (isCMP()) {
129: if (getApplicationMetaData().isEJB2x()) {
130: if (isClustered()) {
131: return ConfigurationMetaData.CLUSTERED_CMP_2x_13;
132: } else {
133: return ConfigurationMetaData.CMP_2x_13;
134: }
135: } else {
136: if (isClustered()) {
137: return ConfigurationMetaData.CLUSTERED_CMP_1x_13;
138: } else {
139: return ConfigurationMetaData.CMP_1x_13;
140: }
141: }
142: } else {
143: if (isClustered()) {
144: return ConfigurationMetaData.CLUSTERED_BMP_13;
145: } else {
146: return ConfigurationMetaData.BMP_13;
147: }
148: }
149: }
150:
151: public boolean doDistributedCacheInvalidations() {
152: return this .doDistCachInvalidations;
153: }
154:
155: public CacheInvalidationConfigMetaData getDistributedCacheInvalidationConfig() {
156: return this .cacheInvalidConfig;
157: }
158:
159: public void importEjbJarXml(Element element)
160: throws DeploymentException {
161: super .importEjbJarXml(element);
162:
163: // set persistence type
164: String persistenceType = getElementContent(getUniqueChild(
165: element, "persistence-type"));
166: if (persistenceType.equals("Bean")) {
167: cmp = false;
168: } else if (persistenceType.equals("Container")) {
169: cmp = true;
170: } else {
171: throw new DeploymentException(getEjbName() + ": "
172: + "persistence-type must be 'Bean' or 'Container'!");
173: }
174:
175: // set primary key class
176: primaryKeyClass = getElementContent(getUniqueChild(element,
177: "prim-key-class"));
178:
179: // set reentrant
180: reentrant = Boolean
181: .valueOf(
182: getElementContent(getUniqueChild(element,
183: "reentrant"))).booleanValue();
184:
185: if (isCMP()) {
186: // cmp-version
187: if (getApplicationMetaData().isEJB2x()) {
188: String cmpVersionString = getElementContent(getOptionalChild(
189: element, "cmp-version"));
190:
191: if (cmpVersionString == null) {
192: // default for ejb 2.0 apps is cmp 2.x
193: cmpVersion = CMP_VERSION_2;
194: } else {
195: if ("1.x".equals(cmpVersionString)) {
196: cmpVersion = 1;
197: } else if ("2.x".equals(cmpVersionString)) {
198: cmpVersion = 2;
199: } else {
200: throw new DeploymentException(
201: getEjbName()
202: + ": "
203: + "cmp-version must be '1.x' or '2.x', if specified");
204: }
205: }
206: } else {
207: // default for 1.0 DTDs is version 2
208: cmpVersion = CMP_VERSION_1;
209: }
210:
211: // abstract-schema-name
212: abstractSchemaName = getOptionalChildContent(element,
213: "abstract-schema-name");
214:
215: if (cmpVersion == 2) {
216: // Enforce several restrictions on abstract-schema-name and
217: // ejb-name Elements, see bug #613360
218:
219: String ejbName = getEjbName();
220:
221: // ejb-name tests
222: if (!Strings.isValidJavaIdentifier(ejbName)) {
223: throw new DeploymentException(
224: "The ejb-name for a CMP"
225: + "2.x Entity must be a valid Java Identifier");
226: }
227:
228: if (Strings.isEjbQlIdentifier(ejbName)) {
229: log
230: .warn(ejbName
231: + ": The ejb-name for a CMP 2.x Entity "
232: + "should not be a reserved EJB-QL keyword");
233: }
234:
235: // Test various things for abstract-schema-name
236: if (abstractSchemaName == null) {
237: throw new DeploymentException(
238: "The abstract-schema-name "
239: + "must be specified for CMP 2.x Beans");
240: }
241:
242: if (!Strings.isValidJavaIdentifier(abstractSchemaName)) {
243: throw new DeploymentException(
244: "The abstract-schema-name "
245: + "must be a valid Java Identifier '"
246: + abstractSchemaName + "'");
247: }
248:
249: if (Strings.isEjbQlIdentifier(abstractSchemaName)) {
250: log.warn(ejbName
251: + ": The abstract-schema-name should "
252: + "not be a reserved EJB-QL Identifier '"
253: + abstractSchemaName + "'");
254: }
255: }
256:
257: // cmp-fields
258: Iterator iterator = getChildrenByTagName(element,
259: "cmp-field");
260: while (iterator.hasNext()) {
261: Element field = (Element) iterator.next();
262: cmpFields.add(getElementContent(getUniqueChild(field,
263: "field-name")));
264: }
265:
266: // set the primary key field
267: primKeyField = getElementContent(getOptionalChild(element,
268: "primkey-field"));
269: if (primKeyField != null
270: && !cmpFields.contains(primKeyField)) {
271: // FIXME: include ejb-name
272: throw new DeploymentException("primkey-field "
273: + primKeyField + " is not a cmp-field");
274: }
275:
276: // queries
277: iterator = getChildrenByTagName(element, "query");
278: while (iterator.hasNext()) {
279: Element queryElement = (Element) iterator.next();
280:
281: QueryMetaData queryMetaData = new QueryMetaData();
282: queryMetaData.importEjbJarXml(queryElement);
283:
284: queries.add(queryMetaData);
285: }
286: }
287: }
288:
289: protected void defaultInvokerBindings() {
290: this .invokerBindings = new HashMap();
291: if (isClustered()) {
292: this .invokerBindings.put(
293: DEFAULT_CLUSTERED_ENTITY_INVOKER_PROXY_BINDING,
294: getJndiName());
295: } else {
296: this .invokerBindings
297: .put(DEFAULT_ENTITY_INVOKER_PROXY_BINDING,
298: getJndiName());
299: }
300: }
301:
302: public void importJbossXml(Element element)
303: throws DeploymentException {
304: super .importJbossXml(element);
305: // set readonly
306: String readOnlyString = getElementContent(getOptionalChild(
307: element, "read-only"));
308: if (readOnlyString != null) {
309: readOnly = Boolean.valueOf(readOnlyString).booleanValue();
310: }
311: // Manage distributed cache-invalidation settings
312: //
313: String distCacheInvalidations = getElementContent(
314: getOptionalChild(element, "cache-invalidation"),
315: (this .doDistCachInvalidations ? "True" : "False"));
316: this .doDistCachInvalidations = distCacheInvalidations
317: .equalsIgnoreCase("True");
318:
319: Element cacheInvalidConfigElement = getOptionalChild(element,
320: "cache-invalidation-config");
321:
322: this .cacheInvalidConfig = new CacheInvalidationConfigMetaData();
323: this .cacheInvalidConfig.init(this );
324: if (cacheInvalidConfigElement != null) {
325: this .cacheInvalidConfig
326: .importJbossXml(cacheInvalidConfigElement);
327: }
328:
329: }
330:
331: // Package protected ---------------------------------------------
332:
333: // Protected -----------------------------------------------------
334:
335: // Private -------------------------------------------------------
336:
337: // Inner classes -------------------------------------------------
338: }
339: /*
340: vim:ts=3:sw=3:et
341: */
|