org.pentaho.platform.repository2.unified.jcr.JcrRepositoryDumpToFile.java Source code

Java tutorial

Introduction

Here is the source code for org.pentaho.platform.repository2.unified.jcr.JcrRepositoryDumpToFile.java

Source

/*
 * This program is free software; you can redistribute it and/or modify it under the
 * terms of the GNU General Public License, version 2 as published by the Free Software
 * Foundation.
 *
 * You should have received a copy of the GNU General Public License along with this
 * program; if not, you can obtain a copy at http://www.gnu.org/licenses/gpl-2.0.html
 * or from the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * 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 General Public License for more details.
 *
 *
 * Copyright 2006 - 2013 Pentaho Corporation.  All rights reserved.
 */

package org.pentaho.platform.repository2.unified.jcr;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.platform.api.engine.IPentahoSession;
import org.pentaho.platform.engine.core.system.PentahoSessionHolder;
import org.pentaho.platform.engine.core.system.StandaloneSession;
import org.springframework.extensions.jcr.JcrCallback;
import org.springframework.extensions.jcr.JcrTemplate;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Value;
import javax.jcr.ValueFormatException;
import javax.jcr.util.TraversingItemVisitor;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * Creates an export of the JCR in various formats.
 * 
 * <p>
 * To use:
 * </p>
 * <ol>
 * <li>Add the following to the end of {@code systemListeners.xml}:
 * 
 * <pre>
 * &lt;bean id="dumpToFilePentahoSystemListener" 
 *   class="org.pentaho.platform.repository2.unified.jcr.DumpToFilePentahoSystemListener" /&gt;
 * </pre>
 * 
 * </li>
 * <li>Add one of the following system properties on the command line:
 * 
 * <pre>
 * -Dpentaho.repository.dumpToFile=/tmp/repodump
 * </pre>
 * 
 * or
 * 
 * <pre>
 * -Dpentaho.repository.dumpToFile.systemView=/tmp/repodump
 * </pre>
 * 
 * or
 * 
 * <pre>
 * -Dpentaho.repository.dumpToFile.documentView=/tmp/repodump
 * </pre>
 * 
 * </li>
 * </ol>
 * 
 * <p>
 * Uses PentahoSystem instead of Spring injection since its collaborators are not yet instantiated when this class
 * is instantiated.
 * </p>
 * 
 * @author mlowery
 */
public class JcrRepositoryDumpToFile {

    // ~ Static fields/initializers
    // ======================================================================================

    private static final Log logger = LogFactory.getLog(JcrRepositoryDumpToFile.class);

    /**
     * Exports the repository using a custom TraversingItemVisitor. (It is human-readable output that is not meant to
     * be parsed.)
     */
    public static final String PROP_DUMP_TO_FILE = "pentaho.repository.dumpToFile"; //$NON-NLS-1$

    /**
     * Exports the repository using System View.
     */
    public static final String PROP_DUMP_TO_FILE_SYSTEM_VIEW = "pentaho.repository.dumpToFile.systemView"; //$NON-NLS-1$

    /**
     * Exports the repository using Document View.
     */
    public static final String PROP_DUMP_TO_FILE_DOCUMENT_VIEW = "pentaho.repository.dumpToFile.documentView"; //$NON-NLS-1$

    public enum Mode {
        CUSTOM, SYS, DOC
    };

    JcrTemplate jcrTemplate;
    TransactionTemplate txnTemplate;
    String repositoryAdminUsername;
    String filename;
    Mode mode;

    // ~ Instance fields
    // =================================================================================================

    // ~ Constructors
    // ====================================================================================================

    // ~ Methods
    // =========================================================================================================

    public JcrRepositoryDumpToFile(final JcrTemplate jcrTemplate, TransactionTemplate txnTemplate,
            String repositoryAdminUsername, String filename, Mode mode) {
        this.jcrTemplate = jcrTemplate;
        this.txnTemplate = txnTemplate;
        this.repositoryAdminUsername = repositoryAdminUsername;
        this.filename = filename;
        this.mode = mode;
    }

