Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 68EEF200CC7 for ; Sun, 16 Jul 2017 20:33:35 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 66E811641F9; Sun, 16 Jul 2017 18:33:35 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id D94701641F2 for ; Sun, 16 Jul 2017 20:33:32 +0200 (CEST) Received: (qmail 85959 invoked by uid 500); 16 Jul 2017 18:33:32 -0000 Mailing-List: contact commits-help@oodt.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@oodt.apache.org Delivered-To: mailing list commits@oodt.apache.org Received: (qmail 85944 invoked by uid 99); 16 Jul 2017 18:33:32 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 16 Jul 2017 18:33:32 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id C1938F31FB; Sun, 16 Jul 2017 18:33:30 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: mattmann@apache.org To: commits@oodt.apache.org Date: Sun, 16 Jul 2017 18:33:32 -0000 Message-Id: <7f8fd1fca3da442c89c868268a785988@git.apache.org> In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [3/6] oodt git commit: - add in xmlquery and product handler code necessary to build this app archived-at: Sun, 16 Jul 2017 18:33:35 -0000 http://git-wip-us.apache.org/repos/asf/oodt/blob/4066b63b/webapp/fmprod/src/main/java/org/apache/oodt/xmlquery/XMLQuery.java ---------------------------------------------------------------------- diff --git a/webapp/fmprod/src/main/java/org/apache/oodt/xmlquery/XMLQuery.java b/webapp/fmprod/src/main/java/org/apache/oodt/xmlquery/XMLQuery.java new file mode 100755 index 0000000..eade767 --- /dev/null +++ b/webapp/fmprod/src/main/java/org/apache/oodt/xmlquery/XMLQuery.java @@ -0,0 +1,981 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ + + +/* + EDA XML Query Class + */ + +package org.apache.oodt.xmlquery; + +import org.apache.oodt.commons.util.EnterpriseEntityResolver; +import org.apache.oodt.commons.util.XML; +import org.apache.oodt.product.Retriever; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.Text; +import org.xml.sax.EntityResolver; +import org.xml.sax.SAXException; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.StreamTokenizer; +import java.io.StringReader; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +/** + * EDA XML query class. Parses a DIS style keyword query and creates query + * SELECT, FROM, and WHERE clauses. An XML DOM structure and an XML document + * representing the query can also be created. A RESULT set can be added to + * and retrieve. + * + */ +public class XMLQuery implements java.io.Serializable, Cloneable { + /** Result mode. */ + private String resultModeId; + + /** Propogation type. */ + private String propogationType; + + /** # of levels to propogate, depending on propogation type. */ + private String propogationLevels; + + /** Max results allowed. */ + private int maxResults = DEFAULT_MAX_RESULTS; + + /** KWQ, as a string. */ + private String kwqString; + + /** List of acceptable MIME types. */ + private List mimeAccept; + + /** List of statistics. */ + private List statistics = new ArrayList(); + + /** Number of results so far. + * + * This could be greater than results.size() because that's limited by maxResults. + * + * Meh, this isn't even updated by anyone as far as I can tell. + */ + protected int numResults; + + private QueryHeader queryHeader; + private List selectElementSet = new ArrayList(); + private List fromElementSet = new ArrayList(); + private List whereElementSet = new ArrayList(); + private QueryResult result = new QueryResult(); + + private transient StreamTokenizer tokens; // Used for parse + private transient String lpart; // parser left part + private transient String opart; // parser operator + private transient String rpart; // parser right part + private transient String previous_token; // parser - allows backout + private transient int qfsc = 0; // query from set item count + private transient int qwsc = 0; // query where set item count + private transient int lit = 0; // last query item type ("from" or "where" clause) + public static final String[] FROM_TOKENS = {}; + + /** Constructor. + * + * @param keywordQuery The DIS style keyword query string. + * @param id A query identifier. + * @param title A terse description of the query for display. + * @param desc A description of the query. + * @param ddId The data dictionary identifier. + * @param resultModeId Indicates the return of INSTANCE, PROFILE, or CLASS. + * @param propType Indicates query BROADCAST or PROPOGATE. + * @param propLevels Number of propogation levels. + * @param maxResults Maximum number of results to be returned. + */ + public XMLQuery(String keywordQuery, String id, String title, String desc, String ddId, String resultModeId, + String propType, String propLevels, int maxResults) { + this(keywordQuery, id, title, desc, ddId, resultModeId, propType, propLevels, maxResults, null, true); + } + + /** Constructor. + * + * @param keywordQuery The DIS style keyword query string. + * @param id A query identifier. + * @param title A terse description of the query for display. + * @param desc A description of the query. + * @param ddId The data dictionary identifier. + * @param resultModeId Indicates the return of INSTANCE, PROFILE, or CLASS. + * @param propType Indicates query BROADCAST or PROPOGATE. + * @param propLevels Number of propogation levels. + * @param maxResults Maximum number of results to be returned. + * @param parseQuery Indicates whether query should be parsed + */ + public XMLQuery(String keywordQuery, String id, String title, String desc, String ddId, String resultModeId, + String propType, String propLevels, int maxResults, boolean parseQuery) { + this(keywordQuery, id, title, desc, ddId, resultModeId, propType, propLevels, maxResults, null, parseQuery); + } + + /** Constructor. + * + * @param keywordQuery The DIS style keyword query string. + * @param id A query identifier. + * @param title A terse description of the query for display. + * @param desc A description of the query. + * @param ddId The data dictionary identifier. + * @param resultModeId Indicates the return of INSTANCE, PROFILE, or CLASS. + * @param propType Indicates query BROADCAST or PROPOGATE. + * @param propLevels Number of propogation levels. + * @param maxResults Maximum number of results to be returned. + * @param mimeAccept List of acceptable MIME types. + */ + public XMLQuery(String keywordQuery, String id, String title, String desc, String ddId, String resultModeId, + String propType, String propLevels, int maxResults, List mimeAccept) { + this(keywordQuery, id, title, desc, ddId, resultModeId, propType, propLevels, maxResults, mimeAccept, true); + } + + /** Constructor. + * + * @param keywordQuery The DIS style keyword query string. + * @param id A query identifier. + * @param title A terse description of the query for display. + * @param desc A description of the query. + * @param ddId The data dictionary identifier. + * @param resultModeId Indicates the return of INSTANCE, PROFILE, or CLASS. + * @param propType Indicates query BROADCAST or PROPOGATE. + * @param propLevels Number of propogation levels. + * @param maxResults Maximum number of results to be returned. + * @param mimeAccept List of acceptable MIME types. + * @param parseQuery Indicates whether query should be parsed + */ + public XMLQuery(String keywordQuery, String id, String title, String desc, String ddId, String resultModeId, + String propType, String propLevels, int maxResults, + List mimeAccept, boolean parseQuery) { + if (mimeAccept == null) { + mimeAccept = new ArrayList(); + mimeAccept.add("*/*"); + } + if (keywordQuery == null) { + keywordQuery = "UNKNOWN"; + } + // init query header (object attributes) + if (id == null) { + id = "UNKNOWN"; + } + if (title == null) { + title = "UNKNOWN"; + } + if (desc == null) { + desc = "UNKNOWN"; + } + if (ddId == null) { + ddId = "UNKNOWN"; + } + queryHeader = new QueryHeader(id, title, desc, /*type*/"QUERY", /*status*/"ACTIVE", /*security*/"UNKNOWN", + /*revision*/"1999-12-12 JSH V1.0 Under Development", ddId); + + // init query attributes + if (resultModeId == null) { + resultModeId = "ATTRIBUTE"; + } + if (propType == null) { + propType = "BROADCAST"; + propLevels = "N/A"; + } + this.resultModeId = resultModeId; + this.propogationType = propType; + this.propogationLevels = propLevels; + this.maxResults = maxResults; + this.kwqString = keywordQuery; + this.mimeAccept = mimeAccept; + + // parse the keyword query string + if (! parseQuery) { + queryHeader.setStatusID("NOTPARSED"); + } else if (!parseKeywordString(keywordQuery)) { + queryHeader.setStatusID("ERROR"); + } + } + + /** Get the list of acceptable MIME types. + * + * @return The list of acceptable MIME types; you may modify the list. + */ + public List getMimeAccept() { + return mimeAccept; + } + + /** + * Instantiates an XMLQuery instance from an XML query structure in string format. + * + * @param xmlQueryString The XML query structure in string format. + */ + public XMLQuery (String xmlQueryString) throws SAXException { + if (xmlQueryString == null) { + xmlQueryString = BLANK; + } + try { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setCoalescing(false); + factory.setNamespaceAware(false); + factory.setValidating(false); + DocumentBuilder builder = factory.newDocumentBuilder(); + builder.setEntityResolver(ENTITY_RESOLVER); + Document doc = builder.parse(new ByteArrayInputStream(xmlQueryString.getBytes())); + loadXMLQueryStruct(doc.getDocumentElement()); + } catch (IOException ex) { + System.err.println("Unexpected no good bloody IOException while parsing doc: " + xmlQueryString); + throw new IllegalStateException("Unexpected no good bloody IOException: " + ex.getMessage() + ", during" + + " parse of " + xmlQueryString); + } catch (ParserConfigurationException ex) { + throw new IllegalStateException("Unexpected ParserConfigurationException: " + ex.getMessage()); + } + } + + /** + * Instantiates an XMLQuery instance from an XML query structure in DOM node format. + * + * @param node The XML <query> node. + */ + public XMLQuery (Node node) { + loadXMLQueryStruct(node); + } + + /** + * Gets the original DIS style keyword query string. + * + * @return The DIS style keyword query string. + */ + public String getKwdQueryString () { + return kwqString; + } + + /** + * Gets the max # of results + * + * @return the results + */ + public int getMaxResults() { + return maxResults; + } + + /** + * @return Gets the select elements + * + */ + public List getSelectElementSet() { + return(selectElementSet); + } + + /** + * @return Gets the from element set from the query + * + */ + public List getFromElementSet() + { + return(fromElementSet); + } + + + /** + * @return Gets the resultModeID + * + */ + public String getResultModeID() + { + return(resultModeId); + } + + /** + * @return Gets the where set + * + */ + public List getWhereElementSet() { + return(whereElementSet); + } + + /** + * Set query where element set. + * @param whereElementSet Thw where element set of XMLQuery. + */ + public void setWhereElementSet(List whereElementSet) { + this.whereElementSet = whereElementSet; + } + /** + * @return Gets the result list + * + */ + public QueryResult getResult() { + return result; + } + + public List getResults() { + return result.getList(); + } + + public void setRetriever(Retriever retriever) { + result.setRetriever(retriever); + } + + /** + * @return The query as an XML DOM structure. + */ + public Document getXMLDoc () { + Document doc = createDocument(); + doc.appendChild(doc.createElement("query")); + createXMLDoc(doc); + return doc; + } + + /** Get the list of stasitics of this query. + * + * @return A list of {@link Statistic} objects. + */ + public List getStatistics() { + return statistics; + } + + /** + * Gets query as an XML document in string format. + * + * @return The query as an XML document in string format. + */ + public String getXMLDocString () { + StringWriter writer = new StringWriter(); + try { + TransformerFactory factory = TransformerFactory.newInstance(); + Transformer transformer = factory.newTransformer(); + transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); + transformer.setOutputProperty(OutputKeys.MEDIA_TYPE, "text/xml"); + transformer.setOutputProperty(OutputKeys.METHOD, "xml"); + transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); + transformer.setOutputProperty(OutputKeys.STANDALONE, "no"); + transformer.setOutputProperty(OutputKeys.VERSION, "1.0"); + transformer.transform(new DOMSource(getXMLDoc()), new StreamResult(writer)); + } catch (TransformerException ex) { + throw new IllegalStateException("Unexpected TransformerException: " + ex.getMessage()); + } finally { + try { + writer.close(); + } catch (IOException ignore) {} + } + return writer.toString(); + } + + /** + * Get the propagation type. + * + * @return a {@link String} value. + */ + public String getPropagationType() { + return propogationType; + } + + /** + * Get the propagation levels. + * + * @return a {@link String} value. + */ + public String getPropagationLevels() { + return propogationLevels; + } + + /** + * Parse keyword query string (simple top down recursion). + */ + private boolean parseKeywordString (String kwdQueryString) { + previous_token = ""; + lpart = ""; + rpart = ""; + + tokens = new java.io.StreamTokenizer(new StringReader(kwdQueryString)); + tokens.resetSyntax(); + tokens.ordinaryChar('/'); + tokens.wordChars('#', '#'); + tokens.wordChars(':', ':'); + tokens.wordChars('0', '9'); + tokens.wordChars('.', '.'); + tokens.wordChars('-', '-'); + tokens.wordChars('[', '['); + tokens.wordChars(']', ']'); + tokens.wordChars('a', 'z'); + tokens.wordChars('A', 'Z'); + tokens.wordChars('_', '_'); + tokens.wordChars('/', '/'); + tokens.eolIsSignificant(true); + tokens.whitespaceChars(0, ' '); + tokens.quoteChar('"'); + tokens.quoteChar('\''); + + return kqOrParse(); + } + + /** + * Parse OR logical operator. + */ + private boolean kqOrParse () + { + boolean lflag, rflag; + + lflag = kqAndParse(); + while (isTokenEqual("OR") | isTokenEqual("or") | isTokenEqual("|")) { + rflag = kqAndParse(); + lflag &= rflag; + appendLogOperator("LOGOP", "OR"); + } + return lflag; + } + + /** + * Parse AND logical operator. + */ + private boolean kqAndParse () + { + boolean lflag, rflag; + + lflag = kqNotParse(); + while (isTokenEqual("AND") | isTokenEqual("and") | isTokenEqual("&")) { + rflag = kqNotParse(); + lflag &= rflag; + appendLogOperator("LOGOP", "AND"); + } + return lflag; + } + + /** + * Parse NOT logical operator. + */ + private boolean kqNotParse () + { + boolean lflag, rflag; + + if (isTokenEqual("NOT") | isTokenEqual("not") | isTokenEqual("!")) { + lflag = kqFactorParse(); + appendLogOperator("LOGOP", "NOT"); + } else { + lflag = kqFactorParse (); + } + return lflag; + } + + /** + * Parse logical operator operand and handle nesting (parens) + * also logic for differentiating SELECT, WHERE, and FROM + */ + private boolean kqFactorParse () + { + String ropn, enm; + if (isTokenEqual("(")) { + return (kqOrParse () & isTokenEqual(")")); + } else { + lpart = getNextToken (); + if (lpart.compareTo("") != 0) { + ropn = getNextToken (); + if (ropn.compareTo("EQ") == 0 || ropn.compareTo("LT") == 0 || ropn.compareTo("LE") == 0 || ropn.compareTo("GT") == 0 || ropn.compareTo("GE")== 0 || ropn.compareTo("NE") == 0 || ropn.compareToIgnoreCase("LIKE") == 0 || ropn.compareToIgnoreCase("NOTLIKE") == 0 || ropn.compareTo("IS") == 0 || ropn.compareTo("ISNOT") == 0) { + rpart = getNextToken (); + if (rpart.compareTo("") != 0) { + lit = 0; + enm = lpart; + if (enm.compareTo("RETURN") == 0) { + selectElementSet.add(new QueryElement("elemName", rpart)); + } else if (isFromToken(lpart)) { + qfsc++; + lit = 1; + fromElementSet.add(new QueryElement("elemName", lpart)); + fromElementSet.add(new QueryElement("LITERAL", rpart)); + fromElementSet.add(new QueryElement("RELOP", ropn)); + } else { + lit = 2; + qwsc++; + whereElementSet.add(new QueryElement("elemName", lpart)); + whereElementSet.add(new QueryElement("LITERAL", rpart)); + whereElementSet.add(new QueryElement("RELOP", ropn)); + } + return true; + } + } + } + } + return false; + } + + /** + * Create Logical Operator DOM node for WHERE clause. + */ + private boolean appendLogOperator (String tt, String ts) + { + if (lit == 1 & qfsc > 1) { + fromElementSet.add(new QueryElement(tt, ts)); + + } else if (lit == 2 & qwsc > 1) { + whereElementSet.add(new QueryElement(tt, ts)); + } + return true; + } + + /** + * Lexical analyzer - find a FROM token. + */ + private static boolean isFromToken (String s1) + { + for (String FROM_TOKEN : FROM_TOKENS) { + if (s1.compareTo(FROM_TOKEN) == 0) { + return true; + } + } + return false; + } + + /** + * Lexical analyzer - return next token - allows lookahead. + */ + private String getNextToken () + { + String ts; + + ts = previous_token; + if (previous_token.compareTo("") == 0) { + ts = getNextTokenFromStream(); + return ts; + } else { + previous_token = ""; + return ts; + } + } + + /** + * Lexical analyzer - check if next token equal to argument. + */ + private boolean isTokenEqual (String s1) { + String ts; + boolean rc; + + if (previous_token.compareTo("") == 0) { + ts = getNextTokenFromStream (); + if (ts.compareTo("") == 0) { + rc = false; + } else { + if (ts.compareTo(s1) == 0) { + previous_token = ""; + rc = true; + } else { + previous_token = ts; + rc = false; + } + } + } else { + if (previous_token.compareTo(s1) == 0) { + previous_token = ""; + rc = true; + } else { + rc = false; + } + } + return rc; + } + + /** + * Lexical analyzer - return next token from instance of StreamTokenizer. + */ + private String getNextTokenFromStream () { + int c, c2; + String rc; + try { + switch (c=tokens.nextToken()) { + case StreamTokenizer.TT_EOF: + rc = ""; + break; + case StreamTokenizer.TT_EOL: + rc = ""; + break; + case StreamTokenizer.TT_NUMBER: // not currently set + rc = ""; + break; + case StreamTokenizer.TT_WORD: + rc = tokens.sval; + break; + case '(': + case ')': + rc = String.valueOf((char)c); + break; + case '"': + case '\'': + rc = tokens.sval; + break; + case '=': + rc = "EQ"; + break; + case '&': + rc = "AND"; + break; + case '|': + rc = "OR"; + break; + case '<': + c2 = tokens.nextToken(); + if (c2 == '=') { + rc = "LE"; + } else { + tokens.pushBack(); + rc = "LT"; + } + break; + case '>': + c2 = tokens.nextToken(); + if (c2 == '=') { + rc = "GE"; + } else { + tokens.pushBack(); + rc = "GT"; + } + break; + case '!': + c2 = tokens.nextToken(); + if (c2 == '=') { + rc = "NE"; + } else { + tokens.pushBack(); + rc = "NOT"; + } + break; + default: + rc = ""; + } + } catch (IOException e1) { + rc = ""; + } + return rc; + } + + /** + * Replace character with string + */ + private String replaceCharWithString (String s1, char c, String rs) + { + int p1, p2, s1l; + StringBuilder s2; + + p1 = 0; + s1l = s1.length(); + s2 = new StringBuilder(); + p2 = s1.indexOf(c, p1); + while (p2 >= 0) { + s2.append(s1.substring(p1, p2)).append(rs); + p1 = p2 + 1; + p2 = s1.indexOf(c, p1); + } + if (p1 < s1l) { + s2.append(s1.substring(p1, s1l)); + } + return s2.toString(); + } + + /** + * Creates a XML DOM structure from a keyword query string. + * Set up the basic structure then calls the query parser. + */ + private void createXMLDoc (Document doc) { + int loc; + String kwd; + String type; + String val; + Element item; + Element elem; + + Element query = doc.getDocumentElement(); + + // create query header (object attributes) + query.appendChild(queryHeader.toXML(doc)); + + // create query attributes + XML.add(query, "queryResultModeId", resultModeId); + XML.add(query, "queryPropogationType", propogationType); + XML.add(query, "queryPropogationLevels", propogationLevels); + XML.add(query, "queryMimeAccept", mimeAccept); + XML.add(query, "queryMaxResults", String.valueOf(maxResults)); + XML.add(query, "queryResults", String.valueOf(numResults)); + XML.add(query, "queryKWQString", kwqString); + + // create and load queryStatistics + elem = doc.createElement("queryStatistics"); + query.appendChild(elem); + for (Object statistic : statistics) { + Statistic s = (Statistic) statistic; + elem.appendChild(s.toXML(doc)); + } + + // create and load querySelectSet + elem = doc.createElement("querySelectSet"); + query.appendChild(elem); + + for (Object aSelectElementSet : selectElementSet) { + QueryElement queryElement = (QueryElement) aSelectElementSet; + elem.appendChild(queryElement.toXML(doc)); + } + + // create and load queryFromSet + elem = doc.createElement("queryFromSet"); + query.appendChild(elem); + + for (Object aFromElementSet : fromElementSet) { + QueryElement queryElement = (QueryElement) aFromElementSet; + elem.appendChild(queryElement.toXML(doc)); + } + + // create and load queryWhereSet + elem = doc.createElement("queryWhereSet"); + query.appendChild(elem); + for (Object aWhereElementSet : whereElementSet) { + QueryElement queryElement = (QueryElement) aWhereElementSet; + elem.appendChild(queryElement.toXML(doc)); + } + + query.appendChild(result.toXML(doc)); + } + + /** + * Creates a leaf (end node - TEXT) in the DOM structure. + */ + private Element createLeaf (Element child, String value) { + child.appendChild(child.getOwnerDocument().createTextNode(value)); + return child; + } + + /** + * Load the internal query structure (dictionary) from an XML DOM structure + */ + private void loadXMLQueryStruct (Node root) { + Node node; + String nodeName; + + initNodes(); + for (node = root.getFirstChild(); + node != null; + node = node.getNextSibling()) { + if (node instanceof Element) { + nodeName = node.getNodeName(); + if (nodeName.compareTo("queryAttributes") == 0) { + queryHeader = new QueryHeader(node); + } else if (nodeName.compareTo("queryResultModeId") == 0) { + resultModeId = XML.unwrappedText(node); + } else if (nodeName.compareTo("queryPropogationType") == 0) { + propogationType = XML.unwrappedText(node); + } else if (nodeName.compareTo("queryPropogationLevels") == 0) { + propogationLevels = XML.unwrappedText(node); + } else if (nodeName.equals("queryMimeAccept")) { + mimeAccept.add(XML.unwrappedText(node)); + } else if (nodeName.compareTo("queryMaxResults") == 0) { + maxResults = Integer.parseInt(XML.unwrappedText(node)); + } else if (nodeName.compareTo("queryResults") == 0) { + numResults = Integer.parseInt(XML.unwrappedText(node)); + } else if (nodeName.compareTo("queryKWQString") == 0) { + kwqString = XML.unwrappedText(node); + } else if (nodeName.compareTo("querySelectSet") == 0) { + scanQueryElements(selectElementSet, node); + } else if (nodeName.compareTo("queryFromSet") == 0) { + scanQueryElements(fromElementSet, node); + } else if (nodeName.compareTo("queryWhereSet") == 0) { + scanQueryElements(whereElementSet, node); + } else if (nodeName.compareTo("queryResultSet") == 0) { + result = new QueryResult(node); + } else if (nodeName.equals("queryStatistics")) { + NodeList children = node.getChildNodes(); + for (int i = 0; i < children.getLength(); ++i) { + Node statisticNode = children.item(i); + if (statisticNode.getNodeType() == Node.ELEMENT_NODE) { + Statistic s = new Statistic(statisticNode); + statistics.add(s); + } + } + } + } + } + } + + /** + * Replace the dictionary keyword value with the DOM text node value. + */ + private void replaceKwdVal (Map map, Node node, String nodeName) { + Node childNode; + + childNode = node.getFirstChild(); + if (childNode instanceof Text) { + map.put(nodeName, childNode.getNodeValue()); + } else { + map.put(nodeName, "UNKNOWN"); + } + } + + /** + * Scan the DOM structure for the SELECT, FROM, or WHERE set. + * + * @param list To what list to add the query elements. + * @param node Where to find the query elements. + */ + private static void scanQueryElements(List list, Node node) { + NodeList children = node.getChildNodes(); + for (int i = 0; i < children.getLength(); ++i) { + Node n = children.item(i); + if (n.getNodeType() == Node.ELEMENT_NODE) { + list.add(new QueryElement(n)); + } + } + } + + /** + * Initialize the Query and Resource attributes in the dictionary. + */ + private void initNodes () { + queryHeader = new QueryHeader(); + resultModeId = "ATTRIBUTE"; + propogationType = "BROADCAST"; + propogationLevels = "N/A"; + maxResults = DEFAULT_MAX_RESULTS; + kwqString = "UNKNOWN"; + mimeAccept = new ArrayList(); + } + + public int hashCode() { + return resultModeId.hashCode() ^ propogationType.hashCode() ^ propogationLevels.hashCode() + ^ (maxResults << 8) ^ kwqString.hashCode() ^ numResults ^ queryHeader.hashCode() + ^ selectElementSet.hashCode() ^ fromElementSet.hashCode() ^ whereElementSet.hashCode() + ^ result.hashCode(); + } + + public boolean equals(Object rhs) { + if (rhs == this) { + return true; + } + if (rhs == null || !(rhs instanceof XMLQuery)) { + return false; + } + XMLQuery obj = (XMLQuery) rhs; + return resultModeId.equals(obj.resultModeId) && propogationType.equals(obj.propogationType) + && propogationLevels.equals(obj.propogationLevels) && maxResults == obj.maxResults + && kwqString.equals(obj.kwqString) && numResults == obj.numResults + && queryHeader.equals(obj.queryHeader) && selectElementSet.equals(obj.selectElementSet) + && fromElementSet.equals(obj.fromElementSet) && whereElementSet.equals(obj.whereElementSet) + && result.equals(obj.result); + } + + public Object clone() { + Object rc = null; + try { + rc = super.clone(); + } catch (CloneNotSupportedException ignored) {} + return rc; + } + + public String toString() { + return getClass().getName() + "[kwqString=" + kwqString + "]"; + } + + /** Create an XML DOM document using the query DTD. + * + * @return An XML DOM document, with a query root element, using the query DTD. + */ + public static Document createDocument() { + try { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setCoalescing(true); + factory.setNamespaceAware(false); + factory.setValidating(false); + DocumentBuilder builder = factory.newDocumentBuilder(); + return builder.newDocument(); + } catch (ParserConfigurationException ex) { + throw new IllegalStateException("Unexpected ParserConfigurationException: " + ex.getMessage()); + } + } + + public static void main(String[] argv) throws Exception { + if (argv.length < 2 || (!argv[0].equals("-expr") && !argv[0].equals("-file")) + || (argv[0].equals("-file") && argv.length > 2)) { + System.err.println("Usage: -expr ..."); + System.err.println(" or: -file "); + System.exit(1); + } + + XMLQuery q; + if (argv[0].equals("-expr")) { + StringBuilder expr = new StringBuilder(); + for (int i = 1; i < argv.length; ++i) { + expr.append(argv[i]).append(' '); + } + q = new XMLQuery(expr.toString().trim(), "expr1", "Command-line Expression Query", + "The expression for this query came from the command-line", /*ddId*/ null, + /*resultModeId*/ null, /*propType*/ null, /*propLevels*/ null, XMLQuery.DEFAULT_MAX_RESULTS); + } else if (argv[0].equals("-file")) { + BufferedReader reader = new BufferedReader(new FileReader(argv[1])); + StringBuilder str = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + str.append(line).append('\n'); + } + reader.close(); + q = new XMLQuery(str.toString()); + } else { + throw new IllegalStateException("Can't get here; only -expr or -file allowed, but got \"" + argv[0] + "\""); + } + + System.out.println("kwdQueryString: " + q.getKwdQueryString()); + System.out.println("fromElementSet: " + q.getFromElementSet()); + System.out.println("results: " + q.getResult()); + System.out.println("whereElementSet: " + q.getWhereElementSet()); + System.out.println("selectElementSet: " + q.getSelectElementSet()); + + System.out.println("======doc string======="); + System.out.println(q.getXMLDocString()); + } + + public QueryHeader getQueryHeader() { + return queryHeader; + } + + /** Maximum number results to get (default). */ + public static final int DEFAULT_MAX_RESULTS = 100; + + /** The Formal Public Identifier of the query DTD. */ + public static final String QUERY_FPI = "-//JPL//DTD OODT Query 1.0//EN"; + + /** The System Identifier of the query DTD. */ + public static final String QUERY_URL = "http://oodt.jpl.nasa.gov/edm-query/query.dtd"; // FIXME: Move to apache.org + + /** A blank query document, as a string. */ + private static String BLANK = "\n\n"; + + /** Resolver for the query DTD. */ + private static final EntityResolver ENTITY_RESOLVER = new EnterpriseEntityResolver(); + + /** Serial version unique ID. */ + static final long serialVersionUID = -7638068782048963710L; +} http://git-wip-us.apache.org/repos/asf/oodt/blob/4066b63b/webapp/fmprod/src/main/java/org/apache/oodt/xmlquery/activity/QueryConstructed.java ---------------------------------------------------------------------- diff --git a/webapp/fmprod/src/main/java/org/apache/oodt/xmlquery/activity/QueryConstructed.java b/webapp/fmprod/src/main/java/org/apache/oodt/xmlquery/activity/QueryConstructed.java new file mode 100755 index 0000000..4598966 --- /dev/null +++ b/webapp/fmprod/src/main/java/org/apache/oodt/xmlquery/activity/QueryConstructed.java @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ + + +package org.apache.oodt.xmlquery.activity; + +import org.apache.oodt.commons.activity.Incident; + +public class QueryConstructed extends Incident {} http://git-wip-us.apache.org/repos/asf/oodt/blob/4066b63b/webapp/fmprod/src/main/java/org/apache/oodt/xmlquery/activity/ResultsReceived.java ---------------------------------------------------------------------- diff --git a/webapp/fmprod/src/main/java/org/apache/oodt/xmlquery/activity/ResultsReceived.java b/webapp/fmprod/src/main/java/org/apache/oodt/xmlquery/activity/ResultsReceived.java new file mode 100755 index 0000000..0c5616d --- /dev/null +++ b/webapp/fmprod/src/main/java/org/apache/oodt/xmlquery/activity/ResultsReceived.java @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ + + +package org.apache.oodt.xmlquery.activity; + +import org.apache.oodt.commons.activity.Incident; + +public class ResultsReceived extends Incident {} http://git-wip-us.apache.org/repos/asf/oodt/blob/4066b63b/webapp/fmprod/src/main/java/org/apache/oodt/xmlquery/package.html ---------------------------------------------------------------------- diff --git a/webapp/fmprod/src/main/java/org/apache/oodt/xmlquery/package.html b/webapp/fmprod/src/main/java/org/apache/oodt/xmlquery/package.html new file mode 100755 index 0000000..5d3b494 --- /dev/null +++ b/webapp/fmprod/src/main/java/org/apache/oodt/xmlquery/package.html @@ -0,0 +1,26 @@ + + + + + JPL OODT XML-based Query/Results + + + +

