1 package org.apache.commons.digester3.examples.api.dbinsert;
2
3 /*
4 * Licensed to the Apache Software Foundation (ASF) under one or more
5 * contributor license agreements. See the NOTICE file distributed with
6 * this work for additional information regarding copyright ownership.
7 * The ASF licenses this file to You under the Apache License, Version 2.0
8 * (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
20 import java.sql.Connection;
21 import java.util.Iterator;
22
23 import org.apache.commons.digester3.Rule;
24 import org.apache.commons.digester3.examples.api.dbinsert.Row.Column;
25
26 /**
27 * See Main.java.
28 */
29 public class RowInserterRule
30 extends Rule
31 {
32
33 private Connection conn;
34
35 public RowInserterRule( Connection conn )
36 {
37 this.conn = conn;
38 }
39
40 /**
41 * This method is invoked when the start tag for an xml element representing
42 * a database row is encountered. It pushes a new Row instance onto the
43 * digester stack (rather like an ObjectCreateRule) so that column data
44 * can be stored on it.
45 */
46 @Override
47 public void begin( String namespace, String name, org.xml.sax.Attributes attrs )
48 {
49 getDigester().push( new Row() );
50 }
51
52 /**
53 * This method is invoked when the end tag for an xml element representing
54 * a database row is encountered. It pops a fully-configured Row instance
55 * off the digester stack, accesses the object below it on the stack (a
56 * Table object) to get the tablename, then does an SQL insert). Actually,
57 * here we just print out text rather than do the sql insert, but the
58 * real implementation should be fairly simple.
59 * <p>
60 * Note that after this rule completes, the row/column information is
61 * <i>discarded</i>, ie this rule performs actions <i>as the input is
62 * parsed</i>. This contrasts with the more usual way digester is used,
63 * which is to build trees of objects for later use. But it's a perfectly
64 * valid use of Digester.
65 */
66 @Override
67 public void end( String namespace, String name )
68 {
69 Row row = getDigester().pop();
70 Table table = getDigester().peek();
71
72 // Obviously, all this would be replaced by code like:
73 // stmt = conn.prepareStatement();
74 // stmt.setString(n, value);
75 //
76 // Many improvements can then be implemented, such as using the
77 // PreparedStatement.getParameterMetaData method to retrieve
78 // retrieve parameter types, etc.
79
80 StringBuilder colnames = new StringBuilder();
81 StringBuilder colvalues = new StringBuilder();
82
83 for ( Iterator<Column> i = row.getColumns().iterator(); i.hasNext(); )
84 {
85 Column column = i.next();
86
87 if ( colnames.length() > 0 )
88 {
89 colnames.append( ", " );
90 colvalues.append( ", " );
91 }
92
93 colnames.append( "'" );
94 colnames.append( column.getName() );
95 colnames.append( "'" );
96
97 colvalues.append( "'" );
98 colvalues.append( column.getValue() );
99 colvalues.append( "'" );
100 }
101
102 StringBuilder buf = new StringBuilder();
103 buf.append( "insert into " );
104 buf.append( table.getName() );
105 buf.append( " (" );
106 buf.append( colnames.toString() );
107 buf.append( ") values (" );
108 buf.append( colvalues.toString() );
109 buf.append( ")" );
110
111 // here the prepared statement would be executed....
112 System.out.println( buf.toString() );
113 }
114
115 }