--- /dev/null
+/*\r
+\r
+ Derby - Class org.apache.derby.jdbc.ReferenceableDataSource\r
+\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to You under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+ */\r
+package org.apache.derby.jdbc;\r
+\r
+import java.sql.SQLException;\r
+import java.lang.reflect.*;\r
+\r
+\r
+import java.io.Serializable;\r
+import java.io.PrintWriter;\r
+import java.util.Properties;\r
+\r
+/* -- JNDI -- */\r
+import javax.naming.NamingException;\r
+import javax.naming.Referenceable;\r
+import javax.naming.Reference;\r
+import javax.naming.StringRefAddr;\r
+import javax.naming.spi.ObjectFactory;\r
+import javax.naming.Context;\r
+import javax.naming.Name;\r
+import javax.naming.Reference;\r
+import javax.naming.RefAddr;\r
+import java.util.Hashtable;\r
+import java.util.Enumeration;\r
+\r
+/** \r
+\r
+ Derby DataSource implementation base class.\r
+ ReferenceableDataSource provides support for JDBC standard DataSource attributes and acts\r
+ as the ObjectFactory to generate Derby DataSource implementations.\r
+ <P>\r
+ The standard attributes provided by this class are:\r
+ <UL>\r
+ <LI>databaseName\r
+ <LI>dataSourceName\r
+ <LI>description\r
+ <LI>password\r
+ <LI>user\r
+ </UL>\r
+ <BR>\r
+ See the specific Derby DataSource implementation for details on their meaning.\r
+ <BR>\r
+ See the JDBC 3.0 specification for more details.\r
+\r
+\r
+*/\r
+public class ReferenceableDataSource implements\r
+ javax.naming.Referenceable,\r
+ java.io.Serializable,\r
+ ObjectFactory\r
+{\r
+\r
+\r
+ private static final long serialVersionUID = 1872877359127597176L;\r
+\r
+\r
+ private static final Class[] STRING_ARG = { "".getClass() };\r
+ private static final Class[] INT_ARG = { Integer.TYPE };\r
+ private static final Class[] BOOLEAN_ARG = { Boolean.TYPE };\r
+\r
+ private String description;\r
+ private String dataSourceName;\r
+ private String databaseName;\r
+ private String password;\r
+ private String user;\r
+ private int loginTimeout;\r
+\r
+\r
+ /** instance variables that will not be serialized */\r
+ transient private PrintWriter printer;\r
+\r
+ /**\r
+ No-arg constructor.\r
+ */\r
+ public ReferenceableDataSource() {\r
+ update();\r
+ }\r
+\r
+\r
+ /*\r
+ * Properties to be seen by Bean - access thru reflection.\r
+ */\r
+\r
+ /** \r
+ Set the database name. Setting this property is mandatory. If a\r
+ database named wombat at g:/db needs to be accessed, database name\r
+ should be set to "g:/db/wombat". The database will be booted if it\r
+ is not already running in the system.\r
+\r
+ @param databaseName the name of the database \r
+ */\r
+ public final synchronized void setDatabaseName(String databaseName) {\r
+ this.databaseName = databaseName;\r
+ update();\r
+ }\r
+ public String getDatabaseName() {\r
+ return databaseName;\r
+ }\r
+\r
+ /** \r
+ Set the data source name. The property is not mandatory. It is used\r
+ for informational purposes only.\r
+\r
+ @param dsn the name of the data source\r
+ */\r
+ public final void setDataSourceName(String dsn) {\r
+ dataSourceName = dsn;\r
+ }\r
+ /** @return data source name */\r
+ public final String getDataSourceName() {\r
+ return dataSourceName;\r
+ }\r
+\r
+ /**\r
+ Set the data source descripton. This property is not mandatory.\r
+ It is used for informational purposes only.\r
+\r
+ @param desc the description of the data source\r
+ */\r
+ public final void setDescription(String desc) {\r
+ description = desc;\r
+ }\r
+ /** @return description */\r
+ public final String getDescription() {\r
+ return description;\r
+ }\r
+\r
+ /**\r
+ Set the <code>user</code> property for the data source.\r
+ This is user name for any data source getConnection() call\r
+ that takes no arguments.\r
+ */\r
+ public final void setUser(String user) {\r
+ this.user = user;\r
+ }\r
+ /** @return user */\r
+ public final String getUser() {\r
+ return user;\r
+ }\r
+\r
+ /**\r
+ Set the <code>password</code> property for the data source.\r
+ This is user's password for any data source getConnection() call\r
+ that takes no arguments.\r
+ */\r
+ public final void setPassword(String password) {\r
+ this.password = password;\r
+ }\r
+ /** @return password */\r
+ public final String getPassword() {\r
+ return password;\r
+ }\r
+\r
+ /*\r
+ * DataSource methods \r
+ */\r
+\r
+\r
+ /**\r
+ * Gets the maximum time in seconds that this data source can wait\r
+ * while attempting to connect to a database. A value of zero\r
+ * means that the timeout is the default system timeout \r
+ * if there is one; otherwise it means that there is no timeout.\r
+ * When a data source object is created, the login timeout is\r
+ * initially zero.\r
+ *\r
+ * @return the data source login time limit\r
+ * @exception SQLException if a database access error occurs.\r
+ */\r
+ public int getLoginTimeout() throws SQLException\r
+ {\r
+ return loginTimeout;\r
+ }\r
+\r
+ /**\r
+ * Sets the maximum time in seconds that this data source will wait\r
+ * while attempting to connect to a database. A value of zero\r
+ * specifies that the timeout is the default system timeout \r
+ * if there is one; otherwise it specifies that there is no timeout.\r
+ * When a data source object is created, the login timeout is\r
+ * initially zero.\r
+ <P>\r
+ Derby ignores this property.\r
+ * @param seconds the data source login time limit\r
+ * @exception SQLException if a database access error occurs.\r
+ */\r
+ public void setLoginTimeout(int seconds) throws SQLException\r
+ {\r
+ loginTimeout = seconds;\r
+ }\r
+\r
+\r
+ /** \r
+ * Get the log writer for this data source. \r
+ *\r
+ * <p>The log writer is a character output stream to which all logging\r
+ * and tracing messages for this data source object instance will be\r
+ * printed. This includes messages printed by the methods of this\r
+ * object, messages printed by methods of other objects manufactured\r
+ * by this object, and so on. Messages printed to a data source\r
+ * specific log writer are not printed to the log writer associated\r
+ * with the java.sql.Drivermanager class. When a data source object is\r
+ * created the log writer is initially null, in other words, logging\r
+ * is disabled.\r
+ *\r
+ * @return the log writer for this data source, null if disabled\r
+ * @exception SQLException if a database-access error occurs. \r
+ */\r
+ public PrintWriter getLogWriter() throws SQLException\r
+ {\r
+ return printer;\r
+ }\r
+\r
+ /**\r
+ * Set the log writer for this data source.\r
+ *\r
+ * <p>The log writer is a character output stream to which all logging\r
+ * and tracing messages for this data source object instance will be\r
+ * printed. This includes messages printed by the methods of this\r
+ * object, messages printed by methods of other objects manufactured\r
+ * by this object, and so on. Messages printed to a data source\r
+ * specific log writer are not printed to the log writer associated\r
+ * with the java.sql.Drivermanager class. When a data source object is\r
+ * created the log writer is initially null, in other words, logging\r
+ * is disabled.\r
+ *\r
+ * @param out the new log writer; to disable, set to null\r
+ * @exception SQLException if a database-access error occurs. \r
+ */\r
+ public void setLogWriter(PrintWriter out) throws SQLException\r
+ {\r
+ printer = out;\r
+ }\r
+\r
+ /*\r
+ ** Reference methods etc.\r
+ */\r
+\r
+ /*\r
+ * Object Factory method\r
+ */\r
+\r
+ /**\r
+ Re-Create Derby datasource given a reference.\r
+\r
+ @param obj The possibly null object containing location or reference\r
+ information that can be used in creating an object. \r
+ @param name The name of this object relative to nameCtx, or null if no\r
+ name is specified. \r
+ @param nameCtx The context relative to which the name parameter is\r
+ specified, or null if name is relative to the default initial context. \r
+ @param environment The possibly null environment that is used in\r
+ creating the object. \r
+\r
+ @return One of the Derby datasource object created; null if an\r
+ object cannot be created. \r
+\r
+ @exception Exception if this object factory encountered an exception\r
+ while attempting to create an object, and no other object factories are\r
+ to be tried. \r
+ */\r
+ public Object getObjectInstance(Object obj,\r
+ Name name,\r
+ Context nameCtx,\r
+ Hashtable environment)\r
+ throws Exception\r
+ {\r
+ Reference ref = (Reference)obj;\r
+ String classname = ref.getClassName();\r
+\r
+ Object ds = Class.forName(classname).newInstance();\r
+ //Added by Jeff Huang\r
+ //TODO: FIXIT\r
+ \r
+ for (Enumeration e = ref.getAll(); e.hasMoreElements(); ) {\r
+ \r
+ RefAddr attribute = (RefAddr) e.nextElement();\r
+\r
+ String propertyName = attribute.getType();\r
+\r
+ String value = (String) attribute.getContent();\r
+\r
+ String methodName = "set" + propertyName.substring(0,1).toUpperCase(java.util.Locale.ENGLISH) + propertyName.substring(1);\r
+\r
+ Method m;\r
+ \r
+ Object argValue;\r
+ try {\r
+ m = ds.getClass().getMethod(methodName, STRING_ARG);\r
+ argValue = value;\r
+ } catch (NoSuchMethodException nsme) {\r
+ try {\r
+ m = ds.getClass().getMethod(methodName, INT_ARG);\r
+ argValue = Integer.valueOf(value);\r
+ } catch (NoSuchMethodException nsme2) {\r
+ m = ds.getClass().getMethod(methodName, BOOLEAN_ARG);\r
+ argValue = Boolean.valueOf(value);\r
+ }\r
+ }\r
+ m.invoke(ds, new Object[] { argValue });\r
+ }\r
+\r
+ return ds;\r
+ }\r
+\r
+ /**\r
+ Referenceable method.\r
+\r
+ @exception NamingException cannot find named object\r
+ */\r
+ public final Reference getReference() throws NamingException \r
+ {\r
+ // These fields will be set by the JNDI server when it decides to\r
+ // materialize a data source.\r
+ Reference ref = new Reference(this.getClass().getName(),\r
+ "org.apache.derby.jdbc.ReferenceableDataSource",\r
+ null);\r
+\r
+\r
+ // Look for all the getXXX methods in the class that take no arguments.\r
+ Method[] methods = this.getClass().getMethods();\r
+\r
+ for (int i = 0; i < methods.length; i++) {\r
+\r
+ Method m = methods[i];\r
+\r
+ // only look for simple getter methods.\r
+ if (m.getParameterTypes().length != 0)\r
+ continue;\r
+\r
+ // only non-static methods\r
+ if (Modifier.isStatic(m.getModifiers()))\r
+ continue;\r
+\r
+ // Only getXXX methods\r
+ String methodName = m.getName();\r
+ if ((methodName.length() < 5) || !methodName.startsWith("get"))\r
+ continue;\r
+\r
+\r
+\r
+ Class returnType = m.getReturnType();\r
+\r
+ if (Integer.TYPE.equals(returnType) || STRING_ARG[0].equals(returnType) || Boolean.TYPE.equals(returnType)) {\r
+\r
+ // setSomeProperty\r
+ // 01234\r
+\r
+ String propertyName = methodName.substring(3,4).toLowerCase(java.util.Locale.ENGLISH).concat(methodName.substring(4));\r
+\r
+ try {\r
+ Object ov = m.invoke(this, null);\r
+\r
+ //Need to check for nullability for all the properties, otherwise\r
+ //rather than null, "null" string gets stored in jndi.\r
+ if (ov != null) {\r
+ ref.add(new StringRefAddr(propertyName, ov.toString()));\r
+ }\r
+ } catch (IllegalAccessException iae) {\r
+ } catch (InvocationTargetException ite) {\r
+ }\r
+\r
+\r
+ }\r
+ }\r
+\r
+ return ref;\r
+ }\r
+\r
+\r
+ void update() {\r
+ }\r
+\r
+ /**\r
+ Return a connection for the Derby family of data source implementations.\r
+ */\r
+ java.sql.Connection getConnection(String username, String password, boolean requestPassword) throws SQLException {\r
+ return null;\r
+ }\r
+\r
+}\r