Package org.pentaho.reporting.ui.datasources.jdbc.connection

Source Code of org.pentaho.reporting.ui.datasources.jdbc.connection.JdbcConnectionDefinitionManager

/*
* 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 (c) 2007 - 2009 Pentaho Corporation..  All rights reserved.
*/

package org.pentaho.reporting.ui.datasources.jdbc.connection;

import java.util.Properties;
import java.util.TreeMap;
import java.util.Map;
import java.util.Iterator;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.reporting.libraries.base.util.StringUtils;

/**
* Manages the list of local database connections for this application.
* <p/>
* The list of local connections is contained in the user preferences for this user. The structure of the preferences is
* as follows: <ul> <li>One node per connection - the name of the node is the JNDI Connection name <li>Under each node,
* the following set of string keys and values which define each connection <ul> <li>driver - the JDBC driver class
* <li>url - the URL of the database <li>username - the username used to connect to the database <li>password - the
* password used to connect to the database </ul> </ul>
*/
public class JdbcConnectionDefinitionManager
{
  // Logger
  private static final Log log = LogFactory.getLog(JdbcConnectionDefinitionManager.class);

  // The default connection (used if no other connections can be loaded)
  private static final JdbcConnectionDefinition SAMPLE_DATA_JNDI_SOURCE =
      new JndiConnectionDefinition("SampleData", "SampleData", "Hypersonic", null, null);
  private static final JdbcConnectionDefinition SAMPLE_DATA_DRIVER_SOURCE =
      new DriverConnectionDefinition("SampleData (Hypersonic)", "org.hsqldb.jdbcDriver",
          "jdbc:hsqldb:hsql://localhost:9001/sampledata", "pentaho_user", "password");
  private static final JdbcConnectionDefinition SAMPLE_DATA_MEMORY_SOURCE =
      new DriverConnectionDefinition("SampleData (Memory)", "org.hsqldb.jdbcDriver",
          "jdbc:hsqldb:mem:SampleData", "pentaho_user", "password");
  private static final JdbcConnectionDefinition LOCAL_SAMPLE_DATA_DRIVER_SOURCE =
      new DriverConnectionDefinition("SampleData (Local)", "org.hsqldb.jdbcDriver",
          "jdbc:hsqldb:./resources/sampledata/sampledata", "pentaho_user", "password");
  private static final JdbcConnectionDefinition MYSQL_SAMPLE_DATA_DRIVER_SOURCE =
      new DriverConnectionDefinition("SampleData (MySQL)", "com.mysql.jdbc.Driver",
          "jdbc:mysql://localhost:3306/sampledata", "pentaho_user", "password");

  // The location in the user preferences tree for the JNDI datasource settings
  private static final String DATASOURCE_PREFERENCES_NODE = "org/pentaho/reporting/ui/datasources/jdbc/Settings";

  // The current set of Sources
  private TreeMap<String,JdbcConnectionDefinition> connectionDefinitions = new TreeMap<String,JdbcConnectionDefinition>();

  /**
   * The reference to the preferences object for the datasource settings
   */
  private Preferences userPreferences;

  private static final String TYPE_KEY = "type";
  // Constants use in the storage of the field information
  private static final String DRIVER_KEY = "driver";
  private static final String URL_KEY = "url";
  private static final String USERNAME_KEY = "username";
  private static final String PASSWORD_KEY = "password";
  private static final String HOSTNAME_KEY = "hostname";
  private static final String PORT_KEY = "port";
  private static final String DATABASE_TYPE_KEY = "database_type";
  private static final String DATABASE_NAME_KEY = "database_name";
  private static final String JNDI_LOCATION = "jndi-location";

  /**
   * Initializes the instance by loading the database connection information from the configuration storage.
   */
  public JdbcConnectionDefinitionManager()
  {
    this(DATASOURCE_PREFERENCES_NODE);
  }

