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 }