Classes to support XML-based representation of queries and + their results. +

+ + http://git-wip-us.apache.org/repos/asf/oodt/blob/4066b63b/webapp/fmprod/src/site/resources/images/delegation.png ---------------------------------------------------------------------- diff --git a/webapp/fmprod/src/site/resources/images/delegation.png b/webapp/fmprod/src/site/resources/images/delegation.png new file mode 100644 index 0000000..aea86e3 Binary files /dev/null and b/webapp/fmprod/src/site/resources/images/delegation.png differ http://git-wip-us.apache.org/repos/asf/oodt/blob/4066b63b/webapp/fmprod/src/site/resources/images/delegation.psd ---------------------------------------------------------------------- diff --git a/webapp/fmprod/src/site/resources/images/delegation.psd b/webapp/fmprod/src/site/resources/images/delegation.psd new file mode 100644 index 0000000..9b74dca Binary files /dev/null and b/webapp/fmprod/src/site/resources/images/delegation.psd differ http://git-wip-us.apache.org/repos/asf/oodt/blob/4066b63b/webapp/fmprod/src/site/resources/images/edm-query.jpg ---------------------------------------------------------------------- diff --git a/webapp/fmprod/src/site/resources/images/edm-query.jpg b/webapp/fmprod/src/site/resources/images/edm-query.jpg new file mode 100755 index 0000000..f6b5829 Binary files /dev/null and b/webapp/fmprod/src/site/resources/images/edm-query.jpg differ http://git-wip-us.apache.org/repos/asf/oodt/blob/4066b63b/webapp/fmprod/src/site/resources/images/grid-product.jpg ---------------------------------------------------------------------- diff --git a/webapp/fmprod/src/site/resources/images/grid-product.jpg b/webapp/fmprod/src/site/resources/images/grid-product.jpg new file mode 100644 index 0000000..7b1126e Binary files /dev/null and b/webapp/fmprod/src/site/resources/images/grid-product.jpg differ http://git-wip-us.apache.org/repos/asf/oodt/blob/4066b63b/webapp/fmprod/src/site/resources/images/large-stack.png ---------------------------------------------------------------------- diff --git a/webapp/fmprod/src/site/resources/images/large-stack.png b/webapp/fmprod/src/site/resources/images/large-stack.png new file mode 100755 index 0000000..4bdcf53 Binary files /dev/null and b/webapp/fmprod/src/site/resources/images/large-stack.png differ http://git-wip-us.apache.org/repos/asf/oodt/blob/4066b63b/webapp/fmprod/src/site/resources/images/large-stack.psd ---------------------------------------------------------------------- diff --git a/webapp/fmprod/src/site/resources/images/large-stack.psd b/webapp/fmprod/src/site/resources/images/large-stack.psd new file mode 100755 index 0000000..caa6be9 Binary files /dev/null and b/webapp/fmprod/src/site/resources/images/large-stack.psd differ http://git-wip-us.apache.org/repos/asf/oodt/blob/4066b63b/webapp/fmprod/src/site/resources/images/results.png ---------------------------------------------------------------------- diff --git a/webapp/fmprod/src/site/resources/images/results.png b/webapp/fmprod/src/site/resources/images/results.png new file mode 100755 index 0000000..eef63e2 Binary files /dev/null and b/webapp/fmprod/src/site/resources/images/results.png differ http://git-wip-us.apache.org/repos/asf/oodt/blob/4066b63b/webapp/fmprod/src/site/resources/images/results.psd ---------------------------------------------------------------------- diff --git a/webapp/fmprod/src/site/resources/images/results.psd b/webapp/fmprod/src/site/resources/images/results.psd new file mode 100755 index 0000000..7e8476c Binary files /dev/null and b/webapp/fmprod/src/site/resources/images/results.psd differ http://git-wip-us.apache.org/repos/asf/oodt/blob/4066b63b/webapp/fmprod/src/site/resources/images/small-stack.png ---------------------------------------------------------------------- diff --git a/webapp/fmprod/src/site/resources/images/small-stack.png b/webapp/fmprod/src/site/resources/images/small-stack.png new file mode 100755 index 0000000..d3604ef Binary files /dev/null and b/webapp/fmprod/src/site/resources/images/small-stack.png differ http://git-wip-us.apache.org/repos/asf/oodt/blob/4066b63b/webapp/fmprod/src/site/resources/images/small-stack.psd ---------------------------------------------------------------------- diff --git a/webapp/fmprod/src/site/resources/images/small-stack.psd b/webapp/fmprod/src/site/resources/images/small-stack.psd new file mode 100755 index 0000000..d13ac6f Binary files /dev/null and b/webapp/fmprod/src/site/resources/images/small-stack.psd differ http://git-wip-us.apache.org/repos/asf/oodt/blob/4066b63b/webapp/fmprod/src/site/resources/images/xmlquery.png ---------------------------------------------------------------------- diff --git a/webapp/fmprod/src/site/resources/images/xmlquery.png b/webapp/fmprod/src/site/resources/images/xmlquery.png new file mode 100755 index 0000000..189feb6 Binary files /dev/null and b/webapp/fmprod/src/site/resources/images/xmlquery.png differ http://git-wip-us.apache.org/repos/asf/oodt/blob/4066b63b/webapp/fmprod/src/site/resources/images/xmlquery.psd ---------------------------------------------------------------------- diff --git a/webapp/fmprod/src/site/resources/images/xmlquery.psd b/webapp/fmprod/src/site/resources/images/xmlquery.psd new file mode 100755 index 0000000..cce0220 Binary files /dev/null and b/webapp/fmprod/src/site/resources/images/xmlquery.psd differ http://git-wip-us.apache.org/repos/asf/oodt/blob/4066b63b/webapp/fmprod/src/site/site.xml ---------------------------------------------------------------------- diff --git a/webapp/fmprod/src/site/site.xml b/webapp/fmprod/src/site/site.xml new file mode 100644 index 0000000..2184b8d --- /dev/null +++ b/webapp/fmprod/src/site/site.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + http://git-wip-us.apache.org/repos/asf/oodt/blob/4066b63b/webapp/fmprod/src/site/xdoc/disquery/index.xml ---------------------------------------------------------------------- diff --git a/webapp/fmprod/src/site/xdoc/disquery/index.xml b/webapp/fmprod/src/site/xdoc/disquery/index.xml new file mode 100755 index 0000000..a9ddf49 --- /dev/null +++ b/webapp/fmprod/src/site/xdoc/disquery/index.xml @@ -0,0 +1,106 @@ + + + + + + DIS-Style Query + Sean Hardman + + + +
+

