BACK
   MobyCore API 
  
    MobyCore is an API to execute BioMoby services. It supports both synchronous and asynchronous services. Library relies on JAX-WS 2.1 API that is a part of 
    Java 6. It also works on JEE5 where JAX-WS is a part of the platform. In case of using Java 5, JAX-WS must be present in a classpath. 
  
  
    Some essencial classes and packages of the library are:
    
    
      
        
          | org.inb.biomoby.shared.datatypes.* | This package contains BioMoby primitive classes (such as MobyString, MobyInteger...) | 
        
          | org.inb.biomoby.shared.message.* | Package contains classes related to BioMoby message structure (MobyMessage, MobyData, MobySimple...) | 
        
          | org.inb.biomoby.shared.registry.* | Classes in this package represent artifacts from BioMoby Registry (such as description of services or datatypes) | 
        
          | MobyMessageContext.class | This is a JAXB Context cache. JAXB Context has all BioMoby artefacts to convert them into an XML. | 
        
          | MobyDispatch.class | The class executes a BioMoby service. | 
      
    
  
   Generating JAXB-annotated ontology classes 
  
    Even MobyCore may work without generated ontology classes, they facilitate a development.
    Generated by MobyGenerator classes are nothing more than JAXB annotated beans with properties.
  
  
  
    
    
      Here is an example of generated datatype class:
    
       
    
@XmlRootElement(name="WeightedAminoAcidSequences")
@XmlType(name="WeightedAminoAcidSequences")
public class WeightedAminoAcidSequences extends AminoAcidSequence implements Serializable {
    public List<? extends AminoAcidSequence> getAminoAcidSequence() {
        return getAttributes("AminoAcidSequence");
    }
    public void addAminoAcidSequence(AminoAcidSequence aminoAcidSequence) {
        putAttribute("AminoAcidSequence", aminoAcidSequence);
    }
    public WeightedObject getWeightedObject() {
        return getAttribute("WeightedObject");
    }
    public void setWeightedObject(WeightedObject weightedObject) {
        putAttribute("WeightedObject", weightedObject);
    }
}
    
    
   
  
   Executing synchronous BioMoby services 
  
    To execute a BioMoby service, first we have to prepare a message.
    This is done by creating a MobyMessage object:
    
MobyObject object = new MobyObject("P00807", "UniProt");
MobySimple simple = new MobySimple(object, "id");        
MobyData data = new MobyData(simple, "sip_1");
MobyMessage request = new MobyMessage(data);
    
  
  
    Next step is to create a BioMoby service description. To execute a service we do not need a complete description.
    
Service service = new Service("getAminoAcidSequence", "inb.bsc.es");
service.setCategory(CATEGORY.moby);
service.setUrl("http://inb.bsc.es/cgi-bin/mobyServices/dispatchersRetrieval/Dispatcher.cgi");
     
  
  
    Now we can create a MobyDispatch object and execute a service.
    
MobyDispatch dispatch = new MobyDispatch(service);
MobyMessage response = dispatch.invoke(request);
    
  
  
    The result of the execution is another MobyMessage that contains a response (or possibly  MobyExceptions).
  
  
    MobyCore supposed to work with generated JAXB-annotated ontology classes. In case when a class can not be found, it is substituted 
    by a special object AnyMobyObject. This object facilitates property access through getAttribute() and 
    getAttributes() methods. Consider that we execute a service that return an AminoAcidSequence object and we do 
    not have AminoAcidSequence class generated. In this case we would have a AnyMobyObject instead of unknown to us AminoAcidSequence.
    
MobyString string = (MobyString) any.getAttribute("SequenceString");
    
  
  
    Well, may be this is not the best example, because we still must know that service returns an AminoAcidSequence or its derivative.
    MobySimple may contain either a primitive type or a complex one, so we have to check. Here is a simple method that traverse a given element:
     
    
public void traverse(AbstractMobyObject object) throws JAXBException
{
  System.out.println(MobyMessageContext.getMobyName(object) + " " + object.getArticleName());
  if (object instanceof MobyObject)
  {
     MobyObject complex = (MobyObject)object;         
     List<AbstractMobyObject> attributes = complex.getAttributes();
     for (AbstractMobyObject o : attributes)
     {
       traverse(o);
     }
  }
}     
    
  
  
    Here we used a MobyMessageContext to resolve a BioMoby name for a given object.
  
  
    AnyMobyObject can also be used to setup a datatype dynamically.
    
