KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > acting > OraAddAction


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.cocoon.acting;
17
18 import java.io.BufferedInputStream JavaDoc;
19 import java.io.BufferedOutputStream JavaDoc;
20 import java.io.ByteArrayInputStream JavaDoc;
21 import java.io.File JavaDoc;
22 import java.io.FileInputStream JavaDoc;
23 import java.io.InputStream JavaDoc;
24 import java.io.OutputStream JavaDoc;
25 import java.sql.Connection JavaDoc;
26 import java.sql.PreparedStatement JavaDoc;
27 import java.sql.ResultSet JavaDoc;
28 import java.sql.SQLException JavaDoc;
29 import java.sql.Statement JavaDoc;
30 import java.util.ArrayList JavaDoc;
31 import java.util.HashMap JavaDoc;
32 import java.util.Map JavaDoc;
33
34 import oracle.jdbc.OracleResultSet;
35 import oracle.sql.BLOB;
36 import oracle.sql.CLOB;
37
38 import org.apache.avalon.excalibur.datasource.DataSourceComponent;
39 import org.apache.avalon.framework.configuration.Configuration;
40 import org.apache.avalon.framework.configuration.ConfigurationException;
41 import org.apache.avalon.framework.parameters.Parameters;
42 import org.apache.cocoon.ProcessingException;
43 import org.apache.cocoon.environment.ObjectModelHelper;
44 import org.apache.cocoon.environment.Redirector;
45 import org.apache.cocoon.environment.Request;
46 import org.apache.cocoon.environment.SourceResolver;
47 import org.apache.cocoon.util.ImageProperties;
48 import org.apache.cocoon.util.ImageUtils;
49
50 /**
51  * Add a record in a database. This Action assumes that there is
52  * only one table at a time to update.
53  *
54  * @author <a HREF="mailto:bloritsch@apache.org">Berin Loritsch</a>
55  * @version CVS $Id: OraAddAction.java 124617 2005-01-08 03:48:10Z antonio $
56  */

