001: /**********************************************************************
002: Copyright (c) 2005 Andy Jefferson 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: ...
018: **********************************************************************/package org.jpox.sco;
019:
020: import java.io.ObjectStreamException;
021: import java.util.Date;
022: import java.util.TimeZone;
023:
024: import org.jpox.StateManager;
025: import org.jpox.state.FetchPlanState;
026:
027: /**
028: * A mutable second-class GregorianCalendar object.
029: *
030: * @version $Revision: 1.27 $
031: */
032: public class GregorianCalendar extends java.util.GregorianCalendar
033: implements SCO {
034: private transient StateManager ownerSM;
035: private transient Object owner;
036: private transient String fieldName;
037:
038: /**
039: * Creates a <tt>GregorianCalendar</tt> object that represents the time at which it was allocated.
040: * Assigns owning object and field name.
041: * @param ownerSM the owning object
042: * @param fieldName the owning field name
043: */
044: public GregorianCalendar(StateManager ownerSM, String fieldName) {
045: super ();
046:
047: if (ownerSM != null) {
048: this .ownerSM = ownerSM;
049: this .owner = ownerSM.getObject();
050: }
051: this .fieldName = fieldName;
052: }
053:
054: /**
055: * Method to initialise the SCO for use.
056: */
057: public void initialise() {
058: }
059:
060: /**
061: * Method to initialise the SCO from an existing value.
062: * @param o The Object
063: * @param forInsert Whether the object needs inserting in the datastore with this value
064: * @param forUpdate Whether to update the datastore with this value
065: */
066: public void initialise(Object o, boolean forInsert,
067: boolean forUpdate) {
068: java.util.Calendar cal = (java.util.Calendar) o;
069: super .setTimeInMillis(cal.getTime().getTime());
070: super .setTimeZone(cal.getTimeZone());
071: }
072:
073: /**
074: * Accessor for the unwrapped value that we are wrapping.
075: * @return The unwrapped value
076: */
077: public Object getValue() {
078: java.util.GregorianCalendar cal = new java.util.GregorianCalendar(
079: getTimeZone());
080: cal.setTime(getTime());
081: return cal;
082: }
083:
084: /**
085: * Utility to unset the owner.
086: **/
087: public void unsetOwner() {
088: owner = null;
089: ownerSM = null;
090: fieldName = null;
091: }
092:
093: /**
094: * Accessor for the owner.
095: * @return The owner
096: **/
097: public Object getOwner() {
098: return owner;
099: }
100:
101: /**
102: * Accessor for the field name
103: * @return The field name
104: */
105: public String getFieldName() {
106: return this .fieldName;
107: }
108:
109: /**
110: * Utility to mark the object as dirty
111: */
112: public void makeDirty() {
113: if (ownerSM != null) {
114: ownerSM.getObjectManager().getApiAdapter().makeFieldDirty(
115: owner, fieldName);
116: }
117: }
118:
119: /**
120: * Method to return a detached copy of the value object.
121: * @param state State for detachment process
122: * @return The detached copy
123: */
124: public Object detachCopy(FetchPlanState state) {
125: // Return a java.util.GregorianCalendar
126: java.util.GregorianCalendar cal = new java.util.GregorianCalendar(
127: getTimeZone());
128: cal.setTime(getTime());
129: return cal;
130: }
131:
132: /**
133: * Method to return an attached version for the passed StateManager and
134: * field, using the passed value.
135: * @param value The new value
136: */
137: public void attachCopy(Object value) {
138: long oldValue = getTimeInMillis();
139: initialise(value, false, true);
140:
141: // Check if the field has changed, and set the owner field as dirty if
142: // necessary
143: long newValue = ((java.util.Calendar) value).getTime()
144: .getTime();
145: if (oldValue != newValue) {
146: makeDirty();
147: }
148: }
149:
150: /**
151: * Creates and returns a copy of this object.
152: * <p>
153: * Mutable second-class Objects are required to provide a public clone
154: * method in order to allow for copying PersistenceCapable objects. In
155: * contrast to Object.clone(), this method must not throw a
156: * CloneNotSupportedException.
157: * @return A clone of the object
158: */
159: public Object clone() {
160: Object obj = super .clone();
161:
162: ((GregorianCalendar) obj).unsetOwner();
163:
164: return obj;
165: }
166:
167: /**
168: * The writeReplace method is called when ObjectOutputStream is preparing to
169: * write the object to the stream. The ObjectOutputStream checks whether the
170: * class defines the writeReplace method. If the method is defined, the
171: * writeReplace method is called to allow the object to designate its
172: * replacement in the stream. The object returned should be either of the
173: * same type as the object passed in or an object that when read and
174: * resolved will result in an object of a type that is compatible with all
175: * references to the object.
176: * @return the replaced object
177: * @throws ObjectStreamException
178: */
179: protected Object writeReplace() throws ObjectStreamException {
180: java.util.GregorianCalendar cal = new java.util.GregorianCalendar(
181: this .getTimeZone());
182: cal.setTime(this .getTime());
183: return cal;
184: }
185:
186: // ------------------------- Implementation of the methods -----------------------------
187:
188: /**
189: * Method to add an amount to a field
190: * @param field The field
191: * @param amount The amount to add
192: */
193: public void add(int field, int amount) {
194: super .add(field, amount);
195: makeDirty();
196: }
197:
198: /**
199: * Method to roll a field by 1.
200: * @param field The field
201: * @param up The whether to move it up
202: */
203: public void roll(int field, boolean up) {
204: super .roll(field, up);
205: makeDirty();
206: }
207:
208: /**
209: * Method to roll the value of a field
210: * @param field The field
211: * @param amount The amount to roll by
212: */
213: public void roll(int field, int amount) {
214: super .roll(field, amount);
215: makeDirty();
216: }
217:
218: /**
219: * Method to set the gregorian cal change date
220: * @param date The new change date
221: */
222: public void setGregorianChange(Date date) {
223: super .setGregorianChange(date);
224: makeDirty();
225: }
226:
227: /**
228: * Method to set the first day of the week
229: * @param value The first day of the week
230: */
231: public void setFirstDayOfWeek(int value) {
232: super .setFirstDayOfWeek(value);
233: makeDirty();
234: }
235:
236: /**
237: * Method to set the lenient setting
238: * @param lenient Whether it is lenient
239: */
240: public void setLenient(boolean lenient) {
241: super .setLenient(lenient);
242: makeDirty();
243: }
244:
245: /**
246: * Method to set the minimal days in the week
247: * @param value The minimal days in the week
248: */
249: public void setMinimalDaysInFirstWeek(int value) {
250: super .setMinimalDaysInFirstWeek(value);
251: makeDirty();
252: }
253:
254: /**
255: * Method to set the time in milliseconds
256: * @param millis The new time in millisecs
257: */
258: public void setTimeInMillis(long millis) {
259: super .setTimeInMillis(millis);
260: makeDirty();
261: }
262:
263: /**
264: * Method to set the timezone
265: * @param value The new timezone
266: */
267: public void setTimeZone(TimeZone value) {
268: super.setTimeZone(value);
269: makeDirty();
270: }
271: }
|