Source code: com/jcorporate/expresso/core/dbobj/HistAuditSecuredDBObject.java
1 /* ====================================================================
2 * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
3 *
4 * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 *
18 * 3. The end-user documentation included with the redistribution,
19 * if any, must include the following acknowledgment:
20 * "This product includes software developed by Jcorporate Ltd.
21 * (http://www.jcorporate.com/)."
22 * Alternately, this acknowledgment may appear in the software itself,
23 * if and wherever such third-party acknowledgments normally appear.
24 *
25 * 4. "Jcorporate" and product names such as "Expresso" must
26 * not be used to endorse or promote products derived from this
27 * software without prior written permission. For written permission,
28 * please contact info@jcorporate.com.
29 *
30 * 5. Products derived from this software may not be called "Expresso",
31 * or other Jcorporate product names; nor may "Expresso" or other
32 * Jcorporate product names appear in their name, without prior
33 * written permission of Jcorporate Ltd.
34 *
35 * 6. No product derived from this software may compete in the same
36 * market space, i.e. framework, without prior written permission
37 * of Jcorporate Ltd. For written permission, please contact
38 * partners@jcorporate.com.
39 *
40 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
41 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
42 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43 * DISCLAIMED. IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
44 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
45 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
46 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
47 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
48 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
49 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
50 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 * ====================================================================
53 *
54 * This software consists of voluntary contributions made by many
55 * individuals on behalf of the Jcorporate Ltd. Contributions back
56 * to the project(s) are encouraged when you make modifications.
57 * Please send them to support@jcorporate.com. For more information
58 * on Jcorporate Ltd. and its products, please see
59 * <http://www.jcorporate.com/>.
60 *
61 * Portions of this software are based upon other open source
62 * products and are subject to their respective licenses.
63 */
64
65 package com.jcorporate.expresso.core.dbobj;
66
67 import com.jcorporate.expresso.core.db.DBConnection;
68 import com.jcorporate.expresso.core.db.DBException;
69 import com.jcorporate.expresso.core.misc.DateTime;
70 import com.jcorporate.expresso.kernel.util.ClassLocator;
71
72 import java.util.Iterator;
73
74
75 /**
76 * HistAuditSecuredDBObject is an object that is audited
77 * (as in the AuditedSecuredDBObject) and is also archived in a history table
78 * that stores the entire record on either ADD or UPDATE.
79 * <p/>
80 * A HistAuditSecuredDBObject MUST have the following fields defined:
81 * <p/>
82 * <SOMEKEY>
83 * ...<ALL FIELDS IN THE MATCHING TABLE>
84 * AUDITLOG_ID
85 * HISTORY_DATE
86 * <p/>
87 * So for example, if you have a table called Vendor that you want to have
88 * history kept for, you would do this:
89 * <p/>
90 * HistAuditSecuredDBObject Vendor fields:
91 * <p/>
92 * VENDOR_ID
93 * VENDOR_NAME
94 * AUDITLOG_ID (because this is also a AuditedSecuredDBObject).
95 * <p/>
96 * There must then be a DBObject called "VendorHistory" with the following
97 * fields:
98 * <p/>
99 * VENDOR_HISTORY_ID (auto-inc)
100 * VENDOR_ID
101 * VENDOR_NAME
102 * AUDITLOG_ID
103 * HISTORY_DATE
104 * <p/>
105 * It is a good idea to set all of the fields in the VendorHistory object as
106 * readonly, and do not have any referential integrity set on any of the fields
107 * (for example, the VENDOR_ID column is the key in the Vendor object, but will
108 * probably repeat in the VendorHistory table).
109 * <p/>
110 * We should probably enhance this by creating a base HISTORY table DBObject
111 * that enforces/automates this.
112 *
113 * @author Adam Rossi, PlatinumSolutions
114 */
115 public class HistAuditSecuredDBObject
116 extends AuditedSecuredDBObject {
117 //private String historyTableClassName = null;
118 /**
119 * Construct an audit secured DBObject
120 */
121 public HistAuditSecuredDBObject()
122 throws DBException {
123 super();
124 }
125
126 /**
127 * Constructor
128 *
129 * @param theConnection Database connection to
130 * communicate with the database
131 * @throws DBException If the new object cannot be
132 * created
133 */
134 public HistAuditSecuredDBObject(DBConnection theConnection)
135 throws DBException {
136 super(theConnection);
137 }
138
139 /**
140 * Method to write an entry to the History table.
141 */
142 private void writeRecordToHistory()
143 throws DBException {
144
145 //recurse through fields and write a copy to the corresponding
146 //history table
147 try {
148 Class clazz = ClassLocator.loadClass(getHistoryTableClassName());
149 SecuredDBObject histObject = (SecuredDBObject) clazz.newInstance();
150
151 if (histObject == null) {
152 throw new DBException("The history object is null.");
153 }
154
155 Iterator fieldsIterator = this.getJDBCMetaData().getFieldListArray().iterator();
156 String fieldName = null;
157
158 while (fieldsIterator.hasNext()) {
159 fieldName = (String) fieldsIterator.next();
160 histObject.setField(fieldName, this.getField(fieldName));
161 }
162
163 histObject.setField("HISTORY_DATE", DateTime.getDateTimeForDB(this.getDataContext()));
164 histObject.add();
165 } catch (Exception e) {
166 throw new DBException("An error occured while trying to write to the history table: " +
167 e.toString());
168 }
169 }
170
171 /**
172 * The assumption here is that the history table DBObject is called
173 * objectname + "History", such as "VendorHistory" for the DBObject "Vendor".
174 *
175 * @return the class name of the history table as a <code>java.lang.String</code>
176 */
177 public String getHistoryTableClassName() {
178 return this.getClass().getName() + "History";
179 }
180
181 /**
182 * On the add method, always write an entry to the history table.
183 *
184 * @throws DBException upon error
185 */
186 public synchronized void add()
187 throws DBException {
188 super.add();
189 this.writeRecordToHistory();
190 }
191
192 /**
193 * On the update method, always write an entry to the history table.
194 */
195 public synchronized void update()
196 throws DBException {
197 super.update();
198 this.writeRecordToHistory();
199 }
200 }