|
||||
|
|
Registered Data Accessors enable ranges of URIs to be accessible to applications running with the NetKernel system. The kernel comes pre-configured with some standard Data Accessors for accessing file:, http:, ftp:, etc. The InterfaceAll accessors must implement the interface Request TypesData accessors can do more that just source representations of resources. This section
describes all the request types that accessors can handle. Request types are declared as
constants in the class
LifecycleAccessors are constructed on demand when the first request that needs them is issued. Accessors
are constructed using the default constructor but shortly afterwards the
After creation an accessor will be used to process a request. The kernel will make a call
to MetadataDuring construction the accessor must create its metadata, this implements
Issuing Sub-requestsUsually a data accessor is a primary source of a resource and it does whatever lower-level work to perform an action on a resource defined by a URI. However there are a few circumstances where an accessor might wish to make further sub-requests before completing:
ExampleAs an example we will develop an accessor to implement an in-memory document storage accessor using a transient: URI scheme. The accessor will allow storage and retrieval of documents under arbitrary keys, i.e.
Step 1 - declare classSubclass
package org.myDomain.myApp;
import org.ten60.netkernel.layer1.accessor.AccessorImpl;
import org.ten60.netkernel.layer1.meta.DataAccessorMeta;
import com.ten60.netkernel.urrequest.URRequest;
import java.util.*;
class TransientDataAccessor extends AccessorImpl
{ private static final int COST = 2;
private static final int REQUEST_TYPES = URRequest.RQT_SOURCE | URRequest.RQT_SINK;
public TransientDataAccessor()
{ super( new DataAccessorMeta(COST,REQUEST_TYPES,THREADSAFE) );
}
private final Map mDocuments = new HashMap();
}
Step 2 - implement functionality
The
The
public void receiveAsyncRequest(URRequest aRequest)
{ try
{ URRepresentation result = null;
switch (aRequest.getType())
{ case URRequest.RQT_SOURCE:
result = source(aRequest);
break;
case URRequest.RQT_SINK:
result = sink(aRequest);
break;
}
URResult urr=new URResult(aRequest, result);
getScheduler().receiveAsyncResult(urr);
}
catch (Exception e)
{ NetKernelException nke=new NetKernelException("Error Processing "+aRequest.toString());
nke.addCause(e);
URRepresentation result=NetKernelExceptionAspect.create(nke);
URResult urr=new URResult(aRequest, result);
getScheduler().receiveAsyncException(urr);
}
}
private URRepresentation source(URRequest aRequest) throws Exception
{
URRepresentation result = null;
String path = aRequest.getURI().getSchemeSpecificPart();
String data;
if (path!=null)
{ String data = mDocuments.get(path);
if (path==null)
{ data="";
}
IURMeta meta = new AlwaysExpiredMeta(cost,mime);
return StringAspect.create(meta,data);
}
else
{ throw new Exception("URI must have path element");
}
}
private URRepresentation sink(URRequest aRequest) throws Exception
{ URRepresentation data = aRequest.getArg(URRequest.URI_SYSTEM);
if (!data.hasAspect(IStringAspect.class))
{ data = transrepresent(aRequest.getURI(),data,aRequest);
}
IStringAspect sa = (IStringAspect)data.getAspect(IStringAspect.class);
String path = aRequest.getURI().getSchemeSpecificPart();
mDocuments.put(path,sa.getString());
return VoidAspect.create();
}
Step 3 - register the accessorThis step maps a range of URIs onto the accessor we have just created. <ura>
This example maps all URIs for the <match>transient:.*</match> <value>org.myDomain.myApp.TransientDataAccessor</value> </ura> transient: scheme to use our new accessor.
For more details see Active Accessor Guide.
|
|||
|
© 2003,2004, 1060® Research Limited
1060 registered trademark, NetKernel trademark of 1060 Research Limited
|
||||