001: /* ====================================================================
002: * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
003: *
004: * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: *
010: * 1. Redistributions of source code must retain the above copyright
011: * notice, this list of conditions and the following disclaimer.
012: *
013: * 2. Redistributions in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in
015: * the documentation and/or other materials provided with the
016: * distribution.
017: *
018: * 3. The end-user documentation included with the redistribution,
019: * if any, must include the following acknowledgment:
020: * "This product includes software developed by Jcorporate Ltd.
021: * (http://www.jcorporate.com/)."
022: * Alternately, this acknowledgment may appear in the software itself,
023: * if and wherever such third-party acknowledgments normally appear.
024: *
025: * 4. "Jcorporate" and product names such as "Expresso" must
026: * not be used to endorse or promote products derived from this
027: * software without prior written permission. For written permission,
028: * please contact info@jcorporate.com.
029: *
030: * 5. Products derived from this software may not be called "Expresso",
031: * or other Jcorporate product names; nor may "Expresso" or other
032: * Jcorporate product names appear in their name, without prior
033: * written permission of Jcorporate Ltd.
034: *
035: * 6. No product derived from this software may compete in the same
036: * market space, i.e. framework, without prior written permission
037: * of Jcorporate Ltd. For written permission, please contact
038: * partners@jcorporate.com.
039: *
040: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
041: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
042: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
043: * DISCLAIMED. IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
044: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
045: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
046: * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
047: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
048: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
049: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
050: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
051: * SUCH DAMAGE.
052: * ====================================================================
053: *
054: * This software consists of voluntary contributions made by many
055: * individuals on behalf of the Jcorporate Ltd. Contributions back
056: * to the project(s) are encouraged when you make modifications.
057: * Please send them to support@jcorporate.com. For more information
058: * on Jcorporate Ltd. and its products, please see
059: * <http://www.jcorporate.com/>.
060: *
061: * Portions of this software are based upon other open source
062: * products and are subject to their respective licenses.
063: */
064:
065: package com.jcorporate.expresso.services.test;
066:
067: import com.jcorporate.expresso.core.db.DBException;
068: import com.jcorporate.expresso.core.dbobj.Schema;
069: import com.jcorporate.expresso.kernel.ConsoleInstallLog;
070: import org.apache.log4j.Logger;
071:
072: import java.util.HashMap;
073: import java.util.TreeSet;
074:
075: /**
076: * This class reference counts references to various Schema objects.
077: * When a reference count drops to zero, the schema is deleted. [If it's not
078: * marked read only] If it is marked readonly, then the schema is created,
079: * but not deleted. [Makes for much faster checking when running unit tests
080: * on, say, a single controller]
081: *
082: * @author Michael Rimov
083: * @version $Revision: 1.12 $ $Date: 2004/11/17 20:48:22 $
084: */
085: public class SchemaManager {
086: static HashMap references = new HashMap();
087: static TreeSet readOnlySet = new TreeSet();
088: static Logger log = Logger.getLogger(SchemaManager.class);
089:
090: public SchemaManager() {
091: }
092:
093: /**
094: * Add a reference to a schema. Create the schema if no previous reference
095: *
096: * @param s The Schema to reference
097: */
098: synchronized static public void addReference(Schema s) {
099: SchemaManager.addReference(s, false);
100: }
101:
102: /**
103: * Add a reference to a schema. Create the schema if no previous reference
104: *
105: * @param s The Schema to reference
106: * @param forceNoCreate Set to true if you just want a reference added, but no
107: * schema created. This is used if DBToolTests are being run in the test
108: * suite.
109: */
110: synchronized static public void addReference(Schema s,
111: boolean forceNoCreate) {
112: if (log.isDebugEnabled()) {
113: log.debug("Adding Reference To Schema: "
114: + s.getClass().getName());
115: }
116: if (readOnlySet.contains(s.getClass().getName())) {
117: readOnlySet.remove(s.getClass().getName());
118: }
119: if (references.containsKey(s)) {
120: Integer i = (Integer) references.get(s);
121:
122: if (i == null) {
123: log
124: .error("Got null reference count, when schema exists in the "
125: + " hash map");
126: references.put(s, new Integer(1));
127: } else {
128: Integer i2 = new Integer(i.intValue() + 1);
129:
130: if (log.isDebugEnabled()) {
131: log.debug("Previous Reference Count: "
132: + i.toString());
133: }
134:
135: references.put(s, i2);
136: }
137: } else {
138: if (log.isDebugEnabled()) {
139: log.debug("Inserting new reference");
140: }
141:
142: references.put(s, new Integer(1));
143:
144: if (forceNoCreate == false) {
145: try {
146:
147: if (SchemaCreator.ensureSchemaExists(s,
148: new ConsoleInstallLog()) == true) {
149:
150: //Schema was already created.
151: //Happens in Cactus test cases where two instances
152: //of this class are running. Just increment the
153: //reference count so that we don't accidentally
154: //delete it before it's time.
155: log
156: .debug("Schema "
157: + s.getClass().getName()
158: + " didn't have a reference but already exists.");
159: references.put(s, new Integer(2));
160: }
161: } catch (DBException e) {
162: log.error("Error Creating Schema", e);
163: }
164: }
165: }
166: }
167:
168: /**
169: * Adds a schema reference that is not removed when the count goes to zero
170: * because it is a read only schema. You can undo this 'read-onliness' by
171: * calling forceSchemaDelete() which will remove the read only flags for
172: * this schema. Note that if any other reference is added for this schema,
173: * then if it's a non-readonly reference, than the schema will be deleted
174: * as usual.
175: *
176: * @param s the Schema to add
177: */
178: synchronized static public void addReadOnlyReference(Schema s) {
179: boolean canBeReadOnly = false;
180:
181: if (!references.containsKey(s)) {
182: canBeReadOnly = true;
183: } else if (readOnlySet.contains(s.getClass().getName())) {
184: canBeReadOnly = true;
185: }
186:
187: addReference(s);
188: readOnlySet.add(s.getClass().getName());
189: }
190:
191: /**
192: * Reduces the reference count to Schema s. Deletes the schema if the
193: * reference count is reduced to zero.
194: *
195: * @param s the Schema to remove a reference.
196: */
197: synchronized static public void removeReference(Schema s) {
198: if (log.isDebugEnabled()) {
199: log.debug("Removing Reference To Schema: "
200: + s.getClass().getName());
201: }
202: if (references.containsKey(s)) {
203: Integer i = (Integer) references.get(s);
204:
205: if (i.intValue() == 1) {
206: references.remove(s);
207:
208: if (!readOnlySet.contains(s.getClass().getName())) {
209: if (log.isDebugEnabled()) {
210: log
211: .debug("Reference going to zero. Removing Schema");
212: }
213:
214: SchemaDeleter.deleteSchema(TestSystemInitializer
215: .getTestContext(), s);
216: } else {
217: readOnlySet.remove(s.getClass().getName());
218:
219: if (log.isDebugEnabled()) {
220: log
221: .debug("Reference to zero, but read only item. Not removing schema");
222: }
223: }
224: } else {
225: Integer i2 = new Integer(i.intValue() - 1);
226: references.put(s, i2);
227: }
228: } else {
229: log.error("Schema : " + s.getClass().getName()
230: + "not found in reference list");
231:
232: return;
233: }
234: }
235:
236: /**
237: * Forces the schema deletion even if the schema is marked "read only"
238: *
239: * @param s the schema to force a delete
240: */
241: synchronized static public void forceSchemaDelete(Schema s) {
242: readOnlySet.remove(s.getClass().getName());
243: }
244:
245: synchronized static public void forceAllSchemaDelete() {
246: readOnlySet.clear();
247: }
248:
249: }
|