001: package com.xoetrope.service.data;
002:
003: import java.io.InputStream;
004: import java.sql.PreparedStatement;
005: import java.text.SimpleDateFormat;
006: import java.util.Enumeration;
007: import java.util.Properties;
008: import net.xoetrope.optional.data.sql.ConnectionObject;
009: import net.xoetrope.optional.data.sql.DatabaseTableModel;
010: import net.xoetrope.optional.service.ServiceContext;
011: import net.xoetrope.optional.service.ServiceProxy;
012: import net.xoetrope.optional.service.ServiceProxyArgs;
013: import net.xoetrope.optional.service.ServiceProxyException;
014: import net.xoetrope.xui.XProject;
015: import net.xoetrope.xui.XProjectManager;
016: import net.xoetrope.xui.data.XBaseModel;
017:
018: /**
019: * ServiceProxy class which is used to format PreparedStatements. The
020: * PreparedStatements need to be declared in a database datasource file and
021: * its parameter need to be defined in a properties file with the same name as
022: * the query name.
023: *
024: * <p> Copyright (c) Xoetrope Ltd., 2001-2006, This software is licensed under
025: * the GNU Public License (GPL), please see license.txt for more details. If
026: * you make commercial use of this software you must purchase a commercial
027: * license from Xoetrope.</p>
028: * <p> $Revision: 1.6 $</p>
029: */
030: public class StoredProcFormatter extends ServiceProxy {
031: /**
032: * The name of the PreparedStatement as declared in the database datasource
033: * file. A properies file of the same name needs to exist which lists the
034: * parameters to be used.
035: */
036: public static final String ARG_NAME_QUERYNAME = "queryexecute:queryname";
037:
038: /**
039: * The connection object used to execute the PreparedStatements
040: */
041: public static final String ARG_NAME_CONN = "queryexecute:conn";
042:
043: /**
044: * The prefix used to access the model.
045: */
046: public static final String ARG_NAME_MODELPREFIX = "queryexecute:modelprefix";
047:
048: private String modelPrefix = null;
049: private XBaseModel dataModel;
050:
051: /**
052: * The owner project and the context in which this object operates.
053: */
054: protected XProject currentProject = XProjectManager
055: .getCurrentProject();
056:
057: /**
058: * Call this proxy with the specified arguments
059: * @return the result of the call
060: * @param context The ServiceContext contain pass and return parameters
061: * @param method the name of the service being called
062: * @throws net.xoetrope.optional.service.ServiceProxyException Throw an exception if there is a problem with the call
063: */
064: public Object call(String method, ServiceContext context)
065: throws ServiceProxyException {
066: return call(method, context, null);
067: }
068:
069: /**
070: * Call this proxy with the specified arguments
071: * @return the result of the call
072: * @param context The ServiceContext contain pass and return parameters
073: * @param method the name of the service being called
074: * @param model the model which will be used to populate the PreparedStatement
075: * @throws net.xoetrope.optional.service.ServiceProxyException Throw an exception if there is a problem with the call
076: */
077: public Object call(String method, ServiceContext context,
078: XBaseModel model) throws ServiceProxyException {
079: try {
080: dataModel = model;
081: ServiceProxyArgs args = context.getArgs();
082: modelPrefix = (String) args
083: .getPassParam(ARG_NAME_MODELPREFIX);
084: modelPrefix = modelPrefix == null ? "" : modelPrefix;
085: Properties props = new Properties();
086: String queryName = (String) args
087: .getPassParam(ARG_NAME_QUERYNAME);
088: InputStream is = currentProject.getInputStream(queryName
089: + ".properties");
090: props.load(is);
091: String[] params = new String[props.size()];
092: Enumeration keys = props.keys();
093: while (keys.hasMoreElements()) {
094: String idx = (String) keys.nextElement();
095: String value = (String) props.get(idx);
096: params[Integer.parseInt(idx)] = parseParam(args, value);
097: }
098: ConnectionObject connObj = (ConnectionObject) args
099: .getPassParam(ARG_NAME_CONN);
100: execStoredProc(connObj, queryName, params);
101: } catch (Exception ex) {
102: ex.printStackTrace();
103: }
104:
105: return callNextProxy(method, context, null);
106: }
107:
108: /**
109: * Retrieve the specified PreparedStatement and populate it with the passed
110: * params array. Execute the PreparedStatement.
111: * @param connObj the Connection object being used by the PreparedStatement
112: * @param name the name of the PreparedStatement as defined in the basebase
113: * datasource file
114: * @param params The String array which is used to populate the PreparedStatement
115: */
116: protected void execStoredProc(ConnectionObject connObj,
117: String name, String[] params) throws Exception {
118: try {
119: DatabaseTableModel dtm = (DatabaseTableModel) XProjectManager
120: .getModel().get(name);
121: String stmt = dtm.getTable().getSQL(null);
122: PreparedStatement ps = connObj.getConnection()
123: .prepareStatement(stmt);
124: for (int i = 0; i < params.length; i++)
125: ps.setString(i + 1, params[i]);
126:
127: ps.execute();
128: } catch (Exception ex) {
129: ex.printStackTrace();
130: throw ex;
131: }
132: }
133:
134: /**
135: * Retrieve a parameter specified by the key parameter. This can be a
136: * parameter, a date or a value from the model. If anything else needs to be
137: * retrieved then the developer should subclass this class and overload this
138: * function call.
139: * @param args The ServiceProxyArgs Object which was passed to the call
140: * function
141: * @param key The key which specifies the data to be used
142: * @return The value of the data being requested
143: */
144: protected String parseParam(ServiceProxyArgs args, String key) {
145: String ret = null;
146: if (key.startsWith("${PARAM|")) {
147: String param = key.substring("${PARAM|".length(), key
148: .length() - 1);
149: ret = (String) args.getPassParam(param);
150: } else if (key.compareTo("${date}") == 0) {
151: SimpleDateFormat sdf = new SimpleDateFormat(
152: "yyyy-MM-dd HH:mm:ss");
153: ret = sdf.format(new java.util.Date());
154: } else
155: ret = (String) ((XBaseModel) dataModel.get(modelPrefix
156: + "/" + key)).get();
157:
158: return ret;
159: }
160: }
|