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 }