  public JdbcConnectionDefinitionManager(final String node)
  {
    // Retrieve the system preferences for the datasource
    userPreferences = Preferences.userRoot().node(node);

    // Load the list of JNDI Sources
    try
    {
      final String[] childNodeNames = userPreferences.childrenNames();
      for (int i = 0; i < childNodeNames.length; i++)
      {
        final String name = childNodeNames[i];
        final Preferences p = userPreferences.node(name);
        final String type = p.get("type", null);
        if (type == null)
        {
          p.removeNode();
        }
        else if (type.equals("local"))
        {
          final Properties props = new Properties();
          if (p.nodeExists("properties"))
          {
            final Preferences preferences = p.node("properties");
            final String[] strings = preferences.keys();
            for (int j = 0; j < strings.length; j++)
            {
              final String string = strings[j];
              final String value = preferences.get(string, null);
              if (value != null)
              {
                props.setProperty(string, value);
              }
              else
              {
                props.remove(string);
              }
            }
          }

          final DriverConnectionDefinition driverConnection = new DriverConnectionDefinition(
              name,
              p.get(DRIVER_KEY, null),
              p.get(URL_KEY, null),
              p.get(USERNAME_KEY, null),
              p.get(PASSWORD_KEY, null),
              p.get(HOSTNAME_KEY, null),
              p.get(DATABASE_NAME_KEY, null),
              p.get(DATABASE_TYPE_KEY, null),
              p.get(PORT_KEY, null),
              props
          );


          connectionDefinitions.put(name, driverConnection);
        }
        else if (type.equals("jndi"))
        {
          final JndiConnectionDefinition connectionDefinition = new JndiConnectionDefinition
              (name, p.get(JNDI_LOCATION, null), p.get(DATABASE_TYPE_KEY, null),
                  p.get(USERNAME_KEY, null), p.get(PASSWORD_KEY, null));
          connectionDefinitions.put(name, connectionDefinition);
        }
        else
        {
          p.removeNode();
        }
      }
    }
    catch (BackingStoreException e)
    {
      // The system preferences system is not working - log this as a message and use defaults
      log.warn("Could not access the user prefererences while loading the " +
          "JNDI connection information - using default JNDI connection entries", e);
    }
    catch (final Exception e)
    {
      log.warn("Configuration information was invalid.", e);
    }

    // If the connectionDefinitions is empty, add any default entries
    if (connectionDefinitions.isEmpty() && DATASOURCE_PREFERENCES_NODE.equals(node))
    {
      if (userPreferences.getBoolean("sample-data-created", false) == true)
      {
        // only create the sample connections once, if we work on a totally fresh config.
        return;
      }
      updateSourceList(SAMPLE_DATA_JNDI_SOURCE);
      updateSourceList(SAMPLE_DATA_DRIVER_SOURCE);
      updateSourceList(SAMPLE_DATA_MEMORY_SOURCE);
      updateSourceList(LOCAL_SAMPLE_DATA_DRIVER_SOURCE);
      updateSourceList(MYSQL_SAMPLE_DATA_DRIVER_SOURCE);
      userPreferences.putBoolean("sample-data-created", true);
      try
      {
        userPreferences.flush();
      }
      catch (BackingStoreException e)
      {
        // ignored ..
      }
    }
  }

  /**
   * Returns a copy of the current list of JNDI sources
   */
  public JdbcConnectionDefinition[] getSources()
  {
    return connectionDefinitions.values().toArray
        (new JdbcConnectionDefinition[connectionDefinitions.size()]);
  }

  /**
   * Removes the specified connection-definition from the list of connections.
   *
   * @param name the name of the JNDI source to remove from the list
   */
  public void removeSource(final String name)
  {
    // Make sure the name provided is not null
    if (StringUtils.isEmpty(name))
    {
      throw new IllegalArgumentException("The provided name is invalid");
    }

    // If the source is in our list, remove it
    connectionDefinitions.remove(name);

    // Remove the entry from the user preferences
    try
    {
      final Preferences node = userPreferences.node(name);
      if (node != null)
      {
        node.removeNode();
        userPreferences.flush();
      }
    }
    catch (BackingStoreException e)
    {
      log.error("Could not remove JNDI connection entry [" + name + ']', e);
    }

  }


