package org.exist.xqdoc.ant; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.Project; import org.apache.tools.ant.types.FileSet; import org.exist.ant.AbstractXMLDBTask; import org.exist.source.Source; import org.exist.source.StringSource; import org.exist.storage.DBBroker; import org.exist.xmldb.XQueryService; import org.exist.xquery.Constants; import org.exist.xquery.value.Base64Binary; import org.xmldb.api.DatabaseManager; import org.xmldb.api.base.Collection; import org.xmldb.api.base.XMLDBException; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class XQDocTask extends AbstractXMLDBTask { private final static String XQUERY = "import module namespace xqdm=\"http://exist-db.org/xquery/xqdoc\";\n" + "import module namespace xdb=\"http://exist-db.org/xquery/xmldb\";\n" + "declare namespace xqdoc=\"http://www.xqdoc.org/1.0\"\n;" + "declare variable $uri external;\n" + "declare variable $name external;\n" + "declare variable $collection external;\n" + "declare variable $data external;\n" + "let $xml :=\n" + "if ($uri) then\n" + " xqdm:scan(xs:anyURI($uri))\n" + "else\n" + " xqdm:scan($data, $name)\n" + "let $moduleURI := $xml//xqdoc:module/xqdoc:uri\n" + "let $docName := concat(util:hash($moduleURI, 'MD5'), '.xml')\n" + "return\n" + " xdb:store($collection, $docName, $xml, 'text/xml')"; private String moduleURI = null; private boolean createCollection = false; private List<FileSet> fileSets = null; @Override public void execute() throws BuildException { registerDatabase(); try { int p = uri.indexOf(DBBroker.ROOT_COLLECTION); if (p == Constants.STRING_NOT_FOUND) throw new BuildException("invalid uri: '" + uri + "'"); String baseURI = uri.substring(0, p); String path; if (p == uri.length() - 3) path = ""; else path = uri.substring(p + 3); Collection root = null; if (createCollection) { root = DatabaseManager.getCollection(baseURI + DBBroker.ROOT_COLLECTION, user, password); root = mkcol(root, baseURI, DBBroker.ROOT_COLLECTION, path); } else root = DatabaseManager.getCollection(uri, user, password); XQueryService service = (XQueryService) root.getService("XQueryService", "1.0"); Source source = new StringSource(XQUERY); service.declareVariable("collection", root.getName()); service.declareVariable("uri", ""); if (moduleURI != null) { service.declareVariable("uri", moduleURI); service.declareVariable("data", ""); service.execute(source); } else { for(FileSet fileSet: fileSets) { DirectoryScanner scanner = fileSet.getDirectoryScanner(getProject()); scanner.scan(); String[] files = scanner.getIncludedFiles(); log("Found " + files.length + " files to upload.\n"); File baseDir=scanner.getBasedir(); for (int i = 0; i < files.length; i++) { File file = new File(baseDir , files[i]); log("Storing " + files[i] + " ...\n"); byte[] data = read(file); try { service.declareVariable("name", file.getName()); service.declareVariable("data", data); service.execute(source); } catch (XMLDBException e) { String msg="XMLDB exception caught: " + e.getMessage(); if(failonerror) throw new BuildException(msg,e); else log(msg,e, Project.MSG_ERR); } } } } } catch (XMLDBException e) { String msg="XMLDB exception caught: " + e.getMessage(); if(failonerror) throw new BuildException(msg,e); else log(msg,e, Project.MSG_ERR); } } public void setCreatecollection(boolean create) { this.createCollection = create; } public void setModuleuri(String uri) { this.moduleURI = uri; } public void addFileset(FileSet set) { if (fileSets == null) fileSets = new ArrayList<FileSet>(); fileSets.add(set); } private byte[] read(File file) throws BuildException { try { ByteArrayOutputStream bos = new ByteArrayOutputStream(4096); FileInputStream fis = new FileInputStream(file); byte[] buf = new byte[4096]; int l; while ((l = fis.read(buf)) > -1) { bos.write(buf, 0, l); } return bos.toByteArray(); } catch (IOException e) { throw new BuildException("IO error while reading XQuery source: " + file.getAbsolutePath() + ": " + e.getMessage(), e); } } }