001: /***************************************************************
002: * This file is part of the [fleXive](R) project.
003: *
004: * Copyright (c) 1999-2008
005: * UCS - unique computing solutions gmbh (http://www.ucs.at)
006: * All rights reserved
007: *
008: * The [fleXive](R) project is free software; you can redistribute
009: * it and/or modify it under the terms of the GNU General Public
010: * License as published by the Free Software Foundation;
011: * either version 2 of the License, or (at your option) any
012: * later version.
013: *
014: * The GNU General Public License can be found at
015: * http://www.gnu.org/copyleft/gpl.html.
016: * A copy is found in the textfile GPL.txt and important notices to the
017: * license from the author are found in LICENSE.txt distributed with
018: * these libraries.
019: *
020: * This library is distributed in the hope that it will be useful,
021: * but WITHOUT ANY WARRANTY; without even the implied warranty of
022: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
023: * GNU General Public License for more details.
024: *
025: * For further information about UCS - unique computing solutions gmbh,
026: * please see the company website: http://www.ucs.at
027: *
028: * For further information about [fleXive](R), please see the
029: * project website: http://www.flexive.org
030: *
031: *
032: * This copyright notice MUST APPEAR in all copies of the file!
033: ***************************************************************/package com.flexive.core;
034:
035: import com.flexive.shared.FxContext;
036: import com.flexive.shared.exceptions.FxUpdateException;
037: import com.flexive.shared.security.LifeCycleInfo;
038: import com.flexive.shared.security.UserTicket;
039: import org.apache.commons.logging.Log;
040: import org.apache.commons.logging.LogFactory;
041:
042: import java.io.Serializable;
043: import java.sql.*;
044: import java.text.SimpleDateFormat;
045: import java.util.Date;
046:
047: /**
048: * LifeCycleInfo implementation
049: *
050: * @author Markus Plesser (markus.plesser@flexive.com), UCS - unique computing solutions gmbh (http://www.ucs.at)
051: */
052: public class LifeCycleInfoImpl implements LifeCycleInfo, Serializable {
053: private static final long serialVersionUID = -7886706421888644107L;
054:
055: /**
056: * our logger
057: */
058: private static final transient Log LOG = LogFactory
059: .getLog(LifeCycleInfoImpl.class);
060:
061: /**
062: * Value to set if a column is not set (=null)
063: */
064: private static final int NOT_DEFINED = -1;
065:
066: private long iCreatorId;
067: private long lCreationTime;
068: private long iModifcatorId;
069: private long lModificationTime;
070:
071: /**
072: * Empty LifeCycleInfo for tables where undefined
073: */
074: public static final LifeCycleInfo EMPTY = new LifeCycleInfoImpl(0,
075: 0, 0, 0);
076:
077: /**
078: * Get the Id of the User that created this entry
079: *
080: * @return Id of the User that created this entry
081: */
082: public long getCreatorId() {
083: return iCreatorId;
084: }
085:
086: /**
087: * Get the timestamp when this object was created
088: *
089: * @return the timestamp when this object was created
090: */
091: public long getCreationTime() {
092: return lCreationTime;
093: }
094:
095: /**
096: * Get the Id of the most recent User that modified this entry
097: *
098: * @return Id of the most recent User that modified this entry
099: */
100: public long getModificatorId() {
101: return iModifcatorId;
102: }
103:
104: /**
105: * Get the timestamp of the most recent modification
106: *
107: * @return timestamp of the most recent modification
108: */
109: public long getModificationTime() {
110: return lModificationTime;
111: }
112:
113: /**
114: * {@inheritDoc}
115: */
116: @Override
117: public String toString() {
118: SimpleDateFormat sdf = new SimpleDateFormat(
119: "dd.MM.yyyy HH:mm:ss");
120: return "LCI:{C:" + this .getCreatorId() + "/"
121: + sdf.format(new Date(this .getCreationTime())) + "|"
122: + "M:" + this .getModificatorId() + "/"
123: + sdf.format(new Date(this .getModificationTime()));
124: }
125:
126: /**
127: * Ctor
128: *
129: * @param creatorId user id of the creator
130: * @param creationTime timestamp of creation
131: * @param modificator user id of the user that made the last modification
132: * @param modificationTime modification timestamp
133: */
134: public LifeCycleInfoImpl(long creatorId, long creationTime,
135: long modificator, long modificationTime) {
136: this .iCreatorId = creatorId;
137: this .lCreationTime = creationTime;
138: this .iModifcatorId = modificator;
139: this .lModificationTime = modificationTime;
140: }
141:
142: /**
143: * Helper function for a less error prone and faster loading from the database
144: *
145: * @param rs ResultSet containing all the required info
146: * @param creatorColumn column index of the create user reference
147: * @param creationTimeColumn column index of the create timestamp
148: * @param modificatorColumns column index of the modified by user reference
149: * @param modificationTimeColumn column index of the modified by timestamp
150: * @return LifeCycleInfo with the relevant data gathered from the ResultSet
151: * @throws java.sql.SQLException if a column could not be read
152: */
153: public static LifeCycleInfo load(ResultSet rs, int creatorColumn,
154: int creationTimeColumn, int modificatorColumns,
155: int modificationTimeColumn) throws SQLException {
156: if (rs == null) {
157: throw new IllegalArgumentException(
158: "Can not read from a null ResultSet!");
159: }
160: int cid;
161: long ct;
162: int mid;
163: long mt;
164: long dTmp;
165: cid = rs.getInt(creatorColumn);
166: if (rs.wasNull()) {
167: cid = NOT_DEFINED;
168: }
169: dTmp = rs.getLong(creationTimeColumn);
170: ct = (rs.wasNull() ? NOT_DEFINED : dTmp);
171: if (modificatorColumns < 0) {
172: mid = NOT_DEFINED;
173: } else {
174: mid = rs.getInt(modificatorColumns);
175: if (rs.wasNull())
176: mid = NOT_DEFINED;
177: }
178: if (modificationTimeColumn < 0) {
179: mt = NOT_DEFINED;
180: } else {
181: dTmp = rs.getLong(modificationTimeColumn);
182: mt = (rs.wasNull() ? NOT_DEFINED : dTmp);
183: }
184: return new LifeCycleInfoImpl(cid, ct, mid, mt);
185: }
186:
187: /**
188: * Store a complete lifecycle info
189: *
190: * @param ps prepared statement
191: * @param creatorColumn column index of the create user reference
192: * @param creationTimeColumn column index of the create timestamp
193: * @param modificatorColumn column index of the modified by user reference
194: * @param modificationTimeColumn column index of the modified by timestamp
195: * @throws java.sql.SQLException if a column could not be set
196: */
197: public static void store(PreparedStatement ps, int creatorColumn,
198: int creationTimeColumn, int modificatorColumn,
199: int modificationTimeColumn) throws SQLException {
200: final UserTicket ticket = FxContext.get().getTicket();
201: final long ts = System.currentTimeMillis();
202: ps.setLong(creatorColumn, ticket.getUserId());
203: ps.setLong(creationTimeColumn, ts);
204: ps.setLong(modificatorColumn, ticket.getUserId());
205: ps.setLong(modificationTimeColumn, ts);
206: }
207:
208: /**
209: * Update a lifyecycle info
210: *
211: * @param ps prepared statement
212: * @param modificatorColumn column index of the modified by user reference
213: * @param modificationTimeColumn column index of the modified by timestamp
214: * @throws java.sql.SQLException if a column could not be set
215: */
216: public static void updateLifeCycleInfo(PreparedStatement ps,
217: int modificatorColumn, int modificationTimeColumn)
218: throws SQLException {
219: final UserTicket ticket = FxContext.get().getTicket();
220: final long ts = System.currentTimeMillis();
221: ps.setLong(modificatorColumn, ticket.getUserId());
222: ps.setLong(modificationTimeColumn, ts);
223: }
224:
225: /**
226: * Update a tables LifeCycleInfo
227: *
228: * @param table table that contains the lifecycle
229: * @param idField field containing the id
230: * @param id the id to update
231: * @throws FxUpdateException if the lifecycle info could not be updated
232: */
233: public static void updateLifeCycleInfo(String table,
234: String idField, long id) throws FxUpdateException {
235: updateLifeCycleInfo(table, idField, null, id, -1, false, true);
236: }
237:
238: /**
239: * Update a tables LifeCycleInfo
240: *
241: * @param table table that contains the lifecycle
242: * @param idField field containing the id
243: * @param id the id to update
244: * @param verField field containing the id (optional)
245: * @param ver the version to update (optional)
246: * @param updateCreated update created by/at as well?
247: * @param throwOnNone throw an exception if no rows were updated?
248: * @throws FxUpdateException if a database field could not be updated
249: */
250: public static void updateLifeCycleInfo(String table,
251: String idField, String verField, long id, int ver,
252: boolean updateCreated, boolean throwOnNone)
253: throws FxUpdateException {
254: final UserTicket ticket = FxContext.get().getTicket();
255:
256: Connection con = null;
257: PreparedStatement stmt = null;
258:
259: try {
260: con = Database.getDbConnection();
261: stmt = con.prepareStatement("UPDATE "
262: + table
263: + " SET MODIFIED_BY=?, MODIFIED_AT=?"
264: + (updateCreated ? ", CREATED_BY=?, CREATED_AT=?"
265: : "")
266: + " WHERE "
267: + idField
268: + "=?"
269: + (verField != null && ver > 0 ? " AND " + verField
270: + "=?" : ""));
271: final long now = System.currentTimeMillis();
272: stmt.setInt(1, (int) ticket.getUserId());
273: stmt.setLong(2, now);
274: if (updateCreated) {
275: stmt.setInt(3, (int) ticket.getUserId());
276: stmt.setLong(4, now);
277: stmt.setLong(5, id);
278: } else
279: stmt.setLong(3, id);
280: if (verField != null && ver > 0)
281: stmt.setInt((updateCreated ? 6 : 4), ver);
282: int iCnt = stmt.executeUpdate();
283: if (iCnt != 1 && throwOnNone)
284: throw new FxUpdateException(
285: "Updating LifeCycleInfo failed. " + iCnt
286: + " rows were updated!");
287: } catch (SQLException se) {
288: throw new FxUpdateException(LOG, se.getMessage(), se);
289: } finally {
290: Database.closeObjects(LifeCycleInfoImpl.class, con, stmt);
291: }
292: }
293:
294: /**
295: * Initialize a new empty lci
296: *
297: * @param ticket the calling user's ticket
298: * @return a new lifecycle info for the calling user
299: */
300: public static LifeCycleInfo createNew(UserTicket ticket) {
301: return new LifeCycleInfoImpl(ticket.getUserId(), System
302: .currentTimeMillis(), ticket.getUserId(), System
303: .currentTimeMillis());
304: }
305: }
|