  /**
   * Adds or updates the source list with the specified source entry. Delagates to JNDI or JDBC method
   *
   * @param source the entry to add/update in the list
   * @throws IllegalArgumentException indicates the source is <code>null</code>
   */
  public boolean updateSourceList(final JdbcConnectionDefinition source)
  {
    if (source == null)
    {
      throw new IllegalArgumentException("The provided source is null");
    }

    if (source instanceof DriverConnectionDefinition)
    {
      return updateSourceList((DriverConnectionDefinition) source);
    }

    if (source instanceof JndiConnectionDefinition)
    {
      return updateSourceList((JndiConnectionDefinition) source);
    }
    else
    {
      throw new IllegalArgumentException("The provided source is not a supported type");
    }
  }

  /**
   * Adds or updates the source list with the specified source entry. If the entry exists (has the same name), the new
   * entry will replace the old entry. If the enrty does not already exist, the new entry will be added to the list.
   * <br> Since the definition of the ConnectionDefintion ensures that it will be valid, no testing will be performed on
   * the contents of the ConnectionDefintion.
   *
   * @param source the entry to add/update in the list
   * @throws IllegalArgumentException indicates the source is <code>null</code>
   */
  private boolean updateSourceList(final DriverConnectionDefinition source) throws IllegalArgumentException
  {
    if (source == null)
    {
      throw new IllegalArgumentException("The provided source is null");
    }

    // Update the node in the list
    final boolean updateExisting =
        (connectionDefinitions.put(source.getName(), source) != null);

    // Update the information in the preferences
    try
    {
      final Preferences node = userPreferences.node(source.getName());
      put(node, TYPE_KEY, "local");
      put(node, DRIVER_KEY, source.getDriverClass());
      put(node, URL_KEY, source.getConnectionString());
      put(node, USERNAME_KEY, source.getUsername());
      put(node, PASSWORD_KEY, source.getPassword());
      put(node, HOSTNAME_KEY, source.getHostName());
      put(node, PORT_KEY, source.getPort());
      put(node, DATABASE_TYPE_KEY, source.getDatabaseType());
      put(node, DATABASE_NAME_KEY, source.getDatabaseName());
      final Preferences preferences = node.node("properties");
      final Properties properties = source.getProperties();
      final Iterator entryIterator = properties.entrySet().iterator();
      while (entryIterator.hasNext())
      {
        final Map.Entry entry = (Map.Entry) entryIterator.next();
        put(preferences, String.valueOf(entry.getKey()), String.valueOf(entry.getValue()));
      }
      node.flush();
    }
    catch (BackingStoreException e)
    {
      log.error("Could not add/update connection entry [" + source.getName() + ']', e);
    }
    return updateExisting;
  }

  private static void put(final Preferences node, final String key, final String value)
  {
    if (value == null)
    {
      node.remove(key);
    }
    else
    {
      node.put(key, value);
    }

  }

  /**
   * Adds or updates the source list with the specified source entry. If the entry exists (has the same name), the new
   * entry will replace the old entry. If the enrty does not already exist, the new entry will be added to the list.
   * <br> Since the definition of the ConnectionDefintion ensures that it will be valid, no testing will be performed on
   * the contents of the ConnectionDefintion.
   *
   * @param source the entry to add/update in the list
   * @throws IllegalArgumentException indicates the source is <code>null</code>
   */
  private boolean updateSourceList(final JndiConnectionDefinition source) throws IllegalArgumentException
  {
    if (source == null)
    {
      throw new IllegalArgumentException("The provided source is null");
    }

    // Update the node in the list
    final boolean updateExisting =
        (connectionDefinitions.put(source.getName(), source) != null);

    // Update the information in the preferences
    try
    {
      final Preferences node = userPreferences.node(source.getName());
      put(node, TYPE_KEY, "jndi");
      put(node, JNDI_LOCATION, source.getJndiName());
      put(node, USERNAME_KEY, null);
      put(node, PASSWORD_KEY, null);
      put(node, DATABASE_TYPE_KEY, source.getDatabaseType());
      node.flush();
    }
    catch (BackingStoreException e)
    {
      log.error("Could not add/update connection entry [" + source.getName() + ']', e);
    }
    return updateExisting;
  }
}
TOP

Related Classes of org.pentaho.reporting.ui.datasources.jdbc.connection.JdbcConnectionDefinitionManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.