A DIS-Style Query is a query using triples linked in a logical expression. Each triple is in the format of (element, relation, literal). The element portion of the triple may be any named data element recognized as a queryable attribute by the target of the query. The relation portion of the triple may contain any of the relational operators from the table below. The literal portion of the triple is the element value to be compared. Multiple sets of triples may be joined using any of the logical operators from the table below. Note that elements or literals containing spaces must be quoted. Also note that case sensitivity and support for the various operators is subject to the capabilities offered by the target of the query. +

+ +

The following table contains the supported relational operators:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Relational Operators
Equal =, EQ
Not Equal !=, NE
Less Than <, LT
Less Than or Equal <=, LE
Greater Than >, GT
Greater Than or Equal >=, GE
Contains LIKE
Does Not Contain NOTLIKE
Is Null IS
Is Not Null ISNOT
+ +

The following table contains the supported logical operators:

+ + + + + + + + + + + + + + +
Logical Operators
And AND, &
Or OR, |
Not NOT, !
+ +

The following are examples of DIS-Style queries:

+ +
    +
  • Title LIKE EDM AND Creator = "Sean Hardman" +

    This query will return all objects where the Title element contains the text "EDM" and the Creator element is equal to "Sean Hardman".

    +
  • + +
  • Title LIKE EDM AND Creator = "Sean Hardman" OR Title LIKE OODT AND Creator = "Sean Kelly" +

    This query will return all objects where either the first set of criteria matches or the second set of criteria matches.

    +
  • + +
  • Temperature > 32 AND Temperature < 212 +

    This query will return all objects where the Temperature element value is between the specified range.

    +
  • + +
  • Subject IS NULL +

    This query will return all objects where the Subject element has no associated value. When using the IS and ISNOT relational operators, the literal must be "NULL" or "null".

    +
  • +
