001: /*
002:
003: Derby - Class org.apache.derbyTesting.functionTests.tests.jdbcapi.dataSourcePermissions
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to You under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derbyTesting.functionTests.tests.jdbcapi;
023:
024: import java.io.ByteArrayInputStream;
025: import java.io.ByteArrayOutputStream;
026: import java.io.ObjectInputStream;
027: import java.io.ObjectOutputStream;
028: import java.lang.reflect.Method;
029: import java.util.ArrayList;
030: import java.util.Arrays;
031:
032: import javax.naming.*;
033: import javax.naming.spi.ObjectFactory;
034:
035: /**
036: * Test obtaining a javax.naming.Reference from a Derby data source
037: * and recreating a Derby data source from it. Tests that the recreated
038: * value has the same value for all the properties the data source supports.
039: * The list of properties is obtained dynamically from the getXXX methods
040: * that return int, String, boolean, short, long. Should Derby data sources
041: * support any other bean property types then this test should be modified
042: * to pick them up and handle them. Hopefully the test should fail when such
043: * a property is added.
044: *
045: * At no point does this test attempt to connect using these data sources.
046: */
047: public class dataSourceReference {
048: public static void main(String[] args) throws Exception {
049:
050: System.out.println("Starting dataSourceReference");
051:
052: testDSReference("org.apache.derby.jdbc.EmbeddedDataSource");
053: testDSReference("org.apache.derby.jdbc.EmbeddedConnectionPoolDataSource");
054: testDSReference("org.apache.derby.jdbc.EmbeddedXADataSource");
055:
056: testDSReference("org.apache.derby.jdbc.ClientDataSource");
057: testDSReference("org.apache.derby.jdbc.ClientConnectionPoolDataSource");
058: testDSReference("org.apache.derby.jdbc.ClientXADataSource");
059:
060: System.out.println("Completed dataSourceReference");
061:
062: }
063:
064: /**
065: * Test a data source
066: * <OL>
067: * <LI> Create an empty one from the class name
068: * <LI> Discover the property list
069: * <LI> Create a reference and recreate a data source
070: * <LI> Compare the two
071: * <LI> Serialize athe data source and recreate
072: * <LI> Compare the two
073: * <LI> Set every property for the data source
074: * <LI> Create a reference and recreate a data source
075: * <LI> Compare the two
076: * </OL>
077: * @param dsName
078: * @throws Exception
079: */
080: private static void testDSReference(String dsName) throws Exception {
081: Object ds = Class.forName(dsName).newInstance();
082:
083: System.out.println("DataSource class " + dsName);
084: String[] properties = getPropertyBeanList(ds);
085: System.out.println(" property list");
086: for (int i = 0; i < properties.length; i++) {
087: System.out.println(" " + properties[i]);
088: }
089:
090: Referenceable refDS = (Referenceable) ds;
091:
092: Reference dsAsReference = refDS.getReference();
093:
094: String factoryClassName = dsAsReference.getFactoryClassName();
095:
096: ObjectFactory factory = (ObjectFactory) Class.forName(
097: factoryClassName).newInstance();
098:
099: Object recreatedDS = factory.getObjectInstance(dsAsReference,
100: null, null, null);
101:
102: System.out
103: .println(" empty DataSource recreated using Reference as "
104: + recreatedDS.getClass().getName());
105: if (recreatedDS == ds)
106: System.out.println("FAIL recreated as same instance!");
107:
108: compareDS(properties, ds, recreatedDS);
109:
110: // now serialize and recreate
111: ByteArrayOutputStream baos = new ByteArrayOutputStream();
112: ObjectOutputStream oos = new ObjectOutputStream(baos);
113: oos.writeObject(ds);
114: oos.flush();
115: oos.close();
116: ByteArrayInputStream bais = new ByteArrayInputStream(baos
117: .toByteArray());
118: ObjectInputStream ois = new ObjectInputStream(bais);
119: recreatedDS = ois.readObject();
120: System.out
121: .println(" empty DataSource recreated using serialization");
122: compareDS(properties, ds, recreatedDS);
123:
124: // now populate the data source
125: for (int i = 0; i < properties.length; i++) {
126: String property = properties[i];
127: Method getMethod = getGet(property, ds);
128:
129: Method setMethod = getSet(getMethod, ds);
130:
131: Class pt = getMethod.getReturnType();
132:
133: // generate a somewhat unique value for a property
134: int val = 0;
135: for (int j = 0; j < property.length(); j++)
136: val += property.charAt(j);
137:
138: if (pt.equals(Integer.TYPE)) {
139: setMethod.invoke(ds, new Object[] { new Integer(val) });
140: continue;
141: }
142: if (pt.equals(String.class)) {
143: String value;
144: if (property.equals("createDatabase"))
145: value = "create";
146: else if (property.equals("shutdownDatabase"))
147: value = "shutdown";
148: else
149: value = "XX_" + property + "_" + val;
150:
151: setMethod.invoke(ds, new Object[] { value });
152: continue;
153: }
154: if (pt.equals(Boolean.TYPE)) {
155: // set the opposite value
156: Object gbv = getMethod.invoke(ds, null);
157: Boolean sbv = Boolean.FALSE.equals(gbv) ? Boolean.TRUE
158: : Boolean.FALSE;
159: setMethod.invoke(ds, new Object[] { sbv });
160: continue;
161: }
162: if (pt.equals(Short.TYPE)) {
163: setMethod.invoke(ds, new Object[] { new Short(
164: (short) val) });
165: continue;
166: }
167: if (pt.equals(Long.TYPE)) {
168: setMethod.invoke(ds, new Object[] { new Long(val) });
169: continue;
170: }
171: System.out.println("FAIL " + property
172: + " not settable - uhpdate test!!");
173: }
174:
175: dsAsReference = refDS.getReference();
176: recreatedDS = factory.getObjectInstance(dsAsReference, null,
177: null, null);
178: System.out
179: .println(" populated DataSource recreated using Reference as "
180: + recreatedDS.getClass().getName());
181: if (recreatedDS == ds)
182: System.out.println("FAIL recreated as same instance!");
183:
184: compareDS(properties, ds, recreatedDS);
185:
186: // now serialize and recreate
187: baos = new ByteArrayOutputStream();
188: oos = new ObjectOutputStream(baos);
189: oos.writeObject(ds);
190: oos.flush();
191: oos.close();
192: bais = new ByteArrayInputStream(baos.toByteArray());
193: ois = new ObjectInputStream(bais);
194: recreatedDS = ois.readObject();
195: System.out
196: .println(" populated DataSource recreated using serialization");
197: compareDS(properties, ds, recreatedDS);
198: }
199:
200: private static String[] getPropertyBeanList(Object ds)
201: throws Exception {
202: Method[] allMethods = ds.getClass().getMethods();
203:
204: ArrayList properties = new ArrayList();
205: for (int i = 0; i < allMethods.length; i++) {
206: Method m = allMethods[i];
207: String methodName = m.getName();
208: // Need at least getXX
209: if (methodName.length() < 5)
210: continue;
211: if (!methodName.startsWith("get"))
212: continue;
213: if (m.getParameterTypes().length != 0)
214: continue;
215:
216: Class rt = m.getReturnType();
217:
218: if (rt.equals(Integer.TYPE) || rt.equals(String.class)
219: || rt.equals(Boolean.TYPE) || rt.equals(Short.TYPE)
220: || rt.equals(Long.TYPE)) {
221: // valid Java Bean property
222: String beanName = methodName.substring(3, 4)
223: .toLowerCase()
224: + methodName.substring(4);
225:
226: properties.add(beanName);
227: continue;
228: }
229:
230: if (rt.isPrimitive())
231: System.out.println("FAIL " + methodName
232: + " not supported - update test!!");
233:
234: }
235:
236: String[] propertyList = (String[]) properties
237: .toArray(new String[0]);
238:
239: Arrays.sort(propertyList);
240:
241: return propertyList;
242: }
243:
244: private static Method getGet(String property, Object ds)
245: throws Exception {
246: String methodName = "get"
247: + property.substring(0, 1).toUpperCase()
248: + property.substring(1);
249: Method m = ds.getClass().getMethod(methodName, null);
250: return m;
251: }
252:
253: private static Method getSet(Method getMethod, Object ds)
254: throws Exception {
255: String methodName = "s" + getMethod.getName().substring(1);
256: Method m = ds.getClass().getMethod(methodName,
257: new Class[] { getMethod.getReturnType() });
258: return m;
259: }
260:
261: private static void compareDS(String[] properties, Object ds,
262: Object rds) throws Exception {
263: System.out.println(" Start compare recreated");
264: for (int i = 0; i < properties.length; i++) {
265: Method getMethod = getGet(properties[i], ds);
266:
267: Object dsValue = getMethod.invoke(ds, null);
268: Object rdsValue = getMethod.invoke(rds, null);
269:
270: if (dsValue == null) {
271: if (rdsValue != null) {
272: System.out.println(" FAIL: " + properties[i]
273: + " originally null, recreated as "
274: + rdsValue);
275: continue;
276: }
277: } else {
278: if (!dsValue.equals(rdsValue)) {
279: System.out.println(" FAIL: " + properties[i]
280: + " originally " + dsValue
281: + ", recreated as " + rdsValue);
282: continue;
283: }
284:
285: }
286: if (dsValue != null)
287: System.out
288: .println(" " + properties[i] + "=" + dsValue);
289:
290: }
291: System.out.println(" Completed compare recreated");
292:
293: }
294:
295: }
|