package org.cagrid.mms.service.impl.cadsr; import gov.nih.nci.cadsr.umlproject.domain.Project; import gov.nih.nci.cadsr.umlproject.domain.UMLClassMetadata; import gov.nih.nci.cagrid.metadata.MetadataUtils; import gov.nih.nci.cagrid.metadata.ServiceMetadata; import gov.nih.nci.cagrid.metadata.common.SemanticMetadata; import gov.nih.nci.cagrid.metadata.common.UMLClass; import gov.nih.nci.cagrid.metadata.service.CaDSRRegistration; import gov.nih.nci.cagrid.metadata.service.InputParameter; import gov.nih.nci.cagrid.metadata.service.Operation; import gov.nih.nci.cagrid.metadata.service.Service; import gov.nih.nci.cagrid.metadata.service.ServiceContext; import gov.nih.nci.system.applicationservice.ApplicationException; import gov.nih.nci.system.applicationservice.ApplicationService; import gov.nih.nci.system.client.ApplicationServiceProvider; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.util.List; import java.util.Map; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.xml.namespace.QName; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * @author oster */ public class ServiceMetadataAnnotator { protected static Log LOG = LogFactory.getLog(ServiceMetadataAnnotator.class.getName()); private ApplicationService defaultcaDSR = null; private final Map<String, QualifiedProject> uri2ServiceMap; public ServiceMetadataAnnotator(Map<String, QualifiedProject> uri2ServiceMap, ApplicationService defaultCaDSR) { if (defaultCaDSR == null) { throw new IllegalArgumentException("Cannot supply a null default ApplicationService."); } this.uri2ServiceMap = uri2ServiceMap; this.defaultcaDSR = defaultCaDSR; } /** * Add caDSR information to model. * * @param metadata * @throws CaDSRGeneralException */ public void annotateServiceMetadata(ServiceMetadata metadata) throws CaDSRGeneralException { if (metadata == null || metadata.getServiceDescription() == null || metadata.getServiceDescription().getService() == null) { return; } Service service = metadata.getServiceDescription().getService(); // TODO: how to set caDSR registration? CaDSRRegistration caDSRRegistration = service.getCaDSRRegistration(); // TODO: set/edit service semantic metadata once service's are // registered in caDSR SemanticMetadata[] semanticMetadatas = (SemanticMetadata[])service.getSemanticMetadata().toArray(); if (service.getServiceContextCollection() == null || service.getServiceContextCollection().getServiceContext() == null) { return; } ServiceContext[] serviceContexts = (ServiceContext[])service.getServiceContextCollection().getServiceContext().toArray(); for (int i = 0; i < serviceContexts.length; i++) { annotateServiceContext(serviceContexts[i]); } } protected void annotateServiceContext(ServiceContext context) throws CaDSRGeneralException { if (context == null || context.getOperationCollection() == null || context.getOperationCollection().getOperation() == null) { return; } Operation[] operations = (Operation[])context.getOperationCollection().getOperation().toArray(); for (int i = 0; i < operations.length; i++) { annotateOperation(operations[i]); } } protected void annotateOperation(Operation operation) throws CaDSRGeneralException { if (operation == null) { return; } // TODO: set/edit operation semantic metadata once services are // registered in caDSR SemanticMetadata[] semanticMetadatas = (SemanticMetadata[])operation.getSemanticMetadata().toArray(); // process input if (operation.getInputParameterCollection() != null && operation.getInputParameterCollection().getInputParameter() != null) { InputParameter[] inputParameters = (InputParameter[])operation.getInputParameterCollection().getInputParameter().toArray(); for (int i = 0; i < inputParameters.length; i++) { InputParameter in = inputParameters[i]; QName qname = in.getQName(); UMLClass uml = getUMLClassForQName(qname); if (uml != null) { LOG.debug("Successfully processed:" + qname); in.setUMLClass(uml); } } } // process output if (operation.getOutput() != null) { QName qname = operation.getOutput().getQName(); UMLClass uml = getUMLClassForQName(qname); if (uml != null) { LOG.debug("Successfully processed:" + qname); operation.getOutput().setUMLClass(uml); } } } /** * @param qname * @return The UML Class matching the QName * @throws CaDSRGeneralException */ protected UMLClass getUMLClassForQName(QName qname) throws CaDSRGeneralException { // look up the UMLClassMetadata we are looking for, based on the QName UMLClassMetadata classMetadata = getUMLClassMetadataForQName(qname); if (classMetadata == null) { return null; } UMLClass result = null; try { String shortName = classMetadata.getProject().getShortName(); String version = classMetadata.getProject().getVersion(); ApplicationService cadsr = defaultcaDSR; QualifiedProject proj = uri2ServiceMap.get(qname.getNamespaceURI()); if (proj != null) { cadsr = proj.getSourceAppServ(); } result = CaDSRUtils.convertClassToUMLClass(cadsr, shortName, version, classMetadata); } catch (ApplicationException e) { LOG.error("Problem converting class to metadata", e); } return result; } /** * NOTE: we used to qualify the Project with the ClassificationScheme * Context name, but there's not really a way to get that information now * (as Project has a unidirectional assoc to ClassificationScheme, so we * can't use the dataservice to query for the CS of a given Project); now * one would need to supply the publicID of the Project of interest if there * were multiple contexts using the same project name and version * * @param qname * @return The UMLClassMetadata matching the qname * @throws CaDSRGeneralException */ protected UMLClassMetadata getUMLClassMetadataForQName(QName qname) throws CaDSRGeneralException { ApplicationService cadsr = null; Project projPrototype = null; // if there are user supplied mappings, we need to try to use the // applicationservice and project identifiers from those if (this.uri2ServiceMap != null) { LOG.debug("Looking for suitable namespace mapping in supplied map."); QualifiedProject proj = uri2ServiceMap.get(qname.getNamespaceURI()); // the user supplied a project to be used for this namespace, so get // the appserv from it, as well as the project prototype if (proj != null) { LOG.debug("Using supplied Project (" + proj.getProjectPrototype().getShortName() + ") version (" + proj.getProjectPrototype().getVersion() + ") for Qname (" + qname + ")."); cadsr = proj.getSourceAppServ(); projPrototype = proj.getProjectPrototype(); } } // we never found a suitable mapping, so use default if (cadsr == null) { LOG.debug("No suitable namespace mapping found; using default ApplicationService."); cadsr = this.defaultcaDSR; } // create a prototype class UMLClassMetadata prototype = new UMLClassMetadata(); // the Project qualifier of the class may have been set above using the // supplied mappings, but if not, the QName is expected to be uniquely // used by a single Class if (projPrototype != null) { prototype.setProject(projPrototype); } else { LOG.debug("No suitable namespace to Project mapping found; issuing a non-project-qualified query."); } prototype.setGmeNamespace(qname.getNamespaceURI()); prototype.setGmeXMLElement(qname.getLocalPart()); List rList = null; try { rList = cadsr.search(UMLClassMetadata.class, prototype); } catch (ApplicationException e) { LOG.error( "Unable to locate UMLClassMetadata for QName (" + qname + "); skipping because:" + e.getMessage(), e); return null; } if (rList == null || rList.size() == 0) { LOG.error("Unable to locate UMLClassMetadata for QName (" + qname + "); skipping because no results were returned from ApplicationService."); return null; } if (rList.size() > 1) { LOG.info("Processing of UMLClassMetadata for QName (" + qname + ") returned more than 1 result, using first."); } return (UMLClassMetadata) rList.get(0); } public static void main(String[] args) { try { JFrame f = new JFrame(); f.setVisible(true); JFileChooser fc = new JFileChooser("."); fc.showOpenDialog(f); File selectedFile = fc.getSelectedFile(); ServiceMetadata model = MetadataUtils.deserializeServiceMetadata(new FileReader(selectedFile)); ApplicationService appService = ApplicationServiceProvider .getApplicationServiceFromUrl("http://cadsrapi-prod2.nci.nih.gov/cadsrapi40/"); ServiceMetadataAnnotator anno = new ServiceMetadataAnnotator(null, appService); anno.annotateServiceMetadata(model); File result = new File(".", selectedFile.getName() + "_annotated"); MetadataUtils.serializeServiceMetadata(model, new FileWriter(result)); System.exit(0); } catch (Exception e) { e.printStackTrace(); System.exit(-1); } } }