+
+ +
http://git-wip-us.apache.org/repos/asf/oodt/blob/4066b63b/webapp/fmprod/src/site/xdoc/servlet/index.xml ---------------------------------------------------------------------- diff --git a/webapp/fmprod/src/site/xdoc/servlet/index.xml b/webapp/fmprod/src/site/xdoc/servlet/index.xml new file mode 100644 index 0000000..d266e1a --- /dev/null +++ b/webapp/fmprod/src/site/xdoc/servlet/index.xml @@ -0,0 +1,640 @@ + + + + + + Query Servlet + Sean Kelly + + + +
+ +

The query servlet enables you to inject generic queries into + the OODT framework using HTTP. This enables you to query for + profiles and products without requiring a Java, RMI, or CORBA + enabled application. +

+
+ +
+ +

The query servlet accepts various parameters for a query and + turns them into an XMLQuery object. It uses this + object internally to send the query around the network and to + gather results. It then returns a text/xml + representation of the XMLQuery object (for product + queries) or a text/xml representation of all matching + profiles (for profile queries). +

+ +

That means you must be able to process XML in + order to use the query servlet. Luckily, this isn't an onerous + restriction, as many languages are more than capable of doing so. +

+ +

For more details, view the Javadocs for the + jpl.oodt.servlets.QueryServlet class.

