package gov.nist.registry.ws.sq.ebxmlrr21;
import gov.nist.registry.common2.exception.ExceptionUtil;
import gov.nist.registry.common2.exception.MetadataException;
import gov.nist.registry.common2.exception.MetadataValidationException;
import gov.nist.registry.common2.exception.XMLParserException;
import gov.nist.registry.common2.exception.XdsException;
import gov.nist.registry.common2.exception.XdsInternalException;
import gov.nist.registry.common2.exception.XdsNonIdenticalHashException;
import gov.nist.registry.common2.registry.And;
import gov.nist.registry.common2.registry.BackendRegistry;
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.SQCodeAnd;
import gov.nist.registry.common2.registry.SQCodeOr;
import gov.nist.registry.common2.registry.SQCodedTerm;
import gov.nist.registry.common2.registry.storedquery.StoredQuerySupport;
import gov.nist.registry.ws.evs.Evs;
import gov.nist.registry.ws.sq.RegistryValidations;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import org.apache.axiom.om.OMElement;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openhealthtools.openxds.log.LoggerException;
public class EbXML21QuerySupport implements RegistryValidations {
private static final Log logger = LogFactory.getLog(EbXML21QuerySupport.class);
StoredQuerySupport sqs;
BackendRegistry br;
boolean where = false;
public EbXML21QuerySupport(StoredQuerySupport storedQuerySupport) {
sqs = storedQuerySupport;
br = new BackendRegistry(sqs.response, sqs.log_message);
init();
}
public StringBuffer getQuery() { return sqs.query; }
private void setQuery(StringBuffer buf) { sqs.query = buf; }
// sql specific
public List<String> getIdsFromRegistryResponse(OMElement rr) {
List<String> ids = new ArrayList<String>();
OMElement ahqr = MetadataSupport.firstChildWithLocalName(rr, "AdhocQueryResponse") ;
if (ahqr == null)
return ids;
OMElement sqr = MetadataSupport.firstChildWithLocalName(ahqr, "SQLQueryResult") ;
if (sqr == null)
return ids;
for (Iterator<OMElement> it=sqr.getChildElements(); it.hasNext();) {
OMElement ele = (OMElement) it.next();
if (sqs.return_leaf_class && ele.getLocalName().equals("ObjectRef"))
continue;
ids.add(ele.getAttributeValue(MetadataSupport.id_qname));
}
return ids;
}
public List<String> getIdsFromAdhocQueryResponse(OMElement rr) {
List<String> ids = new ArrayList<String>();
OMElement rol = MetadataSupport.firstChildWithLocalName(rr, "RegistryObjectList") ;
if (rol == null)
return ids;
for (Iterator<OMElement> it=rol.getChildElements(); it.hasNext();) {
OMElement ele = (OMElement) it.next();
if (sqs.return_leaf_class && ele.getLocalName().equals("ObjectRef"))
continue;
ids.add(ele.getAttributeValue(MetadataSupport.id_qname));
}
return ids;
}
// sql
public String declareClassifications(List<String> names) {
StringBuffer buf = new StringBuffer();
for (String name : names)
buf.append(", Classification " + name + "\n");
return buf.toString();
}
public String declareClassifications(SQCodedTerm term) {
if (term instanceof SQCodeOr)
return declareClassifications((SQCodeOr) term);
if (term instanceof SQCodeAnd)
return declareClassifications((SQCodeAnd) term);
return null;
}
public String declareClassifications(SQCodeOr or) {
StringBuffer buf = new StringBuffer();
buf.append(", Classification " + or.getCodeVarName() + "\n");
buf.append(", Slot " + or.getSchemeVarName() + "\n");
return buf.toString();
}
public String declareClassifications(SQCodeAnd and) {
StringBuffer buf = new StringBuffer();
for (String name : and.getCodeVarNames())
buf.append(", Classification " + name + "\n");
for (String name : and.getSchemeVarNames())
buf.append(", Slot " + name + "\n");
return buf.toString();
}
// sql
public List<String> query_for_object_refs() throws XMLParserException, LoggerException, XdsException {
return br.queryForObjectRefs(getQuery().toString());
}
// sql
public OMElement query() throws XdsException, LoggerException {
String q = getQuery().toString();
if (sqs.log_message != null)
sqs.log_message.addOtherParam("raw query", q);
return br.query(q, sqs.return_leaf_class);
}
// sql
public OMElement query(boolean leaf_class) throws XdsException, LoggerException {
String q = getQuery().toString();
if (sqs.log_message != null)
sqs.log_message.addOtherParam("raw query", q);
return br.query(q, leaf_class );
}
// sql
public void init() {
setQuery(new StringBuffer());
}
// sql
public void where() {
where = true;
String x = "WHERE";
getQuery().append(x);
}
public void and() {
if (!where)
a("AND");
where = false;
}
// sql
public void a(String x) {
where = false;
getQuery().append(x);
}
// sql
public void a_quoted(String x) {
where = false;
getQuery().append("'");
getQuery().append(x);
getQuery().append("'");
}
// sql
public void n() {
getQuery().append("\n");
}
// sql
public void a(List list) throws MetadataException {
getQuery().append("(");
boolean first_time = true;
for (int i=0; i<list.size(); i++) {
if ( !first_time)
getQuery().append(",");
Object o = list.get(i);
if (o instanceof String)
getQuery().append("'" + (String) o + "'");
else if (o instanceof Integer)
getQuery().append(((Integer) o).toString());
else {
String trace = null;
try {
throw new Exception("foo");
} catch (Exception e) {
trace = ExceptionUtil.exception_details(e);
}
throw new MetadataException("Parameter value " + o + " cannot be decoded: \n" + trace);
}
first_time = false;
}
getQuery().append(")");
}
// sql
public OMElement getDocById(String uuid) throws XdsException, LoggerException {
ArrayList<String> ids = new ArrayList<String>();
ids.add(uuid);
return getDocById(ids);
}
// sql
public OMElement getDocById(List<String> uuids) throws XdsException,
LoggerException {
init();
select("eo");
a("FROM ExtrinsicObject eo"); n();
a("WHERE "); n();
a(" eo.id IN "); a(uuids); n();
return query(sqs.return_leaf_class);
}
public OMElement getRegistryObjectById(List<String> uuids) throws XdsException,
LoggerException {
init();
select("eo");
a("FROM RegistryObject eo"); n();
a("WHERE "); n();
a(" eo.id IN "); a(uuids); n();
return query(sqs.return_leaf_class);
}
// sql
public OMElement getDocByUid(String uid) throws XdsException,
LoggerException {
ArrayList<String> uids = new ArrayList<String>();
uids.add(uid);
return getDocByUid(uids);
}
// sql
public OMElement getDocByUid(List<String> uids) throws XdsException,
LoggerException {
init();
select("eo");
a("FROM ExtrinsicObject eo, ExternalIdentifier ei"); n();
a("WHERE "); n();
a(" ei.registryObject=eo.id AND"); n();
a(" ei.identificationScheme='urn:uuid:2e82c1f6-a085-4c72-9da3-8640a32e42ab' AND"); n();
a(" ei.value IN "); a(uids); n();
return query(sqs.return_leaf_class);
}
// sql
public String getDocIdFromUid(String uid) throws XdsException,
LoggerException {
boolean rlc = sqs.return_leaf_class;
sqs.return_leaf_class = false;
OMElement result = getDocByUid(uid);
Metadata metadata = MetadataParser.parseNonSubmission(result);
List<OMElement> obj_refs = metadata.getObjectRefs();
if (obj_refs.size() == 0)
return null;
sqs.return_leaf_class = rlc;
return metadata.getId(obj_refs.get(0));
}
// sql
public OMElement getAssociations(List<String> source_or_target_ids, List<String> assoc_types, List<String> object_types) throws XdsException,
LoggerException {
List<String> a_types = assoc_types;
//No need to strict away namespace for associationTypes for V3
// List<String> a_types = new ArrayList<String>();
// if (assoc_types != null) {
// for (String type : assoc_types) {
// String[] parts = type.split(":");
// if (parts.length > 1)
// a_types.add(parts[parts.length -1]);
// else
// a_types.add(type);
// }
// }
init();
select("a");
a("FROM Association a, ExtrinsicObject doc"); n();
a("WHERE "); n();
a(" (a.sourceObject IN "); a(source_or_target_ids); a(" OR"); n();
a(" a.targetObject IN "); a(source_or_target_ids); a(" )"); n();
if (assoc_types != null) {
a(" AND a.associationType IN "); a(a_types); n();
}
if (object_types != null && object_types.size() > 0) {
a(" AND (doc.id=a.sourceobject OR doc.id=a.targetobject) AND doc.id NOT IN "); a(source_or_target_ids); n();
a(" AND doc.objecttype IN "); a(object_types); n();
}
return query(sqs.return_leaf_class);
}
/**
* Add code selection to restrict selection of DocumentEntries or SubmissionSets. When used
* to build SQL queries, the internal query buffer is appended with additional SELECT clauses
* to add restrictions to the query. Other implementations use other internal mechanisms.
* @param code_var temporary variable name for the code value, Used in building SQL queries
* @param code_scheme_var temporary variable name for the classification scheme
* @param code_class_uuid UUID of the classification scheme
* @param codes collection of code values to match against
* @param schemes collection of coding schemes to match against
* @throws MetadataException
*/
public void addCode(String code_var, String code_scheme_var, String code_class_uuid,
List codes, List schemes) throws MetadataException {
if (codes != null) { a("AND ("); a(code_var); a(".classifiedobject = doc.id AND "); n(); }
if (codes != null) { a(" "); a(code_var); a(".classificationScheme = '"); a(code_class_uuid); a("' AND "); n(); }
if (codes != null) { a(" "); a(code_var); a(".nodeRepresentation IN "); a(codes); a(" )"); n(); }
if (schemes != null) { a("AND ("); a(code_scheme_var); a(".parent = "); a(code_var); a(".id AND "); n(); }
if (schemes != null) { a(" "); a(code_scheme_var); a(".name = 'codingScheme' AND "); n(); }
if (schemes != null) { a(" "); a(code_scheme_var); a(".value IN "); a(schemes); a(" )"); n(); }
}
/**
* Add code selection to restrict selection of DocumentEntries. When used
* to build SQL queries, the internal query buffer is appended with additional SELECT clauses
* to add restrictions to the query. Other implementations use other internal mechanisms.
* @param code_vars - sql vars. Multiple per query param if AND logic invoked
* @param code_scheme_var
* @param code_class_uuid
* @param codes - list of codes to select on (OR logic) OR And structure containing lists of codes (OR structure)
* @param schemes - code schemes
* @throws MetadataException
*/
public void addCode(List<String> code_vars, String code_scheme_var, String code_class_uuid,
List<Object> codes, List schemes) throws MetadataException {
if (codes == null)
return;
if (code_vars.size() == 1) {
if (codes instanceof And)
throw new MetadataException("StoredQuery.add_code(): code_vars.size()==1 but codes have type And");
String code_var = code_vars.get(0);
and(); a(" ("); a(code_var); a(".classifiedobject = doc.id AND "); n();
a(" "); a(code_var); a(".classificationScheme = '"); a(code_class_uuid); a("' AND "); n();
a(" "); a(code_var); a(".nodeRepresentation IN "); a(codes); a(" )"); n();
if (schemes != null) {
and(); a(" ("); a(code_scheme_var); a(".parent = "); a(code_var); a(".id AND "); n();
a(" "); a(code_scheme_var); a(".name = 'codingScheme' AND "); n();
a(" "); a(code_scheme_var); a(".value IN "); a(schemes); a(" )"); n();
}
} else {
if ( !(codes instanceof And))
throw new MetadataException("StoredQuery.add_code(): code_vars.size() > 1 but codes not of type And");
for (int i=0; i<code_vars.size(); i++) {
String code_var = code_vars.get(i);
ArrayList<String> codes2 = (ArrayList<String>) codes.get(i);
and(); a(" ("); a(code_var); a(".classifiedobject = doc.id AND "); n();
a(" "); a(code_var); a(".classificationScheme = '"); a(code_class_uuid); a("' AND "); n();
a(" "); a(code_var); a(".nodeRepresentation IN "); a(codes2); a(" )"); n();
}
}
}
public void addCode(SQCodedTerm term) throws MetadataException {
addCode(term, "doc");
}
public void addCode(SQCodedTerm term, String owner_var) throws MetadataException {
if (term instanceof SQCodeOr)
addCode((SQCodeOr) term, owner_var);
if (term instanceof SQCodeAnd)
addCode((SQCodeAnd) term);
}
void addCode(SQCodeOr term) throws MetadataException {
addCode(term, "doc");
}
public void addCode(SQCodeOr term, String owner_var) throws MetadataException {
and(); a(" ("); a(term.getCodeVarName()); a(".classifiedobject = " + owner_var + ".id AND "); n();
a(" "); a(term.getCodeVarName()); a(".classificationScheme = '"); a(term.classification); a("' AND "); n();
a(" "); a(term.getCodeVarName()); a(".nodeRepresentation IN "); a(term.getCodes()); a(" )"); n();
and(); a(" ("); a(term.getSchemeVarName()); a(".parent = "); a(term.getCodeVarName()); a(".id AND "); n();
a(" "); a(term.getSchemeVarName()); a(".name = 'codingScheme' AND "); n();
a(" "); a(term.getSchemeVarName()); a(".value IN "); a(term.getSchemes()); a(" )"); n();
}
public void addCode(SQCodeAnd term) throws MetadataException {
for (SQCodeOr or : term.getCodeOrs()) {
addCode(or);
}
}
// times come in as numeric values but convert them to string values to avoid numeric overflow
public void addTimes(String att_name, String from_var, String to_var,
String from_limit, String to_limit, String var_name) {
if (from_limit != null) { and(); a(" ("); a(from_var); a(".parent = " + var_name + ".id AND "); n(); }
if (from_limit != null) { a(" ");a(from_var); a(".name = '"); a(att_name); a("' AND "); n(); }
if (from_limit != null) { a(" "); a(from_var); a(".value >= "); a_quoted(from_limit); a(" ) "); n(); }
if (to_limit != null) { and(); a(" ("); a(to_var); a(".parent = " + var_name + ".id AND "); n(); }
if (to_limit != null) { a(" "); a(to_var); a(".name = '"); a(att_name); a("' AND "); n(); }
if (to_limit != null) { a(" "); a(to_var); a(".value < "); a_quoted(to_limit); a(" ) "); n(); }
}
public OMElement getRpByUid(String uid, String identification_scheme) throws XdsException,
LoggerException {
init();
select("ss");
a("FROM RegistryPackage ss, ExternalIdentifier uniq"); n();
a("WHERE"); n();
a(" uniq.registryObject = ss.id AND"); n();
a(" uniq.identificationScheme = '" + identification_scheme + "' AND"); n();
a(" uniq.value = '" + uid + "'");
return query();
}
public OMElement getRpByUid(List<String> uids, String identification_scheme) throws XdsException,
LoggerException {
init();
select("ss");
a("FROM RegistryPackage ss, ExternalIdentifier uniq"); n();
a("WHERE"); n();
a(" uniq.registryObject = ss.id AND"); n();
a(" uniq.identificationScheme = '" + identification_scheme + "' AND"); n();
a(" uniq.value IN "); a(uids);
return query();
}
public OMElement getAssocById(String assoc_id)
throws XdsException, LoggerException {
init();
select("as");
a("FROM Association as"); n();
a("WHERE "); n();
a(" as.id = '" + assoc_id +"'"); n();
return query();
}
public OMElement getAssocById(List<String> assoc_ids)
throws XdsException, LoggerException {
init();
select("ass");
a("FROM Association ass"); n();
a("WHERE "); n();
a(" ass.id IN "); a(assoc_ids); n();
return query();
}
private void select(String varName) {
if (sqs.return_leaf_class)
a("SELECT * ");
else {
a("SELECT "); a(varName); a(".id ");
}
}
public OMElement getRpById(String rp_id, String identification_scheme)
throws XdsException, LoggerException {
init();
select("rp");
a("FROM RegistryPackage rp, ExternalIdentifier uniq"); n();
a("WHERE "); n();
a(" rp.id = '" + rp_id + "' AND"); n();
a(" uniq.registryObject = rp.id AND"); n();
a(" uniq.identificationScheme = '" + identification_scheme + "' "); n();
return query();
}
public OMElement getRpById(List<String> rp_id, String identification_scheme)
throws XdsException, LoggerException {
init();
select("ss");
a("FROM RegistryPackage ss, ExternalIdentifier uniq"); n();
a("WHERE "); n();
a(" ss.id IN "); a(rp_id); a(" AND"); n();
a(" uniq.registryObject = ss.id"); n();
if (identification_scheme != null) {
a(" AND uniq.identificationScheme = '" + identification_scheme + "' "); n();
}
return query();
}
/**
* Load LeafClass form for all objects. New Metadata object returned.
* @param m - metadata to fill in with LeafClass objects. Unaltered.
* @return new Metadata object
* @throws LoggerException
* @throws XdsException
*/
public Metadata convertToLeafClass(Metadata metadata) throws XdsException, LoggerException {
Metadata m = metadata.mkClone();
List<String> objectRefIds = m.getObjectRefIds();
// these could reference any type of object. Only interested in:
// RegistryPackage, ExtrinsicObject, Association
List<String> idsToRemove = new ArrayList<String>();
for (String id : objectRefIds) {
if (m.containsObject(id))
idsToRemove.add(id);
if ( ! m.isUuid(id))
throw new MetadataException("Cannot load object with id " + id + " from Registry, this id is not in UUID format (probabaly a symbolic name)");
}
objectRefIds.removeAll(idsToRemove);
// nothing left to load
if (objectRefIds.size() == 0)
return m;
m.clearObjectRefs();
boolean discard_duplicates = true;
boolean origLeafClass = sqs.return_leaf_class;
sqs.return_leaf_class = true;
m.addMetadata(getDocById(objectRefIds), discard_duplicates);
m.addMetadata(getRpById(objectRefIds, null), discard_duplicates);
m.addMetadata(getAssocById(objectRefIds), discard_duplicates);
sqs.return_leaf_class = origLeafClass;
return m;
}
public Metadata convertToObjectRefs(Metadata metadata, boolean ignoreExistingObjectRefs) throws XdsInternalException, MetadataException, MetadataValidationException {
Metadata m = metadata.mkClone();
if (ignoreExistingObjectRefs)
m.clearObjectRefs();
List<OMElement> leafClasses = m.getAllLeafClasses();
List<String> ids = m.getIdsForObjects(leafClasses);
m.mkObjectRefs(ids);
m.clearLeafClassObjects();
return m;
}
public OMElement getObjectsByUuid(List<String> uuids) throws XdsException, LoggerException {
if (uuids.size() == 0)
return null;
init();
select("ro");
a("FROM RegistryObject ro"); n();
a("WHERE "); n();
a(" ro.id IN "); a(uuids); n();
return query();
}
public OMElement getFolByUuid(String uuid) throws XdsException, LoggerException
{ return getRpById(uuid, "urn:uuid:75df8f67-9973-4fbe-a900-df66cefecc5a"); }
public OMElement getFolByUuid(List<String> uuid) throws XdsException, LoggerException
{ return getRpById(uuid, "urn:uuid:75df8f67-9973-4fbe-a900-df66cefecc5a"); }
public OMElement getFolByUid(String uid) throws XdsException, LoggerException
{ return getRpByUid(uid, "urn:uuid:75df8f67-9973-4fbe-a900-df66cefecc5a"); }
public OMElement getFolByUid(List<String> uid) throws XdsException, LoggerException
{ return getRpByUid(uid, "urn:uuid:75df8f67-9973-4fbe-a900-df66cefecc5a"); }
public OMElement getSsByUuid(String uuid) throws XdsException, LoggerException
{ return getRpById(uuid, "urn:uuid:96fdda7c-d067-4183-912e-bf5ee74998a8"); }
public OMElement getSsByUid(String uid) throws XdsException, LoggerException
{ return getRpByUid(uid, "urn:uuid:96fdda7c-d067-4183-912e-bf5ee74998a8"); }
public OMElement getRPDocs(String rp_uuid, List<String> format_codes, List<String> conf_codes, List<String> object_types)
throws XdsException, LoggerException {
init();
select("doc");
a("FROM ExtrinsicObject doc, Association a"); n();
if (conf_codes != null) { a(", Classification conf"); n(); }
if (format_codes != null){a(", Classification fmtCode"); n(); }
if (false) { a(", Slot adomain"); }
a("WHERE"); n();
a(" a.sourceObject = '" + rp_uuid + "' AND"); n();
a(" a.associationType = '"+ addAssociationTypeNamespace("HasMember") +"' AND"); n();
a(" a.targetObject = doc.id "); n();
if (conf_codes != null && conf_codes.size() > 0) {
a(" AND ("); n();
a(" conf.classificationScheme = 'urn:uuid:f4f85eac-e6cb-4883-b524-f2705394840f' AND"); n();
a(" conf.classifiedObject = doc.id AND"); n();
a(" conf.nodeRepresentation IN "); a(conf_codes); n();
a(")"); n();
}
if (format_codes != null && format_codes.size() > 0) {
a("AND ("); n();
a(" fmtCode.classifiedObject = doc.id AND"); n();
a(" fmtCode.classificationScheme = 'urn:uuid:a09d5840-386c-46f2-b5ad-9c3699a4309d' AND "); n();
a(" fmtCode.nodeRepresentation IN "); a(format_codes); n();
a(" ) "); n();
}
if (false) {
a(" AND (adomain.name='AffinityDomain' AND adomain.parent=doc.id AND adomain.value=$affinitydomain) ");
}
a(" AND doc.objecttype IN "); a(object_types); n();
return query();
}
public OMElement getRPDocs(String rp_uuid, SQCodedTerm format_codes, SQCodedTerm conf_codes, List<String> object_types)
throws XdsException, LoggerException {
init();
select("doc");
a("FROM ExtrinsicObject doc, Association a"); n();
if (conf_codes != null) { a(declareClassifications(conf_codes)); n(); }
if (format_codes != null){a(declareClassifications(format_codes)); n(); }
if (false) { a(", Slot adomain"); }
a("WHERE"); n();
a(" a.sourceObject = '" + rp_uuid + "' AND"); n();
a(" a.associationType = '"+ addAssociationTypeNamespace("HasMember") +"' AND"); n();
a(" a.targetObject = doc.id "); n();
addCode(conf_codes);
addCode(format_codes);
if (false) {
a(" AND (adomain.name='AffinityDomain' AND adomain.parent=doc.id AND adomain.value=$affinitydomain) ");
}
a(" AND doc.objecttype IN "); a(object_types); n();
return query();
}
public OMElement getFolDocs(String fol_uuid, List<String> format_codes, List<String> conf_codes, List<String> object_types)
throws XdsException, LoggerException {
return getRPDocs(fol_uuid, format_codes, conf_codes, object_types);
}
public OMElement getFolDocs(String fol_uuid, SQCodedTerm format_codes, SQCodedTerm conf_codes, List<String> object_types)
throws XdsException, LoggerException {
return getRPDocs(fol_uuid, format_codes, conf_codes, object_types);
}
public OMElement getSsDocs(String fol_uuid, List<String> format_codes, List<String> conf_codes, List<String> object_types)
throws XdsException, LoggerException {
return getRPDocs(fol_uuid, format_codes, conf_codes, object_types);
}
public OMElement getSsDocs(String fol_uuid, SQCodedTerm format_codes, SQCodedTerm conf_codes, List<String> object_types)
throws XdsException, LoggerException {
return getRPDocs(fol_uuid, format_codes, conf_codes, object_types);
}
public OMElement getRegistryPackageAssocs(List<String> package_uuids, List<String> content_uuids) throws XdsException,
LoggerException {
init();
select("ass");
a("FROM Association ass"); n();
a("WHERE"); n();
a(" ass.associationType = '"+ addAssociationTypeNamespace("HasMember") +"' AND"); n();
a(" ass.sourceObject IN (");
for (int i=0; i<package_uuids.size(); i++) {
if (i > 0) a(",");
a("'" + (String) package_uuids.get(i) + "'");
}
a(") AND"); n();
a("ass.targetObject IN (" );
for (int i=0; i<content_uuids.size(); i++) {
if (i > 0) a(",");
a("'" + (String) content_uuids.get(i) + "'");
}
a(")");
n();
return query();
}
public OMElement getRegistryPackageAssocs(List<String> package_uuids) throws XdsException,
LoggerException {
if (package_uuids == null || package_uuids.size() == 0)
return null;
init();
select("ass");
a("FROM Association ass"); n();
a("WHERE"); n();
a(" ass.associationType = '"+ addAssociationTypeNamespace("HasMember") +"' AND"); n();
a(" ass.sourceObject IN (");
for (int i=0; i<package_uuids.size(); i++) {
if (i > 0) a(",");
a("'" + (String) package_uuids.get(i) + "'");
}
a(")");
n();
return query();
}
public OMElement getFoldersForDocument(String uuid) throws XdsException,
LoggerException {
init();
select("fol");
a("FROM RegistryPackage fol, ExternalIdentifier uniq, Association a"); n();
a("WHERE"); n();
a(" a.associationType = '"+ addAssociationTypeNamespace("HasMember") +"' AND"); n();
a(" a.targetObject = '" + uuid + "' AND"); n();
a(" a.sourceObject = fol.id AND"); n();
a(" uniq.registryObject = fol.id AND"); n();
a(" uniq.identificationScheme = '" + "urn:uuid:75df8f67-9973-4fbe-a900-df66cefecc5a" + "' "); n();
return query();
}
public OMElement get_submissionsets_of_contents(List<String> contents_uuids) throws XdsException,
LoggerException {
init();
select("rp");
a("FROM RegistryPackage rp, Association a, ExternalIdentifier ei"); n();
a("WHERE "); n();
a(" a.sourceObject = rp.id AND"); n();
a(" a.associationType = '"+ addAssociationTypeNamespace("HasMember")+"' AND"); n();
a(" a.targetObject IN "); a(contents_uuids); a(" AND"); n();
a(" ei.registryObject = rp.id AND"); n();
a(" ei.identificationScheme = 'urn:uuid:6b5aea1a-874d-4603-a4bc-96a0a7b38446'"); n();
return query(sqs.return_leaf_class);
}
private String addAssociationTypeNamespace(String type) {
return MetadataSupport.association_type_namespace + type;
}
private String addStatusTypeNamespace(String type) {
return MetadataSupport.status_type_namespace + type;
}
public OMElement get_associations(String type, List<String> froms, List<String> tos)
throws XdsException, LoggerException {
init();
select("a");
a("FROM Association a"); n();
a("WHERE "); n();
a(" a.associationType = '" + addAssociationTypeNamespace(type) + "' AND"); n();
a(" a.sourceObject IN"); a(froms); a(" AND"); n();
a(" a.targetObject IN"); a(tos); n();
return query(sqs.return_leaf_class);
}
public OMElement getSsFolders(String ss_uuid) throws XdsException,
LoggerException {
init();
select("fol");
a("FROM RegistryPackage fol, Association a"); n();
a("WHERE"); n();
a(" a.associationType = '"+ addAssociationTypeNamespace("HasMember") +"' AND"); n();
a(" a.sourceObject = '" + ss_uuid + "' AND"); n();
a(" a.targetObject = fol.id "); n();
return query();
}
public List<String> validateApproved(List<String> uuids) throws XdsException,LoggerException {
init();
a("SELECT * FROM ExtrinsicObject eo"); n();
a("WHERE"); n();
a(" eo.status = '"+ addStatusTypeNamespace("Approved") +"' AND"); n();
a(" eo.id IN "); a(uuids); n();
List<String> results1 = query_for_object_refs();
init();
a("SELECT * FROM RegistryPackage rp"); n();
a("WHERE"); n();
a(" rp.status = '"+ addStatusTypeNamespace("Approved") +"' AND"); n();
a(" rp.id IN "); a(uuids); n();
List<String> results = 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;
}
/**
* Validate uids found in metadata are proper. Uids of Folder and Submission Set may not
* be already present in registry. Uid of DocumentEntry objects may be present if hash and
* size match.
* @param metadata
* @throws MetadataValidationException - on all metadata errors
* @throws XdsNonIdenticalHashException - if uid found in registry with different hash
* @throws LoggerException - on error writing to Test Log
* @throws XdsException - on low level interface errors
* @throws XMLParserException
*/
public void validateProperUids(Metadata metadata) throws LoggerException, XMLParserException, XdsException {
// uid_hash is uid => hash (null for non documents)
HashMap<String, List<String>> uid_hash = metadata.getUidHashMap();
List<String> uids = new ArrayList<String>(); // all uids in metadata
uids.addAll(uid_hash.keySet());
List<String> uuids = getUuidForUid(uids);
if (uuids.size() == 0)
return;
// at least one uniqueId is already present in the registry. If it is from a document
// and the hash and size are the same then it is ok. Otherwise it is an error.
sqs.forceLeafClassQueryType();
OMElement offendingObjects = getObjectsByUuid(uuids); // LeafClass for offending objects
sqs.restoreOriginalQueryType();
if (offendingObjects == null)
throw new XdsInternalException("RegistryObjectValidator.validateProperUids(): could not retrieve LeafClass for ObjectRef obtained from registry: UUIDs were " + uuids);
Metadata m = MetadataParser.parseNonSubmission(offendingObjects);
List<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());
// Generate error messages that are object type specific
dupUidErrorException(metadata,
dup_uids,
"SubmissionSet",
metadata.getSubmissionSetIds(),
MetadataSupport.XDSSubmissionSet_uniqueid_uuid);
dupUidErrorException(metadata,
dup_uids,
"Folder",
metadata.getFolderIds(),
MetadataSupport.XDSFolder_uniqueid_uuid);
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 (logger.isDebugEnabled()) {
logger.debug("doc_uid " + doc_uid);
logger.debug("sub_hash " + sub_hash);
logger.debug("reg_hash " + reg_hash);
}
if (sub_hash != null && reg_hash != null && !sub_hash.equals(reg_hash))
throw new XdsNonIdenticalHashException(
"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
);
}
}
}
private void dupUidErrorException(Metadata metadata, List<String> dup_uids,
String type, List<String> ids, String type_uniqueId_type)
throws MetadataException, MetadataValidationException {
for (String suuid : ids) {
String sid = metadata.getExternalIdentifierValue(suuid, type_uniqueId_type);
if (dup_uids.contains(sid)) {
throw new MetadataValidationException(type + " uniqueId " +
sid +
" already present in the registry");
}
}
}
private List<String> getUuidForUid(List<String> uids)
throws MetadataException, XdsException, XMLParserException, LoggerException {
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);
init();
a("SELECT ro.id from RegistryObject ro, ExternalIdentifier ei"); n();
a("WHERE"); n();
a(" ei.registryobject = ro.id AND "); n();
a(" ei.identificationScheme IN "); a(uid_id_schemes); a(" AND"); n();
a(" ei.value IN "); a(uids); n();
// these uuids identify objects that carry one of the uids passed in in the map
List<String> uuids = query_for_object_refs();
return uuids;
}
}