src/core/net/sf/basedb/util/uri/ConnectionManagerUtil.java

Code
Comments
Other
Rev Date Author Line
5582 15 Mar 11 nicklas 1 /**
5582 15 Mar 11 nicklas 2   $Id$
5582 15 Mar 11 nicklas 3
5582 15 Mar 11 nicklas 4   Copyright (C) 2011 Nicklas Nordborg
5582 15 Mar 11 nicklas 5
5582 15 Mar 11 nicklas 6   This file is part of BASE - BioArray Software Environment.
5582 15 Mar 11 nicklas 7   Available at http://base.thep.lu.se/
5582 15 Mar 11 nicklas 8
5582 15 Mar 11 nicklas 9   BASE is free software; you can redistribute it and/or
5582 15 Mar 11 nicklas 10   modify it under the terms of the GNU General Public License
5582 15 Mar 11 nicklas 11   as published by the Free Software Foundation; either version 3
5582 15 Mar 11 nicklas 12   of the License, or (at your option) any later version.
5582 15 Mar 11 nicklas 13
5582 15 Mar 11 nicklas 14   BASE is distributed in the hope that it will be useful,
5582 15 Mar 11 nicklas 15   but WITHOUT ANY WARRANTY; without even the implied warranty of
5582 15 Mar 11 nicklas 16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
5582 15 Mar 11 nicklas 17   GNU General Public License for more details.
5582 15 Mar 11 nicklas 18
5582 15 Mar 11 nicklas 19   You should have received a copy of the GNU General Public License
5582 15 Mar 11 nicklas 20   along with BASE. If not, see <http://www.gnu.org/licenses/>.
5582 15 Mar 11 nicklas 21 */
5582 15 Mar 11 nicklas 22 package net.sf.basedb.util.uri;
5582 15 Mar 11 nicklas 23
5582 15 Mar 11 nicklas 24 import java.net.URI;
5599 31 Mar 11 nicklas 25 import java.util.Iterator;
5582 15 Mar 11 nicklas 26 import java.util.List;
5582 15 Mar 11 nicklas 27
7527 07 Nov 18 nicklas 28 import org.apache.commons.collections4.IteratorUtils;
5599 31 Mar 11 nicklas 29
5599 31 Mar 11 nicklas 30 import net.sf.basedb.core.Application;
5599 31 Mar 11 nicklas 31 import net.sf.basedb.core.DbControl;
5599 31 Mar 11 nicklas 32 import net.sf.basedb.core.File;
5582 15 Mar 11 nicklas 33 import net.sf.basedb.core.ItemNotFoundException;
5599 31 Mar 11 nicklas 34 import net.sf.basedb.util.extensions.ClientContext;
5599 31 Mar 11 nicklas 35 import net.sf.basedb.util.extensions.ExtensionsFilter;
5599 31 Mar 11 nicklas 36 import net.sf.basedb.util.extensions.ExtensionsInvoker;
5599 31 Mar 11 nicklas 37 import net.sf.basedb.util.extensions.Registry;
5599 31 Mar 11 nicklas 38 import net.sf.basedb.util.extensions.SingleExtensionFilter;
5606 14 Apr 11 nicklas 39 import net.sf.basedb.util.extensions.manager.ExtensionsManager;
5582 15 Mar 11 nicklas 40
5582 15 Mar 11 nicklas 41 /**
5599 31 Mar 11 nicklas 42   Collects utility methods related to connection managers.
5599 31 Mar 11 nicklas 43   Connection manager factories should be registered as 
5599 31 Mar 11 nicklas 44   extensions to the {@link #EXTENSION_POINT_ID net.sf.basedb.core.uri.connection-manager}
5599 31 Mar 11 nicklas 45   extension point. The methods in this class can then be used to
5599 31 Mar 11 nicklas 46   get information about installed connection manager factories and
5599 31 Mar 11 nicklas 47   to use them for retreiving external file data and information.
5582 15 Mar 11 nicklas 48
5582 15 Mar 11 nicklas 49   @author Nicklas
5582 15 Mar 11 nicklas 50   @since 3.0
5582 15 Mar 11 nicklas 51   @base.modified $Date$
5582 15 Mar 11 nicklas 52 */
5599 31 Mar 11 nicklas 53 public class ConnectionManagerUtil
5582 15 Mar 11 nicklas 54 {
5582 15 Mar 11 nicklas 55   
5582 15 Mar 11 nicklas 56   /**
5599 31 Mar 11 nicklas 57     The ID of the connection manager extension point.
5582 15 Mar 11 nicklas 58   */
5599 31 Mar 11 nicklas 59   public static final String EXTENSION_POINT_ID = "net.sf.basedb.core.uri.connection-manager";
5599 31 Mar 11 nicklas 60   
5599 31 Mar 11 nicklas 61   /**
5599 31 Mar 11 nicklas 62     Get a list with all connection manager factories. No context
5599 31 Mar 11 nicklas 63     information will be available to the action factories that
5599 31 Mar 11 nicklas 64     creates the connection manager factories.
5599 31 Mar 11 nicklas 65     
5599 31 Mar 11 nicklas 66     @return A list with the factories
5599 31 Mar 11 nicklas 67   */
5599 31 Mar 11 nicklas 68   public static List<ConnectionManagerFactory> getFactories()
5582 15 Mar 11 nicklas 69   {
5599 31 Mar 11 nicklas 70     ExtensionsInvoker<ConnectionManagerFactory> invoker = getInvoker(null, null);
7527 07 Nov 18 nicklas 71     List<ConnectionManagerFactory> list = IteratorUtils.toList(invoker.iterator(), Math.max(invoker.getNumExtensions(), 1));
5599 31 Mar 11 nicklas 72     return list;
5582 15 Mar 11 nicklas 73   }
5582 15 Mar 11 nicklas 74   
5582 15 Mar 11 nicklas 75   /**
5599 31 Mar 11 nicklas 76      Get the connection manager factory with the given extension id.
5599 31 Mar 11 nicklas 77      No context information will be available to the factory
5599 31 Mar 11 nicklas 78      when it is created.
5599 31 Mar 11 nicklas 79      
5599 31 Mar 11 nicklas 80     @param id The ID of the factory
5599 31 Mar 11 nicklas 81     @return A factory instance or null if not found
5582 15 Mar 11 nicklas 82   */
5599 31 Mar 11 nicklas 83   public static ConnectionManagerFactory getFactory(String id)
5582 15 Mar 11 nicklas 84   {
5599 31 Mar 11 nicklas 85     if (id == null) return null;
5599 31 Mar 11 nicklas 86     ExtensionsInvoker<ConnectionManagerFactory> invoker = getInvoker(null, new SingleExtensionFilter(id));
5599 31 Mar 11 nicklas 87     ConnectionManagerFactory factory = getFirst(invoker);
5599 31 Mar 11 nicklas 88     return factory;
5582 15 Mar 11 nicklas 89   }
5599 31 Mar 11 nicklas 90     
5582 15 Mar 11 nicklas 91   /**
5599 31 Mar 11 nicklas 92     Find a factory for the given URI. This method will iterate
5599 31 Mar 11 nicklas 93     the registered factories in their priority/index order and 
5599 31 Mar 11 nicklas 94     call {@link ConnectionManagerFactory#supports(URI)}
5599 31 Mar 11 nicklas 95     for all factories that supports auto-detection. The first
5599 31 Mar 11 nicklas 96     one that gives a successful response is returned. If no factory
5599 31 Mar 11 nicklas 97     supports the given URI, null is returned.
5599 31 Mar 11 nicklas 98     
5599 31 Mar 11 nicklas 99     <p>
5599 31 Mar 11 nicklas 100     Note to extension developers: The given uri is available
5599 31 Mar 11 nicklas 101     to the action factory as "uri" attribute of the context.
5599 31 Mar 11 nicklas 102     
5599 31 Mar 11 nicklas 103     @param uri The URI (null is not allowed)
5599 31 Mar 11 nicklas 104     @return An UriHandlerFactory or null if no factory was found
5582 15 Mar 11 nicklas 105   */
5599 31 Mar 11 nicklas 106   public static ConnectionManagerFactory findFactory(URI uri)
5582 15 Mar 11 nicklas 107   {
5599 31 Mar 11 nicklas 108     if (uri == null) throw new NullPointerException("uri");
5599 31 Mar 11 nicklas 109     
5599 31 Mar 11 nicklas 110     ClientContext context = new ClientContext();
5599 31 Mar 11 nicklas 111     context.setAttribute("uri", uri);
5599 31 Mar 11 nicklas 112     
5599 31 Mar 11 nicklas 113     ExtensionsInvoker<ConnectionManagerFactory> invoker = getInvoker(context, null);
5599 31 Mar 11 nicklas 114     ConnectionManagerFactory factory = autoDetect(invoker, uri);
5599 31 Mar 11 nicklas 115     return factory;
5582 15 Mar 11 nicklas 116   }
5582 15 Mar 11 nicklas 117   
5582 15 Mar 11 nicklas 118   /**
5599 31 Mar 11 nicklas 119     Utility method for creating a connection manager. If a specific factory
5599 31 Mar 11 nicklas 120     is specified in the connection parameters, that factory is used, otherwise
5599 31 Mar 11 nicklas 121     {@link #findFactory(URI)} is used for auto-detection. If no factory is found
5599 31 Mar 11 nicklas 122     an exception is thrown, otherwise a connection manger is created by the
5599 31 Mar 11 nicklas 123     factory method:
5599 31 Mar 11 nicklas 124     {@link ConnectionManagerFactory#createConnectionManager(URI, ConnectionParameters)}
5599 31 Mar 11 nicklas 125     
5599 31 Mar 11 nicklas 126     @param uri The URI (required)
5599 31 Mar 11 nicklas 127     @param parameters Connection parameters, such as user login/password, etc. (optional)
5599 31 Mar 11 nicklas 128     @return A connection manager
5582 15 Mar 11 nicklas 129   */
5599 31 Mar 11 nicklas 130   public static ConnectionManager createConnectionManager(URI uri, ConnectionParameters parameters)
5582 15 Mar 11 nicklas 131   {
5599 31 Mar 11 nicklas 132     if (uri == null) throw new NullPointerException("uri");
5599 31 Mar 11 nicklas 133     ConnectionManagerFactory factory = null;
6497 26 Jun 14 nicklas 134     if (parameters != null)
6497 26 Jun 14 nicklas 135     {  
6497 26 Jun 14 nicklas 136       uri = parameters.changeHost(uri);
6497 26 Jun 14 nicklas 137       if (parameters.getConnectionManagerFactoryId() != null)
5599 31 Mar 11 nicklas 138       {
6497 26 Jun 14 nicklas 139         // Use specific factory
6497 26 Jun 14 nicklas 140         String factoryId = parameters.getConnectionManagerFactoryId();
6497 26 Jun 14 nicklas 141         factory = getFactory(factoryId);
6497 26 Jun 14 nicklas 142         if (factory == null) 
6497 26 Jun 14 nicklas 143         {
6497 26 Jun 14 nicklas 144           throw new ItemNotFoundException("Connection manager factory: " + factoryId);
6497 26 Jun 14 nicklas 145         }
5599 31 Mar 11 nicklas 146       }
5599 31 Mar 11 nicklas 147     }
5599 31 Mar 11 nicklas 148     else
5599 31 Mar 11 nicklas 149     {
5599 31 Mar 11 nicklas 150       // Auto-detect factory base on URI
5599 31 Mar 11 nicklas 151       factory = findFactory(uri);
5599 31 Mar 11 nicklas 152       if (factory == null) 
5599 31 Mar 11 nicklas 153       {
5599 31 Mar 11 nicklas 154         throw new ItemNotFoundException("Connection manager factory for URI: " + uri);
5599 31 Mar 11 nicklas 155       }
5599 31 Mar 11 nicklas 156     }
5599 31 Mar 11 nicklas 157     return factory.createConnectionManager(uri, parameters);
5582 15 Mar 11 nicklas 158   }
5582 15 Mar 11 nicklas 159   
5582 15 Mar 11 nicklas 160   /**
5599 31 Mar 11 nicklas 161     Utility method for creating a connection manager for a file item. If a 
5599 31 Mar 11 nicklas 162     specific factory is specified in the connection parameters, that factory is used, 
5599 31 Mar 11 nicklas 163     otherwise auto-detection is used. The auto-detection is similar
5599 31 Mar 11 nicklas 164     to the {@link #findFactory(URI)} method but this time the context
5599 31 Mar 11 nicklas 165     information for the action factory contains the file object and
5599 31 Mar 11 nicklas 166     connection parameters.
5599 31 Mar 11 nicklas 167     
5599 31 Mar 11 nicklas 168     @param file The (external) file (required)
5599 31 Mar 11 nicklas 169     @param parameters Connection parameters, such as user login/password, etc. (optional)
5599 31 Mar 11 nicklas 170     @return A connection manager
5582 15 Mar 11 nicklas 171   */
5599 31 Mar 11 nicklas 172   public static ConnectionManager createConnectionManager(File file, ConnectionParameters parameters)
5582 15 Mar 11 nicklas 173   {
5599 31 Mar 11 nicklas 174     if (file == null) throw new NullPointerException("file");
5599 31 Mar 11 nicklas 175     // Create ClientContext for extension lookup
5599 31 Mar 11 nicklas 176     URI uri = file.getURI();
6520 18 Aug 14 nicklas 177     DbControl dc = file.getDbControl();
5599 31 Mar 11 nicklas 178     ClientContext context = new ClientContext(dc, file);
5599 31 Mar 11 nicklas 179     context.setAttribute("server", parameters);
5599 31 Mar 11 nicklas 180     context.setAttribute("uri", uri);
5599 31 Mar 11 nicklas 181     
5599 31 Mar 11 nicklas 182     // Use a filter if a specific factory should be used
5599 31 Mar 11 nicklas 183     ExtensionsFilter filter = null;
5618 28 Apr 11 nicklas 184     if (parameters != null)
5582 15 Mar 11 nicklas 185     {
5618 28 Apr 11 nicklas 186       uri = parameters.changeHost(uri);
5618 28 Apr 11 nicklas 187       if (parameters.getConnectionManagerFactoryId() != null)
5618 28 Apr 11 nicklas 188       {
5618 28 Apr 11 nicklas 189         filter = new SingleExtensionFilter(parameters.getConnectionManagerFactoryId());
5618 28 Apr 11 nicklas 190       }
5582 15 Mar 11 nicklas 191     }
5599 31 Mar 11 nicklas 192     
5599 31 Mar 11 nicklas 193     // Find extension
5599 31 Mar 11 nicklas 194     ExtensionsInvoker<ConnectionManagerFactory> invoker = getInvoker(context, filter);
5599 31 Mar 11 nicklas 195     ConnectionManagerFactory factory = filter == null ? autoDetect(invoker, uri) : getFirst(invoker);
5599 31 Mar 11 nicklas 196     if (factory == null) 
5599 31 Mar 11 nicklas 197     {
5599 31 Mar 11 nicklas 198       throw new ItemNotFoundException("Connection manager for file: " + uri);
5599 31 Mar 11 nicklas 199     }
5599 31 Mar 11 nicklas 200     return factory.createConnectionManager(uri, parameters);
5582 15 Mar 11 nicklas 201   }
5582 15 Mar 11 nicklas 202   
5582 15 Mar 11 nicklas 203   /**
5599 31 Mar 11 nicklas 204     Get an invoker for using the connection manager factory extensions.
5582 15 Mar 11 nicklas 205   */
5599 31 Mar 11 nicklas 206   private static ExtensionsInvoker<ConnectionManagerFactory> getInvoker(ClientContext context, ExtensionsFilter filter)
5582 15 Mar 11 nicklas 207   {
5606 14 Apr 11 nicklas 208     ExtensionsManager manager = Application.getExtensionsManager();
5606 14 Apr 11 nicklas 209     if (filter == null) filter = manager.getSettings();
5606 14 Apr 11 nicklas 210     Registry registry = manager.getRegistry();
7605 26 Feb 19 nicklas 211     return registry.useExtensions(context, filter, EXTENSION_POINT_ID);
5582 15 Mar 11 nicklas 212   }
5582 15 Mar 11 nicklas 213   
5582 15 Mar 11 nicklas 214   /**
5599 31 Mar 11 nicklas 215     Get the first factory returned by the invoker.
5582 15 Mar 11 nicklas 216   */
5599 31 Mar 11 nicklas 217   private static ConnectionManagerFactory getFirst(ExtensionsInvoker<ConnectionManagerFactory> invoker)
5582 15 Mar 11 nicklas 218   {
5599 31 Mar 11 nicklas 219     ConnectionManagerFactory factory = null;
5599 31 Mar 11 nicklas 220     Iterator<ConnectionManagerFactory> it = invoker.iterator();
5599 31 Mar 11 nicklas 221     if (it.hasNext()) factory = it.next();
5599 31 Mar 11 nicklas 222     return factory;
5582 15 Mar 11 nicklas 223   }
5599 31 Mar 11 nicklas 224
5582 15 Mar 11 nicklas 225   /**
5599 31 Mar 11 nicklas 226     Use auto-detection and return the first factory that can handle the given uri.
5582 15 Mar 11 nicklas 227   */
5599 31 Mar 11 nicklas 228   private static ConnectionManagerFactory autoDetect(ExtensionsInvoker<ConnectionManagerFactory> invoker, URI uri)
5582 15 Mar 11 nicklas 229   {
5599 31 Mar 11 nicklas 230     for (ConnectionManagerFactory factory : invoker)
5582 15 Mar 11 nicklas 231     {
5582 15 Mar 11 nicklas 232       if (factory.useAutoDetection() && factory.supports(uri)) 
5582 15 Mar 11 nicklas 233       {
5582 15 Mar 11 nicklas 234         return factory;
5582 15 Mar 11 nicklas 235       }
5582 15 Mar 11 nicklas 236     }
5582 15 Mar 11 nicklas 237     return null;
5582 15 Mar 11 nicklas 238   }
5599 31 Mar 11 nicklas 239
5582 15 Mar 11 nicklas 240 }