+
+ +
+ +

In order to use the query servlet, you need to specify three parameters: +

+ +
    +
  1. You need to know the type of the query you + want to make. You will use a string value of + profile to make a profile query, and + product to make a product query. You specify + your choice in a parameter named type. +
  2. + +
  3. You need to know the name of the object + that should receive the query. This takes the form of + urn:eda:protocol:name such + as urn:eda:corba:PDS.Profile or + urn:eda:rmi:NCI-ImageServer. You specify the + object name in a parameter named object. +
  4. + +
  5. You need the actual query you want to + send. You can express this in two ways: + +
      +
    1. As an keyword query expression like + TARGET_NAME = MARS. You specify the + query expression in a parameter named + keywordQuery. +
    2. + +
    3. As a text serialized XMLQuery + object. You specify the XML document in a + parameter named query. +
    4. +
    + +

    Using the latter enables you to fully specify all sorts of + parameters in the query. The former, though, is far + easier to use. +

    + +
  6. +
+ +

You then URL encode parameters' values and make either an HTTP + GET or POST request to the query + servlet. If all goes according to plan, the servlet will execute + the query and return to you a text/xml document + describing the results. You can then manipulate that document as + you see fit. For profile queries, the return value is a + <profiles> document with zero or more matching + profiles. For product queries, it's a <query> + + document with the original XMLQuery object with any + product results in the <queryResults> section. +

