package gov.nist.registry.ws.sq.ebxmlrr21;
import gov.nist.registry.common2.exception.MetadataException;
import gov.nist.registry.common2.exception.MetadataValidationException;
import gov.nist.registry.common2.exception.XdsException;
import gov.nist.registry.common2.exception.XdsInternalException;
import gov.nist.registry.common2.registry.Metadata;
import gov.nist.registry.common2.registry.MetadataParser;
import gov.nist.registry.common2.registry.storedquery.StoredQuerySupport;
import gov.nist.registry.ws.sq.GetRelatedDocuments;
import java.util.ArrayList;
import java.util.List;
import org.apache.axiom.om.OMElement;
import org.openhealthtools.openxds.log.LoggerException;
/**
* Implementation specific class for GetRelatedDocuments stored query.
* All the logic is in the runImplementation() method.
* @author bill
*
*/
public class EbXML21GetRelatedDocuments extends GetRelatedDocuments {
EbXML21QuerySupport eb;
/**
* Constructor
* @param sqs
* @throws MetadataValidationException
*/
public EbXML21GetRelatedDocuments(StoredQuerySupport sqs) {
super(sqs);
eb = new EbXML21QuerySupport(sqs);
}
/**
* Main method, runs query logic
* @return Metadata
* @throws MetadataException
* @throws XdsException
*/
public Metadata runImplementation() throws XdsInternalException,
XdsException, LoggerException, MetadataException,
MetadataValidationException {
Metadata result_metadata = new Metadata();
// this object will be build carefully containing no extra ObjectRefs. At the
// end, its contents will be converted to LeafClass or ObjectRef depending on
// the requested return type.
// the queries that this code depends on are controlled by the StoredQuerySupport
// object. It specifies whether LeafClass or ObjectRef return is
// requested. So, when a specific low level query is issued, it could
// return ObjectRefs or LeafClasses. For some objects, like Associations,
// we must get LeafClass so to get access to the attributes. The
// last operation is to convert everything over to LeafClass or ObjectRef
// objects to conform to the requested return type.
// // are these needed?
// List<String> doc_ids_to_query_for = new ArrayList<String>();
// List<String> doc_ids = new ArrayList<String>();
if (assoc_types == null || assoc_types.size() == 0) {
throw new XdsInternalException("No $AssociationTypes specified in query");
}
// filter HasMember out of assoc_types if it exists
// because we return only related documents and assocs
// and HasMember never exists between documents
String excludeAssocType = "HasMember";
assoc_types = removeAssocType(assoc_types, excludeAssocType);
// if uuid supplied, save it in originalDocId
// if uid supplied, query to get it and save its id in originalDocId
String originalDocId;
if (uid != null) {
OMElement ele = eb.getDocByUid(uid);
Metadata orig_doc_metadata = MetadataParser.parseNonSubmission(ele);
if (orig_doc_metadata.getExtrinsicObjects().size() > 0) {
result_metadata.addExtrinsicObjects(orig_doc_metadata.getExtrinsicObjects());
originalDocId = orig_doc_metadata.getExtrinsicObjectIds().get(0);
}
else if (orig_doc_metadata.getObjectRefs().size() > 0) {
result_metadata.addObjectRefs(orig_doc_metadata.getObjectRefs());
originalDocId = orig_doc_metadata.getObjectRefIds().get(0);
}
else
return result_metadata; // original document not found - return empty
} else {
originalDocId = uuid;
}
sqs.log_message.addOtherParam("originalDocId", originalDocId);
sqs.log_message.addOtherParam("structure", result_metadata.structure());
// at this point result_metadata contains either a single ObjectRef or a single
// ExtrinsicObject representing the target document. originalDocId has its
// id
// load all associations related to combined_ids
List<String> targetIds = new ArrayList<String>();
targetIds.add(originalDocId);
sqs.forceLeafClassQueryType(); // fetch LeafClass for Associations
OMElement associations = eb.getAssociations(targetIds, assoc_types, object_type);
sqs.restoreOriginalQueryType();
Metadata association_metadata = MetadataParser.parseNonSubmission(associations);
// no associations => return nothing
if (association_metadata.getAssociations().size() == 0) {
return new Metadata();
}
// add associations to final result
result_metadata.addToMetadata(association_metadata.getLeafClassObjects(), true);
sqs.log_message.addOtherParam("with Associations", result_metadata.structure());
// discover ids (potentially for documents) that are referenced by the associations
List<String> assocReferences = association_metadata.getAssocReferences();
result_metadata.addObjectRefs(assocReferences);
if (sqs.return_leaf_class) {
return eb.convertToLeafClass(result_metadata);
}
else
return eb.convertToObjectRefs(result_metadata, false);
}
private List<String> removeAssocType(List<String> assoc_types, String excludeAssocType) {
Metadata meta = new Metadata();
List<String> assoc_types2 = new ArrayList<String>();
for (String type : assoc_types) {
String v2_type = meta.v2AssocType(type);
if ( !v2_type.equals(excludeAssocType))
assoc_types2.add(type);
}
return assoc_types2;
}
}