org.exist.replication.shared.MessageHelper.java Source code

Java tutorial

Introduction

Here is the source code for org.exist.replication.shared.MessageHelper.java

Source

/*
 *  eXist Open Source Native XML Database
 *  Copyright (C) 2012 The eXist Project
 *  http://exist-db.org
 *
 *  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.exist.replication.shared;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Map;
import java.util.Properties;
import java.util.zip.GZIPOutputStream;
import javax.xml.transform.OutputKeys;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.log4j.Logger;
import org.exist.dom.BinaryDocument;
import org.exist.dom.DocumentImpl;
import org.exist.dom.DocumentMetadata;
import org.exist.security.Permission;
import org.exist.storage.DBBroker;
import org.exist.storage.serializers.EXistOutputKeys;
import org.exist.storage.serializers.Serializer;
import org.xml.sax.SAXException;

/**
 *  Helper class for retrieving (meta)data from an in eXist stored document.
 * 
 * @author Dannes Wessels
 */
public class MessageHelper {

    public static final String EXIST_RESOURCE_CONTENTLENGTH = "exist.resource.contentlength";
    public static final String EXIST_RESOURCE_DOCUMENTID = "exist.resource.documentid";
    public static final String EXIST_RESOURCE_GROUP = "exist.resource.group";
    public static final String EXIST_RESOURCE_MIMETYPE = "exist.resource.mimetype";
    public static final String EXIST_RESOURCE_OWNER = "exist.resource.owner";
    public static final String EXIST_RESOURCE_TYPE = "exist.resource.type";
    public static final String EXIST_RESOURCE_MODE = "exist.resource.permission.mode";
    public static final String EXIST_MESSAGE_CONTENTENCODING = "exist.message.content-encoding";

    private final static Logger LOG = Logger.getLogger(MessageHelper.class);

    //   Copied from webdav interface ; there is a better one
    public final static Properties OUTPUT_PROPERTIES = new Properties();

    static {
        OUTPUT_PROPERTIES.setProperty(OutputKeys.INDENT, "yes");
        OUTPUT_PROPERTIES.setProperty(OutputKeys.ENCODING, "UTF-8");
        OUTPUT_PROPERTIES.setProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
        OUTPUT_PROPERTIES.setProperty(EXistOutputKeys.EXPAND_XINCLUDES, "no");
        OUTPUT_PROPERTIES.setProperty(EXistOutputKeys.PROCESS_XSL_PI, "no");
    }

    /**
     *  Serialize document to byte array as gzipped document.
     * 
     * @param broker
     * @param document
     * @return
     * @throws IOException 
     */
    public static byte[] gzipSerialize(DBBroker broker, DocumentImpl document) throws IOException {

        // This is the weak spot, the data is serialized into
        // a byte array. Better to have an overloap to a file,
        byte[] payload;

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        GZIPOutputStream gos = new GZIPOutputStream(baos);

        if (document.getResourceType() == DocumentImpl.XML_FILE) {

            // Stream XML document
            Serializer serializer = broker.getSerializer();
            serializer.reset();
            try {
                serializer.setProperties(OUTPUT_PROPERTIES);

                Writer w = new OutputStreamWriter(gos, "UTF-8");
                serializer.serialize(document, w);
                w.flush();
                w.close();

                payload = baos.toByteArray();

            } catch (SAXException e) {
                payload = new byte[0];
                LOG.error(e);
                throw new IOException("Error while serializing XML document: " + e.getMessage(), e);

            } catch (Throwable e) {
                payload = new byte[0];
                System.gc(); // recover from out of memory exception
                LOG.error(e);
                throw new IOException("Error while serializing XML document: " + e.getMessage(), e);
            }

        } else {
            // Stream NON-XML document

            try {
                broker.readBinaryResource((BinaryDocument) document, gos);
                gos.flush();
                gos.close();

                payload = baos.toByteArray();

            } catch (IOException e) {
                payload = new byte[0];
                LOG.error(e);
                throw new IOException("Error while serializing binary document: " + e.getMessage(), e);

            } catch (Throwable e) {
                payload = new byte[0];
                System.gc(); // recover from out of memory exception
                LOG.error(e);
                throw new IOException("Error while serializing binary document: " + e.getMessage(), e);
            }
        }

        return payload;

    }

    public static void retrieveDocMetadata(Map<String, Object> props, DocumentMetadata docMetadata) {
        if (docMetadata == null) {
            LOG.error("no metadata supplied");

        } else {
            props.put(EXIST_RESOURCE_MIMETYPE, docMetadata.getMimeType());
        }
    }

    public static void retrievePermission(Map<String, Object> props, Permission perm) {
        if (perm == null) {
            LOG.error("no permissions supplied");

        } else {
            props.put(EXIST_RESOURCE_OWNER, perm.getOwner().getName());
            props.put(EXIST_RESOURCE_GROUP, perm.getGroup().getName());
            props.put(EXIST_RESOURCE_MODE, perm.getMode());
        }
    }

    public static void retrieveFromDocument(Map<String, Object> props, DocumentImpl document) {
        // We do not differ between DOCUMENT subtypes,
        // mime-type is set in document metadata EXIST_RESOURCE_MIMETYPE. /ljo
        props.put(EXIST_RESOURCE_TYPE, eXistMessage.ResourceType.DOCUMENT);
        props.put(EXIST_RESOURCE_DOCUMENTID, document.getDocId());
        props.put(EXIST_RESOURCE_CONTENTLENGTH, document.getContentLength());

    }
}