/**
* $Id$
* $Date$
*
*/
package org.xmlsh.commands.internal;
import java.io.InputStream;
import java.net.URI;
import java.util.List;
import net.sf.saxon.s9api.Processor;
import net.sf.saxon.s9api.QName;
import net.sf.saxon.s9api.XQueryCompiler;
import net.sf.saxon.s9api.XQueryEvaluator;
import net.sf.saxon.s9api.XQueryExecutable;
import net.sf.saxon.s9api.XdmAtomicValue;
import net.sf.saxon.s9api.XdmItem;
import net.sf.saxon.s9api.XdmNode;
import org.xmlsh.core.IXdmItemOutputStream;
import org.xmlsh.core.InputPort;
import org.xmlsh.core.Namespaces;
import org.xmlsh.core.Options;
import org.xmlsh.core.Options.OptionValue;
import org.xmlsh.core.OutputPort;
import org.xmlsh.core.XCommand;
import org.xmlsh.core.XValue;
import org.xmlsh.sh.shell.SerializeOpts;
import org.xmlsh.sh.shell.Shell;
import org.xmlsh.sh.shell.ShellModuleURIResolver;
import org.xmlsh.util.Util;
import org.xmlsh.xpath.EvalDefinition;
public class xquery extends XCommand {
@Override
public int run( List<XValue> args )
throws Exception
{
Options opts = new Options( "c=context:,cf=context-file:,f=file:,i=input:,n,q:,v,nons,ns:+,s=string,b=bool,baseuri:,noxmlsh" , SerializeOpts.getOptionDefs() );
opts.parse(args);
Processor processor = Shell.getProcessor();
XQueryCompiler compiler = processor.newXQueryCompiler();
compiler.setModuleURIResolver(new ShellModuleURIResolver(getEnv().getShell()));
XdmItem context = null;
SerializeOpts serializeOpts = getSerializeOpts(opts);
InputPort in = null ; // Save to close
boolean bString = opts.hasOpt("s");
boolean bBool = opts.hasOpt("b");
boolean bNoXmlsh = opts.hasOpt("noxmlsh");
String baseURI = opts.getOptString("baseuri", null );
if( baseURI != null )
baseURI = getAbsoluteURI( baseURI );
if( ! opts.hasOpt("n" ) ){ // Has XML data input
// Order of prevelence
// -context
// -context-file
// -i
if( opts.hasOpt("c") )
context = opts.getOptValue("c").asXdmItem();
else
if( opts.hasOpt("cf"))
context = (in=getInput( new XValue(opts.getOptString("cf", "-")))).asXdmItem(serializeOpts);
else
if( opts.hasOpt("i") )
context = (in=getInput( opts.getOptValue("i"))).asXdmItem(serializeOpts);
else
context = (in=getStdin()).asXdmItem(serializeOpts);
}
String query = null;
if( opts.hasOpt("q"))
query = opts.getOpt("q").getValue().toString();
XQueryExecutable expr = null;
List<XValue> xvargs = opts.getRemainingArgs();
OptionValue ov = opts.getOpt("f");
if( ov != null ){
if( query != null )
throwInvalidArg( "Cannot specifify both -q and -f");
InputPort qin = getInput(ov.getValue());
InputStream is = qin.asInputStream(serializeOpts);
query = Util.readString(is, serializeOpts.getInputTextEncoding());
if( baseURI == null ){
String sysid = qin.getSystemId();
if( !Util.isBlank(sysid)){
String uri = getAbsoluteURI(sysid);
baseURI = uri ;
}
}
is.close();
qin.close();
}
if( baseURI == null )
compiler.setBaseURI(getShell().getEnv().getBaseURI());
else
compiler.setBaseURI(new URI(baseURI));
if( query == null ){
if ( xvargs.size() < 1 )
throwInvalidArg("No query specified");
query = xvargs.remove(0).toString(); // remove arg 0
}
/*
* Add namespaces
*/
Namespaces ns = null ;
if( !opts.hasOpt("nons"))
ns = getEnv().getNamespaces();
if( opts.hasOpt("ns")){
Namespaces ns2 = new Namespaces();
if( ns != null )
ns2.putAll(ns);
// Add custom name spaces
for( XValue v : opts.getOpt("ns").getValues() )
ns2.declare(v);
ns = ns2;
}
if( ns != null ){
for( String prefix : ns.keySet() ){
String uri = ns.get(prefix);
compiler.declareNamespace(prefix, uri);
}
}
if( ! bNoXmlsh )
compiler.declareNamespace("xmlsh", EvalDefinition.kXMLSH_EXT_NAMESPACE);
expr = compiler.compile( query );
XQueryEvaluator eval = expr.load();
if( context != null )
eval.setContextItem(context);
if( opts.hasOpt("v")){
// Read pairs from args to set
for( int i = 0 ; i < xvargs.size()/2 ; i++ ){
String name = xvargs.get(i*2).toString();
XValue value = xvargs.get(i*2+1);
// DAL: Bug in 9.1.1 QName vqname = QName.fromClarkName(name );
//QName vqname = Util.fromClarkName(name);
QName vqname = Util.resolveQName( name , ns );
eval.setExternalVariable( vqname , value.asXdmValue() );
}
}
if( in != null )
in.close();
if( bBool ){
XValue value = new XValue(eval.evaluate());
return value.toBoolean() ? 0 : 1 ;
}
// eval.run(getStdout().asDestination(getSerializeOpts()));
OutputPort stdout = getStdout();
IXdmItemOutputStream ser = stdout.asXdmItemOutputStream(serializeOpts);
boolean bFirst = true ;
boolean bAnyOut = false ;
for( XdmItem item : eval ){
bAnyOut = true ;
if( ! bFirst )
stdout.writeSequenceSeperator(serializeOpts); // Thrashes variable output !
bFirst = false ;
if( item instanceof XdmNode ){
XdmNode node = (XdmNode) item ;
if( bString )
item = new XdmAtomicValue( node.getStringValue());
}
//processor.writeXdmValue(item, ser );
// Util.writeXdmValue(item, ser);
ser.write(item);
}
if( bAnyOut )
stdout.writeSequenceTerminator(serializeOpts); // write "\n"
return 0;
}
}
//
//
//Copyright (C) 2008-2014 David A. Lee.
//
//The contents of this file are subject to the "Simplified BSD License" (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.opensource.org/licenses/bsd-license.php
//
//Software distributed under the License is distributed on an "AS IS" basis,
//WITHOUT WARRANTY OF ANY KIND, either express or implied.
//See the License for the specific language governing rights and limitations under the License.
//
//The Original Code is: all this file.
//
//The Initial Developer of the Original Code is David A. Lee
//
//Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
//
//Contributor(s): none.
//