+ +
+ +
+ +

Let's look at a couple of concrete examples. In the first + example, we'll run a profile query against some planetary data + servers; the second example will run a product query for cancer + biomarkers. +

+ + + +

Suppose you wanted to know what PDS product servers supported + the query element ONLINE_FILE_SPECIFICATION_NAME. + You could pass that element to the PDS system profile server named + urn:eda:rmi:PDS.System.Profile using the query + servlet at + http://starbrite.jpl.nasa.gov/servlet/jpl.oodt.servlets.QueryServlet. + You can formulate the HTTP GET request in a URL as + follows: +

+ +

http://starbrite.jpl.nasa.gov/servlet/jpl.oodt.servlets.QueryServlet?
object=urn:eda:rmi:PDS.System.Profile&
type=profile&
keywordQuery=ONLINE_FILE_SPECIFICATION_NAME+%3D+ANY

+ +

Note that we've broken this URL into multiple lines for + readability. There should be no linebreaks in a real URL. Note + the following about this URL: +

+ +
    +
  • The question-mark separates the request URI from its + parameters. +
  • + +
  • The parameters may come in any order.
  • + +
  • The object parameter names the target of the + query; in this case, the RMI product server named + urn:eda:rmi:PDS.System.Profile. +
  • + +
  • The type parameter specifies that we're doing a + profile search.
  • + +
  • The keywordQuery parameter identifies the query + expression. Note the URL encoding: the spaces become + + symbols, and the equals sign become + %3D. +
  • +
+ +

The response from such a query is an XML document; this XML + document describes matching profiles and may take a form such as + the following:

