You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xmlgraphics.apache.org by je...@apache.org on 2007/12/23 16:51:17 UTC

svn commit: r606566 - /xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/xmp/XMPPacketParser.java

Author: jeremias
Date: Sun Dec 23 07:51:16 2007
New Revision: 606566

URL: http://svn.apache.org/viewvc?rev=606566&view=rev
Log:
Simple packet parser which can extract the first XMP packet it finds in a file.

Added:
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/xmp/XMPPacketParser.java   (with props)

Added: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/xmp/XMPPacketParser.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/xmp/XMPPacketParser.java?rev=606566&view=auto
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/xmp/XMPPacketParser.java (added)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/xmp/XMPPacketParser.java Sun Dec 23 07:51:16 2007
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.xmlgraphics.xmp;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.commons.io.output.ByteArrayOutputStream;
+
+/**
+ * This class is a parser for XMP packets. By default, it tries to locate the first XMP packet
+ * it finds and parses it.
+ * <p>
+ * Important: Before you use this class to look for an XMP packet in some random file, please read
+ * the chapter on "Scanning Files for XMP Packets" in the XMP specification! 
+ */
+public class XMPPacketParser {
+
+    private static final byte[] PACKET_HEADER;
+    private static final byte[] PACKET_HEADER_END;
+    private static final byte[] PACKET_TRAILER;
+    
+    static {
+        try {
+            PACKET_HEADER = "<?xpacket begin=".getBytes("US-ASCII");
+            PACKET_HEADER_END = "?>".getBytes("US-ASCII");
+            PACKET_TRAILER = "<?xpacket".getBytes("US-ASCII");
+        } catch (UnsupportedEncodingException e) {
+            throw new RuntimeException("Incompatible JVM! US-ASCII encoding not supported.");
+        }
+    }
+    
+    /**
+     * Locates an XMP packet in a stream, parses it and returns the XMP metadata. If no
+     * XMP packet is found until the stream ends, null is returned. Note: This method
+     * only finds the first XMP packet in a stream. And it cannot determine whether it
+     * has found the right XMP packet if there are multiple packets.
+     * @param in the InputStream to search
+     * @return the parsed XMP metadata or null if no XMP packet is found
+     * @throws IOException if an I/O error occurs
+     * @throws TransformerException if an error occurs while parsing the XMP packet
+     */
+    public static Metadata parse(InputStream in) throws IOException, TransformerException {
+        if (!in.markSupported()) {
+            in = new java.io.BufferedInputStream(in);
+        }
+        boolean foundXMP = skipAfter(in, PACKET_HEADER);
+        if (!foundXMP) {
+            return null;
+        }
+        //TODO Inspect "begin" attribute!
+        if (!skipAfter(in, PACKET_HEADER_END)) {
+            throw new IOException("Invalid XMP packet header!");
+        }
+        //TODO think about not buffering this but for example, parse in another thread
+        //ex. using PipedInput/OutputStream
+        ByteArrayOutputStream baout = new ByteArrayOutputStream();
+        //TODO Do with TeeInputStream when Commons IO 1.4 is available
+        if (!skipAfter(in, PACKET_TRAILER, baout)) {
+            throw new IOException("XMP packet not properly terminated!");
+        }
+        
+        Metadata metadata = XMPParser.parseXMP(
+                new StreamSource(new ByteArrayInputStream(baout.toByteArray())));
+        return metadata;
+    }
+    
+    private static boolean skipAfter(InputStream in, byte[] match) throws IOException {
+        return skipAfter(in, match, null);
+    }
+    
+    private static boolean skipAfter(InputStream in, byte[] match, OutputStream out)
+            throws IOException {
+        int found = 0;
+        int len = match.length;
+        int b;
+        while ((b = in.read()) >= 0) {
+            if (b == match[found]) {
+                found++;
+                if (found == len) {
+                    return true;
+                }
+            } else {
+                if (out != null) {
+                    if (found > 0) {
+                        out.write(match, 0, found);
+                    }
+                    out.write(b);
+                }
+                found = 0;
+            }
+        }
+        return false;
+    }
+    
+}

Propchange: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/xmp/XMPPacketParser.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/xmp/XMPPacketParser.java
------------------------------------------------------------------------------
    svn:keywords = Id



---------------------------------------------------------------------
Apache XML Graphics Project URL: http://xmlgraphics.apache.org/
To unsubscribe, e-mail: commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: commits-help@xmlgraphics.apache.org