57 public class OraAddAction extends DatabaseAddAction {
58     private static final Map JavaDoc selectLOBStatements = new HashMap JavaDoc();
59
60     /**
61      * Add a record to the database. This action assumes that
62      * the file referenced by the "descriptor" parameter conforms
63      * to the AbstractDatabaseAction specifications.
64      */

65     public Map JavaDoc act(Redirector redirector, SourceResolver resolver, Map JavaDoc objectModel, String JavaDoc source, Parameters param) throws Exception JavaDoc {
66         DataSourceComponent datasource = null;
67         Connection JavaDoc conn = null;
68         int currentIndex = 0;
69
70         try {
71             Configuration conf = this.getConfiguration(param.getParameter("descriptor", null));
72             String JavaDoc query = this.getAddQuery(conf);
73
74             datasource = this.getDataSource(conf);
75             conn = datasource.getConnection();
76             Request request = ObjectModelHelper.getRequest(objectModel);
77
78             if (conn.getAutoCommit()) {
79                 conn.setAutoCommit(false);
80             }
81
82             PreparedStatement JavaDoc statement = conn.prepareStatement(query);
83             getLogger().info(query);
84
85             Configuration[] keys = conf.getChild("table").getChild("keys").getChildren("key");
86             Configuration[] values = conf.getChild("table").getChild("values").getChildren("value");
87             currentIndex = 1;
88
89             // Insert the keys into the query
90
for (int i = 0; i < keys.length; i++) {
91                 String JavaDoc mode = keys[i].getAttribute("mode", "automatic");
92
93                 if ("manual".equals(mode)) {
94                     String JavaDoc selectQuery = this.getSelectQuery(keys[i]);
95                     Statement JavaDoc stmt =null;
96                     ResultSet JavaDoc set = null;
97                     try {
98                         stmt = conn.createStatement();
99                         set = stmt.executeQuery(selectQuery);
100                         set.next();
101                         int value = set.getInt("maxid") + 1;
102                         statement.setInt(currentIndex, value);
103                         request.setAttribute(keys[i].getAttribute("param"), String.valueOf(value));
104                     } catch (SQLException JavaDoc sqle){
105                         getLogger().warn("There was an error retrieving the next key while inserting on the database", sqle);
106                         throw sqle;
107                     } finally {
108                         set.close();
109                         stmt.close();
110                         currentIndex++;
111                     }
112                 } else if ("form".equals(mode)) {
113                     String JavaDoc parameter = keys[i].getAttribute("param");
114                     request.setAttribute(parameter, request.getParameter(parameter));
115                     this.setColumn(statement, currentIndex, request, keys[i]);
116                     currentIndex++;
117                 }
118             }
119
120             // insert the values into the query
121
for (int i = 0; i < values.length; i++) {
122                 String JavaDoc type = values[i].getAttribute("type");
123                 String JavaDoc parameter = values[i].getAttribute("param");
124
125                 if (type.equals("image")) {
126                     File JavaDoc binaryFile = (File JavaDoc) request.get(parameter);
127                     Parameters iparam = new Parameters();
128
129                     iparam.setParameter("image-size", String.valueOf(binaryFile.length()));
130
131                     ImageProperties prop = ImageUtils.getImageProperties(binaryFile);
132                     iparam.setParameter("image-width", Integer.toString(prop.width));
133                     iparam.setParameter("image-height", Integer.toString(prop.height));
134
135                     synchronized (this.files) {
136                         this.files.put(binaryFile, param);
137                     }
138                 }
139
140                 if (! this.isLargeObject(type)) {
141                     this.setColumn(statement, currentIndex, request, values[i]);
142                     currentIndex++;
143                 }
144             }
145
146             statement.execute();
147             statement.close();
148
149             query = this.getSelectLOBQuery(conf);
150
151             // Process the large objects if they exist
152
if (query != null) {
153                 PreparedStatement JavaDoc LOBstatement = conn.prepareStatement(query);
154                 getLogger().info(query);
155
156                 if (keys.length > 0) {
157                     currentIndex = 1;
158
159                     for (int i = 0; i < keys.length; i++) {
160                         this.setColumn(LOBstatement, currentIndex, request, keys[i]);
161                         currentIndex++;
162                     }
163                 }
164
165                 OracleResultSet set = (OracleResultSet) LOBstatement.executeQuery();
166
167                 if (set.next()) {
168                     int index = 0;
169
170                     for (int i = 0; i < values.length; i++) {
171                         String JavaDoc type = values[i].getAttribute("type", "");
172                         if (this.isLargeObject(type)) {
173                             Object JavaDoc attr = request.get(values[i].getAttribute("param"));
174                             int length = -1;
175                             InputStream JavaDoc stream = null;
176                             OutputStream JavaDoc output = null;
177                             int bufSize = 1024;
178
179                             index++;
180
181                             if (type.equals("ascii")) {
182                                 CLOB ascii = set.getCLOB(index);
183
184                                 if (attr instanceof File JavaDoc) {
185                                     File JavaDoc asciiFile = (File JavaDoc) attr;
186                                     stream = new BufferedInputStream JavaDoc(new FileInputStream JavaDoc(asciiFile));
187                                 } else {
188                                     String JavaDoc asciiText = (String JavaDoc) attr;
189                                     stream = new BufferedInputStream JavaDoc(new ByteArrayInputStream JavaDoc(asciiText.getBytes()));
190                                 }
191
192                                 output = new BufferedOutputStream JavaDoc(ascii.getAsciiOutputStream());
193                                 bufSize = ascii.getBufferSize();
194                             } else {
195                                 BLOB binary = set.getBLOB(index);
196                                 File JavaDoc binaryFile = (File JavaDoc) attr;
197                                 stream = new BufferedInputStream JavaDoc(new FileInputStream JavaDoc(binaryFile));
198                                 length = (int) binaryFile.length();
199
200                                 output = new BufferedOutputStream JavaDoc(binary.getBinaryOutputStream());
201                                 bufSize = binary.getBufferSize();
202                             }
203
204                             byte[] buffer = new byte[bufSize];
205                             while ((length = stream.read(buffer)) != -1) {
206                                 output.write(buffer, 0, length);
207                             }
208
209                             stream.close();
210                             output.close();
211                         }
212                     }
213                 }
214
215                 set.close();
216                 set.getStatement().close();
217             }
218
219             conn.commit();
220         } catch (Exception JavaDoc e) {
221             if (conn != null) {
222                 try {
223                     conn.rollback();
224                 } catch (SQLException JavaDoc se) {
225                     getLogger().debug("There was an error rolling back the transaction", se);
226                 }
227             }
228
229             throw new ProcessingException("Could not add record :position = " + (currentIndex - 1), e);
230         } finally {
231             if (conn != null) {
232                 try {
233                     conn.close();
234                 } catch (SQLException JavaDoc sqe) {
235                     getLogger().warn("There was an error closing the datasource", sqe);
236                 }
237             }
238             if (datasource != null) {
239                 this.dbselector.release(datasource);
240             }
241         }
242
243         return null;
244     }
245
246     /**
247      * Get the String representation of the PreparedStatement. This is
248      * mapped to the Configuration object itself, so if it doesn't exist,
249      * it will be created.
250      */

251     protected final String JavaDoc getAddQuery(Configuration conf) throws ConfigurationException {
252         String JavaDoc query = null;
253
254         synchronized (DatabaseAddAction.addStatements) {
255             query = (String JavaDoc) DatabaseAddAction.addStatements.get(conf);
256
257             if (query == null) {
258                 Configuration table = conf.getChild("table");
259                 Configuration[] values = table.getChild("values").getChildren("value");
260                 Configuration[] keys = table.getChild("keys").getChildren("key");
261
262                 StringBuffer JavaDoc queryBuffer = new StringBuffer JavaDoc("INSERT INTO ");
263                 queryBuffer.append(table.getAttribute("name"));
264                 queryBuffer.append(" (");
265
266                 int numKeys = 0;
267
268                 for (int i = 0; i < keys.length; i++) {
269                     String JavaDoc mode = keys[i].getAttribute("mode", "automatic");
270                     if (numKeys > 0) {
271                         queryBuffer.append(", ");
272                     }
273
274                     queryBuffer.append(keys[i].getAttribute("dbcol"));
275
276                     if ("manual".equals(mode)) {
277                         this.setSelectQuery(table.getAttribute("name"), keys[i]);
278                     }
279
280                     numKeys++;
281                 }
282
283                 for (int i = 0; i < values.length; i++) {
284                     if ((numKeys + i) > 0) {
285                         queryBuffer.append(", ");
286                     }
287
288                     queryBuffer.append(values[i].getAttribute("dbcol"));
289                 }
290
291                 queryBuffer.append(") VALUES (");
292
293                 numKeys = 0;
294                 ArrayList JavaDoc sequences = new ArrayList JavaDoc();
295
296                 for (int i = 0; i < keys.length; i++) {
297                     if (numKeys > 0) queryBuffer.append(", ");
298                     if ("automatic".equals(keys[i].getAttribute("mode", "automatic"))) {
299                         String JavaDoc sequence = keys[i].getAttribute("sequence", "");
300                         queryBuffer.append(sequence);
301
302                         if (sequences.contains(sequence)) {
303                             queryBuffer.append(".CURRVAL");
304                         } else {
305                             sequences.add(sequence);
306                             queryBuffer.append(".NEXTVAL");
307                         }
308
309                         numKeys++;
310                     } else {
311                         queryBuffer.append("?");
312                         numKeys++;
313                     }
314                 }
315
316                 for (int i = 0; i < values.length; i++) {
317                     if ((numKeys + i) > 0) {
318                         queryBuffer.append(", ");
319                     }
320
321                     if (this.isLargeObject(values[i].getAttribute("type"))) {
322                         if (values[i].getAttribute("type").equals("ascii")) {
323                              queryBuffer.append("empty_clob()");
324                         } else {
325                              queryBuffer.append("empty_blob()");
326                         }
327                     } else {
328                         queryBuffer.append("?");
329                     }
330                 }
331
332                 queryBuffer.append(")");
333
334                 query = queryBuffer.toString();
335
336                 DatabaseAddAction.addStatements.put(conf, query);
337             }
338         }
339
340         if ("".equals(query)) return null;
341
342         return query;
343     }
344
345     /**
346      * Get the String representation of the PreparedStatement. This is
347      * mapped to the Configuration object itself, so if it doesn't exist,
348      * it will be created.
349      */

350     private final String JavaDoc getSelectLOBQuery (Configuration conf)
351     throws ConfigurationException {
352         String JavaDoc query = null;
353
354         synchronized (OraAddAction.selectLOBStatements) {
355             query = (String JavaDoc) OraAddAction.selectLOBStatements.get(conf);
356
357             // executes only if query is null.
358
if (query == null) {
359                 StringBuffer JavaDoc queryBuffer = new StringBuffer JavaDoc("SELECT ");
360                 Configuration table = conf.getChild("table");
361                 Configuration[] values = table.getChild("values").getChildren("value");
362                 Configuration[] keys = table.getChild("keys").getChildren("key");
363                 int numLobs = 0;
364
365                 // Add the values to the query
366
for (int i = 0; i < values.length; i++) {
367                     if (this.isLargeObject(values[i].getAttribute("type"))) {
368                         numLobs++;
369                         if (numLobs > 1) {
370                             queryBuffer.append(", ");
371                         }
372                         queryBuffer.append(values[i].getAttribute("dbcol"));
373                     }
374                 }
375
376                 if (numLobs < 1) {
377                     // if query is set to "", then the Action won't
378
// try to process it again.
379
query = "";
380                     OraAddAction.selectLOBStatements.put(conf, query);
381                     return null;
382                 }
383
384                 queryBuffer.append(" FROM ").append(table.getAttribute("name"));
385
386                 // Process the WHERE clause
387
if (keys.length > 0) {
388                     queryBuffer.append(" WHERE ");
389                     // Add the keys to the query
390
queryBuffer.append(buildList(keys, " AND "));
391                 }
392                 query = queryBuffer.toString().trim();
393                 OraAddAction.selectLOBStatements.put(conf, query);
394             }
395         }
396         return ("".equals(query)) ? null : query;
397     }
398 }
399
Popular Tags