+ + +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE profiles PUBLIC "-//JPL//DTD OODT Profile 1.1//EN" +"http://starshine.jpl.nasa.gov:80/dtd/prof.dtd"> + +<profiles> + <profile> + <profAttributes> + <profId>1.3.6.1.4.1.1306.2.1.1.7</profId> + <profType>profile</profType> + <profStatusId>active</profStatusId> + </profAttributes> + <resAttributes> + <Identifier>PDS.ASU.Product</Identifier> + <Title> + PDS Arizona State University Data Node Product Server + </Title> + <Format>text/html</Format> + <resContext>NASA.PDS.ASU</resContext> + <resClass>system.productServer</resClass> + <resLocation> + http://starbrite.jpl.nasa.gov/servlet/ + jpl.oodt.servlets.ProductServlet?object=PDS.ASU.Product + </resLocation> + <resLocation>urn:eda:rmi:PDS.ASU.Product</resLocation> + </resAttributes> + <profElement> + <elemName>ONLINE_FILE_SPECIFICATION_NAME</elemName> + <elemType>CHARACTER</elemType> + <elemEnumFlag>T</elemEnumFlag> + <elemMaxOccurrence>0</elemMaxOccurrence> + </profElement> + <profElement> + <elemName>RETURN_TYPE</elemName> + <elemType>CHARACTER</elemType> + <elemEnumFlag>T</elemEnumFlag> + <elemValue>PDS_ZIP</elemValue> + <elemValue>PDS_LABEL</elemValue> + <elemValue>RAW</elemValue> + <elemMaxOccurrence>0</elemMaxOccurrence> + </profElement> + </profile> + + <profile> + <profAttributes> + <profId>1.3.6.1.4.1.1306.2.1.1.6</profId> + <profType>profile</profType> + <profStatusId>active</profStatusId> + </profAttributes> + <resAttributes> + <Identifier>PDS.RS.Product</Identifier> + <Title>PDS Radio Science Product Server</Title> + <Format>text/html</Format> + <resContext>NASA.PDS.RS</resContext> + <resClass>system.productServer</resClass> + <resLocation> + http://starbrite.jpl.nasa.gov/servlet/ + jpl.oodt.servlets.ProductServlet?object=PDS.RS.Product + </resLocation> + <resLocation>urn:eda:rmi:PDS.RS.Product</resLocation> + </resAttributes> + <profElement> + <elemName>ONLINE_FILE_SPECIFICATION_NAME</elemName> + <elemType>CHARACTER</elemType> + <elemEnumFlag>T</elemEnumFlag> + <elemMaxOccurrence>0</elemMaxOccurrence> + </profElement> + <profElement> + <elemName>RETURN_TYPE</elemName> + <elemType>CHARACTER</elemType> + <elemEnumFlag>T</elemEnumFlag> + <elemValue>PDS_ZIP</elemValue> + <elemValue>PDS_LABEL</elemValue> + <elemValue>RAW</elemValue> + <elemMaxOccurrence>0</elemMaxOccurrence> + </profElement> + </profile> + + <profile> + <profAttributes> + <profId>1.3.6.1.4.1.1306.2.1.1.4</profId> + <profType>profile</profType> + <profStatusId>active</profStatusId> + </profAttributes> + <resAttributes> + <Identifier>PDS.Atmos.Product</Identifier> + <Title>PDS Atmospheres Product Server</Title> + <Format>text/html</Format> + <resContext>NASA.PDS.Atmos</resContext> + <resClass>system.productServer</resClass> + <resLocation> + http://starbrite.jpl.nasa.gov/servlet/ + jpl.oodt.servlets.ProductServlet?object=PDS.Atmos.Product + </resLocation> + <resLocation>urn:eda:rmi:PDS.Atmos.Product</resLocation> + </resAttributes> + <profElement> + <elemName>ONLINE_FILE_SPECIFICATION_NAME</elemName> + <elemType>CHARACTER</elemType> + <elemEnumFlag>T</elemEnumFlag> + <elemMaxOccurrence>0</elemMaxOccurrence> + </profElement> + <profElement> + <elemName>RETURN_TYPE</elemName> + <elemType>CHARACTER</elemType> + <elemEnumFlag>T</elemEnumFlag> + <elemValue>PDS_ZIP</elemValue> + <elemValue>PDS_LABEL</elemValue> + <elemValue>RAW</elemValue> + <elemMaxOccurrence>0</elemMaxOccurrence> + </profElement> + </profile> + + <profile> + <profAttributes> + <profId>1.3.6.1.4.1.1306.2.1.1.3</profId> + <profType>profile</profType> + <profStatusId>active</profStatusId> + </profAttributes> + <resAttributes> + <Identifier>PDS.NAIF.Product</Identifier> + <Title>PDS NAIF Product Server</Title> + <Format>text/html</Format> + <resContext>NASA.PDS.NAIF</resContext> + <resClass>system.productServer</resClass> + <resLocation> + http://starbrite.jpl.nasa.gov/servlet/ + jpl.oodt.servlets.ProductServlet?object=PDS.NAIF.Product + </resLocation> + <resLocation>urn:eda:rmi:PDS.NAIF.Product</resLocation> + </resAttributes> + <profElement> + <elemName>ONLINE_FILE_SPECIFICATION_NAME</elemName> + <elemType>CHARACTER</elemType> + <elemEnumFlag>T</elemEnumFlag> + <elemMaxOccurrence>0</elemMaxOccurrence> + </profElement> + <profElement> + <elemName>RETURN_TYPE</elemName> + <elemType>CHARACTER</elemType> + <elemEnumFlag>T</elemEnumFlag> + <elemValue>PDS_ZIP</elemValue> + <elemValue>PDS_LABEL</elemValue> + <elemValue>RAW</elemValue> + <elemMaxOccurrence>0</elemMaxOccurrence> + </profElement> + </profile> + + <profile> + <profAttributes> + <profId>1.3.6.1.4.1.1306.2.1.1.2</profId> + <profType>profile</profType> + <profStatusId>active</profStatusId> + </profAttributes> + <resAttributes> + <Identifier>PDS.Geo.Product</Identifier> + <Title>PDS Geosciences Product Server</Title> + <Format>text/html</Format> + <resContext>NASA.PDS.GEO</resContext> + <resClass>system.productServer</resClass> + <resLocation> + http://starbrite.jpl.nasa.gov/servlet/ + jpl.oodt.servlets.ProductServlet?object=PDS.Geo.Product + </resLocation> + <resLocation>urn:eda:rmi:PDS.Geo.Product</resLocation> + </resAttributes> + <profElement> + <elemName>ONLINE_FILE_SPECIFICATION_NAME</elemName> + <elemType>CHARACTER</elemType> + <elemEnumFlag>T</elemEnumFlag> + <elemMaxOccurrence>0</elemMaxOccurrence> + </profElement> + <profElement> + <elemName>RETURN_TYPE</elemName> + <elemType>CHARACTER</elemType> + <elemEnumFlag>T</elemEnumFlag> + <elemValue>PDS_ZIP</elemValue> + <elemValue>PDS_LABEL</elemValue> + <elemValue>RAW</elemValue> + <elemMaxOccurrence>0</elemMaxOccurrence> + </profElement> + </profile> + + <profile> + <profAttributes> + <profId>1.3.6.1.4.1.1306.2.1.1.1</profId> + <profType>profile</profType> + <profStatusId>active</profStatusId> + </profAttributes> + <resAttributes> + <Identifier>PDS.CN.Product</Identifier> + <Title>PDS Central Node Archive Product Server</Title> + <Format>text/html</Format> + <resContext>NASA.PDS.CN</resContext> + <resClass>system.productServer</resClass> + <resLocation> + http://starbrite.jpl.nasa.gov/servlet/ + jpl.oodt.servlets.ProductServlet?object=PDS.CN.Product + </resLocation> + <resLocation>urn:eda:rmi:PDS.CN.Product</resLocation> + </resAttributes> + <profElement> + <elemName>ONLINE_FILE_SPECIFICATION_NAME</elemName> + <elemType>CHARACTER</elemType> + <elemEnumFlag>T</elemEnumFlag> + <elemMaxOccurrence>0</elemMaxOccurrence> + </profElement> + <profElement> + <elemName>RETURN_TYPE</elemName> + <elemType>CHARACTER</elemType> + <elemEnumFlag>T</elemEnumFlag> + <elemValue>PDS_ZIP</elemValue> + <elemValue>PDS_LABEL</elemValue> + <elemValue>RAW</elemValue> + <elemMaxOccurrence>0</elemMaxOccurrence> + </profElement> + </profile> + + <profile> + <profAttributes> + <profId>1.3.6.1.4.1.1306.2.1.1.10</profId> + <profType>profile</profType> + <profStatusId>active</profStatusId> + </profAttributes> + <resAttributes> + <Identifier>PDS.CN.Profile</Identifier> + <Title>PDS.CN.Profile</Title> + <Format>text/html</Format> + <resContext>NASA.PDS.CN</resContext> + <resClass>system.productServer</resClass> + <resLocation> + http://starbrite.jpl.nasa.gov/servlet/ + jpl.oodt.servlets.ProductServlet?object=PDS.CN.Profile + </resLocation> + <resLocation>urn:eda:rmi:PDS.CN.Profile</resLocation> + </resAttributes> + <profElement> + <elemName>ONLINE_FILE_SPECIFICATION_NAME</elemName> + <elemType>CHARACTER</elemType> + <elemEnumFlag>T</elemEnumFlag> + <elemMaxOccurrence>0</elemMaxOccurrence> + </profElement> + <profElement> + <elemName>RETURN_TYPE</elemName> + <elemType>CHARACTER</elemType> + <elemEnumFlag>T</elemEnumFlag> + <elemValue>PDS_ZIP</elemValue> + <elemValue>PDS_LABEL</elemValue> + <elemValue>RAW</elemValue> + <elemMaxOccurrence>0</elemMaxOccurrence> + </profElement> + </profile> + + <profile> + <profAttributes> + <profId>1.3.6.1.4.1.1306.2.1.1.9</profId> + <profType>profile</profType> + <profStatusId>active</profStatusId> + </profAttributes> + <resAttributes> + <Identifier>PDS.PPI.Product</Identifier> + <Title> + PDS Planetary Plasma Interactions Product Server + </Title> + <Format>text/html</Format> + <resContext>NASA.PDS.PPI</resContext> + <resClass>system.productServer</resClass> + <resLocation> + http://starbrite.jpl.nasa.gov/servlet/ + jpl.oodt.servlets.ProductServlet?object=PDS.PPI.Product + </resLocation> + <resLocation>urn:eda:rmi:PDS.PPI.Product</resLocation> + </resAttributes> + <profElement> + <elemName>ONLINE_FILE_SPECIFICATION_NAME</elemName> + <elemType>CHARACTER</elemType> + <elemEnumFlag>T</elemEnumFlag> + <elemMaxOccurrence>0</elemMaxOccurrence> + </profElement> + <profElement> + <elemName>RETURN_TYPE</elemName> + <elemType>CHARACTER</elemType> + <elemEnumFlag>T</elemEnumFlag> + <elemValue>PDS_ZIP</elemValue> + <elemValue>PDS_LABEL</elemValue> + <elemValue>RAW</elemValue> + <elemMaxOccurrence>0</elemMaxOccurrence> + </profElement> + </profile> + + <profile> + <profAttributes> + <profId>1.3.6.1.4.1.1306.2.1.1.8</profId> + <profType>profile</profType> + <profStatusId>active</profStatusId> + </profAttributes> + <resAttributes> + <Identifier>PDS.Img.Product</Identifier> + <Title>PDS Imaging Product Server</Title> + <Format>text/html</Format> + <resContext>NASA.PDS.Img</resContext> + <resClass>system.productServer</resClass> + <resLocation> + http://starbrite.jpl.nasa.gov/servlet/ + jpl.oodt.servlets.ProductServlet?object=PDS.Img.Product + </resLocation> + <resLocation>urn:eda:rmi:PDS.Img.Product</resLocation> + </resAttributes> + <profElement> + <elemName>ONLINE_FILE_SPECIFICATION_NAME</elemName> + <elemType>CHARACTER</elemType> + <elemEnumFlag>T</elemEnumFlag> + <elemMaxOccurrence>0</elemMaxOccurrence> + </profElement> + <profElement> + <elemName>RETURN_TYPE</elemName> + <elemType>CHARACTER</elemType> + <elemEnumFlag>T</elemEnumFlag> + <elemValue>PDS_ZIP</elemValue> + <elemValue>PDS_LABEL</elemValue> + <elemValue>RAW</elemValue> + <elemMaxOccurrence>0</elemMaxOccurrence> + </profElement> + </profile> +</profiles> + + +
+ + + +

