/** * Copyright (c) 2009-2010 Misys Open Source Solutions (MOSS) and others * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. * * Contributors: * Misys Open Source Solutions - initial API and implementation * - */ package org.openhealthtools.openxds.webapp.control; import gov.nist.registry.common2.exception.MetadataException; import gov.nist.registry.common2.exception.MetadataValidationException; import gov.nist.registry.common2.registry.Metadata; import gov.nist.registry.common2.registry.MetadataSupport; import gov.nist.registry.common2.xml.Util; import gov.nist.registry.common2.xml.XmlFormatter; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.axiom.om.OMElement; /** * Class to control the query objects. * @author <a href="anilkumar.reddy@misys.com">Anil Kumar</a> */ public class QueryControl { String endpoint; // uuid => <query_type, queryContents> // in case of error, uuid could be uid instead // HashMap<String, HashMap<String, QueryContents>> map; ArrayList<QueryContents> queryContents; // repositoryUniqueId -> [secure endpoint, unsecure endpoint] public HashMap<String, ArrayList<String>> repositories; Metadata metadata = null; // contents of all queries combined // query types static final String ssac="ssac"; // GetSubmissionSetAndContents boolean leafClassQuery = true; String queryAction = "urn:ihe:iti:2007:RegistryStoredQuery"; String queryResultAction = "urn:ihe:iti:2007:RegistryStoredQueryResponse"; /*public String getHome(String id) throws MetadataException { String home = null; for (QueryContents qc : queryContents) { String h = qc.getHome(id); if (h == null) continue; if (h.equals("") && home == null) { home = h; continue; } if (home == null) home = h; else if ( !home.equals(h)) { // oops, two homes for this object throw new MetadataException("Multiple homeCommunityIds for object " + id + " " + home + " and " + h); } } return home; }*/ public void leafClassQuery(boolean newvalue) { leafClassQuery = newvalue; } public QueryControl() { // map = new HashMap<String, HashMap<String, QueryContents>>(); metadata = new Metadata(); queryContents = new ArrayList<QueryContents>(); } public QueryControl(QueryContents qc) { this.endpoint = null; // map = null; metadata = qc.getMetadata(); queryContents = new ArrayList<QueryContents>(); queryContents.add(qc); } void logException(Exception e, QueryContents qc) { StackTraceElement[] st = e.getStackTrace(); StringBuffer buf = new StringBuffer(); for (StackTraceElement ste : st) { buf.append(ste.toString()); buf.append("\n"); } qc.addFatalError(buf.toString()); } public QueryControl(String filecontents) { this.endpoint = null; // this.map = null; this.metadata = new Metadata(); this.queryContents = new ArrayList<QueryContents>(); OMElement ele = null; try { ele = Util.parse_xml(filecontents); } catch (Exception e) { QueryContents qc = new BasicQueryContents(); qc.setQueryType("BadResults"); logException(e, qc); try { this.addQueryContents(qc); } catch (Exception e1 ) { logException(e1, qc); } } System.out.println("file input parse complete: root is " + ele.getLocalName()); if (ele.getLocalName().equals("TestResults")) { OMElement fatalele = MetadataSupport.firstChildWithLocalName(ele, "FatalError"); if (fatalele != null) { System.out.println("fatal error: " + fatalele.getText()); String fatalmessage = fatalele.getText(); if (fatalmessage != null && !fatalmessage.equals("")) { QueryContents qc = new BasicQueryContents(); qc.addFatalError(fatalmessage); qc.setQueryType("FatalError"); try { this.addQueryContents(qc); } catch (Exception e) { logException(e,qc); } } } for(OMElement ts : MetadataSupport.childrenWithLocalName(ele, "TestStep")) { try { String id = ts.getAttributeValue(MetadataSupport.id_qname); String step_status = ts.getAttributeValue(MetadataSupport.status_qname); OMElement trans_output = find_transaction_output(ts); if (trans_output == null) { throw new Exception("Cannot find transaction output from step " + id); } OMElement input = MetadataSupport.firstChildWithLocalName(trans_output, "InputMetadata"); if (input == null) { throw new Exception("Cannot find InputMetadata from step " + id); } OMElement result = MetadataSupport.firstChildWithLocalName(trans_output, "Result"); if (result == null) { throw new Exception("Cannot find Result from step " + id); } OMElement result_1 = result.getFirstElement(); if (result_1 == null) { throw new Exception("Cannot find content of Result from step " + id); } String result_status = result_1.getAttributeValue(MetadataSupport.status_qname); OMElement expected_status_ele = MetadataSupport.firstChildWithLocalName(ts, "ExpectedStatus"); String expected_status = "none"; if (expected_status_ele == null) { throw new Exception("Cannot find ExpectedStatus from step " + id); } else { expected_status = expected_status_ele.getText(); } LogFileQueryContents qc = new LogFileQueryContents(); qc.setQueryType("Step " + id); qc.expected_status = expected_status; qc.reference_id = id; qc.step_status = step_status; qc.input = (input != null) ? input.getFirstElement() : null; qc.result = (result != null) ? result.getFirstElement() : null; qc.teststep = ts; qc.findMetadata(); System.out.println("Found step " + id); //qc.validate_inputs(); if (qc.getMetadata() == null) System.out.println("Did not find metadata in step"); else System.out.println("Found metadata in step"); try { this.addQueryContents(qc); } catch (Exception e1 ) { logException(e1, qc); } } catch (Exception e) { QueryContents qc = new BasicQueryContents(); qc.setQueryType("BadResults"); logException(e, qc); System.out.println("log exception: " + e.getMessage()); try { this.addQueryContents(qc); } catch (Exception e1 ) { logException(e1, qc); } } } } else { QueryContents qc = new SSandContentsQueryContents(); qc.parseMetadataFromLogFile(ele); try { this.addQueryContents(qc); } catch (Exception e ) { logException(e, qc); } } } public void deleteQueryContents(int i) { if (i < this.queryContents.size()) this.queryContents.set(i, null); } OMElement find_transaction_output(OMElement stepele) { for (Iterator<OMElement> it=stepele.getChildElements(); it.hasNext(); ) { OMElement child = it.next(); String name = child.getLocalName(); if (name.endsWith("Transaction")) return child; } return null; } public void setEndpoint(String endpoint) { this.endpoint = endpoint; } public boolean hasEndpoint() { return endpoint != null; } boolean is_uuid(String id) { return id.startsWith("urn:uuid:"); } // void add_results_for_object(String uuid, String query_type, QueryContents contents) { // HashMap<String, QueryContents> contents_map = map.get(uuid); // if (contents_map == null) { // contents_map = new HashMap<String, QueryContents>(); // map.put(uuid, contents_map); // } // contents_map.put(query_type, contents); // queryContents.add(contents); // } // // public QueryContents get_results_for_object(String uuid, String query_type) { // HashMap<String, QueryContents> contents_map = map.get(uuid); // if (contents_map == null) // return null; // return contents_map.get(query_type); // } public ArrayList<QueryContents> getAllQueryContents() { return queryContents; } public QueryContents getQueryContents(int i) { if (i < 0 || i >= queryContents.size()) return null; return queryContents.get(i); } public int getQueryContentsIndex(QueryContents contents) { for (int i=0; i<queryContents.size(); i++) { if (queryContents.get(i) == contents) return i; } return -1; } boolean is_endpoint_secure() { return endpoint.startsWith("https"); } public QueryContents queryFindFol(String pid) throws MetadataValidationException, MetadataException { FolQueryContents queryContents = new FolQueryContents(); queryContents.setQueryType("Find Fol for"); runQuery(singleton(pid), new FindFolders(), queryContents, queryAction, queryResultAction); Metadata m = queryContents.getMetadata(); boolean object_refs = m.isObjectRefsOnly(); if (object_refs) { queryContents.init(this); queryContents.type_ss(); queryContents.preload(); } return queryContents; } public QueryContents queryFindSS(String pid) throws MetadataValidationException, MetadataException { SSQueryContents queryContents = new SSQueryContents(); queryContents.setQueryType("Find SS for"); runQuery(singleton(pid), new FindSubmissionSets(), queryContents, queryAction, queryResultAction); Metadata m = queryContents.getMetadata(); boolean object_refs = m.isObjectRefsOnly(); if (object_refs) { queryContents.init(this); queryContents.type_ss(); queryContents.preload(); } return queryContents; } public QueryContents queryFindDoc(String pid) throws MetadataValidationException, MetadataException { FindDocsQueryContents queryContents = new FindDocsQueryContents(); queryContents.setQueryType("Find Docs for"); if (leafClassQuery) runQuery(singleton(pid), new FindDocuments(true, queryContents), queryContents, queryAction, queryResultAction); else runQuery(singleton(pid), new FindDocuments(false, queryContents), queryContents, queryAction, queryResultAction); Metadata m = queryContents.getMetadata(); boolean object_refs = m.isObjectRefsOnly(); if (object_refs) { queryContents.init(this); queryContents.type_doc(); queryContents.preload(); } // remember returned homeCommunityId for later if it is present List<OMElement> objects = m.getMajorObjects(); return queryContents; } // id may be id or uid public QueryContents queryGetDocuments(ArrayList<String> ids) throws MetadataException { QueryContents queryContents = new DocsQueryContents(); queryContents.setQueryType("Documents"); runQuery(ids, new GetDocument(), queryContents, queryAction, queryResultAction); return queryContents; } // id may be id or uid public QueryContents queryGetSSandContents(ArrayList<String> ids) throws MetadataException { QueryContents queryContents = new SSandContentsQueryContents(); queryContents.setQueryType("SSandContents"); runQuery(ids, new GetSubmissionSetAndContents(), queryContents, queryAction, queryResultAction); return queryContents; } // id may be id or uid public QueryContents queryGetFolandContents(ArrayList<String> ids) throws MetadataException { QueryContents queryContents = new FolandContentsQueryContents(); queryContents.setQueryType("FolandContents"); runQuery(ids, new GetFolderAndContents(), queryContents, queryAction, queryResultAction); return queryContents; } /*public QueryContents retrieve_b(ArrayList<String> ids) throws MetadataException { RetrieveBQueryContents queryContents = new RetrieveBQueryContents(); queryContents.setQueryType("Retrieve.b"); queryContents.secure(is_endpoint_secure()); queryContents.setInitialEvidence(ids); queryContents.setEndpoint(this.endpoint); System.out.println("Ret.b: XCA? " + isXca() + " id = " + ids.get(0) + " home = " + getHome(ids.get(0))); RetrieveBEngine ret = new RetrieveBEngine(); ret.setIsXca(isXca()); ret.retrieve(ids.get(0), queryContents, getMetadata(), getRepositories(), getHome(ids.get(0))); try { Metadata save = queryContents.getMetadata(); queryContents.setMetadata(null); this.addQueryContents(queryContents); queryContents.setMetadata(save); } catch (Exception e) { queryContents.addException(e); } return queryContents; }*/ /*String getSingleHomeForIds(ArrayList<String> ids) throws MetadataException { String home = null; for (String id : ids) { String h = getHome(id); if (h == null) continue; if (h.equals("")) continue; if (home == null) { home = h; continue; } if ( ! home.equals(h)) throw new MetadataException("Trying to issue single SQ for ids " + ids + " but multiple homeCommunityId values found"); } return home; }*/ private void runQuery(ArrayList<String> ids, Sq query, QueryContents queryContents, String action, String returnAction) throws MetadataException { OMElement result = null; try { result = query.run(endpoint, ids, action, returnAction); queryContents.parseMetadataFromRegistryResponse(result); this.addQueryContents(queryContents); } catch (Exception e) { queryContents.addException(e.getClass(), e.getMessage()); try { this.addQueryContents(queryContents); } catch (Exception e1) {} } Metadata m = queryContents.getMetadata(); String uuid; String id = ids.get(0); if ( m != null) { uuid = (is_uuid(id)) ? id : m.getSubmissionSetId(); } else { uuid = id; // best we can do } queryContents.setReferenceId(uuid); } public QueryContents queryGetSubmissionSets(ArrayList<String> ids) throws MetadataException { QueryContents queryContents = new SSQueryContents(); queryContents.setQueryType("Get SS of"); runQuery(ids, new GetSubmissionSet(), queryContents, queryAction, queryResultAction); Metadata m = queryContents.getMetadata(); if (m.getSubmissionSets().size() == 0) queryContents.addError("No SubmissionSet returned"); if (m.getAssociations().size() == 0) queryContents.addError("No Association returned"); if (m.getSubmissionSets().size() > 1) queryContents.addError("Multiple SubmissionSets returned"); if (m.getAssociations().size() > 1) queryContents.addError("Multiple Associations returned"); return queryContents; } public QueryContents queryGetRelated(ArrayList<String> ids) throws MetadataException { QueryContents queryContents = new RelatedQueryContents(); queryContents.setQueryType("Get related to"); runQuery(ids, new GetRelatedDocuments(), queryContents, queryAction, queryResultAction); return queryContents; } void addQueryContents(QueryContents qc) throws MetadataValidationException, MetadataException { queryContents.add(qc); if (qc.getMetadata() == null) qc.setMetadata(new Metadata()); else metadata.addMetadata(qc.getMetadata(), false /* discard_duplicates */); } public String structures() { StringBuffer buf = new StringBuffer(); buf.append(metadata.structure() + "\n"); for (int i=0; i<this.queryContents.size(); i++) { QueryContents qc = this.queryContents.get(i); buf.append(i + " " + qc.getMetadata().structure() + "\n"); } return buf.toString(); } public String structure() { return metadata.structure(); } public Metadata getMetadata() { return metadata; } public Xdsview displayDetail(String verb, Map<String, String[]> parms, HttpUtils h) { String localid = getParm(parms, "id"); String cntl = getParm(parms, "cntl"); int cntl_i = 0; if (cntl != null) cntl_i = Integer.parseInt(cntl); if (localid != null && !localid.equals("")) { try { Metadata m; if (cntl != null) { QueryContents qc = getQueryContents(cntl_i); m = qc.getMetadata(); } else m = this.getMetadata(); System.out.println("Structure " + m.structure()); System.out.println("verb " + verb); System.out.println("id " + localid); System.out.println("docids " + m.getExtrinsicObjectIds()); Xdsview xv = new Xdsview(m, h); xv.start(); if (verb.equals("details")) { xv.displayRegistryObject(m, localid); } else if (verb.equals("xml")) { xv.displayXml(m, localid); } xv.end(); return xv; } catch (Exception e) { h.alert(e.getClass().getName() + ": " + e.getMessage()); e.printStackTrace(); } } else if (verb.equals("errors") && cntl !=null) { QueryContents qc = this.getQueryContents(Integer.parseInt(cntl)); if (qc != null) { display_arraylist(h, qc.getErrors()); } } else if (verb.equals("exceptions") && cntl !=null) { QueryContents qc = this.getQueryContents(Integer.parseInt(cntl)); if (qc != null) { display_arraylist(h, qc.getExceptions()); } } else if (verb.equals("fatal") && cntl !=null) { QueryContents qc = this.getQueryContents(Integer.parseInt(cntl)); if (qc != null) { display_arraylist(h, qc.getFatalErrors()); } } else if (verb.equals("queryresponsexml") && cntl !=null) { QueryContents qc = this.getQueryContents(Integer.parseInt(cntl)); if (qc != null) { OMElement ele = qc.getResultXml(); Xdsview xv = new Xdsview(h); xv.start(); if (ele != null) xv.out(XmlFormatter.htmlize(ele.toString(), false)); else xv.out("null"); xv.end(); return xv; } } else if (verb.equals("queryrequestxml") && cntl !=null) { QueryContents qc = this.getQueryContents(Integer.parseInt(cntl)); if (qc != null) { OMElement ele = qc.getRequestXml(); Xdsview xv = new Xdsview(h); xv.start(); if (ele != null) xv.out(XmlFormatter.htmlize(ele.toString(), false)); else xv.out("null"); xv.end(); return xv; } } else if (verb.equals("inputxml")) { Xdsview xv = new Xdsview(h); xv.start(); LogFileQueryContents qc = (LogFileQueryContents) this.getQueryContents(cntl_i); qc.displayInput(xv); xv.end(); return xv; } else if (verb.equals("resultxml")) { Xdsview xv = new Xdsview(h); xv.start(); LogFileQueryContents qc = (LogFileQueryContents) this.getQueryContents(cntl_i); qc.displayResult(xv); xv.end(); return xv; } else if (verb.equals("stepxml")) { Xdsview xv = new Xdsview(h); xv.start(); LogFileQueryContents qc = (LogFileQueryContents) this.getQueryContents(cntl_i); qc.displayTestStep(xv); xv.end(); return xv; } return null; } private String getParm(Map<String, String[]> parms, String parm_name) { String value; String[] id_array = (String[]) parms.get(parm_name); if (id_array != null && id_array.length > 0) value = id_array[0]; else { value = null; } return value; } void display_arraylist(HttpUtils h, ArrayList<String> al) { for (String s : al) { h.o(s); h.br(); } } public ArrayList<String> singleton(String value) { ArrayList<String> al = new ArrayList<String>(1); al.add(value); return al; } public void setRepositories(HashMap<String, ArrayList<String>> repositories) { this.repositories = repositories; } public HashMap<String, ArrayList<String>> getRepositories() { return repositories; } }