KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > scriptella > core > QueryExecutor


1 /*
2  * Copyright 2006-2007 The Scriptella Project Team.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package scriptella.core;
17
18 import scriptella.configuration.ContentEl;
19 import scriptella.configuration.QueryEl;
20 import scriptella.configuration.ScriptEl;
21 import scriptella.configuration.ScriptingElement;
22 import scriptella.spi.Connection;
23 import scriptella.spi.ParametersCallback;
24 import scriptella.spi.QueryCallback;
25 import scriptella.spi.Resource;
26
27 import java.io.InputStream JavaDoc;
28 import java.io.Reader JavaDoc;
29 import java.util.HashMap JavaDoc;
30 import java.util.List JavaDoc;
31 import java.util.Map JavaDoc;
32 import java.util.logging.Level JavaDoc;
33 import java.util.logging.Logger JavaDoc;
34
35
36 /**
37  * TODO: Add documentation
38  *
39  * @author Fyodor Kupolov
40  * @version 1.0
41  */

42 public class QueryExecutor extends ContentExecutor<QueryEl> {
43     private ExecutableElement[] nestedElements;
44     private static final Logger JavaDoc LOG = Logger.getLogger(QueryExecutor.class.getName());
45     private final boolean debug=LOG.isLoggable(Level.FINE);
46
47     private QueryExecutor(QueryEl queryEl) {
48         super(queryEl);
49         initNestedExecutors();
50     }
51
52     private void initNestedExecutors() {
53         final List JavaDoc<ScriptingElement> childElements = getElement().getChildScriptinglElements();
54         nestedElements = new ExecutableElement[childElements.size()];
55
56         for (int i = 0; i < nestedElements.length; i++) {
57             ScriptingElement element = childElements.get(i);
58             if (element instanceof QueryEl) {
59                 nestedElements[i]=QueryExecutor.prepare((QueryEl) element);
60             } else if (element instanceof ScriptEl) {
61                 nestedElements[i]=ScriptExecutor.prepare((ScriptEl) element);
62             } else {
63                 throw new IllegalStateException JavaDoc("Type " + element.getClass() +
64                         " not supported");
65             }
66         }
67     }
68
69     public void execute(final DynamicContext ctx) {
70         final Connection c = ctx.getConnection();
71
72         final Resource content = getContent(c.getDialectIdentifier());
73         if (content == ContentEl.NULL_CONTENT) {
74             //skip queries without content
75
return;
76         }
77         final QueryCtxDecorator ctxDecorator = new QueryCtxDecorator(ctx);
78         if (debug) {
79             LOG.fine("Executing query " + getLocation());
80         }
81         c.executeQuery(content, ctx,
82                 new QueryCallback() {
83                     public void processRow(final ParametersCallback params) {
84                         EtlCancelledException.checkEtlCancelled();
85                         ctxDecorator.rownum++;
86                         ctxDecorator.setParams(params);
87                         if (debug) {
88                             LOG.fine("Processing row #" + ctxDecorator.rownum + " for query " + getLocation());
89                         }
90
91                         for (ExecutableElement exec : nestedElements) {
92                             exec.execute(ctxDecorator);
93                         }
94                     }
95                 });
96         if (debug) {
97             if (ctxDecorator.rownum == 0) {
98                 LOG.fine("Query " + getLocation() + " returned no results.");
99             } else {
100                 LOG.fine("Query " + getLocation() + " processed.");
101             }
102
103         }
104
105     }
106
107
108     public static ExecutableElement prepare(final QueryEl queryEl) {
109         ExecutableElement q = new QueryExecutor(queryEl);
110         q = StatisticInterceptor.prepare(q, queryEl.getLocation());
111         q = ConnectionInterceptor.prepare(q, queryEl);
112         q = ExceptionInterceptor.prepare(q, queryEl.getLocation());
113         q = IfInterceptor.prepare(q, queryEl);
114
115         return q;
116     }
117
118     private static final class QueryCtxDecorator extends DynamicContextDecorator {
119         private static final Object JavaDoc NULL = new Object JavaDoc(); //NULL object flag
120
private ParametersCallback params;
121         private int rownum; //current row number
122
private Map JavaDoc<String JavaDoc, Object JavaDoc> cachedParams;
123
124
125         public QueryCtxDecorator(DynamicContext context) {
126             super(context);
127         }
128
129         void setParams(final ParametersCallback params) {
130             this.params = params;
131             if (cachedParams != null) {
132                 cachedParams.clear();
133             }
134         }
135
136         @Override JavaDoc
137         public final Object JavaDoc getParameter(final String JavaDoc name) {
138             if ("rownum".equals(name)) { //return current row number
139
return rownum;
140             }
141             Object JavaDoc res = cachedParams==null?null:cachedParams.get(name);
142             if (res == null) {
143                 res = params.getParameter(name);
144                 if (res == null) {
145                     res = NULL;
146                 }
147                 if (isCacheable(res)) {
148                     if (cachedParams==null) {
149                         cachedParams=new HashMap JavaDoc<String JavaDoc, Object JavaDoc>();
150                     }
151                     cachedParams.put(name, res);
152                 }
153             }
154             return res == NULL ? null : res;
155         }
156
157         /**
158          * Check if object is cacheable, i.e. no need to fetch it again.
159          * @param o object to check.
160          * @return true if object is cacheable.
161          */

162         private boolean isCacheable(Object JavaDoc o) {
163             return !(o instanceof InputStream JavaDoc || o instanceof Reader JavaDoc);
164         }
165
166     }
167 }
168
Popular Tags