001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.commons.dbutils.wrappers; 018 019 import java.lang.reflect.InvocationHandler; 020 import java.lang.reflect.Method; 021 import java.sql.ResultSet; 022 023 import org.apache.commons.dbutils.ProxyFactory; 024 025 /** 026 * Wraps a <code>ResultSet</code> to trim strings returned by the 027 * <code>getString()</code> and <code>getObject()</code> methods. 028 * 029 * <p> 030 * Usage Example: 031 * This example shows how to decorate ResultSets so processing continues as 032 * normal but all Strings are trimmed before being returned from the 033 * <code>ResultSet</code>. 034 * </p> 035 * 036 * <pre> 037 * ResultSet rs = // somehow get a ResultSet; 038 * 039 * // Substitute wrapped ResultSet with additional behavior for real ResultSet 040 * rs = StringTrimmedResultSet.wrap(rs); 041 * 042 * // Pass wrapped ResultSet to processor 043 * List list = new BasicRowProcessor().toBeanList(rs); 044 * </pre> 045 */ 046 public class StringTrimmedResultSet implements InvocationHandler { 047 048 /** 049 * The factory to create proxies with. 050 */ 051 private static final ProxyFactory factory = ProxyFactory.instance(); 052 053 /** 054 * Wraps the <code>ResultSet</code> in an instance of this class. This is 055 * equivalent to: 056 * <pre> 057 * ProxyFactory.instance().createResultSet(new StringTrimmedResultSet(rs)); 058 * </pre> 059 * 060 * @param rs The <code>ResultSet</code> to wrap. 061 * @return wrapped ResultSet 062 */ 063 public static ResultSet wrap(ResultSet rs) { 064 return factory.createResultSet(new StringTrimmedResultSet(rs)); 065 } 066 067 /** 068 * The wrapped result. 069 */ 070 private final ResultSet rs; 071 072 /** 073 * Constructs a new instance of <code>StringTrimmedResultSet</code> 074 * to wrap the specified <code>ResultSet</code>. 075 * @param rs ResultSet to wrap 076 */ 077 public StringTrimmedResultSet(ResultSet rs) { 078 super(); 079 this.rs = rs; 080 } 081 082 /** 083 * Intercept calls to the <code>getString()</code> and 084 * <code>getObject()</code> methods and trim any Strings before they're 085 * returned. 086 * 087 * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[]) 088 * @param proxy Not used; all method calls go to the internal result set 089 * @param method The method to invoke on the result set 090 * @param args The arguments to pass to the result set 091 * @return string trimmed result 092 * @throws Throwable error 093 */ 094 public Object invoke(Object proxy, Method method, Object[] args) 095 throws Throwable { 096 097 Object result = method.invoke(this.rs, args); 098 099 if (method.getName().equals("getObject") 100 || method.getName().equals("getString")) { 101 102 if (result instanceof String) { 103 result = ((String) result).trim(); 104 } 105 } 106 107 return result; 108 } 109 110 }