/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2002-2008, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotools.jdbc; import java.io.IOException; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import javax.naming.Context; import javax.naming.NamingException; import javax.sql.DataSource; import org.geotools.data.DataStore; import org.geotools.factory.GeoTools; /** * Abstract implementation of DataStoreFactory for jdbc datastores which obtain * a JNDI connection. * <p> * Subclasses should not need to override any methods, only just call the * parent constructor passing in the non JNDI datastore factory to delegate to. * </p> * * @author Christian Mueller * * @source $URL$ */ public abstract class JDBCJNDIDataStoreFactory extends JDBCDataStoreFactory { public final static String J2EERootContext="java:comp/env/"; /** * JNDI data source name */ public static final Param JNDI_REFNAME = new Param("jndiReferenceName", String.class, "JNDI data source", true, J2EERootContext+"jdbc/mydatabase"); /** * regular datastore factory to delegate to. */ protected JDBCDataStoreFactory delegate; protected JDBCJNDIDataStoreFactory(JDBCDataStoreFactory delegate) { this.delegate = delegate; } /** * Override which explicitly returns null because with a JNDI connection * the driver is not known ahead of time. */ @Override protected String getDriverClassName() { return null; } /** * Override which explicitly returns null, validation queries are * not supported, my be part of the external data source configuration */ @Override protected String getValidationQuery() { return null; } /** * Override which explicitly returns null since there is no jdbc url, the * connection is identified by the JNDI name. */ @Override protected String getJDBCUrl(Map params) throws IOException { return null; } /** * Override to create the datasource from the external JNDI conection. */ protected DataSource createDataSource(Map params, SQLDialect dialect) throws IOException { String jndiName = (String) JNDI_REFNAME.lookUp(params); if (jndiName == null) throw new IOException("Missing " + JNDI_REFNAME.description); Context ctx = null; DataSource ds = null; try { ctx = GeoTools.getInitialContext(GeoTools.getDefaultHints()); } catch (NamingException e) { throw new RuntimeException(e); } try { ds = (DataSource) ctx.lookup(jndiName); } catch (NamingException e1) { // check if the user did not specify "java:comp/env" // and this code is running in a J2EE environment try { if (jndiName.startsWith(J2EERootContext)==false) { ds = (DataSource) ctx.lookup(J2EERootContext+jndiName); // success --> issue a waring Logger.getLogger(this.getClass().getName()).log( Level.WARNING,"Using "+J2EERootContext+jndiName+" instead of " + jndiName+ " would avoid an unnecessary JNDI lookup"); } } catch (NamingException e2) { // do nothing, was only a try } } if (ds == null) throw new IOException("Cannot find JNDI data source: " + jndiName); else return ds; } /** * Determines if the datastore is available. * <p> * Check in an Initial Context is available, that is all what can be done * Checking for the right jdbc jars in the classpath is not possible here * </p> */ public boolean isAvailable() { try { GeoTools.getInitialContext(GeoTools.getDefaultHints()); return true; } catch (NamingException e) { return false; } } /** * Override to omit all those parameters which define the creation of * the connection. */ protected void setupParameters(Map parameters) { parameters.put(DBTYPE.key, new Param(DBTYPE.key, DBTYPE.type, DBTYPE.description, DBTYPE.required, getDatabaseID())); parameters.put(JNDI_REFNAME.key, JNDI_REFNAME); parameters.put(SCHEMA.key, SCHEMA); parameters.put(NAMESPACE.key, NAMESPACE); parameters.put(PK_METADATA_TABLE.key, PK_METADATA_TABLE); } @Override protected String getDatabaseID() { return delegate.getDatabaseID(); } @Override public String getDisplayName() { return delegate.getDisplayName() + " (JNDI)"; } public String getDescription() { return delegate.getDescription() + " (JNDI)"; } @Override protected JDBCDataStore createDataStoreInternal(JDBCDataStore dataStore, Map params) throws IOException { return delegate.createDataStoreInternal(dataStore, params); } public DataStore createNewDataStore(Map params) throws IOException { return delegate.createNewDataStore(params); } public Map getImplementationHints() { return delegate.getImplementationHints(); } @Override protected SQLDialect createSQLDialect(JDBCDataStore dataStore) { return delegate.createSQLDialect(dataStore); } @Override protected boolean checkDBType(Map params) { return delegate.checkDBType(params); } }