View Javadoc

1   /*
2    *  Copyright 1999-2004 The Apache Software Foundation.
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 org.apache.struts.flow.ibatis;
17  
18  import org.mozilla.javascript.*;
19  import com.ibatis.sqlmap.engine.mapping.statement.*;
20  import com.ibatis.sqlmap.engine.impl.*;
21  import com.ibatis.sqlmap.client.*;
22  import org.apache.struts.flow.core.*;
23  import org.apache.struts.flow.core.javascript.*;
24  import org.apache.struts.flow.sugar.*;
25  
26  import org.mozilla.javascript.JavaScriptException;
27  import java.util.*;
28  import java.io.*;
29  import java.sql.SQLException;
30  
31  import org.codehaus.janino.SimpleCompiler;
32  
33  import org.apache.commons.logging.*;
34  
35  /***
36   *  JavaScript interface to the log facility.
37   *
38   *@jsname log
39   */
40  public class SqlMap extends ScriptableObject {
41      protected static SqlMapClient client;
42      protected String namespace;
43      protected Map statements = new HashMap();
44      
45      protected static final Log log = LogFactory.getLog(SqlMap.class);
46  
47  
48      /***  Constructor for the JSLog object */
49      public SqlMap() { }
50  
51      public static void setSqlMapClient(SqlMapClient c) {
52          client = c;
53      }
54      
55      public static Map buildNamespaceClasses() {
56          InputStream in = SqlMap.class.getResourceAsStream("SqlMap.template");
57          BufferedReader reader = new BufferedReader(new InputStreamReader(in));
58          StringBuffer sb = new StringBuffer();
59          String line;
60          try {
61              while ((line = reader.readLine()) != null) {
62                  sb.append(line);
63              }
64          } catch (IOException ex) {
65              ex.printStackTrace();
66              return null;
67          }
68             
69          String templateText = sb.toString();
70          
71          Map classes = new HashMap();
72          Set namespaces = getNamespaces();
73          String name, source;
74          for (Iterator i = namespaces.iterator(); i.hasNext(); ) {
75              name = (String) i.next(); 
76              source = templateText.replaceAll("%ns", name);
77              try {
78                  SimpleCompiler compiler = new SimpleCompiler(name+".java", new StringReader(source));
79                  ClassLoader cl = compiler.getClassLoader();
80                  
81                  Class cls = cl.loadClass("org.apache.struts.flow.ibatis."+name);
82                  if (cls != null) {
83                      classes.put(name, cls);
84                  } else {
85                      System.err.println("Unable to compile class for namespace "+name);
86                  }
87              } catch (Exception ex) {
88                  ex.printStackTrace();
89              }
90          }
91          
92          return classes;
93      }
94  
95      public Object jsFunction_setNamespace(String ns) throws JavaScriptException {
96          setNamespace(ns);
97          return null;
98      }
99  
100     public void setNamespace(String ns) {
101         log.debug("setting namespace");
102         this.namespace = ns;
103         statements.clear();
104         SqlMapClientImpl cimpl = (SqlMapClientImpl)client;
105         SqlMapExecutorDelegate del = cimpl.getDelegate();
106         String name;
107         for (Iterator i = del.getMappedStatementNames(); i.hasNext(); ) {
108             name = (String) i.next();
109             log.debug("looking at statement "+name);
110             if (name.startsWith(namespace+".")) {
111                 log.debug("adding statement "+name);
112                 statements.put(name.substring(namespace.length() + 1), del.getMappedStatement(name));
113             }
114         }
115     }
116 
117     public static Set getNamespaces() {
118         Set result = new HashSet();
119         SqlMapClientImpl cimpl = (SqlMapClientImpl)client;
120         SqlMapExecutorDelegate del = cimpl.getDelegate();
121         String name, ns;
122         int pos;
123         for (Iterator i = del.getMappedStatementNames(); i.hasNext(); ) {
124             name = (String) i.next();
125             pos = name.indexOf('.');
126             if (pos > -1) {
127                 ns = name.substring(0, pos);    
128                 result.add(ns);
129             }
130         }
131         return result;
132     }
133 
134 
135     /***
136      *  Gets the class name
137      *
138      *@return    The className value
139      */
140     public String getClassName() {
141         return (this.namespace == null ? "SqlMap" : this.namespace);
142     }
143 
144     public Object get(final String name, Scriptable start) {
145 
146         log.debug("getting property "+name);
147         final MappedStatement ms = (MappedStatement) statements.get(name);
148         if (ms != null) {
149             log.debug("found as a function");
150             return new ExtensionFunction() {    
151                 public Object execute(Context cx, Scriptable scope, Scriptable thisObj, java.lang.Object[] args) 
152                     throws IOException {
153                     
154                     Map params = null;
155                     if (args.length == 1 && args[0] instanceof Scriptable) {
156                         params = ConversionHelper.jsobjectToMap((Scriptable)args[0]);
157                     } else {
158                         params = ConversionHelper.jsobjectToMap(thisObj);
159                     }
160                     String stmName = namespace+"."+name;
161                     Object result = null;
162                     StatementType type = ms.getStatementType();
163                     try {  
164                         if (type == StatementType.INSERT) {
165                             result = client.insert(stmName, params);
166                         } else if (type == StatementType.DELETE) {
167                             result = new Integer(client.delete(stmName, params));
168                         } else if (type == StatementType.UPDATE) {
169                             result = new Integer(client.update(stmName, params));
170                         } else {
171                             result = client.queryForList(stmName, params);
172                         }
173                     } catch (SQLException ex) {
174                         ex.printStackTrace();
175                     }
176                     return result;
177                 }
178             };
179         } else {
180             return super.get(name, start);
181         }
182     }
183  
184     
185 }
186