AnyMobyObject any = new AnyMobyObject("AminoAcidSequece");
any.putAttribute("SequenceString", new MobyString("ATCG"));
any.putAttribute("Length", new MobyInteger(4));
    
  
  
    Even we can perfectly mix AnyMobyObject with ontology generated classes, it is better to use one way or another.
  
  
    Here is an example of parsing a MobyMessage response:
    
MobyMessage response = dispatch.invoke(request);
if (response.hasExceptions())
{
  throw response.getExceptions(); // MobyExceptions is a java Exception object!
}
ArrayList<MobyData> data_list = response.getMobyDataList();
if (data_list.isEmpty())
{
  throw new Exception("Empty response!");
}
for (MobyData data : data_list)
{
   List<MobyDataElement> elements = data.getMobyDataElements(); // for example a list of simples
   for (MobyDataElement element : elements)
   {
     if (element instanceof MobySimple)
     {
       MobySimple simple = (MobySimple)element;
       AbstractMobyObject object = simple.getObject();
       if (object instanceof AminoAcidSequence)
       {
         AminoAcidSequence sequence = (AminoAcidSequence)object;
         MobyString str = sequence.getSequenceString();
         System.out.println(str.getString());
       }
       else if (object instanceof AnyMobyObject)
       {
         AnyMobyObject any = (AnyMobyObject)object;
         AbstractMobyObject attr = any.getAttribute("SequenceString");
         if (attr != null && attr instanceof MobyString)
         {
           MobyString str = (MobyString)attr;
           System.out.println(str.getString());
         }
         else
         {
           throw new Exception(); // object has no "SequenceString" property of type MobyString
         }
       }
       else
       {
         throw new Exception(); // expected AminoAcidSequence
       }
     }
     else
     {
       throw new Exception(); // expected MobySimple
     }
   }
}  
    
  
   Executing asynchronous BioMoby services 
  
    BioMoby uses a subset of WSRF specification for the asynchrony.
    The main difference between asynchronous and synchronous services is in a way of obtaining a result. 
    Note also that we set a service category to "moby-async".
    The rest of the things are pretty the same as for synchronous invocation:
    
// AminoAcidSequence sequence = new AminoAcidSequence();
// sequence.setSequenceString(new MobyString("ATCG")):
// sequence.setLength(new MobyInteger(4));
AnyMobyObject sequence = new AnyMobyObject("AminoAcidSequence");
sequence.putAttribute("SequenceString", new MobyString("ATCG"));
sequence.putAttribute("Length", new MobyInteger(4));
MobySimple simple = new MobySimple(sequence, "sequence");
MobyData data = new MobyData(simple, "sip_1");       
MobyMessage request = new MobyMessage(data);
        
Service service = new Service("runNCBIBlastp", null);
service.setCategory(CATEGORY.moby_async);
service.setUrl("http://inb.bsc.es/cgi-bin/mobyServices/dispatchers/asyncDispatcher.cgi");
        
MobyDispatch dispatch = new MobyDispatch(service);
MobyWSRFResource wsrf = dispatch.invokeAsync(request);
    
  
  
    The result object is an WSRF resource through which we can poll to check our execution status:
    
while(true)
{
  AnalysisEvent lsae = wsrf.getResourcePropertyStatus("sip_1");
  Event event = lsae.getEvent();
  if (event instanceof StateChanged)
  {
     StateChanged stateChanged = (StateChanged)event;
     StateChanged.STATE state = stateChanged.getNewState();
     if (state == StateChanged.STATE.completed)
     { // the resource (result) is ready
        MobyMessage response = wsrf.getResourcePropertyResult("sip_1");
        wsrf.destroy(); // we can remove a resource if we do not need it anymore
     }
     else if (state == StateChanged.STATE.created ||
              state == StateChanged.STATE.running)
     { // the result is not ready
        Thread.currentThread().sleep(2000);
        continue;
     }
   }
   // actually must be an error...
   break;
}
    
  
  
    An obtained MobyMessage parsed the same way as for synchronous service.