use of org.exist.xquery.value.JavaObjectValue in project exist by eXist-db.
the class JavaCall method eval.
/* (non-Javadoc)
* @see org.exist.xquery.Expression#eval(org.exist.xquery.value.Sequence, org.exist.xquery.value.Item)
*/
public Sequence eval(Sequence contextSequence, Item contextItem) throws XPathException {
if (context.getProfiler().isEnabled()) {
context.getProfiler().start(this);
context.getProfiler().message(this, Profiler.DEPENDENCIES, "DEPENDENCIES", Dependency.getDependenciesName(this.getDependencies()));
if (contextSequence != null) {
context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT SEQUENCE", contextSequence);
}
if (contextItem != null) {
context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT ITEM", contextItem.toSequence());
}
}
// get the actual arguments
final Sequence[] args = getArguments(contextSequence, contextItem);
AccessibleObject bestMethod = candidateMethods.get(0);
int[] conversionPrefs = getConversionPreferences(bestMethod, args);
for (AccessibleObject nextMethod : candidateMethods) {
int[] prefs = getConversionPreferences(nextMethod, args);
for (int j = 0; j < prefs.length; j++) {
if (prefs[j] < conversionPrefs[j]) {
bestMethod = nextMethod;
conversionPrefs = prefs;
break;
}
}
}
// LOG.debug("calling method " + bestMethod.toString());
Class<?>[] paramTypes = null;
boolean isStatic = true;
if (bestMethod instanceof Constructor<?>) {
paramTypes = ((Constructor<?>) bestMethod).getParameterTypes();
} else {
paramTypes = ((Method) bestMethod).getParameterTypes();
isStatic = Modifier.isStatic(((Method) bestMethod).getModifiers());
}
final Object[] params = new Object[isStatic ? args.length : args.length - 1];
if (isStatic) {
for (int i = 0; i < args.length; i++) {
params[i] = args[i].toJavaObject(paramTypes[i]);
}
} else {
for (int i = 1; i < args.length; i++) {
params[i - 1] = args[i].toJavaObject(paramTypes[i - 1]);
}
}
Sequence result;
if (bestMethod instanceof Constructor<?>) {
try {
final Object object = ((Constructor<?>) bestMethod).newInstance(params);
result = new JavaObjectValue(object);
} catch (final IllegalArgumentException e) {
throw new XPathException(this, "illegal argument to constructor " + bestMethod.toString() + ": " + e.getMessage(), e);
} catch (final Exception e) {
if (e instanceof XPathException) {
throw (XPathException) e;
} else {
throw new XPathException(this, "exception while calling constructor " + bestMethod.toString() + ": " + e.getMessage(), e);
}
}
} else {
try {
Object invocationResult;
if (isStatic) {
invocationResult = ((Method) bestMethod).invoke(null, params);
} else {
invocationResult = ((Method) bestMethod).invoke(args[0].toJavaObject(myClass), params);
}
result = XPathUtil.javaObjectToXPath(invocationResult, getContext());
} catch (final IllegalArgumentException e) {
throw new XPathException(this, "illegal argument to method " + bestMethod.toString() + ": " + e.getMessage(), e);
} catch (final Exception e) {
if (e instanceof XPathException) {
throw (XPathException) e;
} else {
throw new XPathException(this, "exception while calling method " + bestMethod.toString() + ": " + e.getMessage(), e);
}
}
}
if (context.getProfiler().isEnabled()) {
context.getProfiler().end(this, "", result);
}
if (result == null) {
result = Sequence.EMPTY_SEQUENCE;
}
return result;
}
use of org.exist.xquery.value.JavaObjectValue in project exist by eXist-db.
the class CollectionName method eval.
/* (non-Javadoc)
* @see org.exist.xquery.BasicFunction#eval(org.exist.xquery.value.Sequence[], org.exist.xquery.value.Sequence)
*/
public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
if (args[0].isEmpty()) {
return Sequence.EMPTY_SEQUENCE;
}
final Item item = args[0].itemAt(0);
if (item.getType() == Type.JAVA_OBJECT) {
final Object o = ((JavaObjectValue) item).getObject();
if (!(o instanceof Collection)) {
throw new XPathException(this, "Passed Java object should be of type org.xmldb.api.base.Collection");
}
final Collection collection = (Collection) o;
try {
return new StringValue(collection.getName());
} catch (final XMLDBException e) {
throw new XPathException(this, "Failed to retrieve collection name", e);
}
} else if (Type.subTypeOf(item.getType(), Type.STRING)) {
final String path = item.getStringValue();
try {
final XmldbURI uri = XmldbURI.xmldbUriFor(path).removeLastSegment();
return new StringValue(uri.toString());
} catch (final URISyntaxException e) {
throw new XPathException(this, "Illegal URI for resource path: " + path);
}
} else if (Type.subTypeOf(item.getType(), Type.NODE)) {
final NodeValue node = (NodeValue) item;
if (node.getImplementationType() == NodeValue.PERSISTENT_NODE) {
final NodeProxy p = (NodeProxy) node;
// TODO: use xmldbUri
return new StringValue(p.getOwnerDocument().getCollection().getURI().toString());
}
} else {
throw new XPathException(this, "First argument to util:collection-name should be either " + "a Java object of type org.xmldb.api.base.Collection or a node; got: " + Type.getTypeName(item.getType()));
}
return Sequence.EMPTY_SEQUENCE;
}
use of org.exist.xquery.value.JavaObjectValue in project exist by eXist-db.
the class XMLDBStore method evalWithCollection.
@Override
public Sequence evalWithCollection(Collection collection, Sequence[] args, Sequence contextSequence) throws XPathException {
String docName = args[1].isEmpty() ? null : args[1].getStringValue();
if (docName != null && docName.isEmpty()) {
docName = null;
} else if (docName != null) {
docName = new AnyURIValue(docName).toXmldbURI().toString();
}
final Item item = args[2].itemAt(0);
// determine the mime type
final boolean storeAsBinary = isCalledAs(FS_STORE_BINARY_NAME);
MimeType mimeType = null;
if (getSignature().getArgumentCount() == 4) {
final String strMimeType = args[3].getStringValue();
mimeType = MimeTable.getInstance().getContentType(strMimeType);
}
if (mimeType == null && docName != null) {
mimeType = MimeTable.getInstance().getContentTypeFor(docName);
}
if (mimeType == null) {
mimeType = (storeAsBinary || !Type.subTypeOf(item.getType(), Type.NODE)) ? MimeType.BINARY_TYPE : MimeType.XML_TYPE;
} else if (storeAsBinary) {
mimeType = new MimeType(mimeType.getName(), MimeType.BINARY);
}
Resource resource;
try {
if (Type.subTypeOf(item.getType(), Type.JAVA_OBJECT)) {
final Object obj = ((JavaObjectValue) item).getObject();
if (obj instanceof java.io.File) {
resource = loadFromFile(collection, ((java.io.File) obj).toPath(), docName, mimeType);
} else if (obj instanceof java.nio.file.Path) {
resource = loadFromFile(collection, (Path) obj, docName, mimeType);
} else {
LOGGER.error("Passed java object should be either a java.nio.file.Path or java.io.File");
throw new XPathException(this, "Passed java object should be either a java.nio.file.Path or java.io.File");
}
} else if (Type.subTypeOf(item.getType(), Type.ANY_URI)) {
try {
final URI uri = new URI(item.getStringValue());
resource = loadFromURI(collection, uri, docName, mimeType);
} catch (final URISyntaxException e) {
LOGGER.error("Invalid URI: {}", item.getStringValue());
throw new XPathException(this, "Invalid URI: " + item.getStringValue(), e);
}
} else {
if (mimeType.isXMLType()) {
resource = collection.createResource(docName, "XMLResource");
} else {
resource = collection.createResource(docName, "BinaryResource");
}
if (Type.subTypeOf(item.getType(), Type.STRING)) {
resource.setContent(item.getStringValue());
} else if (item.getType() == Type.BASE64_BINARY) {
resource.setContent(((BinaryValue) item).toJavaObject());
} else if (Type.subTypeOf(item.getType(), Type.NODE)) {
if (mimeType.isXMLType()) {
final ContentHandler handler = ((XMLResource) resource).setContentAsSAX();
handler.startDocument();
item.toSAX(context.getBroker(), handler, SERIALIZATION_PROPERTIES);
handler.endDocument();
} else {
try (final StringWriter writer = new StringWriter()) {
final SAXSerializer serializer = new SAXSerializer();
serializer.setOutput(writer, null);
item.toSAX(context.getBroker(), serializer, SERIALIZATION_PROPERTIES);
resource.setContent(writer.toString());
} catch (final IOException e) {
LOGGER.error(e.getMessage(), e);
}
}
} else {
LOGGER.error("Data should be either a node or a string");
throw new XPathException(this, "Data should be either a node or a string");
}
((EXistResource) resource).setMimeType(mimeType.getName());
collection.storeResource(resource);
}
} catch (final XMLDBException e) {
LOGGER.error(e.getMessage(), e);
throw new XPathException(this, "XMLDB reported an exception while storing document: " + e.getMessage(), e);
} catch (final SAXException e) {
LOGGER.error(e.getMessage());
throw new XPathException(this, "SAX reported an exception while storing document", e);
}
if (resource == null) {
return Sequence.EMPTY_SEQUENCE;
} else {
try {
// TODO : use dedicated function in XmldbURI
return new StringValue(collection.getName() + "/" + resource.getId());
} catch (final XMLDBException e) {
LOGGER.error(e.getMessage());
throw new XPathException(this, "XMLDB reported an exception while retrieving the " + "stored document", e);
}
}
}
use of org.exist.xquery.value.JavaObjectValue in project exist by eXist-db.
the class Shared method getStreamSource.
public static StreamSource getStreamSource(Item item, XQueryContext context) throws XPathException, IOException {
final StreamSource streamSource = new StreamSource();
if (item.getType() == Type.JAVA_OBJECT) {
LOG.debug("Streaming Java object");
final Object obj = ((JavaObjectValue) item).getObject();
if (!(obj instanceof File)) {
throw new XPathException("Passed java object should be a File");
}
final File inputFile = (File) obj;
final InputStream is = new FileInputStream(inputFile);
streamSource.setInputStream(is);
streamSource.setSystemId(inputFile.toURI().toURL().toString());
} else if (item.getType() == Type.ANY_URI) {
LOG.debug("Streaming xs:anyURI");
// anyURI provided
String url = item.getStringValue();
// Fix URL
if (url.startsWith("/")) {
url = "xmldb:exist://" + url;
}
final InputStream is = new URL(url).openStream();
streamSource.setInputStream(is);
streamSource.setSystemId(url);
} else if (item.getType() == Type.ELEMENT || item.getType() == Type.DOCUMENT) {
LOG.debug("Streaming element or document node");
if (item instanceof NodeProxy) {
final NodeProxy np = (NodeProxy) item;
final String url = "xmldb:exist://" + np.getOwnerDocument().getBaseURI();
LOG.debug("Document detected, adding URL {}", url);
streamSource.setSystemId(url);
}
// Node provided
final DBBroker broker = context.getBroker();
final ConsumerE<ConsumerE<Serializer, IOException>, IOException> withSerializerFn = fn -> {
final Serializer serializer = broker.borrowSerializer();
try {
fn.accept(serializer);
} finally {
broker.returnSerializer(serializer);
}
};
final NodeValue node = (NodeValue) item;
final InputStream is = new NodeInputStream(context.getBroker().getBrokerPool(), withSerializerFn, node);
streamSource.setInputStream(is);
} else if (item.getType() == Type.BASE64_BINARY || item.getType() == Type.HEX_BINARY) {
LOG.debug("Streaming base64 binary");
final BinaryValue binary = (BinaryValue) item;
final byte[] data = binary.toJavaObject(byte[].class);
final InputStream is = new UnsynchronizedByteArrayInputStream(data);
streamSource.setInputStream(is);
if (item instanceof Base64BinaryDocument) {
final Base64BinaryDocument b64doc = (Base64BinaryDocument) item;
final String url = "xmldb:exist://" + b64doc.getUrl();
LOG.debug("Base64BinaryDocument detected, adding URL {}", url);
streamSource.setSystemId(url);
}
} else {
LOG.error("Wrong item type {}", Type.getTypeName(item.getType()));
throw new XPathException("wrong item type " + Type.getTypeName(item.getType()));
}
return streamSource;
}
Aggregations