diff --git a/pdf/src/main/java/org/expath/exist/pdf/ExistExpathPdfModule.java b/pdf/src/main/java/org/expath/exist/pdf/ExistExpathPdfModule.java index 2d947f4..e405306 100644 --- a/pdf/src/main/java/org/expath/exist/pdf/ExistExpathPdfModule.java +++ b/pdf/src/main/java/org/expath/exist/pdf/ExistExpathPdfModule.java @@ -28,6 +28,8 @@ import org.exist.xquery.FunctionDef; import org.expath.exist.pdf.formControls.GetTextFieldsFunction; import org.expath.exist.pdf.formControls.SetTextFieldsFunction; +import org.expath.exist.pdf.metadata.GetContentMetadataFunction; +import org.expath.exist.pdf.metadata.SetContentMetadataFunction; import org.expath.exist.pdf.stamp.StampFunction; import ro.kuberam.libs.java.pdf.ModuleDescription; @@ -47,6 +49,10 @@ public class ExistExpathPdfModule extends AbstractInternalModule { private final static FunctionDef[] functions = { new FunctionDef(GetTextFieldsFunction.signature, GetTextFieldsFunction.class), new FunctionDef(SetTextFieldsFunction.signature, SetTextFieldsFunction.class), + new FunctionDef(GetContentMetadataFunction.signatures[0], GetContentMetadataFunction.class), + new FunctionDef(GetContentMetadataFunction.signatures[1], GetContentMetadataFunction.class), + new FunctionDef(SetContentMetadataFunction.signatures[0], SetContentMetadataFunction.class), + new FunctionDef(SetContentMetadataFunction.signatures[1], SetContentMetadataFunction.class), new FunctionDef(StampFunction.signatures[0], StampFunction.class), new FunctionDef(StampFunction.signatures[1], StampFunction.class) }; diff --git a/pdf/src/main/java/org/expath/exist/pdf/metadata/GetContentMetadataFunction.java b/pdf/src/main/java/org/expath/exist/pdf/metadata/GetContentMetadataFunction.java new file mode 100644 index 0000000..6b75819 --- /dev/null +++ b/pdf/src/main/java/org/expath/exist/pdf/metadata/GetContentMetadataFunction.java @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2011 Claudius Teodorescu + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * $Id$ + */ + +package org.expath.exist.pdf.metadata; + +/** + * Implements the get-content-metadata() function for eXist. + * + * @author W.S. Hager + */ + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.TimeZone; +import java.text.SimpleDateFormat; +import java.text.DateFormat; + +import javax.xml.transform.stream.StreamResult; + +import org.apache.log4j.Logger; +import org.exist.dom.QName; +import org.exist.xquery.modules.ModuleUtils; +import org.exist.xquery.BasicFunction; +import org.exist.xquery.Cardinality; +import org.exist.xquery.FunctionSignature; +import org.exist.xquery.XPathException; +import org.exist.xquery.XQueryContext; +import org.exist.xquery.functions.map.MapType; +import org.exist.xquery.value.Base64BinaryValueType; +import org.exist.xquery.value.BinaryValue; +import org.exist.xquery.value.BinaryValueFromInputStream; +import org.exist.xquery.value.FunctionParameterSequenceType; +import org.exist.xquery.value.FunctionReturnSequenceType; +import org.exist.xquery.value.Sequence; +import org.exist.xquery.value.SequenceType; +import org.exist.xquery.value.StringValue; +import org.exist.xquery.value.Type; +import org.exist.xquery.value.ValueSequence; +import org.exist.xquery.value.NodeValue; +import org.expath.exist.pdf.ExistExpathPdfModule; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; + +import ro.kuberam.libs.java.pdf.metadata.Metadata; + +public class GetContentMetadataFunction extends BasicFunction { + + private final static Logger log = Logger.getLogger(GetContentMetadataFunction.class); + + public final static FunctionSignature signatures[] = { + new FunctionSignature(new QName("get-content-metadata", + ExistExpathPdfModule.NAMESPACE_URI, ExistExpathPdfModule.PREFIX), + "Get the XMP metadata from a PDF contents.", + new SequenceType[] { + new FunctionParameterSequenceType("contents", Type.BASE64_BINARY, + Cardinality.ZERO_OR_ONE, "PDF contents where to get the metadata from.") + }, + new FunctionReturnSequenceType(Type.NODE, Cardinality.ZERO_OR_ONE, + "an XML document containing XMP metadata.") + ), + new FunctionSignature(new QName("get-content-metadata", + ExistExpathPdfModule.NAMESPACE_URI, ExistExpathPdfModule.PREFIX), + "Get document information metadata attributes from a PDF contents.", + new SequenceType[] { + new FunctionParameterSequenceType("contents", Type.BASE64_BINARY, + Cardinality.ZERO_OR_ONE, "PDF contents where to get the metadata from."), + new FunctionParameterSequenceType("properties", Type.STRING, + Cardinality.ZERO_OR_MORE, "List of properties to retrieve.") + }, + new FunctionReturnSequenceType(Type.STRING, Cardinality.ZERO_OR_MORE, + "a map containing document information metadata.") + ) + }; + + public GetContentMetadataFunction(XQueryContext context, FunctionSignature signature) { + super(context, signature); + } + + @Override + public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException { + + Sequence result = new ValueSequence(); + BinaryValue data = null; + try { + byte[] binary = (byte[]) ((BinaryValue) args[0].itemAt(0)).toJavaObject(byte[].class); + data = BinaryValueFromInputStream.getInstance(context, new Base64BinaryValueType(), + new ByteArrayInputStream(binary)); + } catch (Exception ex) { + throw new XPathException(ex.getMessage()); + } + if (args.length == 1) { + String resultAsString = null; + try { + resultAsString = Metadata.getDocumentXMP(data.getInputStream()); + } catch (Exception ex) { + throw new XPathException(ex.getMessage()); + } + try { + result = (NodeValue) ModuleUtils.stringToXML(context,resultAsString); + } catch (SAXException saxe) { + // do nothing, we will default to trying to return a string below + } catch (IOException ioe) { + // do nothing, we will default to trying to return a string below + } + } else if (args.length == 2) { + ArrayList resultAsStringList = new ArrayList(); + ArrayList properties = new ArrayList(); + for(int i = 0; i < args[1].getItemCount(); i++) { + properties.add(args[1].itemAt(i).toString()); + } + try { + resultAsStringList = Metadata.getDocumentInfo(data.getInputStream(),properties); + for (String val : resultAsStringList) { + result.add(new StringValue(val)); + } + } catch (Exception ex) { + throw new XPathException(ex.getMessage()); + } + } + + return result; + } +} \ No newline at end of file diff --git a/pdf/src/main/java/org/expath/exist/pdf/metadata/SetContentMetadataFunction.java b/pdf/src/main/java/org/expath/exist/pdf/metadata/SetContentMetadataFunction.java new file mode 100644 index 0000000..daee599 --- /dev/null +++ b/pdf/src/main/java/org/expath/exist/pdf/metadata/SetContentMetadataFunction.java @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2011 Claudius Teodorescu + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * $Id$ + */ + +package org.expath.exist.pdf.metadata; + +/** + * Implements the pdf:set-content-metadata() function for eXist. + * + * @author W.S. Hager + */ + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.util.ArrayList; + +import org.apache.log4j.Logger; +import org.exist.dom.QName; +import org.exist.xquery.BasicFunction; +import org.exist.xquery.Cardinality; +import org.exist.xquery.FunctionSignature; +import org.exist.xquery.XPathException; +import org.exist.xquery.XQueryContext; +import org.exist.xquery.functions.map.AbstractMapType; +import org.exist.xquery.value.AtomicValue; +import org.exist.xquery.value.Base64BinaryValueType; +import org.exist.xquery.value.BinaryValue; +import org.exist.xquery.value.BinaryValueFromInputStream; +import org.exist.xquery.value.FunctionParameterSequenceType; +import org.exist.xquery.value.FunctionReturnSequenceType; +import org.exist.xquery.value.Sequence; +import org.exist.xquery.value.SequenceType; +import org.exist.xquery.value.Type; +import org.exist.xquery.value.ValueSequence; +import org.expath.exist.pdf.ExistExpathPdfModule; + +import org.exist.storage.serializers.Serializer; +import org.exist.validation.internal.node.NodeInputStream; +import org.exist.xquery.value.NodeValue; + +import ro.kuberam.libs.java.pdf.metadata.Metadata; + +public class SetContentMetadataFunction extends BasicFunction { + + private final static Logger log = Logger.getLogger(SetContentMetadataFunction.class); + + public final static FunctionSignature signatures[] = { + new FunctionSignature(new QName("set-content-metadata", + ExistExpathPdfModule.NAMESPACE_URI, ExistExpathPdfModule.PREFIX), + "Set the XMP metadata of a PDF contents.", new SequenceType[] { + new FunctionParameterSequenceType("contents", Type.BASE64_BINARY, + Cardinality.ZERO_OR_ONE, "the PDF contents where to set the metadata to."), + new FunctionParameterSequenceType("metadata", Type.NODE, Cardinality.ZERO_OR_ONE, + "A XML document node in XMP format") + }, + new FunctionReturnSequenceType(Type.BASE64_BINARY, Cardinality.ZERO_OR_MORE, + "A new PDF file with the new metadata inserted.") + ), + new FunctionSignature(new QName("set-content-metadata", + ExistExpathPdfModule.NAMESPACE_URI, ExistExpathPdfModule.PREFIX), + "Set the document info metadata of a PDF contents.", new SequenceType[] { + new FunctionParameterSequenceType("contents", Type.BASE64_BINARY, + Cardinality.ZERO_OR_ONE, "the PDF contents where to set the metadata to."), + new FunctionParameterSequenceType("properties", Type.STRING, Cardinality.ZERO_OR_MORE, + "The property to update"), + new FunctionParameterSequenceType("values", Type.STRING, Cardinality.ZERO_OR_MORE, + "The new value") + }, + new FunctionReturnSequenceType(Type.BASE64_BINARY, Cardinality.ZERO_OR_MORE, + "A new PDF file with the new metadata inserted.") + ) + }; + + public SetContentMetadataFunction(XQueryContext context, FunctionSignature signature) { + super(context, signature); + } + + @Override + public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException { + byte[] binary = (byte[]) ((BinaryValue) args[0].itemAt(0)).toJavaObject(byte[].class); + + Sequence result = new ValueSequence(); + + ByteArrayOutputStream resultAsStreamResult = new ByteArrayOutputStream(); + BinaryValue data = null; + + try { + data = BinaryValueFromInputStream.getInstance(context, new Base64BinaryValueType(), + new ByteArrayInputStream(binary)); + } catch (Exception ex) { + throw new XPathException(ex.getMessage()); + } + + if(args.length == 2) { + Serializer serializer = context.getBroker().getSerializer(); + NodeValue inputNode = (NodeValue) args[1].itemAt(0); + InputStream inputNodeStream = new NodeInputStream(serializer, inputNode); + try { + resultAsStreamResult = Metadata.setDocumentXMP(data.getInputStream(), inputNodeStream); + } catch (Exception ex) { + throw new XPathException(ex.getMessage()); + } + } else if(args.length == 3) { + ArrayList properties = new ArrayList(); + ArrayList values = new ArrayList(); + for(int i = 0; i < args[1].getItemCount(); i++) { + properties.add(args[1].itemAt(i).toString()); + } + for(int i = 0; i < args[2].getItemCount(); i++) { + values.add(args[2].itemAt(i).toString()); + } + try { + resultAsStreamResult = Metadata.setDocumentInfo(data.getInputStream(), properties, values); + } catch (Exception ex) { + throw new XPathException(ex.getMessage()); + } + } + + result.add(BinaryValueFromInputStream.getInstance(context, new Base64BinaryValueType(), + new ByteArrayInputStream(resultAsStreamResult.toByteArray()))); + + return result; + } +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index 73cc0b1..ef43e01 100644 --- a/pom.xml +++ b/pom.xml @@ -55,11 +55,10 @@ provided - com.trifork - clj_ds - 0.0.1 - provided - + com.github.krukow + clj-ds + 0.0.4 +