Changeset 5599


Ignore:
Timestamp:
Mar 31, 2011, 1:38:56 PM (10 years ago)
Author:
Nicklas Nordborg
Message:

References #1582: Extended support for external files

Defined an extension point for external file support ('net.sf.basedb.core.uri.connection-manager').

Added possibility to set a specific connection manager factory on a FileServer. If not set automatic detection is used as before.

Location:
trunk
Files:
3 added
18 edited
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/src/clients/web/net/sf/basedb/clients/web/extensions/ExtensionsControl.java

    r5490 r5599  
    2525import java.util.EnumSet;
    2626import java.util.Iterator;
     27import java.util.List;
    2728import java.util.Set;
    2829import java.util.TimerTask;
     
    493494    @see Registry#getExtensionPoints()
    494495  */
    495   public Iterator<ExtensionPoint<?>> getExtensionPoints()
     496  public List<ExtensionPoint<?>> getExtensionPoints()
    496497  {
    497498    return registry.getExtensionPoints();
     
    558559    @see Registry#getExtensions()
    559560  */
    560   public Iterator<Extension<?>> getExtensions()
     561  public List<Extension<?>> getExtensions()
    561562  {
    562563    return registry.getExtensions();
     
    569570    @see Registry#getExtensions(String)
    570571  */
    571   public Iterator<Extension<?>> getExtensions(String id)
     572  public List<Extension<?>> getExtensions(String id)
    572573  {
    573574    return registry.getExtensions(id);
  • trunk/src/core/core-extensions.xml

    r5598 r5599  
    3333    </description>
    3434  </about>
     35 
     36  <extension-point
     37    id="net.sf.basedb.core.uri.connection-manager"
     38    >
     39    <action-class>net.sf.basedb.util.uri.ConnectionManagerFactory</action-class>
     40    <name>Connection manager</name>
     41    <description>
     42      Extension point for external file support. A connection manager is
     43      something that knows how to access an external file pointed to by an
     44      URI. Actions are ConnectionManagerFactory instances and are typically
     45      used in two ways.
     46      1) In a single-file context when getting metadata or the contents of
     47      a single File item. The ClientContext object is populated with an active
     48      DbControl and the current item is the file.
     49      2) A standalone context with the external reference as an URI. No
     50      DbControl is used and no current item.
     51      Extensions to this extension point must not return more than one
     52      factory since we need to associate each factory with the id
     53      of the extension.
     54    </description>
     55  </extension-point>
     56 
     57  <extension
     58    id="net.sf.basedb.core.uri.http-connection-manager"
     59    extends="net.sf.basedb.core.uri.connection-manager"
     60    >
     61    <about>
     62      <name>HTTP(s) connection manager</name>
     63      <description>
     64        Provides support for regular HTTP and HTTPS including Basic
     65        and Digest authentication as well as server- and client-side
     66        certificates. Auto-detection matches all URI:s with 'http'
     67        or 'https' scheme.
     68      </description>
     69    </about>
     70    <action-factory>
     71      <factory-class>net.sf.basedb.util.uri.http.HttpConnectionManagerActionFactory</factory-class>
     72    </action-factory>
     73 
     74  </extension>
    3575
    3676</extensions>
  • trunk/src/core/net/sf/basedb/core/Application.java

    r5598 r5599  
    4141import net.sf.basedb.util.extensions.xml.XmlLoader;
    4242import net.sf.basedb.util.timer.Scheduler;
    43 import net.sf.basedb.util.uri.ConnectionManagerRegistry;
    4443
    4544import java.util.ArrayList;
     
    6362import java.sql.SQLException;
    6463
    65 import org.jdom.Element;
    66 
    6764
    6865/**
     
    201198  */
    202199  private static LogManagerFactory logManagerFactory;
    203  
    204   /**
    205     The URI handler registry that is currently in use.
    206   */
    207   private static ConnectionManagerRegistry connectionManagerRegistry;
    208200 
    209201  /**
     
    564556          logManagerFactory = (LogManagerFactory)factoryClass.newInstance();
    565557        }
    566        
    567         connectionManagerRegistry = new ConnectionManagerRegistry();
    568         ConnectionManagerRegistry.registerDefaultUriHandlers(connectionManagerRegistry);
    569         // TODO - load more handlers as configured in .... (base.config?)
    570         connectionManagerRegistry.lock();
    571        
     558             
    572559        // Adding a task that cleans the session control cache at regular intervals
    573560        long milliSeconds = 60000L * sessionCacheTimeout;  // minutes --> milliseconds
     
    689676    cleanSessionControlCache(true);
    690677    sessionCache = null;
    691     connectionManagerRegistry = null;
    692678   
    693679    Keyring.unload();
     
    755741  }
    756742 
    757   /**
    758     Get the (read-only) connection manager registry that contains factories
    759     for accessing file on external locations.
    760     @since 3.0
    761   */
    762   public static ConnectionManagerRegistry getConnectionManagerRegistry()
    763   {
    764     return connectionManagerRegistry;
     743 
     744  public static ExtensionsManager getExtensionsManager()
     745  {
     746    return xtManager;
    765747  }
    766748 
  • trunk/src/core/net/sf/basedb/core/File.java

    r5582 r5599  
    3636import net.sf.basedb.util.uri.ConnectionParameters;
    3737import net.sf.basedb.util.uri.ConnectionManager;
    38 import net.sf.basedb.util.uri.ConnectionManagerFactory;
    39 import net.sf.basedb.util.uri.ConnectionManagerRegistry;
     38import net.sf.basedb.util.uri.ConnectionManagerUtil;
    4039import net.sf.basedb.util.uri.UriMetadata;
    4140
     
    896895    Set the URL to an external file that should represent this file
    897896    object. NOTE! The location, size, md5, internal file, etc. will be reset
    898     as a result of this call.
     897    as a result of this call. NOTE 2! If the file server is also updated
     898    at the same time it is important that the file server has been changed
     899    before setting the URL, otherwise the old file server is used.
     900   
    899901    @param url The url to the file (null is not allowed)
    900902    @param loadMetadata If TRUE, a HEAD request will be issued to the given
     
    916918    // Validate the URL
    917919    URI uri = null;
    918     ConnectionManagerRegistry registry = Application.getConnectionManagerRegistry();
    919     ConnectionManagerFactory factory = null;
    920920    try
    921921    {
    922922      uri = new URI(url);
    923       factory = registry.findFactory(uri);
    924       if (factory == null)
    925       {
    926         throw new InvalidDataException("Can't find any connection manager for URL: " + url);
    927       }
    928923    }
    929924    catch (URISyntaxException ex)
     
    945940    {
    946941      ConnectionParameters server = getServerInfo();
    947       ConnectionManager manager = factory.createConnectionManager(uri, server);
     942      ConnectionManager manager = ConnectionManagerUtil.createConnectionManager(this, server);
    948943      try
    949944      {
     
    13491344      if (location == Location.EXTERNAL)
    13501345      {
    1351         URI uri = getURI();
    13521346        ConnectionParameters server = getServerInfo();
    1353         ConnectionManagerRegistry registry = Application.getConnectionManagerRegistry();
    1354         ConnectionManager manager = registry.createConnectionManager(uri, server);
     1347        ConnectionManager manager = ConnectionManagerUtil.createConnectionManager(this, server);
    13551348        download = manager.getInputStream();
    13561349        setMetadataFromURI(manager.getMetadata());
  • trunk/src/core/net/sf/basedb/core/FileServer.java

    r5362 r5599  
    162162 
    163163  /**
     164    The maximum length of the connection manager factory id that can be stored in
     165    the database.
     166    @see #setConnectionManagerFactoryId(String)
     167  */
     168  public static final int MAX_CONNECTION_MANAGER_FACTORY_LENGTH = FileServerData.MAX_CONNECTION_MANAGER_FACTORY_LENGTH;
     169 
     170  /**
     171    Get the ID of the connection manager factory that should be
     172    used to access file contents and metadata. A null value mean
     173    that auto-detection based on the file URI should be used.
     174    @return An ID or null if using auto-detection
     175  */
     176  public String getConnectionManagerFactoryId()
     177  {
     178    return getData().getConnectionManagerFactory();
     179  }
     180 
     181  /**
     182    Set the ID of the connection manager factory.
     183     
     184    @param factoryId The new ID of the factory, null if using auto-detection
     185    @throws PermissionDeniedException If the logged in user doesn't have
     186      write permission
     187    @throws InvalidDataException If the ID is longer than {@link #MAX_CONNECTION_MANAGER_FACTORY_LENGTH}
     188  */
     189  public void setConnectionManagerFactoryId(String factoryId)
     190    throws PermissionDeniedException, InvalidDataException
     191  {
     192    checkPermission(Permission.WRITE);
     193    getData().setConnectionManagerFactory(
     194        StringUtil.setNullableString(factoryId, "factoryId", MAX_CONNECTION_MANAGER_FACTORY_LENGTH));
     195  }
     196 
     197  /**
    164198    The maximum length of the username that can be stored in the database.
    165199    @see #setUsername(String)
  • trunk/src/core/net/sf/basedb/core/data/FileServerData.java

    r5362 r5599  
    4040  public FileServerData()
    4141  {}
     42 
     43  public static final int MAX_CONNECTION_MANAGER_FACTORY_LENGTH = 255;
     44  private String connectionManagerFactory;
     45  /**
     46    Get the ID of the connection manager factory that should be
     47    used to retreieve the file contents and metadata. If null
     48    auto-detection is used to find a suitable connection manager
     49    factory.
     50    @since 3.0
     51    @hibernate.property column="`cm_factory`" type="string" length="255" not-null="false"
     52  */
     53  public String getConnectionManagerFactory()
     54  {
     55    return connectionManagerFactory;
     56  }
     57  public void setConnectionManagerFactory(String connectionManagerFactory)
     58  {
     59    this.connectionManagerFactory = connectionManagerFactory;
     60  }
    4261 
    4362  public static final int MAX_USERNAME_LENGTH = 255;
  • trunk/src/core/net/sf/basedb/util/extensions/ClientContext.java

    r4515 r5599  
    7373 
    7474  /**
     75    Create a new context with no session or current item.
     76    @since 3.0
     77  */
     78  public ClientContext()
     79  {
     80    this(null, null, null);
     81  }
     82 
     83  /**
    7584    Create a new context with a session and no DbControl. The session
    7685    is final and can't be replaced.
  • trunk/src/core/net/sf/basedb/util/extensions/Registry.java

    r5487 r5599  
    2727import java.util.Comparator;
    2828import java.util.HashMap;
    29 import java.util.Iterator;
    3029import java.util.LinkedList;
    3130import java.util.List;
     
    305304 
    306305  /**
    307     Get an iterator returning all registered extension points.
    308     The returned iterator doesn't support removal and will not reflect
    309     changes made to the registry by the same or other threads after this
    310     call has returned.
    311    
    312     @return An iterator object
    313   */
    314   public synchronized Iterator<ExtensionPoint<?>> getExtensionPoints()
    315   {
    316     // Create a copy, or the iterator will fail if new
    317     // extension points are registered by another thread
     306    Get a list with all registered extension points.
     307    The returned list is a copy of the registered extension points
     308    at the time of this call and will not reflect changes
     309    made to the registry after this call has returned.
     310   
     311    @return A list
     312    @since 3.0 (Returned an Iterator in BASE 2.x)
     313  */
     314  public synchronized List<ExtensionPoint<?>> getExtensionPoints()
     315  {
    318316    List<ExtensionPoint<?>> copy =
    319317      new ArrayList<ExtensionPoint<?>>(extensionPoints.values());
    320318    Collections.sort(copy, EXTENSIONPOINT_COMPARATOR);
    321     return Collections.unmodifiableList(copy).iterator();
     319    return copy;
    322320  }
    323321 
     
    454452 
    455453  /**
    456     Get an iterator returning all registered extensions.
    457     The returned iterator doesn't support removal and will not reflect
    458     changes made to the registry by the same or other threads after this
    459     call has returned.
    460     @return An iterator object
    461   */
    462   public synchronized Iterator<Extension<?>> getExtensions()
    463   {
    464     // Create a copy, or the iterator will fail if new
    465     // extension points are registered by another thread
     454    Get a list with all registered extensions.
     455    The returned list is a copy of the registered extensions
     456    at the time of this call and will not reflect changes
     457    made to the registry after this call has returned.
     458
     459    @return A list
     460    @since 3.0 (Returned an Iterator in BASE 2.x)
     461  */
     462  public synchronized List<Extension<?>> getExtensions()
     463  {
    466464    List<Extension<?>> copy =
    467465      new ArrayList<Extension<?>>(extensions.values());
    468     return Collections.unmodifiableList(copy).iterator();
    469   }
    470  
    471   /**
    472     Get an iterator returning all registered extensions
     466    return copy;
     467  }
     468 
     469  /**
     470    Get a list with all registered extensions
    473471    for a given extension point. If the extension point is not found
    474     an empty iterator is returned. The returned iterator doesn't
    475     support removal and will not reflect changes made to the registry
    476     by the same or other threads after this call has returned.
     472    an empty list is returned.
     473    The returned list is a copy of the registered extension points
     474    at the time of this call and will not reflect changes
     475    made to the registry after this call has returned.
    477476   
    478477    @param id The ID of the extension point
    479     @return An iterator object
    480   */
    481   public synchronized Iterator<Extension<?>> getExtensions(String id)
     478    @return A list
     479    @since 3.0 (Returned an Iterator in BASE 2.x)
     480  */
     481  public synchronized List<Extension<?>> getExtensions(String id)
    482482  {
    483483    RegisteredExtensionPoint<?> rep = extensionPoints.get(id);
    484484    if (rep == null)
    485485    {
    486       List<Extension<?>> empty = Collections.emptyList();
    487       return empty.iterator();
     486      return Collections.emptyList();
    488487    }
    489488    else
     
    494493        new ArrayList<Extension<?>>(rep.getExtensions());
    495494      Collections.sort(copy, DefaultFilter.INDEX_COMPARATOR_EXT);
    496       return Collections.unmodifiableList(copy).iterator();
     495      return copy;
    497496    }
    498497  }
  • trunk/src/core/net/sf/basedb/util/uri/ConnectionManagerFactory.java

    r5582 r5599  
    2424import java.net.URI;
    2525
     26import net.sf.basedb.util.extensions.Action;
     27
    2628/**
    2729  A connection manager factory is responsible for creating connection
     
    3537*/
    3638public interface ConnectionManagerFactory
     39  extends Action
    3740{
    3841
    3942  /**
    40     Get the ID of this connection manager factory. If the factory is
    41     registered in a {@link ConnectionManagerRegistry} the ID must
    42     be a unique string. The recommended approach is to use the class
    43     name as a base for the ID.
     43    Get the ID of this connection manager factory. This should be
     44    a unique string matching the id of extension that has been
     45    registered with BASE.
    4446  */
    4547  public String getId();
     
    5153  */
    5254  public String getDisplayName();
    53 
     55 
    5456  /**
    5557    Get a longer description that can be used by client applications to
     
    5961  */
    6062  public String getDescription();
    61  
     63
    6264  /**
    6365    Does this factory support auto-detection if an URI is
  • trunk/src/core/net/sf/basedb/util/uri/ConnectionManagerUtil.java

    r5597 r5599  
    2323
    2424import java.net.URI;
    25 import java.util.ArrayList;
    26 import java.util.LinkedHashMap;
     25import java.util.Iterator;
    2726import java.util.List;
    28 import java.util.Map;
    29 
    30 import net.sf.basedb.core.ItemAlreadyExistsException;
     27
     28import org.apache.commons.collections.IteratorUtils;
     29
     30import net.sf.basedb.core.Application;
     31import net.sf.basedb.core.DbControl;
     32import net.sf.basedb.core.File;
    3133import net.sf.basedb.core.ItemNotFoundException;
    32 import net.sf.basedb.core.PermissionDeniedException;
    33 import net.sf.basedb.util.uri.http.HttpConnectionManagerFactory;
     34import net.sf.basedb.util.extensions.ClientContext;
     35import net.sf.basedb.util.extensions.ExtensionsFilter;
     36import net.sf.basedb.util.extensions.ExtensionsInvoker;
     37import net.sf.basedb.util.extensions.Registry;
     38import net.sf.basedb.util.extensions.SingleExtensionFilter;
    3439
    3540/**
    36   Registry for keeping track of connection manager factories. An
    37   application can call {@link #findFactory(URI)} to find
    38   a suitable factory for a given URI.
     41  Collects utility methods related to connection managers.
     42  Connection manager factories should be registered as
     43  extensions to the {@link #EXTENSION_POINT_ID net.sf.basedb.core.uri.connection-manager}
     44  extension point. The methods in this class can then be used to
     45  get information about installed connection manager factories and
     46  to use them for retreiving external file data and information.
    3947
    4048  @author Nicklas
     
    4250  @base.modified $Date$
    4351*/
    44 public class ConnectionManagerRegistry
     52public class ConnectionManagerUtil
    4553{
    4654 
    4755  /**
    48     Register the default connection manager factory implementations. Currently
    49     this is {@link HttpConnectionManagerFactory} and
    50     {@link HdfsConnectionManagerFactory}.
    51   */
    52   public static void registerDefaultUriHandlers(ConnectionManagerRegistry registry)
    53   {
    54     registry.registerFactory(new HttpConnectionManagerFactory());
    55     //registry.registerFactory(new HdfsConnectionManagerFactory());
    56   }
    57  
    58   private final Map<String, ConnectionManagerFactory> factories;
    59   private boolean locked;
    60  
    61   /**
    62     Create a new unlocked registry.
    63   */
    64   public ConnectionManagerRegistry()
    65   {
    66     this.factories = new LinkedHashMap<String, ConnectionManagerFactory>();
    67   }
    68  
    69   /**
    70     Lock the registry for further modifications. Once this method has been
    71     called it is not possible to add or remove factories from the
    72     registry. It is not possible to unlock a locked registry.
    73   */
    74   public void lock()
    75   {
    76     this.locked = true;
    77   }
    78  
    79   /**
    80     Check if this registry is locked.
    81   */
    82   public boolean isLocked()
    83   {
    84     return locked;
    85   }
    86  
    87   /**
    88     Register the given connection manager factory in this registry.
    89     It is not allowed to register factories to a locked registry.
    90     @param factory The factory to register (null is not allowed)
    91   */
    92   public void registerFactory(ConnectionManagerFactory factory)
    93   {
    94     if (locked) throw new PermissionDeniedException("This URI handler registry is locked");
    95     if (factory == null) throw new NullPointerException("factory");
    96     String id = factory.getId();
    97     if (factories.containsKey(id))
    98     {
    99       throw new ItemAlreadyExistsException("Another factory with id '" + id + "' is already registered.");
    100     }
    101     factories.put(id, factory);
    102   }
    103  
    104   /**
    105     Get a list with all factories that have been registered
    106     with this registry.
     56    The ID of the connection manager extension point.
     57  */
     58  public static final String EXTENSION_POINT_ID = "net.sf.basedb.core.uri.connection-manager";
     59 
     60  /**
     61    Get a list with all connection manager factories. No context
     62    information will be available to the action factories that
     63    creates the connection manager factories.
     64   
    10765    @return A list with the factories
    10866  */
    109   public List<ConnectionManagerFactory> listFactories()
    110   {
    111     return new ArrayList<ConnectionManagerFactory>(factories.values());
    112   }
    113  
    114   /**
    115     Get the factory with the given id.
     67  @SuppressWarnings("unchecked")
     68  public static List<ConnectionManagerFactory> getFactories()
     69  {
     70    ExtensionsInvoker<ConnectionManagerFactory> invoker = getInvoker(null, null);
     71    List list = IteratorUtils.toList(invoker.iterator(), Math.max(invoker.getNumExtensions(), 1));
     72    return list;
     73  }
     74 
     75  /**
     76    Get the connection manager factory with the given extension id.
     77    No context information will be available to the factory
     78    when it is created.
     79   
    11680    @param id The ID of the factory
    11781    @return A factory instance or null if not found
    11882  */
    119   public ConnectionManagerFactory getFactory(String id)
    120   {
    121     return factories.get(id);
    122   }
    123  
     83  public static ConnectionManagerFactory getFactory(String id)
     84  {
     85    if (id == null) return null;
     86    ExtensionsInvoker<ConnectionManagerFactory> invoker = getInvoker(null, new SingleExtensionFilter(id));
     87    ConnectionManagerFactory factory = getFirst(invoker);
     88    return factory;
     89  }
     90   
    12491  /**
    12592    Find a factory for the given URI. This method will iterate
    126     the registered factories in the order they
    127     were registered and call {@link ConnectionManagerFactory#supports(URI)}
     93    the registered factories in their priority/index order and
     94    call {@link ConnectionManagerFactory#supports(URI)}
    12895    for all factories that supports auto-detection. The first
    12996    one that gives a successful response is returned. If no factory
    13097    supports the given URI, null is returned.
    13198   
     99    <p>
     100    Note to extension developers: The given uri is available
     101    to the action factory as "uri" attribute of the context.
     102   
    132103    @param uri The URI (null is not allowed)
    133104    @return An UriHandlerFactory or null if no factory was found
    134105  */
    135   public ConnectionManagerFactory findFactory(URI uri)
     106  public static ConnectionManagerFactory findFactory(URI uri)
    136107  {
    137108    if (uri == null) throw new NullPointerException("uri");
    138     for (ConnectionManagerFactory factory : factories.values())
     109   
     110    ClientContext context = new ClientContext();
     111    context.setAttribute("uri", uri);
     112   
     113    ExtensionsInvoker<ConnectionManagerFactory> invoker = getInvoker(context, null);
     114    ConnectionManagerFactory factory = autoDetect(invoker, uri);
     115    return factory;
     116  }
     117 
     118  /**
     119    Utility method for creating a connection manager. If a specific factory
     120    is specified in the connection parameters, that factory is used, otherwise
     121    {@link #findFactory(URI)} is used for auto-detection. If no factory is found
     122    an exception is thrown, otherwise a connection manger is created by the
     123    factory method:
     124    {@link ConnectionManagerFactory#createConnectionManager(URI, ConnectionParameters)}
     125   
     126    @param uri The URI (required)
     127    @param parameters Connection parameters, such as user login/password, etc. (optional)
     128    @return A connection manager
     129  */
     130  public static ConnectionManager createConnectionManager(URI uri, ConnectionParameters parameters)
     131  {
     132    if (uri == null) throw new NullPointerException("uri");
     133    ConnectionManagerFactory factory = null;
     134    if (parameters != null && parameters.getConnectionManagerFactoryId() != null)
     135    {
     136      // Use specific factory
     137      String factoryId = parameters.getConnectionManagerFactoryId();
     138      factory = getFactory(factoryId);
     139      if (factory == null)
     140      {
     141        throw new ItemNotFoundException("Connection manager factory: " + factoryId);
     142      }
     143    }
     144    else
     145    {
     146      // Auto-detect factory base on URI
     147      factory = findFactory(uri);
     148      if (factory == null)
     149      {
     150        throw new ItemNotFoundException("Connection manager factory for URI: " + uri);
     151      }
     152    }
     153    return factory.createConnectionManager(uri, parameters);
     154  }
     155 
     156  /**
     157    Utility method for creating a connection manager for a file item. If a
     158    specific factory is specified in the connection parameters, that factory is used,
     159    otherwise auto-detection is used. The auto-detection is similar
     160    to the {@link #findFactory(URI)} method but this time the context
     161    information for the action factory contains the file object and
     162    connection parameters.
     163   
     164    @param file The (external) file (required)
     165    @param parameters Connection parameters, such as user login/password, etc. (optional)
     166    @return A connection manager
     167  */
     168  public static ConnectionManager createConnectionManager(File file, ConnectionParameters parameters)
     169  {
     170    if (file == null) throw new NullPointerException("file");
     171    // Create ClientContext for extension lookup
     172    URI uri = file.getURI();
     173    DbControl dc = null;
     174    if (!file.isDetached()) dc = file.getDbControl();
     175    ClientContext context = new ClientContext(dc, file);
     176    context.setAttribute("server", parameters);
     177    context.setAttribute("uri", uri);
     178   
     179    // Use a filter if a specific factory should be used
     180    ExtensionsFilter filter = null;
     181    if (parameters != null && parameters.getConnectionManagerFactoryId() != null)
     182    {
     183      filter = new SingleExtensionFilter(parameters.getConnectionManagerFactoryId());
     184    }
     185   
     186    // Find extension
     187    ExtensionsInvoker<ConnectionManagerFactory> invoker = getInvoker(context, filter);
     188    ConnectionManagerFactory factory = filter == null ? autoDetect(invoker, uri) : getFirst(invoker);
     189    if (factory == null)
     190    {
     191      throw new ItemNotFoundException("Connection manager for file: " + uri);
     192    }
     193    return factory.createConnectionManager(uri, parameters);
     194  }
     195 
     196  /**
     197    Get an invoker for using the connection manager factory extensions.
     198  */
     199  @SuppressWarnings("unchecked")
     200  private static ExtensionsInvoker<ConnectionManagerFactory> getInvoker(ClientContext context, ExtensionsFilter filter)
     201  {
     202    Registry registry = Application.getExtensionsManager().getRegistry();
     203    return (ExtensionsInvoker<ConnectionManagerFactory>)registry.useExtensions(context, filter, EXTENSION_POINT_ID);
     204  }
     205 
     206  /**
     207    Get the first factory returned by the invoker.
     208  */
     209  private static ConnectionManagerFactory getFirst(ExtensionsInvoker<ConnectionManagerFactory> invoker)
     210  {
     211    ConnectionManagerFactory factory = null;
     212    Iterator<ConnectionManagerFactory> it = invoker.iterator();
     213    if (it.hasNext()) factory = it.next();
     214    return factory;
     215  }
     216
     217  /**
     218    Use auto-detection and return the first factory that can handle the given uri.
     219  */
     220  private static ConnectionManagerFactory autoDetect(ExtensionsInvoker<ConnectionManagerFactory> invoker, URI uri)
     221  {
     222    for (ConnectionManagerFactory factory : invoker)
    139223    {
    140224      if (factory.useAutoDetection() && factory.supports(uri))
     
    145229    return null;
    146230  }
    147  
    148   /**
    149     Utility method for creating a connection manager. This first calls
    150     {@link #findFactory(URI)} and then, if one was found,
    151     {@link ConnectionManagerFactory#createConnectionManager(URI, ConnectionParameters)}.
    152     If no connection manager can be created, an exception is thrown.
    153    
    154     @param uri The URI (required)
    155     @param parameters Connection parameters, such as user login/password, etc. (optional)
    156     @return A connection manager
    157   */
    158   public ConnectionManager createConnectionManager(URI uri, ConnectionParameters parameters)
    159   {
    160     ConnectionManagerFactory factory = findFactory(uri);
    161     if (factory == null)
    162     {
    163       throw new ItemNotFoundException("Can't find connection manager for URI: " + uri);
    164     }
    165     return factory.createConnectionManager(uri, parameters);
    166   }
    167  
     231
    168232}
  • trunk/src/core/net/sf/basedb/util/uri/ConnectionParameters.java

    r5582 r5599  
    4545   
    4646    ConnectionParameters parameters = new ConnectionParameters();
     47    parameters.setConnectionManagerFactoryId(fileServer.getConnectionManagerFactory());
    4748    parameters.setUsername(fileServer.getUsername());
    4849    parameters.setPassword(fileServer.getPassword());
     
    5354  }
    5455 
     56  private String factoryId;
    5557  private String username;
    5658  private String password;
     
    6466  public ConnectionParameters()
    6567  {}
     68 
     69  /**
     70    Get the connection manager factory that we should use to
     71    access the file, or null to use auto-detection.
     72  */
     73  public String getConnectionManagerFactoryId()
     74  {
     75    return factoryId;
     76  }
     77  public void setConnectionManagerFactoryId(String factoryId)
     78  {
     79    this.factoryId = factoryId;
     80  }
    6681 
    6782  /**
  • trunk/src/core/net/sf/basedb/util/uri/http/HttpConnectionManagerFactory.java

    r5582 r5599  
    2929
    3030/**
    31   Connection manager factory for HTTP and HTTPS URI:s.
     31  Connection manager factory for HTTP and HTTPS URI:s. Auto-detection
     32  is supported for "http" and "https" URI:s.
    3233 
    3334  @author Nicklas
     
    4041{
    4142
     43  private String id;
     44  private String name;
     45  private String description;
    4246 
     47  /**
     48    Create a new http connection manager factory.
     49  */
    4350  public HttpConnectionManagerFactory()
    4451  {}
     
    5158  public String getId()
    5259  {
    53     return this.getClass().getName();
     60    return id;
    5461  }
    5562
     
    5764  public String getDisplayName()
    5865  {
    59     return "Generic HTTP/HTTPS connection manager";
     66    return name;
    6067  }
    6168
     
    6370  public String getDescription()
    6471  {
    65     return "Provides support for regular HTTP and HTTPS including Basic and " +
    66         "Digest authentication as well as server- and client-side certificates. " +
    67         "Auto-detection matches all URI:s with http or https scheme.";
     72    return description;
    6873  }
    69 
     74 
    7075  @Override
    7176  public boolean useAutoDetection()
     
    8994  // --------------------------------------------
    9095
     96  /**
     97    Initialize this factory with some information.
     98  */
     99  public void init(String id, String name, String description)
     100  {
     101    this.id = id;
     102    this.name = name;
     103    this.description = description;
     104  }
     105 
    91106}
  • trunk/www/admin/extensions/tree.jsp

    r5519 r5599  
    134134    <%
    135135    ExtensionsControl ec = ExtensionsControl.get(dc);
    136     Iterator<ExtensionPoint<?>> extensionPoints = ec.getExtensionPoints();
    137     while (extensionPoints.hasNext())
    138     {
    139       ExtensionPoint ep = extensionPoints.next();
     136    List<ExtensionPoint<?>> extensionPoints = ec.getExtensionPoints();
     137    for (ExtensionPoint ep : extensionPoints)
     138    {
    140139      String id = ep.getId();
    141140      String parent = "byExtPoint";
     
    146145      <%=getJoustExtensionPoint(parent, ec, ep)%>
    147146      <%
    148       Iterator<Extension<?>> extensions = ec.getExtensions(ep.getId());
    149       while (extensions.hasNext())
    150       {
    151         Extension ext = extensions.next();
     147      List<Extension<?>> extensions = ec.getExtensions(ep.getId());
     148      for (Extension ext : extensions)
     149      {
    152150        %>
    153151        <%=getJoustExtension("ep", ec, ext, false)%>
  • trunk/www/filemanager/files/index.jsp

    r5590 r5599  
    208208      {
    209209        boolean loadMetadata = Values.getBoolean(request.getParameter("loadMetadata"));
    210         file.setUrl(Values.getStringOrNull(request.getParameter("url")), loadMetadata);
    211210        int serverId = Values.getInt(request.getParameter("server_id"), -1);
    212211        if (serverId >= 0) // < 0 = denied or unchanged
     
    216215          if (server != null) cc.setRecent(server, maxRecent);
    217216        }
     217        file.setUrl(Values.getStringOrNull(request.getParameter("url")), loadMetadata);
    218218      }
    219219     
  • trunk/www/filemanager/fileservers/edit_fileserver.jsp

    r5501 r5599  
    3131  import="net.sf.basedb.clients.web.util.HTML"
    3232  import="net.sf.basedb.util.Values"
     33  import="net.sf.basedb.util.uri.ConnectionManagerUtil"
     34  import="net.sf.basedb.util.uri.ConnectionManagerFactory"
    3335  import="net.sf.basedb.core.plugin.GuiContext"
    3436  import="net.sf.basedb.clients.web.extensions.ExtensionsControl"
     
    3638  import="net.sf.basedb.clients.web.extensions.edit.EditUtil"
    3739  import="net.sf.basedb.util.extensions.ExtensionsInvoker"
     40  import="java.util.List"
    3841%>
    3942<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
     
    6972  JspContext jspContext = ExtensionsControl.createContext(dc, pageContext, GuiContext.item(itemType), server);
    7073  ExtensionsInvoker invoker = EditUtil.useEditExtensions(jspContext);
     74  List<ConnectionManagerFactory> cmFactories = ConnectionManagerUtil.getFactories();
    7175  %>
    7276  <base:page type="popup" title="<%=title%>">
     
    115119      }
    116120      %>
    117     }
     121      connectionManagerOnChange();
     122    }
     123   
     124    var currentCMF;
     125    function connectionManagerOnChange()
     126    {
     127      var frm = document.forms['server'];
     128      if (currentCMF) Main.hide(currentCMF);
     129     
     130      var cmfId = frm.connectionManager[frm.connectionManager.selectedIndex].value;
     131      if (!cmfId) cmfId = 'auto';
     132      currentCMF = 'cmf.' + cmfId + '.description';
     133      Main.show(currentCMF);
     134    }
     135
     136   
    118137    function removeServerCertificateOnClick()
    119138    {
     
    161180          value="<%=HTML.encodeTags(server == null ? Values.getString(cc.getPropertyValue("name"), "New file server") : server.getName())%>"
    162181          size="40" maxlength="<%=FileServer.MAX_NAME_LENGTH%>"></td>
     182      </tr>
     183      <tr>
     184        <td class="prompt">Connection manager</td>
     185        <td>
     186          <select name="connectionManager" onchange="connectionManagerOnChange()">
     187          <option value="">- auto -
     188          <%
     189          String currentFactoryId = server == null ? cc.getPropertyValue("connectionManagerFactory") : server.getConnectionManagerFactoryId();
     190          for (ConnectionManagerFactory cmf : cmFactories)
     191          {
     192            String cmfId = cmf.getId();
     193            String selected = cmfId.equals(currentFactoryId) ? "selected" : "";
     194            %>
     195            <option value="<%=cmf.getId()%>" <%=selected%>><%=HTML.encodeTags(cmf.getDisplayName())%><%=cmf.useAutoDetection() ? " (•)" : "" %>
     196            <%
     197          }
     198          %>
     199          </select>
     200          • = Supports auto-detection
     201        </td>
     202      </tr>
     203      <tr>
     204        <td></td>
     205        <td>
     206          <div class="helpmessage" style="margin: 0px 10px 8px 0px; height: <%=(int)(scale*50)%>px; overflow: auto;">
     207          <div id="cmf.auto.description" style="display: none;">
     208            Automatically select a connection manager among those
     209            that supports auto-detection.
     210          </div>
     211          <%
     212          for (ConnectionManagerFactory cmf : cmFactories)
     213          {
     214            String cmfId = cmf.getId();
     215            %>
     216            <div id="cmf.<%=cmfId%>.description" style="display: none;">
     217              <%=HTML.encodeTags(cmf.getDescription())%>
     218            </div>
     219            <%
     220          }
     221          %>
     222          </div>
     223        </td>
    163224      </tr>
    164225      <tr>
  • trunk/www/filemanager/fileservers/index.jsp

    r5590 r5599  
    1 
    2 <%@page import="java.io.ByteArrayOutputStream"%><%-- $Id $
     1<%-- $Id $
    32  ------------------------------------------------------------------
    43  Copyright (C) 2010 Nicklas Nordborg
     
    5150  import="net.sf.basedb.clients.web.extensions.edit.EditUtil"
    5251  import="net.sf.basedb.clients.web.extensions.edit.OnSaveRenderer"
     52  import="java.io.ByteArrayOutputStream"
    5353  import="java.util.Enumeration"
    5454  import="java.util.Set"
     
    173173      server.setName(Values.getStringOrNull(upload.getParameter("name")));
    174174      server.setDescription(Values.getStringOrNull(upload.getParameter("description")));
     175      server.setConnectionManagerFactoryId(Values.getStringOrNull(upload.getParameter("connectionManager")));
    175176      server.setUsername(Values.getStringOrNull(upload.getParameter("username")));
    176177      String password = Values.getStringOrNull(upload.getParameter("password"));
  • trunk/www/filemanager/fileservers/list_fileservers.jsp

    r5590 r5599  
    4141  import="net.sf.basedb.util.ShareableUtil"
    4242  import="net.sf.basedb.util.Values"
     43  import="net.sf.basedb.util.Enumeration"
    4344  import="net.sf.basedb.util.formatter.Formatter"
    4445  import="net.sf.basedb.clients.web.formatter.FormatterFactory"
     
    4849  import="net.sf.basedb.clients.web.extensions.toolbar.ToolbarUtil"
    4950  import="net.sf.basedb.util.extensions.ExtensionsInvoker"
     51  import="net.sf.basedb.util.extensions.ExtensionsUtil"
     52  import="net.sf.basedb.util.uri.ConnectionManagerUtil"
     53  import="net.sf.basedb.util.uri.ConnectionManagerFactory"
    5054  import="java.util.Date"
    5155  import="java.util.Iterator"
     
    230234        filterable="true"
    231235        exportable="true"
     236      />
     237      <%
     238      Enumeration<String, String> cm = new Enumeration<String, String>();
     239      cm.add("", "- auto -");
     240      for (ConnectionManagerFactory cmf : ConnectionManagerUtil.getFactories())
     241      {
     242        cm.add(cmf.getId(), cmf.getDisplayName());
     243      }
     244      %>
     245      <tbl:columndef
     246        id="connectionManager"
     247        property="connectionManagerFactory"
     248        datatype="string"
     249        title="Connection manager"
     250        sortable="true"
     251        filterable="true"
     252        exportable="true"
     253        enumeration="<%=cm%>"
    232254      />
    233255      <tbl:columndef
     
    383405              index++;
    384406              numListed++;
     407              ConnectionManagerFactory cmf = ConnectionManagerUtil.getFactory(item.getConnectionManagerFactoryId());
    385408              %>
    386409              <tbl:row>
     
    433456                    enablePropertyLink="<%=mode.hasPropertyLink()%>"
    434457                  /></tbl:cell>
     458                <tbl:cell column="connectionManager"><%=cmf == null ? "<i>- auto -</i>" : HTML.encodeTags(cmf.getDisplayName())%></tbl:cell>
    435459                <tbl:cell column="username"><%=HTML.encodeTags(item.getUsername())%></tbl:cell>
    436460                <tbl:cell column="description"><%=HTML.encodeTags(item.getDescription())%></tbl:cell>
  • trunk/www/filemanager/fileservers/view_fileserver.jsp

    r5502 r5599  
    2020  ------------------------------------------------------------------
    2121--%>
     22<%@page import="net.sf.basedb.util.uri.ConnectionManagerFactory"%>
    2223<%@ page pageEncoding="UTF-8" session="false"
    2324  import="net.sf.basedb.core.SessionControl"
     
    5354  import="net.sf.basedb.clients.web.extensions.toolbar.ToolbarUtil"
    5455  import="net.sf.basedb.util.extensions.ExtensionsInvoker"
     56  import="net.sf.basedb.util.extensions.ExtensionsUtil"
     57  import="net.sf.basedb.util.uri.ConnectionManagerUtil"
    5558  import="java.util.Date"
    5659  import="java.util.Collections"
     
    120123  JspContext jspContext = ExtensionsControl.createContext(dc, pageContext, guiContext, server);
    121124  ExtensionsInvoker invoker = ToolbarUtil.useExtensions(jspContext);
     125  ConnectionManagerFactory cmf = ConnectionManagerUtil.getFactory(server.getConnectionManagerFactoryId());
    122126  %>
    123127  <base:page title="<%=title%>">
     
    268272        <td class="prompt">Name</td>
    269273        <td><%=HTML.encodeTags(server.getName())%></td>
     274      </tr>
     275      <tr>
     276        <td class="prompt">ConnectionManager</td>
     277        <td><%=cmf == null ? "<i>- auto -</i>" : HTML.encodeTags(cmf.getDisplayName())%></td>
    270278      </tr>
    271279      <tr>
  • trunk/www/include/styles/main.css

    r5562 r5599  
    269269
    270270.tabcontents_bottom .helpmessage {
    271   background: #ffffff;
     271  background: #ffffd8;
    272272}
    273273
Note: See TracChangeset for help on using the changeset viewer.