Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/ibatis/sqlmap/engine/mapping/sql/dynamic/DynamicSql.java


1   /*
2    *  Copyright 2004 Clinton Begin
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 com.ibatis.sqlmap.engine.mapping.sql.dynamic;
17  
18  import com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate;
19  import com.ibatis.sqlmap.engine.mapping.parameter.BasicParameterMap;
20  import com.ibatis.sqlmap.engine.mapping.parameter.InlineParameterMapParser;
21  import com.ibatis.sqlmap.engine.mapping.parameter.ParameterMap;
22  import com.ibatis.sqlmap.engine.mapping.parameter.ParameterMapping;
23  import com.ibatis.sqlmap.engine.mapping.result.ResultMap;
24  import com.ibatis.sqlmap.engine.mapping.sql.Sql;
25  import com.ibatis.sqlmap.engine.mapping.sql.SqlChild;
26  import com.ibatis.sqlmap.engine.mapping.sql.SqlText;
27  import com.ibatis.sqlmap.engine.mapping.sql.dynamic.elements.*;
28  import com.ibatis.sqlmap.engine.mapping.sql.simple.SimpleDynamicSql;
29  import com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement;
30  import com.ibatis.sqlmap.engine.scope.RequestScope;
31  
32  import java.io.PrintWriter;
33  import java.io.StringWriter;
34  import java.util.ArrayList;
35  import java.util.Iterator;
36  import java.util.List;
37  
38  public class DynamicSql implements Sql, DynamicParent {
39  
40    private static final InlineParameterMapParser PARAM_PARSER = new InlineParameterMapParser();
41  
42    private List children = new ArrayList();
43    private SqlMapExecutorDelegate delegate;
44  
45    public DynamicSql(SqlMapExecutorDelegate delegate) {
46      this.delegate = delegate;
47    }
48  
49    public String getSql(RequestScope request, Object parameterObject) {
50      String sql = request.getDynamicSql();
51      if (sql == null) {
52        process(request, parameterObject);
53        sql = request.getDynamicSql();
54      }
55      return sql;
56    }
57  
58    public ParameterMap getParameterMap(RequestScope request, Object parameterObject) {
59      ParameterMap map = request.getDynamicParameterMap();
60      if (map == null) {
61        process(request, parameterObject);
62        map = request.getDynamicParameterMap();
63      }
64      return map;
65    }
66  
67    public ResultMap getResultMap(RequestScope request, Object parameterObject) {
68      return request.getResultMap();
69    }
70  
71    public void cleanup(RequestScope request) {
72      request.setDynamicSql(null);
73      request.setDynamicParameterMap(null);
74    }
75  
76    private void process(RequestScope request, Object parameterObject) {
77      SqlTagContext ctx = new SqlTagContext();
78      List localChildren = children;
79      processBodyChildren(request, ctx, parameterObject, localChildren.iterator());
80  
81      BasicParameterMap map = new BasicParameterMap(delegate);
82      map.setId(request.getStatement().getId() + "-InlineParameterMap");
83      map.setParameterClass(((GeneralStatement) request.getStatement()).getParameterClass());
84      map.setParameterMappingList(ctx.getParameterMappings());
85  
86      String dynSql = ctx.getBodyText();
87  
88      // Processes $substitutions$ after DynamicSql
89      if (SimpleDynamicSql.isSimpleDynamicSql(dynSql)) {
90        dynSql = new SimpleDynamicSql(delegate, dynSql).getSql(request, parameterObject);
91      }
92  
93      request.setDynamicSql(dynSql);
94      request.setDynamicParameterMap(map);
95    }
96  
97    private void processBodyChildren(RequestScope request, SqlTagContext ctx, Object parameterObject, Iterator localChildren) {
98      PrintWriter out = ctx.getWriter();
99      processBodyChildren(request, ctx, parameterObject, localChildren, out);
100   }
101 
102   private void processBodyChildren(RequestScope request, SqlTagContext ctx, Object parameterObject, Iterator localChildren, PrintWriter out) {
103     while (localChildren.hasNext()) {
104       SqlChild child = (SqlChild) localChildren.next();
105       if (child instanceof SqlText) {
106         SqlText sqlText = (SqlText) child;
107         String sqlStatement = sqlText.getText();
108         if (sqlText.isWhiteSpace()) {
109           out.print(sqlStatement);
110         } else {
111           // BODY OUT
112           out.print(sqlStatement);
113 
114           ParameterMapping[] mappings = sqlText.getParameterMappings();
115           if (mappings != null) {
116             for (int i = 0, n = mappings.length; i < n; i++) {
117               ctx.addParameterMapping(mappings[i]);
118             }
119           }
120         }
121       } else if (child instanceof SqlTag) {
122         SqlTag tag = (SqlTag) child;
123         SqlTagHandler handler = tag.getHandler();
124         int response = SqlTagHandler.INCLUDE_BODY;
125         do {
126           StringWriter sw = new StringWriter();
127           PrintWriter pw = new PrintWriter(sw);
128           
129           response = handler.doStartFragment(ctx, tag, parameterObject);
130           if (response != SqlTagHandler.SKIP_BODY) {
131 
132             processBodyChildren(request, ctx, parameterObject, tag.getChildren(), pw);
133             pw.flush();
134             pw.close();
135             StringBuffer body = sw.getBuffer();
136             response = handler.doEndFragment(ctx, tag, parameterObject, body);
137             handler.doPrepend(ctx, tag, parameterObject, body);
138             
139             if (response != SqlTagHandler.SKIP_BODY) {
140               if (body.length() > 0) {
141                 // BODY OUT
142 
143                 if (tag.isPostParseRequired()) {
144                   SqlText sqlText = PARAM_PARSER.parseInlineParameterMap(delegate.getTypeHandlerFactory(), body.toString());
145                   out.print(sqlText.getText());
146                   ParameterMapping[] mappings = sqlText.getParameterMappings();
147                   if (mappings != null) {
148                     for (int i = 0, n = mappings.length; i < n; i++) {
149                       ctx.addParameterMapping(mappings[i]);
150                     }
151                   }
152                 } else {
153                   out.print(body.toString());
154                 }
155               }
156             }
157             
158           }
159         } while (response == SqlTagHandler.REPEAT_BODY);
160         
161         ctx.popRemoveFirstPrependMarker(tag);
162         
163         if(ctx.peekIterateContext()!= null && ctx.peekIterateContext().getTag() == tag) {
164           ctx.popIterateContext();
165         }
166         
167       }
168     }
169   }
170 
171   public void addChild(SqlChild child) {
172     children.add(child);
173   }
174 
175 }