package gov.nist.registry.ws.sq.ebxmlrr21; 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.MetadataSupport; import gov.nist.registry.common2.registry.storedquery.StoredQuerySupport; import gov.nist.registry.ws.sq.RegistryObjectValidator; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.axiom.om.OMElement; import org.openhealthtools.openxds.log.LoggerException; public class EbXML21RegistryObjectValidator implements RegistryObjectValidator { StoredQuerySupport sqs; EbXML21QuerySupport eb; public EbXML21RegistryObjectValidator(StoredQuerySupport sqs) { this.sqs = sqs; this.eb = new EbXML21QuerySupport(sqs); } /* (non-Javadoc) * @see gov.nist.registry.ws.sq.ebxmlrr21.RegistryObjectValidator#validateExists(java.util.List) */ public List<String> validateExists(List<String> uuids) throws XdsException, LoggerException { eb.init(); eb.a("SELECT * FROM RegistryObject ro"); eb.n(); eb.a("WHERE"); eb.n(); eb.a(" ro.id IN "); eb.a(uuids); eb.n(); List<String> results = eb.query_for_object_refs(); List<String> missing = null; for (int i=0; i<uuids.size(); i++) { String uuid = (String) uuids.get(i); if ( !results.contains(uuid)) { if (missing == null) missing = new ArrayList<String>(); missing.add(uuid); } } return missing; } List<String> uuidsOnly(List<String> ids) { List<String> uuids = new ArrayList<String>(); for (String id : ids) { if (id.startsWith("urn:uuid:")) uuids.add(id); } return uuids; } // returns UUIDs that do exist in registry /* (non-Javadoc) * @see gov.nist.registry.ws.sq.ebxmlrr21.RegistryObjectValidator#validateNotExists(java.util.ArrayList) */ public List<String> validateNotExists(List<String> ids) throws XdsException, LoggerException { List<String> uuids = uuidsOnly(ids); eb.init(); eb.a("SELECT * FROM RegistryObject ro"); eb.n(); eb.a("WHERE"); eb.n(); eb.a(" ro.id IN "); eb.a(uuids); eb.n(); List<String> results = eb.query_for_object_refs(); return results; } // uid_hash is uid => hash (null for non documents) /* (non-Javadoc) * @see gov.nist.registry.ws.sq.ebxmlrr21.RegistryObjectValidator#validateProperUids(gov.nist.registry.common2.registry.Metadata) */ public void validateProperUids(Metadata metadata) throws XdsException, LoggerException { Map<String, List<String>> uid_hash = metadata.getUidHashMap(); List<String> uids = new ArrayList<String>(); uids.addAll(uid_hash.keySet()); List<String> uid_id_schemes = new ArrayList<String>(); uid_id_schemes.add(MetadataSupport.XDSFolder_uniqueid_uuid); uid_id_schemes.add(MetadataSupport.XDSSubmissionSet_uniqueid_uuid); uid_id_schemes.add(MetadataSupport.XDSDocumentEntry_uniqueid_uuid); eb.init(); eb.a("SELECT ro.id from RegistryObject ro, ExternalIdentifier ei"); eb.n(); eb.a("WHERE"); eb.n(); eb.a(" ei.registryobject = ro.id AND "); eb.n(); eb.a(" ei.identificationScheme IN "); eb.a(uid_id_schemes); eb.a(" AND"); eb.n(); eb.a(" ei.value IN "); eb.a(uids); eb.n(); // these uuids identify objects that carry one of the uids passed in in the map List<String> uuids = eb.query_for_object_refs(); if (uuids.size() == 0) return; // at least one uniqueId is already present in the registry. If it is from a document // and the hashes are the same. Otherwise it is an error. sqs.return_leaf_class = true; OMElement objects = eb.getObjectsByUuid(uuids); // LeafClass for offending objects if (objects == null) throw new XdsInternalException("RegistryObjectValidator.validateProperUids(): could not retrieve LeafClass for ObjectRef obtained from registry: UUIDs were " + uuids); Metadata m = MetadataParser.parseNonSubmission(objects); ArrayList<String> dup_uids = new ArrayList<String>(); HashMap<String, OMElement> dup_objects = m.getUidMap(); dup_uids.addAll(dup_objects.keySet()); sqs.log_message.addOtherParam("dup uuids", uuids.toString()); sqs.log_message.addOtherParam("dup uids", dup_uids.toString()); for (String suuid : metadata.getSubmissionSetIds()) { String sid = metadata.getExternalIdentifierValue(suuid, MetadataSupport.XDSSubmissionSet_uniqueid_uuid); sqs.log_message.addOtherParam("ssuid", sid); if (dup_uids.contains(sid)) { throw new MetadataValidationException("SubmissionSet uniqueId " + sid + " ( id = " + suuid + " ) " + " already present in the registry"); } } for (String fuuid : metadata.getFolderIds()) { String fuid = metadata.getExternalIdentifierValue(fuuid, MetadataSupport.XDSFolder_uniqueid_uuid); sqs.log_message.addOtherParam("fuid", fuid); if (dup_uids.contains(fuid)) { throw new MetadataValidationException("Folder uniqueId " + fuid + " ( id = " + fuuid + " ) " + " already present in the registry"); } } HashMap<String, OMElement> docs_submit_uid_map = metadata.getUidMap(metadata.getExtrinsicObjects()); for (String doc_uid : docs_submit_uid_map.keySet()) { if (dup_uids.contains(doc_uid)) { OMElement reg_obj = dup_objects.get(doc_uid); String type = reg_obj.getLocalName(); if ( !type.equals("ExtrinsicObject")) throw new MetadataValidationException("Document uniqueId " + doc_uid + " already present in the registry on a non-document object"); OMElement sub_obj = docs_submit_uid_map.get(doc_uid); String sub_hash = m.getSlotValue(sub_obj, "hash", 0); String reg_hash = m.getSlotValue(reg_obj, "hash", 0); if (sub_hash != null && reg_hash != null && !sub_hash.equals(reg_hash)) sqs.response.add_error(MetadataSupport.XDSNonIdenticalHash, "UniqueId " + doc_uid + " exists in both the submission and Registry and the hash value is not the same: " + "Submission Hash Value = " + sub_hash + " and " + "Registry Hash Value = " + reg_hash, "RegistryObjectValidation.java", sqs.log_message); } } } /* (non-Javadoc) * @see gov.nist.registry.ws.sq.ebxmlrr21.RegistryObjectValidator#validateDocuments(java.util.List) */ public List<String> validateDocuments(List<String> uuids) throws XdsException,LoggerException { eb.init(); eb.a("SELECT * FROM ExtrinsicObject eo"); eb.n(); eb.a("WHERE"); eb.n(); eb.a(" eo.id IN "); eb.a(uuids); eb.n(); List<String> results = eb.query_for_object_refs(); List<String> missing = null; for (int i=0; i<uuids.size(); i++) { String uuid = (String) uuids.get(i); if ( !results.contains(uuid)) { if (missing == null) missing = new ArrayList<String>(); missing.add(uuid); } } return missing; } // validate the ids are in registry and belong to folders // return any that aren't /* (non-Javadoc) * @see gov.nist.registry.ws.sq.ebxmlrr21.RegistryObjectValidator#validateAreFolders(java.util.List) */ public List<String> validateAreFolders(List<String> ids) throws XdsException,LoggerException { eb.init(); eb.a("SELECT rp.id FROM RegistryPackage rp, ExternalIdentifier ei"); eb.n(); eb.a("WHERE"); eb.n(); eb.a(" rp.status = '"+ addStatusTypeNamespace("Approved")+"' AND"); eb.n(); eb.a(" rp.id IN "); eb.a(ids); eb.a(" AND"); eb.n(); eb.a(" ei.registryObject = rp.id AND"); eb.n(); eb.a(" ei.identificationScheme = '" + MetadataSupport.XDSFolder_patientid_uuid + "'"); eb.n(); //br.setReason("Verify are Folders"); List<String> results1 = eb.query_for_object_refs(); List<String> missing = null; for (String id : ids) { if ( !results1.contains(id)) { if (missing == null) missing = new ArrayList<String>(); missing.add(id); } } return missing; } // these selects cannot work!!! /* (non-Javadoc) * @see gov.nist.registry.ws.sq.ebxmlrr21.RegistryObjectValidator#validateApproved(java.util.List) */ public List<String> validateApproved(List<String> uuids) throws XdsException,LoggerException { eb.init(); eb.a("SELECT * FROM ExtrinsicObject eo"); eb.n(); eb.a("WHERE"); eb.n(); eb.a(" eo.status = '"+ addStatusTypeNamespace("Approved")+"' AND"); eb.n(); eb.a(" eo.id IN "); eb.a(uuids); eb.n(); List<String> results1 = eb.query_for_object_refs(); eb.init(); eb.a("SELECT * FROM RegistryPackage eo"); eb.n(); eb.a("WHERE"); eb.n(); eb.a(" eo.status = '"+ addStatusTypeNamespace("Approved") +"' AND"); eb.n(); eb.a(" eo.id IN "); eb.a(uuids); eb.n(); List<String> results = eb.query_for_object_refs(); results.addAll(results1); List<String> missing = null; for (int i=0; i<uuids.size(); i++) { String uuid = (String) uuids.get(i); if ( !results.contains(uuid)) { if (missing == null) missing = new ArrayList<String>(); missing.add(uuid); } } return missing; } /* (non-Javadoc) * @see gov.nist.registry.ws.sq.ebxmlrr21.RegistryObjectValidator#validateSamePatientId(java.util.List, java.lang.String) */ public List<String> validateSamePatientId(List<String> uuids, String patient_id) throws XdsException,LoggerException { if (uuids.size() == 0) return null; eb.init(); eb.a("SELECT eo.id FROM ExtrinsicObject eo, ExternalIdentifier pid"); eb.n(); eb.a("WHERE"); eb.n(); eb.a(" eo.id IN "); eb.a(uuids); eb.a(" AND "); eb.n(); eb.a(" pid.registryobject = eo.id AND"); eb.n(); eb.a(" pid.identificationScheme='urn:uuid:58a6f841-87b3-4a3e-92fd-a8ffeff98427' AND"); eb.n(); eb.a(" pid.value = '"); eb.a(patient_id); eb.a("'"); eb.n(); List<String> results1 = eb.query_for_object_refs(); eb.init(); eb.a("SELECT eo.id FROM RegistryPackage eo, ExternalIdentifier pid"); eb.n(); eb.a("WHERE"); eb.n(); eb.a(" eo.id IN "); eb.a(uuids); eb.a(" AND"); eb.n(); eb.a(" pid.registryobject = eo.id AND"); eb.n(); eb.a(" pid.identificationScheme IN ('urn:uuid:6b5aea1a-874d-4603-a4bc-96a0a7b38446','urn:uuid:f64ffdf0-4b97-4e06-b79f-a52b38ec2f8a') AND"); eb.n(); eb.a(" pid.value = '"); eb.a(patient_id); eb.a("'"); eb.n(); List<String> results = eb.query_for_object_refs(); results.addAll(results1); List<String> missing = null; for (int i=0; i<uuids.size(); i++) { String uuid = (String) uuids.get(i); if ( !results.contains(uuid)) { if (missing == null) missing = new ArrayList<String>(); missing.add(uuid); } } return missing; } /* (non-Javadoc) * @see gov.nist.registry.ws.sq.ebxmlrr21.RegistryObjectValidator#getXFRMandAPNDDocuments(java.util.List) */ public List<String> getXFRMandAPNDDocuments(List<String> uuids) throws XdsException, LoggerException { if (uuids.size() == 0) return new ArrayList<String>(); eb.init(); eb.a("SELECT eo.id FROM ExtrinsicObject eo, Association a"); eb.n(); eb.a("WHERE"); eb.n(); eb.a(" a.associationType in ('"+ addAssociationTypeNamespace("XFRM") +"', '"+ addAssociationTypeNamespace("APND") +"') AND"); eb.n(); eb.a(" a.targetObject IN "); eb.a(uuids); eb.a(" AND"); eb.n(); eb.a(" a.sourceObject = eo.id"); eb.n(); return eb.query_for_object_refs(); } private String addAssociationTypeNamespace(String type) { return MetadataSupport.association_type_namespace + type; } private String addStatusTypeNamespace(String type) { return MetadataSupport.status_type_namespace + type; } }