
com.marklogic.client.impl.Utilities Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of marklogic-client-api Show documentation
Show all versions of marklogic-client-api Show documentation
The official MarkLogic Java client API.
The newest version!
/*
* Copyright © 2024 MarkLogic Corporation. All Rights Reserved.
*/
package com.marklogic.client.impl;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.StringReader;
import java.io.Writer;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.XMLEvent;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import org.xml.sax.SAXException;
import com.marklogic.client.MarkLogicIOException;
import com.marklogic.client.MarkLogicInternalException;
import com.marklogic.client.io.BaseHandle;
import com.marklogic.client.io.Format;
import com.marklogic.client.io.OutputStreamSender;
import com.marklogic.client.io.marker.AbstractReadHandle;
import com.marklogic.client.io.marker.AbstractWriteHandle;
import com.marklogic.client.io.marker.ContentHandle;
import com.marklogic.client.io.marker.StructureWriteHandle;
import com.marklogic.client.io.marker.XMLWriteHandle;
public final class Utilities {
private static DocumentBuilderFactory factory;
private static DatatypeFactory datatypeFactory;
static private int BUFFER_SIZE = 8192;
private static DocumentBuilderFactory getFactory() {
if (factory == null)
factory = makeDocumentBuilderFactory();
return factory;
}
private static DocumentBuilderFactory makeDocumentBuilderFactory() {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
factory.setValidating(false);
return factory;
}
/**
* Construct a dom Element from a string. A utility function for creating
* DOM elements when needed for other builder functions.
*
* @param xmlString
* XML for an element.
* @return w3c.dom.Element representation the provided XML.
*/
public static org.w3c.dom.Element domElement(String xmlString) {
org.w3c.dom.Element element = null;
try {
ByteArrayInputStream bais = new ByteArrayInputStream(
xmlString.getBytes(Charset.forName("UTF-8")));
element = getFactory().newDocumentBuilder().parse(bais)
.getDocumentElement();
} catch (SAXException e) {
throw new MarkLogicIOException(
"Could not make Element from xmlString" + xmlString, e);
} catch (IOException e) {
throw new MarkLogicIOException(
"Could not make Element from xmlString" + xmlString, e);
} catch (ParserConfigurationException e) {
throw new MarkLogicIOException(
"Could not make Element from xmlString" + xmlString, e);
}
return element;
}
public static List importFromHandle(AbstractWriteHandle writeHandle) {
if (writeHandle == null) {
return null;
}
@SuppressWarnings("rawtypes")
HandleImplementation baseHandle = HandleAccessor.checkHandle(writeHandle,
"import");
return objectToEvents(baseHandle.sendContent());
}
static public List objectToEvents(Object content) {
if (content == null) {
return null;
} else if (content instanceof byte[]) {
return bytesToEvents((byte[]) content);
} else if (content instanceof File) {
return fileToEvents((File) content);
} else if (content instanceof InputStream) {
return inputStreamToEvents((InputStream) content);
} else if (content instanceof Reader) {
return readerToEvents((Reader) content);
} else if (content instanceof String) {
return stringToEvents((String) content);
} else if (content instanceof OutputStreamSender) {
return outputSenderToEvents((OutputStreamSender) content);
} else {
throw new IllegalArgumentException(
"Unrecognized class for import: "+content.getClass().getName()
);
}
}
static public List bytesToEvents(byte[] bytes) {
return readerToEvents(readBytes(bytes));
}
static public List fileToEvents(File file) {
return readerToEvents(readFile(file));
}
static public List inputStreamToEvents(InputStream stream) {
return readerToEvents(readInputStream(stream));
}
static public List outputSenderToEvents(OutputStreamSender sender) {
return readerToEvents(readOutputSender(sender));
}
static public List readerToEvents(Reader reader) {
return readerToEvents(readReader(reader));
}
static public List stringToEvents(String string) {
return readerToEvents(readString(string));
}
static XMLEventReader readBytes(byte[] bytes) {
if (bytes == null || bytes.length == 0) {
return null;
}
return readInputStream(new ByteArrayInputStream(bytes));
}
static XMLEventReader readFile(File file) {
try {
if (file == null) {
return null;
}
return readInputStream(new FileInputStream(file));
} catch (FileNotFoundException e) {
throw new MarkLogicIOException(e);
}
}
static XMLEventReader readInputStream(InputStream stream) {
try {
if (stream == null) {
return null;
}
return makeInputFactory().createXMLEventReader(stream);
} catch (XMLStreamException e) {
throw new MarkLogicIOException(e);
}
}
static XMLEventReader readOutputSender(OutputStreamSender sender) {
try {
if (sender == null) {
return null;
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
sender.write(baos);
return readBytes(baos.toByteArray());
} catch (IOException e) {
throw new MarkLogicIOException(e);
}
}
static XMLEventReader readReader(Reader reader) {
try {
if (reader == null) {
return null;
}
return makeInputFactory().createXMLEventReader(reader);
} catch (XMLStreamException e) {
throw new MarkLogicIOException(e);
}
}
static XMLEventReader readString(String string) {
if (string == null) {
return null;
}
return readReader(new StringReader(string));
}
static XMLInputFactory makeInputFactory() {
XMLInputFactory factory = XMLInputFactory.newInstance();
factory.setProperty("javax.xml.stream.isNamespaceAware", true);
factory.setProperty("javax.xml.stream.isValidating", false);
return factory;
}
static public List readerToEvents(XMLEventReader reader) {
try {
if (reader == null) {
return null;
}
List events = new ArrayList<>();
while (reader.hasNext()) {
XMLEvent event = reader.nextEvent();
switch (event.getEventType()) {
case XMLEvent.START_DOCUMENT:
case XMLEvent.END_DOCUMENT:
// skip prolog and end
break;
default:
events.add(event);
break;
}
}
if (events.size() == 0) {
return null;
}
return events;
} catch (XMLStreamException e) {
throw new MarkLogicIOException(e);
}
}
@SuppressWarnings("unchecked")
public static T exportToHandle(
List events, T handle
) {
if (handle == null) {
return null;
}
@SuppressWarnings("rawtypes")
HandleImplementation baseHandle = HandleAccessor.checkHandle(handle,
"export");
baseHandle.receiveContent(
eventsToObject(events, baseHandle.receiveAs())
);
return handle;
}
public static Object eventsToObject(List events, Class> as) {
if (events == null || events.size() == 0) {
return null;
}
if (byte[].class.isAssignableFrom(as)) {
return eventsToBytes(events);
} else if (File.class.isAssignableFrom(as)) {
return eventsToFile(events, ".xml");
} else if (InputStream.class.isAssignableFrom(as)) {
return eventsToInputStream(events);
} else if (Reader.class.isAssignableFrom(as)) {
return eventsToReader(events);
} else if (String.class.isAssignableFrom(as)) {
return eventsToString(events);
} else {
throw new IllegalArgumentException(
"Unrecognized class for export: "+as.getName()
);
}
}
public static byte[] eventsToBytes(List events) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (!writeEvents(events, baos)) {
return null;
}
return baos.toByteArray();
}
public static File eventsToFile(List events, String extension) {
try {
File tempFile = File.createTempFile("tmp", extension);
if (!writeEvents(events, new FileOutputStream(tempFile))) {
if (tempFile.exists()) {
tempFile.delete();
}
return null;
}
return tempFile;
} catch (FileNotFoundException e) {
throw new MarkLogicIOException(e);
} catch (IOException e) {
throw new MarkLogicIOException(e);
}
}
public static InputStream eventsToInputStream(List events) {
byte[] bytes = eventsToBytes(events);
if (bytes == null || bytes.length == 0) {
return null;
}
return new ByteArrayInputStream(bytes);
}
public static Reader eventsToReader(List events) {
String string = eventsToString(events);
if (string == null) {
return null;
}
return new StringReader(string);
}
public static String eventsToString(List events) {
byte[] bytes = eventsToBytes(events);
if (bytes == null || bytes.length == 0) {
return null;
}
return new String(bytes, StandardCharsets.UTF_8);
}
public static boolean writeEvents(List events, OutputStream out) {
if (events == null || events.size() == 0) {
return false;
}
try {
XMLOutputFactory factory = XmlFactories.getOutputFactory();
XMLEventWriter eventWriter = factory.createXMLEventWriter(out, "UTF-8");
for (XMLEvent event: events) {
eventWriter.add(event);
}
eventWriter.flush();
eventWriter.close();
return true;
} catch (XMLStreamException e) {
throw new MarkLogicIOException(e);
}
}
@SuppressWarnings("unchecked")
public static T exportTextToHandle(
List events, T handle
) {
if (handle == null) {
return null;
}
@SuppressWarnings("rawtypes")
HandleImplementation baseHandle = HandleAccessor.checkHandle(handle,
"export");
baseHandle.receiveContent(
eventTextToObject(events, baseHandle.receiveAs())
);
return handle;
}
public static Object eventTextToObject(List events, Class> as) {
if (events == null || events.size() == 0) {
return null;
}
if (byte[].class.isAssignableFrom(as)) {
return eventTextToBytes(events);
} else if (File.class.isAssignableFrom(as)) {
return eventTextToFile(events, ".txt");
} else if (InputStream.class.isAssignableFrom(as)) {
return eventTextToInputStream(events);
} else if (Reader.class.isAssignableFrom(as)) {
return eventTextToReader(events);
} else if (String.class.isAssignableFrom(as)) {
return eventTextToString(events);
} else {
throw new IllegalArgumentException(
"Unrecognized class for text export: "+as.getName()
);
}
}
public static byte[] eventTextToBytes(List events) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (!writeEventText(events, baos)) {
return null;
}
return baos.toByteArray();
}
public static File eventTextToFile(List events, String extension) {
try {
File tempFile = File.createTempFile("tmp", extension);
if (!writeEventText(events, new FileOutputStream(tempFile))) {
if (tempFile.exists()) {
tempFile.delete();
}
return null;
}
return tempFile;
} catch (FileNotFoundException e) {
throw new MarkLogicIOException(e);
} catch (IOException e) {
throw new MarkLogicIOException(e);
}
}
public static InputStream eventTextToInputStream(List events) {
byte[] bytes = eventTextToBytes(events);
if (bytes == null || bytes.length == 0) {
return null;
}
return new ByteArrayInputStream(bytes);
}
public static Reader eventTextToReader(List events) {
String string = eventTextToString(events);
if (string == null) {
return null;
}
return new StringReader(string);
}
public static String eventTextToString(List events) {
if (events == null || events.size() == 0) {
return null;
}
StringBuilder buf = new StringBuilder();
for (XMLEvent event: events) {
if (event.isCharacters()) {
buf.append(event.asCharacters().getData());
}
}
return buf.toString();
}
public static boolean writeEventText(List events, OutputStream out) {
if (events == null || events.size() == 0) {
return false;
}
try {
for (XMLEvent event: events) {
if (event.isCharacters()) {
out.write(event.asCharacters().getData().getBytes());
}
}
out.flush();
out.close();
return true;
} catch (IOException e) {
throw new MarkLogicIOException(e);
}
}
public static Source handleToSource(XMLWriteHandle handle) {
try {
if (handle == null) {
return null;
}
@SuppressWarnings("rawtypes")
HandleImplementation baseHandle =
HandleAccessor.checkHandle(handle, "source");
Object content = baseHandle.sendContent();
if (content instanceof byte[]) {
return new StreamSource(
new ByteArrayInputStream((byte[]) content));
} else if (content instanceof File) {
return new StreamSource(
new FileInputStream((File) content));
} else if (content instanceof InputStream) {
return new StreamSource((InputStream) content);
} else if (content instanceof OutputStreamSender) {
ByteArrayOutputStream buf = new ByteArrayOutputStream();
((OutputStreamSender) content).write(buf);
return new StreamSource(
new ByteArrayInputStream(buf.toByteArray()));
} else if (content instanceof Reader) {
return new StreamSource((Reader) content);
} else if (content instanceof String) {
return new StreamSource(
new StringReader((String) content));
} else {
throw new IllegalArgumentException("Unrecognized handle for source");
}
} catch (FileNotFoundException e) {
throw new MarkLogicIOException(e);
} catch (IOException e) {
throw new MarkLogicIOException(e);
}
}
static public XMLEventReader makeEventListReader(List events) {
if (events == null || events.size() == 0) {
return null;
}
return new XMLEventListReader(events);
}
static class XMLEventListReader implements XMLEventReader {
private List events;
private int curr = -1;
XMLEventListReader(List events) {
super();
this.events = events;
}
@Override
public Object next() {
return nextEvent();
}
@Override
public void remove() {
if (!hasItem(curr)) {
return;
}
events.remove(curr);
}
@Override
public XMLEvent nextEvent() {
if (!hasNext()) {
return null;
}
return events.get(++curr);
}
@Override
public boolean hasNext() {
return hasItem(curr + 1);
}
boolean hasItem(int i) {
return (events == null || i < events.size());
}
@Override
public XMLEvent peek() {
int peek = curr + 1;
if (!hasItem(peek)) {
return null;
}
return events.get(peek);
}
@Override
public String getElementText() throws XMLStreamException {
if (!hasNext() || !events.get(curr).isStartElement()) {
throw new XMLStreamException("no start element for text");
}
StringBuilder buf = new StringBuilder();
while (++curr < events.size()) {
XMLEvent event = events.get(curr);
int eventType = event.getEventType();
if (eventType == XMLEvent.CHARACTERS || eventType == XMLEvent.CDATA ||
eventType == XMLEvent.SPACE) {
buf.append(event.asCharacters().getData());
} else if (eventType == XMLEvent.END_ELEMENT) {
break;
} else if (eventType == XMLEvent.START_ELEMENT) {
throw new XMLStreamException("found subelement instead of text");
}
}
return buf.toString();
}
@Override
public XMLEvent nextTag() throws XMLStreamException {
if (!hasNext()) {
throw new XMLStreamException("no next tag");
}
XMLEvent event = events.get(curr);
int eventType = event.getEventType();
if (eventType != XMLEvent.START_ELEMENT && eventType != XMLEvent.END_ELEMENT) {
throw new XMLStreamException("no start tag for next tag");
}
while (++curr < events.size()) {
event = events.get(curr);
eventType = event.getEventType();
if (eventType == XMLEvent.START_ELEMENT || eventType == XMLEvent.END_ELEMENT) {
break;
} else if (eventType != XMLEvent.SPACE) {
throw new XMLStreamException("event other than space before next tag");
}
}
return event;
}
@Override
public Object getProperty(String name) {
if (name == null) return null;
if ("javax.xml.stream.isValidating".equals(name)) return false;
if ("javax.xml.stream.isNamespaceAware".equals(name)) return true;
if ("javax.xml.stream.isCoalescing".equals(name)) return false;
if ("javax.xml.stream.isReplacingEntityReferences".equals(name)) return false;
if ("javax.xml.stream.isSupportingExternalEntities".equals(name)) return false;
if ("javax.xml.stream.supportDTD".equals(name)) return false;
return null;
}
@Override
public void close() {
events = null;
curr = -1;
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
static public void setHandleContent(ContentHandle handle, Object content) {
if (handle == null) {
return;
}
handle.set(content);
}
@SuppressWarnings("rawtypes")
static public void setHandleStructuredFormat(ContentHandle handle, Format format) {
if (handle == null || format == null) {
return;
}
if (BaseHandle.class.isAssignableFrom(handle.getClass())) {
setHandleStructuredFormat((BaseHandle) handle, format);
}
}
@SuppressWarnings("rawtypes")
static public void setHandleStructuredFormat(StructureWriteHandle handle, Format format) {
if (handle == null || format == null) {
return;
}
if (BaseHandle.class.isAssignableFrom(handle.getClass())) {
setHandleStructuredFormat((BaseHandle) handle, format);
}
}
@SuppressWarnings("rawtypes")
static private void setHandleStructuredFormat(BaseHandle handle, Format format) {
if (format != Format.JSON && format != Format.XML) {
throw new IllegalArgumentException("Received "+format.name()+" format instead of JSON or XML");
}
handle.setFormat(format);
}
static public DatatypeFactory getDatatypeFactory() {
if (datatypeFactory == null) {
try {
datatypeFactory = DatatypeFactory.newInstance();
} catch (DatatypeConfigurationException e) {
throw new MarkLogicInternalException(e);
}
}
return datatypeFactory;
}
/**
* Writes bytes from the input stream to the output stream.
* @param in - the input stream passed in.
* @param outStream - output stream where the bytes are written.
*/
static public void write(InputStream in, OutputStream outStream) throws IOException {
if(in == null || outStream == null)
return;
try {
byte[] byteArray = new byte[BUFFER_SIZE * 2];
int byteCount = 0;
while ((byteCount = in.read(byteArray)) != -1) {
outStream.write(byteArray, 0, byteCount);
}
outStream.flush();
} finally {
in.close();
}
}
/**
* Writes bytes from the input Reader to the Writer stream.
* @param in - the Reader passed in.
* @param out - Writer stream where the bytes are written.
*/
static public void write(Reader in, Writer out) throws IOException {
if(in == null || out == null)
return;
try {
char[] charArray = new char[BUFFER_SIZE * 2];
int charCount = 0;
while ((charCount = in.read(charArray)) != -1) {
out.write(charArray, 0, charCount);
}
out.flush();
} finally {
in.close();
}
}
/**
* Writes bytes from the input Reader to the output stream.
* @param in - the Reader passed in.
* @param out - OutputStream where the bytes are written.
*/
static public void write(Reader in, OutputStream out) throws IOException {
write(in, new OutputStreamWriter(out));
}
static String escapeMultipartParamAssignment(CharsetEncoder asciiEncoder, String value) {
if (value == null) return null;
String assignment = null;
if (asciiEncoder.canEncode(value)) {
// escape any quotes or back-slashes
assignment = "=\"" + value.replace("\"", "\\\"").replace("\\", "\\\\") + "\"";
} else {
try {
assignment = "*=UTF-8''" + URLEncoder.encode(value, "UTF-8");
} catch (Throwable ex) {
throw new IllegalArgumentException("Uri cannot be encoded as UFT-8: "+value, ex);
}
}
asciiEncoder.reset();
return assignment;
}
public static double parseDouble(String value) {
return parseDouble(value, -1);
}
public static double parseDouble(String value, double defaultValue) {
return (value == null || value.length() == 0) ? defaultValue : Double.parseDouble(value);
}
public static int parseInt(String value) {
return parseInt(value, -1);
}
public static int parseInt(String value, int defaultValue) {
return (value == null || value.length() == 0) ? defaultValue : Integer.parseInt(value);
}
public static long parseLong(String value) {
return parseLong(value, -1L);
}
public static long parseLong(String value, long defaultValue) {
return (value == null || value.length() == 0) ? defaultValue : Long.parseLong(value);
}
public static void setHandleToString(AbstractReadHandle handle, String content) {
if (!(handle instanceof BaseHandle)) {
throw new IllegalArgumentException("cannot export with handle that doesn't extend base");
}
@SuppressWarnings("rawtypes")
BaseHandle baseHandle = (BaseHandle) handle;
@SuppressWarnings("rawtypes")
Class as = baseHandle.receiveAs();
if (InputStream.class.isAssignableFrom(as)) {
baseHandle.receiveContent(new ByteArrayInputStream(content.getBytes()));
} else if (Reader.class.isAssignableFrom(as)) {
baseHandle.receiveContent(new StringReader(content));
} else if (byte[].class.isAssignableFrom(as)) {
baseHandle.receiveContent(content.getBytes());
} else if (String.class.isAssignableFrom(as)) {
baseHandle.receiveContent(content);
} else {
throw new IllegalArgumentException("cannot export with handle that doesn't accept content as byte[], input stream, reader, or string");
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy