KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > acting > modular > DatabaseAddAction


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
17 package org.apache.cocoon.acting.modular;
18
19 import java.sql.Connection JavaDoc;
20 import java.sql.PreparedStatement JavaDoc;
21 import java.sql.SQLException JavaDoc;
22 import java.sql.Statement JavaDoc;
23 import java.util.Map JavaDoc;
24
25 import org.apache.avalon.framework.configuration.Configuration;
26 import org.apache.avalon.framework.configuration.ConfigurationException;
27 import org.apache.avalon.framework.service.ServiceException;
28 import org.apache.avalon.framework.service.ServiceSelector;
29
30 import org.apache.cocoon.components.modules.database.AutoIncrementModule;
31
32 /**
33  * Adds record in a database. The action can update one or more
34  * tables, and can add more than one row to a table at a time. See
35  * {@link DatabaseAction} for details.
36  *
37  * @author <a HREF="mailto:haul@apache.org">Christian Haul</a>
38  * @version CVS $Id: DatabaseAddAction.java 124674 2005-01-08 20:18:13Z antonio $
39  */

40 public class DatabaseAddAction extends DatabaseAction {
41
42     /**
43      * set all necessary ?s and execute the query
44      */

45     protected int processRow ( Map JavaDoc objectModel, Connection JavaDoc conn, PreparedStatement JavaDoc statement, String JavaDoc outputMode,
46                                Configuration table, CacheHelper queryData, Object JavaDoc[][] columnValues,
47                                int rowIndex, Map JavaDoc results )
48         throws SQLException JavaDoc, ConfigurationException, Exception JavaDoc {
49
50         int currentIndex = 1;
51         for (int i = 0; i < queryData.columns.length; i++) {
52             Column col = queryData.columns[i];
53             if ( col.isAutoIncrement && col.isKey ) {
54                 currentIndex += setKeyAuto( table, col, currentIndex, rowIndex,
55                                             conn, statement, objectModel, outputMode, results );
56             } else {
57                 this.setOutput( objectModel, outputMode, results, table, col.columnConf, rowIndex,
58                                 columnValues[ i ][ ( col.isSet ? rowIndex : 0 ) ]);
59                 this.setColumn( statement, currentIndex, col.columnConf,
60                                 columnValues[ i ][ ( col.isSet ? rowIndex : 0 ) ]);
61                 currentIndex++;
62             }
63         }
64         int rowCount = statement.executeUpdate();
65         // get resulting ids for autoincrement columns
66
for (int i = 0; i < queryData.columns.length; i++) {
67             if ( queryData.columns[i].isAutoIncrement && queryData.columns[i].isKey ) {
68                 storeKeyValue( table, queryData.columns[i], rowIndex,
69                                conn, statement, objectModel, outputMode, results );
70             }
71         }
72         return rowCount;
73     }
74
75
76     /**
77      * Sets the key value on the prepared statement for an autoincrement type.
78      *
79      * @param table the table's configuration object
80      * @param column the key's configuration object
81      * @param currentIndex the position of the key column
82      * @param rowIndex the position in the current row set
83      * @param conn the database connection
84      * @param statement the insert statement
85      * @param objectModel the objectModel object
86      * @param outputMode name of the requested output module
87      * @param results sitemap result object
88      * @return the number of columns by which to increment the currentIndex
89      */

90     protected int setKeyAuto(Configuration table, Column column, int currentIndex, int rowIndex,
91                                Connection JavaDoc conn, PreparedStatement JavaDoc statement, Map JavaDoc objectModel, String JavaDoc outputMode, Map JavaDoc results)
92         throws ConfigurationException, SQLException JavaDoc, Exception JavaDoc {
93
94         int columnCount = 0;
95         ServiceSelector autoincrSelector = null;
96         AutoIncrementModule autoincr = null;
97         try {
98             autoincrSelector = (ServiceSelector)this.manager.lookup(DATABASE_MODULE_SELECTOR);
99             if (column.mode != null && autoincrSelector != null && autoincrSelector.isSelectable(column.mode)){
100                 autoincr = (AutoIncrementModule)autoincrSelector.select(column.mode);
101             }
102             if (autoincr != null) {
103                 if (autoincr.includeInQuery()) {
104                     if (autoincr.includeAsValue()) {
105                         Object JavaDoc value = autoincr.getPreValue(table, column.columnConf, column.modeConf, conn, objectModel);
106                         this.setColumn(objectModel, outputMode, results, table, column.columnConf, rowIndex, value, statement, currentIndex);
107                         columnCount = 1;
108                     }
109                 } else {
110                     if (getLogger().isDebugEnabled()) {
111                         getLogger().debug("Automatically setting key");
112                     }
113                 }
114             } else if (getLogger().isWarnEnabled()) {
115                     getLogger().warn("Could not select autoincrement module" + outputMode + ". Defaulting to automatically setting key.");
116             }
117         } finally {
118             if (autoincrSelector != null) {
119                 if (autoincr != null) {
120                     autoincrSelector.release(autoincr);
121                 }
122                 this.manager.release(autoincrSelector);
123             }
124          }
125         return columnCount;
126     }
127
128     /**
129      * Put key values into request attributes. Checks whether the
130      * value needs to be retrieved from the database module first.
131      *
132      */

133     protected void storeKeyValue(Configuration tableConf, Column key, int rowIndex, Connection JavaDoc conn,
134                                   Statement JavaDoc statement, Map JavaDoc objectModel, String JavaDoc outputMode, Map JavaDoc results)
135         throws SQLException JavaDoc, ConfigurationException, ServiceException {
136
137         ServiceSelector autoincrSelector = null;
138         AutoIncrementModule autoincr = null;
139         try {
140             autoincrSelector = (ServiceSelector)this.manager.lookup(DATABASE_MODULE_SELECTOR);
141             if (key.mode != null && autoincrSelector != null && autoincrSelector.isSelectable(key.mode)){
142                 autoincr = (AutoIncrementModule)autoincrSelector.select(key.mode);
143             }
144             if (autoincr != null) {
145                 if (!autoincr.includeAsValue()) {
146                     Object JavaDoc value = autoincr.getPostValue(tableConf, key.columnConf, key.modeConf, conn, statement, objectModel);
147                     this.setOutput(objectModel, outputMode, results, tableConf, key.columnConf, rowIndex, value);
148                 }
149             } else {
150                 throw new ConfigurationException("Could not obtain key value");
151             }
152         } finally {
153             if (autoincrSelector != null) {
154                 if (autoincr != null) {
155                     autoincrSelector.release(autoincr);
156                 }
157                 this.manager.release(autoincrSelector);
158             }
159          }
160     }
161
162     /**
163      * determine which mode to use as default mode
164      * here: INSERT
165      * highly specific to operation INSERT / UPDATE / DELETE / SELECT
166      */

167     protected String JavaDoc selectMode ( boolean isAutoIncrement, Map JavaDoc modes ) {
168
169         if ( isAutoIncrement )
170             return (String JavaDoc) modes.get( MODE_AUTOINCR );
171         else
172             return (String JavaDoc) modes.get( MODE_OTHERS );
173     }
174
175
176     /**
177      * determine whether autoincrement columns should be honoured by
178      * this operation. This is usually snsible only for INSERTs.
179      */

180     protected boolean honourAutoIncrement() { return true; }
181
182
183     /**
184      * Fetch all values for all columns that are needed to do the
185      * database operation.
186      */

187     protected Object JavaDoc[][] getColumnValues( Configuration tableConf, CacheHelper queryData,
188                                           Map JavaDoc objectModel )
189         throws ConfigurationException, ServiceException {
190
191         Object JavaDoc[][] columnValues = new Object JavaDoc[ queryData.columns.length ][];
192         for ( int i = 0; i < queryData.columns.length; i++ ){
193             columnValues[i] = this.getColumnValue( tableConf, queryData.columns[i], objectModel );
194         }
195         return columnValues;
196     }
197
198
199     /**
200      * Get the String representation of the PreparedStatement. This is
201      * mapped to the Configuration object itself, so if it doesn't exist,
202      * it will be created.
203      * @param table the table's configuration object
204      * @return the insert query as a string
205      */

206     protected CacheHelper getQuery( Configuration table, Map JavaDoc modeTypes, Map JavaDoc defaultModeNames )
207         throws ConfigurationException, ServiceException {
208
209         LookUpKey lookUpKey = new LookUpKey( table, modeTypes );
210         CacheHelper queryData = null;
211         synchronized( this.cachedQueryData ) {
212             queryData = (CacheHelper) this.cachedQueryData.get( lookUpKey );
213
214             if (queryData == null) {
215                 Configuration[] values = table.getChild("values").getChildren("value");
216                 Configuration[] keys = table.getChild("keys").getChildren("key");
217
218                 queryData = new CacheHelper( keys.length, keys.length + values.length );
219                 fillModes( keys, true, defaultModeNames, modeTypes, queryData );
220                 fillModes( values, false, defaultModeNames, modeTypes, queryData );
221
222                 StringBuffer JavaDoc queryBuffer = new StringBuffer JavaDoc("INSERT INTO ");
223                 StringBuffer JavaDoc valueBuffer = new StringBuffer JavaDoc(") VALUES (");
224
225                 queryBuffer.append(table.getAttribute("name"));
226                 queryBuffer.append(" (");
227                 int actualColumns = 0;
228
229                 for (int i = 0; i < queryData.columns.length; i++) {
230                     if ( actualColumns > 0 ) {
231                         queryBuffer.append( ", " );
232                         valueBuffer.append( ", " );
233                     }
234                     if ( queryData.columns[i].isKey && queryData.columns[i].isAutoIncrement ) {
235
236                         ServiceSelector autoincrSelector = null;
237                         AutoIncrementModule autoincr = null;
238                         try {
239                             autoincrSelector = (ServiceSelector) this.manager.lookup(DATABASE_MODULE_SELECTOR);
240                             if (queryData.columns[i].mode != null &&
241                                 autoincrSelector != null &&
242                                 autoincrSelector.isSelectable(queryData.columns[i].mode)){
243                                 autoincr = (AutoIncrementModule) autoincrSelector.select(queryData.columns[i].mode);
244                                 
245                                 if ( autoincr.includeInQuery() ) {
246                                     actualColumns++;
247                                     queryBuffer.append( queryData.columns[i].columnConf.getAttribute( "name" ) );
248                                     if ( autoincr.includeAsValue() ) {
249                                         valueBuffer.append( "?" );
250                                     } else {
251                                         valueBuffer.append(
252                                                            autoincr.getSubquery( table, queryData.columns[i].columnConf,
253                                                                                  queryData.columns[i].modeConf ) );
254                                     }
255                                 }
256                             } else {
257                                 if (getLogger().isErrorEnabled())
258                                     getLogger().error("Could not find mode description "
259                                                       + queryData.columns[i].mode + " for column #"+i);
260                                 if (getLogger().isDebugEnabled()) {
261                                     getLogger().debug("Column data "+queryData.columns[i]);
262                                 }
263                                 throw new ConfigurationException("Could not find mode description "+queryData.columns[i].mode+" for column "+i);
264                             }
265                         } finally {
266                             if (autoincrSelector != null) {
267                                 if (autoincr != null)
268                                     autoincrSelector.release(autoincr);
269                                 this.manager.release(autoincrSelector);
270                             }
271                         }
272                     } else {
273                         actualColumns++;
274                         queryBuffer.append( queryData.columns[i].columnConf.getAttribute( "name" ) );
275                         valueBuffer.append( "?" );
276                     }
277                 }
278                 valueBuffer.append(")");
279                 queryBuffer.append(valueBuffer);
280
281                 queryData.queryString = queryBuffer.toString();
282
283                 this.cachedQueryData.put( lookUpKey, queryData );
284             }
285         }
286         return queryData;
287     }
288 }
289
Popular Tags