net.refractions.udig.catalog
Class IService

java.lang.Object
  extended by net.refractions.udig.catalog.IService
All Implemented Interfaces:
IResolve

public abstract class IService
extends java.lang.Object
implements IResolve

Represents a geo spatial service handle. Follows the same design as IResource.

Represents a spatial service, which may be lazily loaded. The existance of this object does not ensure that the advertized data is guaranteed to exist, nor does this interface guarantee that the service exists based on this object's existance. We should also note the resource management is left to the user, and that resolve() is not guaranteed to return the same instance object from two subsequent calls, but may. This is merely a handle to some information about a service, and a method of aquiring an instance of the service ...

NOTE: This may be the result of communications with a metadata service, and as such this service described may not be running right now. Remember to check the service status.

Implementing an IService

Implement the abstract methods and you are good to go.

Extending an IService

You may want to implement your own IService in order to provide a handle for a new kind of API.
  1. New method:
    
      public API getAPI( ProgressMonitor monitor){
          if (monitor == null) monitor = new NullProgressMonitor();
          
          monitor.beingTask("Connect to API",2);
          try {            
              String server = getConnectionParams().get("server");
              monitor.worked(1);
              return new API( s );
          }
          finally {
              monitor.done();
          }
      }
      
    (note the use of NullProgressMonitor)
  2. Optional: Customize resolve method to advertise your new API "dynamically"
    
     public <T> boolean canResolve( Class<T> adaptee ) {
         return adaptee != null
                 && (adaptee.isAssignableFrom(API.class) || super.canResolve(adaptee));
     }
     public <T> T resolve( Class<T> adaptee, IProgressMonitor monitor ) throws IOException {
         if (monitor == null) monitor = new NullProgressMonitor(); 
         if (adaptee == null)
             throw new NullPointerException("No adaptor specified" );
             
         if (adaptee.isAssignableFrom(API.class)) {
             return adaptee.cast(getAPI(monitor));
         }
         return super.resolve(adaptee, monitor);
     }
     
    (note the call to super)
  3. Optional: cache your API as the "connection"
    
      API api = null;
      Throwable msg = null;
      public synchronized API getAPI( ProgressMonitor monitor){
          if( api != null ) return api;
          
          if (monitor == null) monitor = new NullProgressMonitor();
          
          monitor.beingTask("Connect to API",2);
          try {            
              String server = getConnectionParams().get("server");
              monitor.worked(1);
              api = new API( s );
              monitor.worked(1);
              return api;
          }
          finally {
              monitor.done();
          }
      }
      public Status getStatus() {
          return msg != null? Status.BROKEN : api == null? Status.NOTCONNECTED : Status.CONNECTED;
      }
      public Throwable getMessage(){
          return msg;
      }
      public synchronized void dispose( ProgressMonitor monitor ){
          if( api != null ){
               api.dispose();
               api = null;
          }
          if( msg != null ) msg = null;
      }
     
    (Note the use of getMessage and getStatus)

Since:
0.6
Author:
David Zwiers, Refractions Research
See Also:
IServiceInfo, IServiceFactory

Nested Class Summary
 
Nested classes/interfaces inherited from interface net.refractions.udig.catalog.IResolve
IResolve.Status
 
Constructor Summary
IService()
           
 
Method Summary
<T> boolean
canResolve(java.lang.Class<T> adaptee)
          Harded coded to capture the IService contract.
 void dispose(IProgressMonitor monitor)
          Clean up after aquired resources - the handle will not function after being disposed.
 boolean equals(java.lang.Object arg0)
          This should represent the identifier
abstract  java.util.Map<java.lang.String,java.io.Serializable> getConnectionParams()
          Accessor to the set of params used to create this entry.
abstract  IServiceInfo getInfo(IProgressMonitor monitor)
           
 int hashCode()
          This should represent the identified
abstract  java.util.List<? extends IGeoResource> members(IProgressMonitor monitor)
          Return list of IGeoResources managed by this service.
 ICatalog parent(IProgressMonitor monitor)
          Returns LocalCatalog by defaul, subclass must override iff a custom catalog is used.
<T> T
resolve(java.lang.Class<T> adaptee, IProgressMonitor monitor)
          Will attempt to morph into the adaptee, and return that object.
 java.lang.String toString()
          Indicate class and id.
 
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
 
Methods inherited from interface net.refractions.udig.catalog.IResolve
getIdentifier, getMessage, getStatus
 

