/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright 2008 - 2009 Pentaho Corporation. All rights reserved. */ package org.pentaho.pac.server.common; import java.io.File; import java.io.FilenameFilter; import java.net.MalformedURLException; import java.sql.Driver; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import org.apache.commons.lang.StringUtils; import org.pentaho.pac.client.JdbcDriverDiscoveryService; import org.pentaho.pac.common.JdbcDriverDiscoveryServiceException; import org.pentaho.pac.common.NameValue; import org.pentaho.pac.server.i18n.Messages; import org.pentaho.pac.server.util.ResolverUtil; import com.google.gwt.user.server.rpc.RemoteServiceServlet; public class JdbcDriverDiscoveryServiceImpl extends RemoteServiceServlet implements JdbcDriverDiscoveryService { /** * */ private static final long serialVersionUID = 420L; private static final long interval = 300000; // every five mins private final HashMap<String,CacheInfo> cache = new HashMap<String,CacheInfo>(); private static final String DEFAULT_JDBC_PATH_2 = "./lib"; //$NON-NLS-1$ private static final String DEFAULT_JDBC_PATH_1 = "./lib-ext/jdbc";//$NON-NLS-1$ private static String jdbcDriverPath; public JdbcDriverDiscoveryServiceImpl() { } public void init(ServletConfig config) throws ServletException { super.init(config); initialize(); } public void initialize() { initFromConfiguration(); } private void initFromConfiguration() { AppConfigProperties appCfg = AppConfigProperties.getInstance(); jdbcDriverPath = StringUtils.defaultIfEmpty(appCfg.getJdbcDriverPath(), System.getProperty("jdbc.drivers.path")); //$NON-NLS-1$ if(!isExist(jdbcDriverPath)) { jdbcDriverPath = DEFAULT_JDBC_PATH_1; } if(!isExist(jdbcDriverPath)){ jdbcDriverPath = DEFAULT_JDBC_PATH_2; } cache.clear(); } public NameValue[] getAvailableJdbcDrivers() throws JdbcDriverDiscoveryServiceException { if (jdbcDriverPath != null && jdbcDriverPath.length() > 0) { return getAvailableJdbcDrivers(jdbcDriverPath); } else { throw new JdbcDriverDiscoveryServiceException(Messages .getErrorString("JdbcDriverDiscoveryService.ERROR_0002_NO_DRIVERS_FOUND_IN_JDBC_DRIVER_PATH"));//$NON-NLS-1$ } } public NameValue[] getAvailableJdbcDrivers(String location) throws JdbcDriverDiscoveryServiceException { try { return getDrivers(location,false); } catch(JdbcDriverDiscoveryServiceException jdse) { jdbcDriverPath = DEFAULT_JDBC_PATH_2; return getDrivers(location,false); } } private NameValue[] getDrivers(String location,boolean relative) throws JdbcDriverDiscoveryServiceException { CacheInfo ci = cache.get(location); try { long timeMil = System.currentTimeMillis(); if (ci!=null){ long inte = timeMil - ci.lastCall; if (inte < interval) { return ci.cachedObj; } } if (location != null && location.length() > 0) { File parent = relative?new File(getServletContext().getRealPath(location)):new File(location); FilenameFilter libs = new FilenameFilter() { public boolean accept(File dir, String pathname) { return pathname.endsWith("jar") || pathname.endsWith("zip"); //$NON-NLS-1$//$NON-NLS-2$ } }; ResolverUtil<Driver> resolver = new ResolverUtil<Driver>(); if (parent.exists()) { for (File lib : parent.listFiles(libs)) { try { resolver.loadImplementationsInJar("", lib.toURI().toURL(), //$NON-NLS-1$ new ResolverUtil.IsA(Driver.class)); } catch (MalformedURLException e) { e.printStackTrace(); continue; } } List<NameValue> drivers = new ArrayList<NameValue>(); for (Class<? extends Driver> cd : resolver.getClasses()) drivers.add(new NameValue(cd.getName(), cd.getName())); if(drivers.size() > 0) { if(ci == null) { ci = new CacheInfo(); ci.lastCall = timeMil; cache.put(location, ci); } ci.cachedObj = drivers.toArray(new NameValue[drivers.size()]); } else { throw new JdbcDriverDiscoveryServiceException(Messages .getErrorString("JdbcDriverDiscoveryService.ERROR_0002_NO_DRIVERS_FOUND_IN_JDBC_DRIVER_PATH")); //$NON-NLS-1$ } } else { throw new JdbcDriverDiscoveryServiceException(Messages .getErrorString("JdbcDriverDiscoveryService.ERROR_0002_NO_DRIVERS_FOUND_IN_JDBC_DRIVER_PATH")); //$NON-NLS-1$ } } else { throw new JdbcDriverDiscoveryServiceException(Messages .getErrorString("JdbcDriverDiscoveryService.ERROR_0001_NO_JDBC_DRIVER_PATH_SPECIFIED")); //$NON-NLS-1$ } } catch (Exception e) { throw new JdbcDriverDiscoveryServiceException(Messages .getErrorString("JdbcDriverDiscoveryService.ERROR_0001_NO_JDBC_DRIVER_PATH_SPECIFIED"), e); //$NON-NLS-1$ } return ci.cachedObj; } public NameValue[] getRelativeAvailableJdbcDrivers(String location) throws JdbcDriverDiscoveryServiceException { return getDrivers(location,true); } private class CacheInfo { private long lastCall; private NameValue[] cachedObj; } private boolean isExist(String location) { File file = new File(location); return (file != null && file.isDirectory()); } }