package org.cagrid.mms.service.impl.cadsr;
import gov.nih.nci.cadsr.umlproject.domain.Project;
import gov.nih.nci.cagrid.metadata.ServiceMetadata;
import gov.nih.nci.cagrid.metadata.dataservice.DomainModel;
import gov.nih.nci.system.applicationservice.ApplicationService;
import java.net.URI;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.cagrid.mms.model.ModelSourceMetadata;
import org.cagrid.mms.model.Property;
import org.cagrid.mms.model.PropertyDescriptor;
import org.cagrid.mms.model.SourceDescriptor;
import org.cagrid.mms.model.SupportedProjectProperties;
import org.cagrid.mms.model.UMLAssociationExclude;
import org.cagrid.mms.model.UMLProjectIdentifer;
import org.cagrid.mms.service.InvalidUMLProjectIndentifier;
import org.cagrid.mms.service.MMS;
import org.cagrid.mms.service.MMSGeneralException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class CaDSRMMSImpl implements MMS {
public static final String SOURCE_PROPERTY_PUBLIC_ID = "publicID";
public static final String SOURCE_PROPERTY_LONG_NAME = "longName";
public static final String SOURCE_PROPERTY_GME_NAMESPACE = "gmeNamespace";
private ApplicationContext ctx = null;
private ModelSourceMetadata metadata;
private final Map<String, String> sourceToURLMap;
public CaDSRMMSImpl(ModelSourceMetadata metadata, Map<String, String> sourceToURLMap, String applicationContextFile) {
this.sourceToURLMap = sourceToURLMap;
this.metadata = metadata;
ctx = new FileSystemXmlApplicationContext(applicationContextFile);
// go through the supplied sources and add the properties we support
for (SourceDescriptor source : this.metadata.getSupportedModelSources().getSource()) {
SupportedProjectProperties supportedProjectProperties = new SupportedProjectProperties();
source.setSupportedProjectProperties(supportedProjectProperties);
PropertyDescriptor[] propertyDescriptors = new PropertyDescriptor[3];
supportedProjectProperties.getPropertyDescriptor().addAll(Arrays.asList(propertyDescriptors));
propertyDescriptors[0] = new PropertyDescriptor();
propertyDescriptors[0].setName(SOURCE_PROPERTY_GME_NAMESPACE);
propertyDescriptors[0].setDescription("The " + SOURCE_PROPERTY_GME_NAMESPACE
+ " attribute of the caDSR Project.");
propertyDescriptors[0].setRequired(false);
propertyDescriptors[1] = new PropertyDescriptor();
propertyDescriptors[1].setName(SOURCE_PROPERTY_LONG_NAME);
propertyDescriptors[1].setDescription("The " + SOURCE_PROPERTY_LONG_NAME
+ " attribute of the caDSR Project.");
propertyDescriptors[1].setRequired(false);
propertyDescriptors[2] = new PropertyDescriptor();
propertyDescriptors[2].setName(SOURCE_PROPERTY_PUBLIC_ID);
propertyDescriptors[2].setDescription("The " + SOURCE_PROPERTY_PUBLIC_ID
+ " attribute of the caDSR Project.");
propertyDescriptors[2].setRequired(false);
}
}
public ModelSourceMetadata getModelSourceMetadata() {
return metadata;
}
public ServiceMetadata annotateServiceMetadata(ServiceMetadata serviceMetadata,
Map<URI, UMLProjectIdentifer> namespaceToProjectMappings) throws MMSGeneralException,
InvalidUMLProjectIndentifier {
Map<String, QualifiedProject> uriToProjectMap = new HashMap<String, QualifiedProject>();
if (namespaceToProjectMappings != null) {
for (URI namespace : namespaceToProjectMappings.keySet()) {
UMLProjectIdentifer projId = namespaceToProjectMappings.get(namespace);
QualifiedProject proj = new QualifiedProject(getApplicationServiceForUMLProjectIdentifier(projId),
createProjectPrototypeFromIdentifier(projId));
uriToProjectMap.put(namespace.toString(), proj);
}
}
ServiceMetadataAnnotator annotator = new ServiceMetadataAnnotator(uriToProjectMap,
getApplicationService(getModelSourceMetadata().getDefaultSourceIdentifier()));
try {
annotator.annotateServiceMetadata(serviceMetadata);
} catch (CaDSRGeneralException e) {
throw new MMSGeneralException("Problem from remote caDSR:" + e.getMessage(), e);
}
return serviceMetadata;
}
public DomainModel generateDomainModelForClasses(UMLProjectIdentifer umlProjectIdentifer,
Collection<String> fullyQualifiedClassNames) throws MMSGeneralException, InvalidUMLProjectIndentifier {
ApplicationService applicationService = getApplicationServiceForUMLProjectIdentifier(umlProjectIdentifer);
DomainModelBuilder builder = new DomainModelBuilder(applicationService);
try {
String classes[] = new String[fullyQualifiedClassNames.size()];
return builder.createDomainModelForClasses(createProjectPrototypeFromIdentifier(umlProjectIdentifer),
fullyQualifiedClassNames.toArray(classes));
} catch (DomainModelGenerationException e) {
throw new MMSGeneralException("Problem from remote caDSR:" + e.getMessage(), e);
}
}
public DomainModel generateDomainModelForClassesWithExcludes(UMLProjectIdentifer umlProjectIdentifer,
Collection<String> fullyQualifiedClassNames, Collection<UMLAssociationExclude> umlAssociationExclude)
throws InvalidUMLProjectIndentifier, MMSGeneralException {
ApplicationService applicationService = getApplicationServiceForUMLProjectIdentifier(umlProjectIdentifer);
DomainModelBuilder builder = new DomainModelBuilder(applicationService);
try {
String classes[] = new String[fullyQualifiedClassNames.size()];
UMLAssociationExclude excludes[] = new UMLAssociationExclude[umlAssociationExclude.size()];
return builder.createDomainModelForClassesWithExcludes(
createProjectPrototypeFromIdentifier(umlProjectIdentifer), fullyQualifiedClassNames.toArray(classes),
umlAssociationExclude.toArray(excludes));
} catch (DomainModelGenerationException e) {
throw new MMSGeneralException("Problem from remote caDSR:" + e.getMessage(), e);
}
}
public DomainModel generateDomainModelForPackages(UMLProjectIdentifer umlProjectIdentifer,
Collection<String> packageNames) throws InvalidUMLProjectIndentifier, MMSGeneralException {
ApplicationService applicationService = getApplicationServiceForUMLProjectIdentifier(umlProjectIdentifer);
DomainModelBuilder builder = new DomainModelBuilder(applicationService);
try {
String packages[] = new String[packageNames.size()];
return builder.createDomainModelForPackages(createProjectPrototypeFromIdentifier(umlProjectIdentifer),
packageNames.toArray(packages));
} catch (DomainModelGenerationException e) {
throw new MMSGeneralException("Problem from remote caDSR:" + e.getMessage(), e);
}
}
public DomainModel generateDomainModelForProject(UMLProjectIdentifer umlProjectIdentifer)
throws MMSGeneralException, InvalidUMLProjectIndentifier {
ApplicationService applicationService = getApplicationServiceForUMLProjectIdentifier(umlProjectIdentifer);
DomainModelBuilder builder = new DomainModelBuilder(applicationService);
try {
return builder.createDomainModel(createProjectPrototypeFromIdentifier(umlProjectIdentifer));
} catch (DomainModelGenerationException e) {
throw new MMSGeneralException("Problem from remote caDSR:" + e.getMessage(), e);
}
}
private Project createProjectPrototypeFromIdentifier(UMLProjectIdentifer umlProjectIdentifer)
throws InvalidUMLProjectIndentifier {
// create the prototype
Project prototype = new Project();
prototype.setVersion(umlProjectIdentifer.getVersion());
// TODO is this what I want to map identifier too (or could I map it to
// either short or long name)
prototype.setShortName(umlProjectIdentifer.getIdentifier());
// process any additional source properties
Property[] props = (Property[])umlProjectIdentifer.getAdditionalSourceProperty().toArray(new Property[0]);
if (props != null) {
for (Property prop : props) {
String name = prop.getName();
String value = prop.getValue();
if (name.equals(SOURCE_PROPERTY_PUBLIC_ID)) {
//TODO: Why does this not exist
//prototype.setPublicID(Long.valueOf(value));
} else if (name.equals(SOURCE_PROPERTY_LONG_NAME)) {
prototype.setLongName(value);
} else if (name.equals(SOURCE_PROPERTY_GME_NAMESPACE)) {
prototype.setGmeNamespace(value);
} else {
throw new InvalidUMLProjectIndentifier();
}
}
}
return prototype;
}
private ApplicationService getApplicationService(String sourceID) throws MMSGeneralException {
ApplicationService appService = null;
String url = this.sourceToURLMap.get(sourceID);
if (url == null) {
throw new MMSGeneralException("Unable to locate appropriate caDSR service for specified source ("
+ sourceID + ")");
}
try {
System.out.println("GETTING APPLICATION SERVICE FOR: " + url);
appService = ApplicationServiceProvider.getApplicationServiceFromUrl(this.ctx,url);
System.out.println(" FOUND APPLICATION SERVICE");
} catch (Exception e) {
throw new MMSGeneralException("Problem loading caDSR ApplicationService", e);
}
return appService;
}
private SourceDescriptor getSourceDescriptorForUMLProjectIdentifier(UMLProjectIdentifer umlProjectIdentifer)
throws InvalidUMLProjectIndentifier, MMSGeneralException {
String sourceID = umlProjectIdentifer.getSourceIdentifier();
boolean usingDefault = false;
if (sourceID == null || sourceID.trim().equals("")) {
sourceID = getModelSourceMetadata().getDefaultSourceIdentifier();
usingDefault = true;
}
for (SourceDescriptor source : getModelSourceMetadata().getSupportedModelSources().getSource()) {
if (source.getIdentifier().equals(sourceID)) {
return source;
}
}
if (usingDefault) {
// if we got here the default was requested, but it's ID wasn't
// found in the supported list, so the metadata is wrong
throw new MMSGeneralException("Internal Error! The default Model Source ("
+ getModelSourceMetadata().getDefaultSourceIdentifier()
+ ") was not found in the supported Model Sources");
}
return null;
}
private ApplicationService getApplicationServiceForUMLProjectIdentifier(UMLProjectIdentifer umlProjectIdentifer)
throws InvalidUMLProjectIndentifier, MMSGeneralException {
SourceDescriptor desc = getSourceDescriptorForUMLProjectIdentifier(umlProjectIdentifer);
if (desc == null) {
throw new InvalidUMLProjectIndentifier();
}
return getApplicationService(desc.getIdentifier());
}
}