Constructor Detail

IService

public IService()
Method Detail

resolve

public <T> T resolve(java.lang.Class<T> adaptee,
                     IProgressMonitor monitor)
          throws java.io.IOException
Will attempt to morph into the adaptee, and return that object. Harded coded to capture the IService contract.

That is we *must* resolve the following:

Recomended adaptations: May Block.

Example implementation:


 public <T> T resolve( Class<T> adaptee, IProgressMonitor monitor ) throws IOException {
     if (monitor == null) monitor = new NullProgressMonitor(); 
     if (adaptee == null)
         throw new NullPointerException("No adaptor specified" );
         
     if (adaptee.isAssignableFrom(API.class)) {
         return adaptee.cast(getAPI(monitor));
     }
     return super.resolve(adaptee, monitor);
 }
 

Specified by:
resolve in interface IResolve
Parameters:
adaptee -
monitor -
Returns:
instance of adaptee, or null if unavailable (IServiceInfo and List must be supported)
Throws:
java.io.IOException - if result was unavailable due to a technical problem
See Also:
IServiceInfo, IGeoResource, IResolve.resolve(Class, IProgressMonitor)

canResolve

public <T> boolean canResolve(java.lang.Class<T> adaptee)
Harded coded to capture the IService contract.

That is we *must* resolve the following:

Here is an implementation example (for something that can adapt to DataStore):


 public <T> boolean canResolve( Class<T> adaptee ) {
     return adaptee != null
             && (adaptee.isAssignableFrom(DataStore.class) || super.canResolve(adaptee));
 }
 

Specified by:
canResolve in interface IResolve
Returns:
true if a resolution for adaptee is avaialble
See Also:
IResolve.resolve(Class, IProgressMonitor);

parent

public ICatalog parent(IProgressMonitor monitor)
Returns LocalCatalog by defaul, subclass must override iff a custom catalog is used.

Specified by:
parent in interface IResolve
Parameters:
monitor - used to provide feedback during parent lookup
Returns:
Parent IResolve, null if unknown

members

public abstract java.util.List<? extends IGeoResource> members(IProgressMonitor monitor)
                                                        throws java.io.IOException
Return list of IGeoResources managed by this service.

Many file based serivces will just contain a single IGeoResource.

Specified by:
members in interface IResolve
Parameters:
monitor - Monitor used to provide feedback during member lookup
Returns:
List, possibly empty, of members. Will be EMPTY_LIST if this is a leaf.
Throws:
java.io.IOException - in the event of a technical problem

getInfo

public abstract IServiceInfo getInfo(IProgressMonitor monitor)
                              throws java.io.IOException
Returns:
IServiceInfo resolve(IServiceInfo.class,IProgressMonitor monitor);
Throws:
java.io.IOException
See Also:
resolve(Class, IProgressMonitor)

getConnectionParams

public abstract java.util.Map<java.lang.String,java.io.Serializable> getConnectionParams()
Accessor to the set of params used to create this entry. There is no guarantee that these params created a usable service (@see getStatus() ). These params may have been modified within the factory during creation. This method is intended to be used for cloning (@see IServiceFactory) or for persistence between sessions.

IMPORTANT: Because of the serialization currently used only types that can be reconstructed from their toString() representation can be used. For example:


 valueThatIsSaved=url.toString().
 URL restoredValue=new URL(valueThatIsSaved);
 
Also only classes that this plugin can load can be loaded so custom classes from downstream plugins cannot be used. It is recommended that only "normal" types be used like Integer, URL, Float, etc...

This restriction will be lifted in the future. (Except for the loading issue that is a design issue that we will live with.)

Returns:
See Also:
IServiceFactory

equals

public final boolean equals(java.lang.Object arg0)
This should represent the identifier

Overrides:
equals in class java.lang.Object
Parameters:
arg0 -
Returns:
See Also:
Object.equals(java.lang.Object)

hashCode

public final int hashCode()
This should represent the identified

Overrides:
hashCode in class java.lang.Object
Returns:
See Also:
Object.hashCode()

toString

public java.lang.String toString()
Indicate class and id.

Overrides:
toString in class java.lang.Object
Returns:
string representing this IResolve

dispose

public void dispose(IProgressMonitor monitor)
Description copied from interface: IResolve
Clean up after aquired resources - the handle will not function after being disposed.

Specified by:
dispose in interface IResolve