001: /**********************************************************************
002: Copyright (c) 2004 Erik Bengtson and others. All rights reserved.
003: Licensed under the Apache License, Version 2.0 (the "License");
004: you may not use this file except in compliance with the License.
005: You may obtain a copy of the License at
006:
007: http://www.apache.org/licenses/LICENSE-2.0
008:
009: Unless required by applicable law or agreed to in writing, software
010: distributed under the License is distributed on an "AS IS" BASIS,
011: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: See the License for the specific language governing permissions and
013: limitations under the License.
014:
015:
016: Contributors:
017: 2004 Andy Jefferson - added javadocs
018: 2004 Andy Jefferson - changed to use Column spec from MetaData
019: ...
020: **********************************************************************/package org.jpox.store.mapping;
021:
022: import java.sql.Timestamp;
023:
024: import org.jpox.ClassLoaderResolver;
025: import org.jpox.ObjectManager;
026: import org.jpox.exceptions.JPOXUserException;
027: import org.jpox.metadata.ColumnMetaData;
028: import org.jpox.metadata.VersionMetaData;
029: import org.jpox.metadata.VersionStrategy;
030: import org.jpox.store.DatastoreContainerObject;
031: import org.jpox.store.DatastoreField;
032: import org.jpox.store.DatastoreAdapter;
033: import org.jpox.store.DatastoreIdentifier;
034: import org.jpox.store.IdentifierFactory;
035: import org.jpox.store.expression.QueryExpression;
036: import org.jpox.store.expression.ScalarExpression;
037: import org.jpox.store.expression.LogicSetExpression;
038:
039: /**
040: * Mapping class for mapping version state/timestamp columns in the database.
041: * This class is for internal use only. It should not be used in user mappings.
042: *
043: * @version $Revision: 1.29 $
044: */
045: public final class VersionMapping extends SingleFieldMapping implements
046: SimpleDatastoreRepresentation {
047: private final JavaTypeMapping delegate;
048:
049: private final VersionMetaData versionMetaData;
050:
051: /**
052: * Constructor.
053: * @param dba Datastore Adapter
054: * @param datastoreContainer Datastore table
055: * @param delegate The JavaTypeMapping to delegate the storage
056: */
057: public VersionMapping(DatastoreAdapter dba,
058: DatastoreContainerObject datastoreContainer,
059: JavaTypeMapping delegate) {
060: initialize(dba, delegate.getType());
061: this .delegate = delegate;
062: this .versionMetaData = datastoreContainer.getVersionMetaData();
063:
064: // Currently we only use a single column mapping for versioning.
065: // The MetaData supports multiple columns and so we could extend this in the future
066: // to use all MetaData information.
067: ColumnMetaData[] versionColumnMetaData = versionMetaData
068: .getColumnMetaData();
069: ColumnMetaData colmd;
070: IdentifierFactory idFactory = datastoreContainer
071: .getStoreManager().getIdentifierFactory();
072: DatastoreIdentifier id = null;
073: if (versionColumnMetaData.length == 0) {
074: // No column name so generate a default
075: id = idFactory.newVersionFieldIdentifier();
076: colmd = new ColumnMetaData(versionMetaData, id
077: .getIdentifier());
078: datastoreContainer.getVersionMetaData().addColumn(colmd);
079: } else {
080: // Column name defined
081: colmd = versionColumnMetaData[0];
082: id = idFactory.newDatastoreFieldIdentifier(colmd.getName());
083: }
084: DatastoreField column = datastoreContainer.addDatastoreField(
085: getType(), id, this , colmd);
086: datastoreContainer.getStoreManager().getMappingManager()
087: .createDatastoreMapping(delegate,
088: datastoreContainer.getStoreManager(), column,
089: getType());
090: }
091:
092: /**
093: * Accessor for a sample value for this column
094: * @return The sample value
095: */
096: public Object getSampleValue(ClassLoaderResolver clr) {
097: return delegate.getSampleValue(clr);
098: }
099:
100: /**
101: * Accessor for a new literal for this mapping.
102: * @param qs The QueryStatement
103: * @param value The value of the object
104: * @return The new literal
105: */
106: public ScalarExpression newLiteral(QueryExpression qs, Object value) {
107: return delegate.newLiteral(qs, value);
108: }
109:
110: /**
111: * Accessor for a new literal for this mapping.
112: * @param qs The QueryStatement
113: * @param te The table expression
114: * @return The new literal
115: */
116: public ScalarExpression newScalarExpression(QueryExpression qs,
117: LogicSetExpression te) {
118: return delegate.newScalarExpression(qs, te);
119: }
120:
121: /**
122: * Accessor for whether to include this column in any fetch statement
123: * @return Whether to include the column when fetching.
124: */
125: public boolean includeInFetchStatement() {
126: return false;
127: }
128:
129: /**
130: * Accessor for the number of datastore fields.
131: * @return Number of datastore fields.
132: */
133: public int getNumberOfDatastoreFields() {
134: return delegate.getNumberOfDatastoreFields();
135: }
136:
137: /**
138: * Accessor for a datastore mapping.
139: * @param index The mapping index
140: * @return the datastore mapping
141: */
142: public DatastoreMapping getDataStoreMapping(int index) {
143: return delegate.getDataStoreMapping(index);
144: }
145:
146: /**
147: * Method to add a datastore mapping.
148: * @param datastoreMapping The mapping
149: */
150: public void addDataStoreMapping(DatastoreMapping datastoreMapping) {
151: delegate.addDataStoreMapping(datastoreMapping);
152: }
153:
154: /**
155: * Accessor for the type represented here, returning the class itself
156: * @return This class.
157: */
158: public Class getJavaType() {
159: return VersionMapping.class;
160: }
161:
162: /**
163: * Mutator for the object in this column
164: * @param om The ObjectManager
165: * @param preparedStatement The statement
166: * @param exprIndex The indexes
167: * @param value The value to set it to
168: */
169: public void setObject(ObjectManager om, Object preparedStatement,
170: int[] exprIndex, Object value) {
171: delegate.setObject(om, preparedStatement, exprIndex, value);
172: }
173:
174: /**
175: * Accessor for the object in this column
176: * @param om The ObjectManager
177: * @param resultSet The ResultSet to get the value from
178: * @param exprIndex The indexes
179: * @return The object
180: */
181: public Object getObject(ObjectManager om, Object resultSet,
182: int[] exprIndex) {
183: return delegate.getObject(om, resultSet, exprIndex);
184: }
185:
186: /**
187: * Accessor for the next version of the object.
188: * Returns an object of type Long (NONE, VERSION_NUMBER strategy) or Timestamp (DATE_TIME strategy).
189: * TODO Move this to a utilities class where it can be used by other datastore that dont use mappings.
190: * @param vermd MetaData defining the version.
191: * @param currentVersion The current version
192: * @return The next version
193: */
194: public static Object getNextVersion(VersionMetaData vermd,
195: Object currentVersion) {
196: if (vermd == null) {
197: // TODO Support optimistic when not using strategy
198: throw new JPOXUserException(
199: "JPOX doesnt currently support the use of optimistic transactions when "
200: + "no strategy is specified");
201: } else if (vermd.getVersionStrategy() == VersionStrategy.NONE) {
202: // Just increment the version
203: if (currentVersion == null) {
204: return new Long(1);
205: }
206: return new Long(((Long) currentVersion).longValue() + 1);
207: } else if (vermd.getVersionStrategy() == VersionStrategy.DATE_TIME) {
208: return new Timestamp(System.currentTimeMillis());
209: } else if (vermd.getVersionStrategy() == VersionStrategy.VERSION_NUMBER) {
210: if (currentVersion == null) {
211: return new Long(1);
212: }
213: return new Long(((Long) currentVersion).longValue() + 1);
214: } else if (vermd.getVersionStrategy() == VersionStrategy.STATE_IMAGE) {
215: // TODO Support state-image strategy
216: throw new JPOXUserException(
217: "JPOX doesnt currently support optimistic version strategy \"state-image\"");
218: } else {
219: throw new JPOXUserException(
220: "Unknown optimistic version strategy - not supported");
221: }
222: }
223: }
|