Suppose you had a query servlet available at + http://pancreas/qs, and you want to query the CORBA + product server urn:eda:corba:TissueBank with the + query expression SeverityLevel = 3. You can + formulate the entire GET request as the following + URL: +

+ + + http://pancreas/qs? + type=product& + object=urn:eda:corba:TissueBank& + keywordQuery=SeverityLevel+%3D+3 + + +

(Again, we've broken the URL for readability.) The result to + this query could be an XML document like the following: +

+ + +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE query PUBLIC "-//JPL//DTD OODT Query 1.0//EN" + "http://pancreas/dtd/query.dtd"> + +<query> + <queryAttributes> + <queryId>UNKNOWN</queryId> + <queryTitle>UNKNOWN</queryTitle> + <queryDesc>UNKNOWN</queryDesc> + <queryType>QUERY</queryType> + <queryStatusId>ACTIVE</queryStatusId> + <querySecurityType>UNKNOWN</querySecurityType> + <queryRevisionNote> + 1999-12-12 JSH V1.0 Under Development + </queryRevisionNote> + <queryDataDictId>UNKNOWN</queryDataDictId> + </queryAttributes> + <queryResultModeId>ATTRIBUTE</queryResultModeId> + <queryPropogationType>BROADCAST</queryPropogationType> + <queryPropogationLevels>N/A</queryPropogationLevels> + <queryMimeAccept>*/*</queryMimeAccept> + <queryMaxResults>100</queryMaxResults> + <queryResults>0</queryResults> + <queryKWQString>SeverityLevel = 3</queryKWQString> + <querySelectSet> + <queryElement> + <tokenRole>LITERAL</tokenRole> + <tokenValue>3</tokenValue> + </queryElement> + <queryElement> + <tokenRole>elemName</tokenRole> + <tokenValue>SeverityLevel</tokenValue> + </queryElement> + <queryElement> + <tokenRole>RELOP</tokenRole> + <tokenValue>EQ</tokenValue> + </queryElement> + </querySelectSet> + <queryFromSet/> + <queryWhereSet/> + <queryResultSet> + <resultElement> + <resultId>1</resultId> + <resultMimeType>text/plain</resultMimeType> + <profId>TissueBank</profId> + <identifier/> + <resultHeader> + <headerElement> + <elemName>UNKNOWN</elemName> + <elemType>TEXT</elemType> + </headerElement> + </resultHeader> + <Resultvalue xml:space="preserve"> + PatientIDs=[1,2,4,7,11,19,22]</resultValue> + </resultElement> + </queryResultSet> +</query> + + +

Instead of using the keywordQuery parameter, you + can create your own XMLQuery document and pass it in + as the query parameter instead. The query document + would look like this: +

+ + +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE query PUBLIC "-//JPL//DTD OODT Query 1.0//EN" + "http://pancreas:80/dtd/query.dtd"> + +<query> + <queryAttributes> + <queryId>expr1</queryId> + <queryTitle>Command-line Expression Query</queryTitle> + <queryDesc> + The expression for this query came from the command-line. + </queryDesc> + <queryType>QUERY</queryType> + <queryStatusId>ACTIVE</queryStatusId> + <querySecurityType>UNKNOWN</querySecurityType> + <queryRevisionNote> + 1999-12-12 JSH V1.0 Under Development + </queryRevisionNote> + <queryDataDictId>UNKNOWN</queryDataDictId> + </queryAttributes> + <queryResultModeId>ATTRIBUTE</queryResultModeId> + <queryPropogationType>BROADCAST</queryPropogationType> + <queryPropogationLevels>N/A</queryPropogationLevels> + <queryMimeAccept>*/*</queryMimeAccept> + <queryMaxResults>100</queryMaxResults> + <queryResults>0</queryResults> + <queryKWQString>SeverityLevel = 3</queryKWQString> + <querySelectSet/> + <queryFromSet/> + <queryWhereSet> + <queryElement> + <tokenRole>elemName</tokenRole> + <tokenValue>SeverityLevel</tokenValue> + </queryElement> + <queryElement> + <tokenRole>LITERAL</tokenRole> + <tokenValue>3</tokenValue> + </queryElement> + <queryElement> + <tokenRole>RELOP</tokenRole> + <tokenValue>EQ</tokenValue> + </queryElement> + </queryWhereSet> + <queryResultSet/> +</query> + + +

Passing such a long string as a URL parameter in a + GET request can be tricky, though. For such long + parameters, it's better to use a POST request + instead. See your HTTP API documentation for details on + formulating POST requests. +

+
+
+ +