Source code: org/objectstyle/cayenne/access/DefaultOperationObserver.java
1 /* ====================================================================
2 *
3 * The ObjectStyle Group Software License, Version 1.0
4 *
5 * Copyright (c) 2002 The ObjectStyle Group
6 * and individual authors of the software. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. The end-user documentation included with the redistribution, if
21 * any, must include the following acknowlegement:
22 * "This product includes software developed by the
23 * ObjectStyle Group (http://objectstyle.org/)."
24 * Alternately, this acknowlegement may appear in the software itself,
25 * if and wherever such third-party acknowlegements normally appear.
26 *
27 * 4. The names "ObjectStyle Group" and "Cayenne"
28 * must not be used to endorse or promote products derived
29 * from this software without prior written permission. For written
30 * permission, please contact andrus@objectstyle.org.
31 *
32 * 5. Products derived from this software may not be called "ObjectStyle"
33 * nor may "ObjectStyle" appear in their names without prior written
34 * permission of the ObjectStyle Group.
35 *
36 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39 * DISCLAIMED. IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47 * SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This software consists of voluntary contributions made by many
51 * individuals on behalf of the ObjectStyle Group. For more
52 * information on the ObjectStyle Group, please see
53 * <http://objectstyle.org/>.
54 *
55 */
56
57 package org.objectstyle.cayenne.access;
58
59 import java.io.PrintWriter;
60 import java.util.ArrayList;
61 import java.util.HashMap;
62 import java.util.Iterator;
63 import java.util.List;
64 import java.util.Map;
65
66 import org.apache.log4j.Level;
67 import org.apache.log4j.Logger;
68 import org.objectstyle.cayenne.query.Query;
69
70 /**
71 * Simple implementation of OperationObserver interface.
72 * Useful as a superclass of other implementations of OperationObserver.
73 *
74 * <p><i>For more information see <a href="../../../../../../userguide/index.html"
75 * target="_top">Cayenne User Guide.</a></i></p>
76 *
77 * @author Andrei Adamchik
78 */
79 public class DefaultOperationObserver implements OperationObserver {
80 private static Logger logObj = Logger.getLogger(DefaultOperationObserver.class);
81
82 public static final Level DEFAULT_LOG_LEVEL = Query.DEFAULT_LOG_LEVEL;
83
84 protected List globalExceptions = new ArrayList();
85 protected Map queryExceptions = new HashMap();
86 protected boolean transactionCommitted;
87 protected boolean transactionRolledback;
88 protected Level loggingLevel = DEFAULT_LOG_LEVEL;
89
90 /**
91 * Prints the information about query and global exceptions. */
92 public void printExceptions(PrintWriter out) {
93 if (globalExceptions.size() > 0) {
94 if (globalExceptions.size() == 1) {
95 out.println("Global Exception:");
96 } else {
97 out.println("Global Exceptions:");
98 }
99
100 Iterator it = globalExceptions.iterator();
101 while (it.hasNext()) {
102 Throwable th = (Throwable) it.next();
103 th.printStackTrace(out);
104 }
105 }
106
107 if (queryExceptions.size() > 0) {
108 if (queryExceptions.size() == 1) {
109 out.println("Query Exception:");
110 } else {
111 out.println("Query Exceptions:");
112 }
113
114 Iterator it = queryExceptions.keySet().iterator();
115 while (it.hasNext()) {
116 Throwable th = (Throwable) queryExceptions.get(it.next());
117 th.printStackTrace(out);
118 }
119 }
120 }
121
122 /** Returns a list of global exceptions that occured during data operation run. */
123 public List getGlobalExceptions() {
124 return globalExceptions;
125 }
126
127 /** Returns a list of exceptions that occured during data operation run by query. */
128 public Map getQueryExceptions() {
129 return queryExceptions;
130 }
131
132 /** Returns <code>true</code> if at least one exception was registered
133 * during query execution. */
134 public boolean hasExceptions() {
135 return globalExceptions.size() > 0 || queryExceptions.size() > 0;
136 }
137
138 public boolean isTransactionCommitted() {
139 return transactionCommitted;
140 }
141
142 public boolean isTransactionRolledback() {
143 return transactionRolledback;
144 }
145
146 /**
147 * Returns a log level level that should be used when
148 * logging query execution.
149 */
150 public Level getLoggingLevel() {
151 return loggingLevel;
152 }
153
154 /**
155 * Sets log level that should be used for queries.
156 * If <code>level</code> argument is null, level is set to
157 * DEFAULT_LOG_LEVEL. If <code>level</code> is equal or higher
158 * than log level configured for QueryLogger, query SQL statements
159 * will be logged.
160 */
161 public void setLoggingLevel(Level level) {
162 this.loggingLevel = (level == null) ? DEFAULT_LOG_LEVEL : level;
163 }
164
165 public void nextCount(Query query, int resultCount) {
166 logObj.debug("update count: " + resultCount);
167 }
168
169 public void nextDataRows(Query query, List dataRows) {
170 int count = (dataRows == null) ? -1 : dataRows.size();
171 logObj.debug("result count: " + count);
172 }
173
174 public void nextDataRows(Query q, ResultIterator it) {
175 logObj.debug("result: (iterator)");
176 }
177
178 public void nextQueryException(Query query, Exception ex) {
179 logObj.log(Level.WARN, "query exception", ex);
180 queryExceptions.put(query, ex);
181 }
182
183 public void nextGlobalException(Exception ex) {
184 logObj.log(Level.WARN, "global exception", ex);
185 globalExceptions.add(ex);
186 }
187
188 public void transactionCommitted() {
189 logObj.debug("transaction committed");
190 transactionCommitted = true;
191 }
192
193 public void transactionRolledback() {
194 logObj.debug("*** transaction rolled back");
195 transactionRolledback = true;
196 }
197
198 /** Returns <code>true</code> so that individual queries are executed in separate
199 * transactions. */
200 public boolean useAutoCommit() {
201 return true;
202 }
203
204 /** Returns query list without altering its ordering. */
205 public List orderQueries(DataNode aNode, List queryList) {
206 return queryList;
207 }
208
209 /**
210 * Returns <code>false</code>.
211 */
212 public boolean isIteratedResult() {
213 return false;
214 }
215 }