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.ejb.plugins.cmp.jdbc.metadata;
023:
024: import org.jboss.deployment.DeploymentException;
025: import org.jboss.metadata.MetaData;
026: import org.jboss.logging.Logger;
027: import org.w3c.dom.Element;
028:
029: /**
030: * Optimistick locking metadata
031: *
032: * @author <a href="mailto:aloubyansky@hotmail.com">Alex Loubyansky</a>
033: * @version $Revision: 57209 $
034: */
035: public final class JDBCOptimisticLockingMetaData {
036: // Constants ---------------------------------------
037: public static final Integer FIELD_GROUP_STRATEGY = new Integer(1);
038: public static final Integer MODIFIED_STRATEGY = new Integer(2);
039: public static final Integer READ_STRATEGY = new Integer(4);
040: public static final Integer VERSION_COLUMN_STRATEGY = new Integer(8);
041: public static final Integer TIMESTAMP_COLUMN_STRATEGY = new Integer(
042: 16);
043: public static final Integer KEYGENERATOR_COLUMN_STRATEGY = new Integer(
044: 32);
045:
046: // Attributes --------------------------------------
047: /** locking strategy */
048: final private Integer lockingStrategy;
049:
050: /** group name for field group strategy */
051: final private String groupName;
052:
053: /** locking field for verion- or timestamp-column strategy */
054: final private JDBCCMPFieldMetaData lockingField;
055:
056: /** key generator factory */
057: final private String keyGeneratorFactory;
058:
059: /** logger */
060: final private Logger log;
061:
062: // Constructors ------------------------------------
063: /**
064: * Constructs optimistic locking metadata reading
065: * optimistic-locking XML element
066: */
067: public JDBCOptimisticLockingMetaData(
068: JDBCEntityMetaData entityMetaData, Element element)
069: throws DeploymentException {
070: log = Logger.getLogger(entityMetaData.getName());
071:
072: Element strategyEl;
073: if ((strategyEl = MetaData.getOptionalChild(element,
074: "group-name")) != null) {
075: lockingStrategy = FIELD_GROUP_STRATEGY;
076: groupName = MetaData.getElementContent(strategyEl);
077: lockingField = null;
078: keyGeneratorFactory = null;
079:
080: log.debug("optimistic locking: group=" + groupName);
081: } else if ((strategyEl = MetaData.getOptionalChild(element,
082: "modified-strategy")) != null) {
083: lockingStrategy = MODIFIED_STRATEGY;
084: groupName = null;
085: lockingField = null;
086: keyGeneratorFactory = null;
087:
088: log.debug("optimistic locking: modified strategy");
089: } else if ((strategyEl = MetaData.getOptionalChild(element,
090: "read-strategy")) != null) {
091: lockingStrategy = READ_STRATEGY;
092: groupName = null;
093: lockingField = null;
094: keyGeneratorFactory = null;
095:
096: log.debug("optimistic locking: read strategy");
097: } else if ((strategyEl = MetaData.getOptionalChild(element,
098: "version-column")) != null) {
099: String fieldType = MetaData.getOptionalChildContent(
100: element, "field-type");
101: if (fieldType != null)
102: throw new DeploymentException(
103: "field-type is not allowed for version column. It is implicitly set to java.lang.Long.");
104:
105: lockingStrategy = VERSION_COLUMN_STRATEGY;
106: lockingField = constructLockingField(entityMetaData,
107: element);
108: groupName = null;
109: keyGeneratorFactory = null;
110:
111: log.debug("optimistic locking: version-column="
112: + lockingField.getFieldName());
113: } else if ((strategyEl = MetaData.getOptionalChild(element,
114: "timestamp-column")) != null) {
115: String fieldType = MetaData.getOptionalChildContent(
116: element, "field-type");
117: if (fieldType != null)
118: throw new DeploymentException(
119: "field-type is not allowed for timestamp column. It is implicitly set to java.util.Date.");
120:
121: lockingStrategy = TIMESTAMP_COLUMN_STRATEGY;
122: lockingField = constructLockingField(entityMetaData,
123: element);
124: groupName = null;
125: keyGeneratorFactory = null;
126:
127: log.debug("optimistic locking: timestamp-column="
128: + lockingField.getFieldName());
129: } else if ((keyGeneratorFactory = MetaData
130: .getOptionalChildContent(element,
131: "key-generator-factory")) != null) {
132: lockingStrategy = KEYGENERATOR_COLUMN_STRATEGY;
133: lockingField = constructLockingField(entityMetaData,
134: element);
135: groupName = null;
136:
137: log.debug("optimistic locking: key-generator-factory="
138: + keyGeneratorFactory);
139: } else {
140: throw new DeploymentException(
141: "Unexpected error: entity "
142: + entityMetaData.getName()
143: + " has unkown/incorrect optimistic locking configuration.");
144: }
145: }
146:
147: // Public ------------------------------------------
148: public Integer getLockingStrategy() {
149: return lockingStrategy;
150: }
151:
152: public String getGroupName() {
153: return groupName;
154: }
155:
156: public JDBCCMPFieldMetaData getLockingField() {
157: return lockingField;
158: }
159:
160: public String getKeyGeneratorFactory() {
161: return keyGeneratorFactory;
162: }
163:
164: // Private -----------------------------------------
165: /**
166: * Constructs a locking field metadata from
167: * XML element
168: */
169: private JDBCCMPFieldMetaData constructLockingField(
170: JDBCEntityMetaData entity, Element element)
171: throws DeploymentException {
172: // field name
173: String fieldName = MetaData.getOptionalChildContent(element,
174: "field-name");
175: if (fieldName == null || fieldName.trim().length() < 1)
176: fieldName = (lockingStrategy == VERSION_COLUMN_STRATEGY ? "version_lock"
177: : (lockingStrategy == TIMESTAMP_COLUMN_STRATEGY ? "timestamp_lock"
178: : "generated_lock"));
179:
180: // column name
181: String columnName = MetaData.getOptionalChildContent(element,
182: "column-name");
183: if (columnName == null || columnName.trim().length() < 1)
184: columnName = (lockingStrategy == VERSION_COLUMN_STRATEGY ? "version_lock"
185: : (lockingStrategy == TIMESTAMP_COLUMN_STRATEGY ? "timestamp_lock"
186: : "generated_lock"));
187:
188: // field type
189: Class fieldType = null;
190: if (lockingStrategy == VERSION_COLUMN_STRATEGY)
191: fieldType = java.lang.Long.class;
192: else if (lockingStrategy == TIMESTAMP_COLUMN_STRATEGY)
193: fieldType = java.util.Date.class;
194: String fieldTypeStr = MetaData.getOptionalChildContent(element,
195: "field-type");
196: if (fieldTypeStr != null) {
197: try {
198: fieldType = GetTCLAction.getContextClassLoader()
199: .loadClass(fieldTypeStr);
200: } catch (ClassNotFoundException e) {
201: throw new DeploymentException(
202: "Could not load field type for optimistic locking field "
203: + fieldName + ": " + fieldTypeStr);
204: }
205: }
206:
207: // JDBC/SQL Type
208: int jdbcType;
209: String sqlType;
210: String jdbcTypeName = MetaData.getOptionalChildContent(element,
211: "jdbc-type");
212: if (jdbcTypeName != null) {
213: jdbcType = JDBCMappingMetaData
214: .getJdbcTypeFromName(jdbcTypeName);
215: sqlType = MetaData.getUniqueChildContent(element,
216: "sql-type");
217: } else {
218: jdbcType = Integer.MIN_VALUE;
219: sqlType = null;
220: }
221:
222: return new JDBCCMPFieldMetaData(entity, fieldName, fieldType,
223: columnName, jdbcType, sqlType);
224: }
225: }
|