package com.bagri.xquery.saxon; import static com.bagri.core.Constants.cmd_get_document; import static com.bagri.core.Constants.cmd_remove_cln_documents; import static com.bagri.core.Constants.cmd_remove_document; import static com.bagri.core.Constants.cmd_store_document; import static com.bagri.core.Constants.pn_query_command; import static com.bagri.support.util.XQUtils.context2Props; import static com.bagri.support.util.XQUtils.getXQException; import static com.bagri.xquery.saxon.SaxonUtils.itemToXQItem; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Properties; import javax.xml.xquery.XQException; import javax.xml.xquery.XQItem; import javax.xml.xquery.XQStaticContext; import com.bagri.core.api.QueryManagement; import com.bagri.core.api.ResultCursor; import com.bagri.core.api.BagriException; import com.bagri.core.api.impl.ResultCursorBase; import com.bagri.core.model.Query; import com.bagri.core.xquery.api.XQProcessor; import net.sf.saxon.expr.instruct.GlobalParameterSet; import net.sf.saxon.om.Item; import net.sf.saxon.om.StructuredQName; import net.sf.saxon.trans.XPathException; public class XQProcessorClient extends XQProcessorImpl implements XQProcessor { @Override public void cancelExecution() throws XQException { try { getQueryManagement().cancelExecution(); } catch (BagriException ex) { throw getXQException(ex); } } @Override public Iterator<Object> executeXCommand(String command, Map<String, Object> params, XQStaticContext ctx) throws XQException { return executeXCommand(command, params, collectProperties(ctx)); } @Override public Iterator<Object> executeXCommand(String command, Map<String, Object> params, Properties props) throws XQException { //logger.trace("executeXCommand.enter; command: {}", command); try { Object result; if (command.equals(cmd_store_document)) { String content = ((XQItem) params.remove("content")).getAtomicValue(); String uri = getDocumentUri(params); result = getDocumentManagement().storeDocumentFromString(uri, content, fillProperties(params, props)); } else if (command.equals(cmd_get_document)) { String uri = getDocumentUri(params); result = getDocumentManagement().getDocumentAsString(uri, props); } else if (command.equals(cmd_remove_document)) { String uri = getDocumentUri(params); getDocumentManagement().removeDocument(uri); result = new Integer(1); } else if (command.equals(cmd_remove_cln_documents)) { String collection = (String) params.get("collection"); getDocumentManagement().removeCollectionDocuments(collection); result = new Integer(0); } else { props = ensureProperty(props, pn_query_command, "true"); QueryManagement qMgr = getQueryManagement(); ResultCursorBase cursor = (ResultCursorBase) qMgr.executeQuery(command, params, props); result = new Integer(1); //return cursor; } return Collections.singletonList(result).iterator(); } catch (BagriException ex) { throw getXQException(ex); } } @Override public Iterator<Object> executeXQuery(String query, Properties props) throws XQException { // implement it? what for..? throw new XQException("Not implemented on the client side. Use another executeXQuery method taking XQStaticContext as a parameter instead"); } @Override public ResultCursor executeXQuery(String query, XQStaticContext ctx) throws XQException { Properties props = collectProperties(ctx); props = ensureProperty(props, pn_query_command, "false"); try { Map<String, Object> params = getXQItemParams(); return getQueryManagement().executeQuery(query, params, props); } catch (XPathException | BagriException ex) { throw getXQException(ex); } } @Override public Collection<String> prepareXQuery(String query, XQStaticContext ctx) throws XQException { QueryManagement qMgr = getQueryManagement(); Collection<String> names = qMgr.prepareQuery(query); if (names != null) { return names; } return super.prepareXQuery(query, ctx); } @Override public Query getCurrentQuery(final String query) throws XQException { // throw ex? return null; } @Override public ResultCursor getResults() { // throw ex? return null; } @Override public void setResults(ResultCursor cursor) { // no-op // throw ex? } private Properties collectProperties(XQStaticContext ctx) throws XQException { Properties props = context2Props(ctx); for (String name: properties.stringPropertyNames()) { if (!props.containsKey(name)) { props.setProperty(name, properties.getProperty(name)); } } return props; } private Properties ensureProperty(Properties props, String key, String value) { if (props == null) { props = new Properties(); } props.setProperty(key, value); return props; } private Properties fillProperties(Map<String, Object> params, Properties props) { if (props == null) { props = new Properties(); } for (Map.Entry<String, Object> e: params.entrySet()) { props.put(e.getKey(), e.getValue()); } return props; } private String getDocumentUri(Map<String, Object> params) throws XQException { XQItem uri = (XQItem) params.remove("uri"); if (uri == null) { throw new XQException("No document uri passed"); } return uri.getAtomicValue(); } private Map<String, Object> getXQItemParams() throws XQException, XPathException { GlobalParameterSet paramSet = dqc.getParameters(); Map<String, Object> params = new HashMap<>(paramSet.getNumberOfKeys()); for (StructuredQName qName: paramSet.getKeys()) { String pName = qName.getClarkName(); params.put(pName, itemToXQItem((Item) paramSet.get(qName), this.getXQDataFactory())); } return params; } @Override public boolean isQueryReadOnly(String query, Properties props) throws XQException { return isQueryReadOnly(query); } }