    public void execute() {
        if (filename != null) {
            final String ZIP_EXTENSION = ".zip"; //$NON-NLS-1$
            // let the user know this is a zip
            if (!filename.endsWith(ZIP_EXTENSION)) {
                filename = filename + ZIP_EXTENSION;
            }
            logger.debug(String.format("dumping repository to file \"%s\"", filename)); //$NON-NLS-1$
            ZipOutputStream tmpOut = null;
            try {
                tmpOut = new ZipOutputStream(
                        new BufferedOutputStream(FileUtils.openOutputStream(new File(filename))));
            } catch (IOException e) {
                IOUtils.closeQuietly(tmpOut);
                throw new RuntimeException(e);
            }
            final ZipOutputStream out = tmpOut;
            // stash existing session
            IPentahoSession origPentahoSession = PentahoSessionHolder.getSession();
            // run as repo super user
            PentahoSessionHolder.setSession(createRepositoryAdminPentahoSession(repositoryAdminUsername));
            try {
                txnTemplate.execute(new TransactionCallbackWithoutResult() {
                    public void doInTransactionWithoutResult(final TransactionStatus status) {
                        jcrTemplate.execute(new JcrCallback() {
                            public Object doInJcr(final Session session) throws RepositoryException, IOException {
                                switch (mode) {
                                case SYS: {
                                    final boolean SKIP_BINARY = false;
                                    final boolean NO_RECURSE = false;
                                    out.putNextEntry(new ZipEntry("repository.xml")); //$NON-NLS-1$
                                    session.exportSystemView("/", out, SKIP_BINARY, NO_RECURSE); //$NON-NLS-1$
                                    return null;
                                }
                                case DOC: {
                                    final boolean SKIP_BINARY = false;
                                    final boolean NO_RECURSE = false;
                                    out.putNextEntry(new ZipEntry("repository.xml")); //$NON-NLS-1$
                                    session.exportDocumentView("/", out, SKIP_BINARY, NO_RECURSE); //$NON-NLS-1$
                                    return null;
                                }
                                default: {
                                    out.putNextEntry(new ZipEntry("repository.txt")); //$NON-NLS-1$
                                    session.getRootNode().accept(new DumpToFileTraversingItemVisitor(out));
                                    return null;
                                }
                                }
                            }
                        });
                    }
                });
            } finally {
                // restore original session
                PentahoSessionHolder.setSession(origPentahoSession);
                IOUtils.closeQuietly(out);
            }
            logger.debug(String.format("dumped repository to file \"%s\"", filename)); //$NON-NLS-1$
        }
    }

    protected IPentahoSession createRepositoryAdminPentahoSession(final String repositoryAdminUsername) {
        StandaloneSession pentahoSession = new StandaloneSession(repositoryAdminUsername);
        pentahoSession.setAuthenticated(repositoryAdminUsername);
        return pentahoSession;
    }

    public static class DumpToFileTraversingItemVisitor extends TraversingItemVisitor {

        private OutputStream out;

        public DumpToFileTraversingItemVisitor(final OutputStream out) {
            this.out = out;
        }

        private static final String INDENT = "  "; //$NON-NLS-1$

        private static final String ENCODING = "UTF-8"; //$NON-NLS-1$

        private static final String NL = System.getProperty("line.separator"); //$NON-NLS-1$

        @Override
        protected void entering(final Property property, final int level) throws RepositoryException {
            StringBuilder buf = new StringBuilder();
            for (int i = 0; i < level; i++) {
                buf.append(INDENT);
            }
            propertyToString(property, buf);
            try {
                IOUtils.write(buf, out, ENCODING);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        protected void propertyToString(final Property property, final StringBuilder buf)
                throws RepositoryException {
            buf.append("@"); //$NON-NLS-1$
            buf.append(property.getName());
            buf.append("="); //$NON-NLS-1$
            try {
                Value value = property.getValue();
                valueToString(value, buf);
            } catch (ValueFormatException e) {
                // multi-valued
                Value[] values = property.getValues();
                buf.append("["); //$NON-NLS-1$
                for (int i = 0; i < values.length; i++) {
                    if (i > 0) {
                        buf.append(","); //$NON-NLS-1$
                    }
                    valueToString(values[i], buf);
                }
                buf.append("]"); //$NON-NLS-1$
            }
            buf.append(NL);
        }

        protected void valueToString(final Value value, final StringBuilder buf) throws RepositoryException {
            buf.append(value.getString());
            buf.append(" ("); //$NON-NLS-1$
            buf.append(PropertyType.nameFromValue(value.getType()));
            buf.append(")"); //$NON-NLS-1$
        }

        @Override
        protected void entering(final Node node, final int level) throws RepositoryException {
            StringBuilder buf = new StringBuilder();
            for (int i = 0; i < level; i++) {
                buf.append(INDENT);
            }
            nodeToString(node, buf);
            try {
                IOUtils.write(buf, out, ENCODING);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        protected void nodeToString(final Node node, final StringBuilder buf) throws RepositoryException {
            buf.append(node.getName());
            buf.append("/"); //$NON-NLS-1$
            buf.append(NL);
        }

        @Override
        protected void leaving(final Property property, final int level) throws RepositoryException {

        }

        @Override
        protected void leaving(final Node node, final int level) throws RepositoryException {

        }

    }

}