com.enonic.cms.upgrade.task.UpgradeModel0204.java Source code

Java tutorial

Introduction

Here is the source code for com.enonic.cms.upgrade.task.UpgradeModel0204.java

Source

/*
 * Copyright 2000-2013 Enonic AS
 * http://www.enonic.com/license
 */

package com.enonic.cms.upgrade.task;

import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.jdbc.core.RowMapper;

import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.io.Files;

import com.enonic.cms.framework.blob.BlobKey;

import com.enonic.cms.upgrade.UpgradeContext;
import com.enonic.cms.upgrade.UpgradeException;

final class UpgradeModel0204 extends AbstractUpgradeTask {

    private static final String GET_CHILDREN_OF_SQL = "select * from tVirtualFile where vf_sParentKey = ?";

    private static final String ROOT_KEY = DigestUtils.shaHex("/".getBytes());

    private File resourceRoot;

    private File blobstoreRoot;

    public UpgradeModel0204() {
        super(204);
    }

    @Override
    public void upgrade(final UpgradeContext context) throws Exception {
        context.logInfo("Moving all resource files from blobstore to resource folder");

        initBlobstore(context);
        initResourceRoot(context);

        VirtualFileItem root = getRootElement(context);

        if (root == null) {
            context.logInfo("No resource root found, no resources to process.");
        } else {
            processFiles(context, root, "");
        }
    }

    private void initResourceRoot(final UpgradeContext context) throws UpgradeException {
        resourceRoot = new File(context.getProperty("cms.resource.path"));

        if (resourceRoot.exists()) {
            context.logWarning("Resource folder " + resourceRoot.getAbsolutePath() + " already exists");
        }

        context.logInfo("Initializing resource root at " + resourceRoot.getAbsolutePath());
        resourceRoot.mkdirs();

        if (!resourceRoot.exists()) {
            throw new UpgradeException("Not able to create resource folder " + resourceRoot.getAbsolutePath());
        }
    }

    private void initBlobstore(final UpgradeContext context) throws UpgradeException {
        blobstoreRoot = new File(context.getProperty("cms.blobstore.dir"));

        if (!blobstoreRoot.exists() || !blobstoreRoot.canRead()) {
            throw new UpgradeException(("Cannot read blobstore " + blobstoreRoot.getAbsolutePath()));
        }
    }

    private void processFiles(final UpgradeContext context, final VirtualFileItem root, final String currentPath)
            throws Exception {
        final List<VirtualFileItem> elementsWithParent = getElementsWithParent(context, root.key);

        for (VirtualFileItem item : elementsWithParent) {
            final String itemPath = createPath(currentPath, item);

            final boolean isFolder = item.length < 0;

            if (isFolder) {
                createFolder(context, itemPath);
                processFiles(context, item, itemPath);
            } else {
                createFile(context, item, itemPath);
            }
        }
    }

    private boolean createFolder(UpgradeContext context, String path) {
        context.logInfo("Create folder: " + path);

        File newFolder = new File(resourceRoot + "/" + path);

        if (newFolder.exists()) {
            return false;
        }

        return newFolder.mkdirs();
    }

    private boolean createFile(UpgradeContext context, VirtualFileItem fileItem, String path) {
        context.logInfo("Copy file: " + path);

        if (Strings.isNullOrEmpty(fileItem.blobkey)) {
            context.logWarning("No blobkey found for file " + fileItem.name);
            return false;
        }

        File blobFile = getBlobFile(new BlobKey(fileItem.blobkey));

        if (!blobFile.exists()) {
            context.logWarning("No blobfile found for file with name " + fileItem.name + ", blobKey = "
                    + fileItem.blobkey + ", blobFile = " + blobFile.getAbsolutePath());
            return false;
        }

        File newFile = new File(resourceRoot + "/" + path);

        try {
            Files.copy(blobFile, newFile);
            return true;
        } catch (IOException e) {
            context.logError(
                    "Not able to copy file " + blobFile.getAbsolutePath() + " to " + newFile.getAbsolutePath(), e);
            return false;
        }
    }

    private File getBlobFile(final BlobKey key) {
        final String id = key.toString();
        File file = blobstoreRoot;
        file = new File(file, id.substring(0, 2));
        file = new File(file, id.substring(2, 4));
        file = new File(file, id.substring(4, 6));
        return new File(file, id);
    }

    private String createPath(final String currentPath, final VirtualFileItem item) {
        return currentPath + "/" + item.name;
    }

    private List<VirtualFileItem> getElementsWithParent(UpgradeContext context, String parentKey) throws Exception {
        List<VirtualFileItem> children = Lists.newArrayList();

        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            conn = context.getConnection();

            ps = conn.prepareStatement(GET_CHILDREN_OF_SQL);
            ps.setString(1, parentKey);
            rs = ps.executeQuery();

            while (rs.next()) {
                children.add(createVirtualFileItem(rs));
            }
        } finally {
            context.close(rs);
            context.close(ps);
            context.close(conn);
        }

        return children;
    }

    private VirtualFileItem getRootElement(UpgradeContext context) throws Exception {
        context.logInfo("Fetching root with key: " + ROOT_KEY);

        final List<VirtualFileItem> rootItems = context.getJdbcTemplate().query(
                "SELECT * FROM tVirtualFile where vf_skey = '" + ROOT_KEY + "'", new VirtualFileItemExtractor());

        return rootItems != null && rootItems.size() == 1 ? rootItems.get(0) : null;
    }

    private static VirtualFileItem createVirtualFileItem(final ResultSet rs) throws SQLException {
        VirtualFileItem item = new VirtualFileItem();

        final String vf_skey = rs.getString("vf_skey");
        item.key = vf_skey;
        item.name = rs.getString("vf_sname");
        item.parentKey = rs.getString("vf_sparentkey");
        item.length = rs.getLong("vf_llength");
        item.blobkey = rs.getString("vf_sblobkey");
        return item;
    }

    private static class VirtualFileItemExtractor implements RowMapper {
        @Override
        public Object mapRow(final ResultSet resultSet, final int i) throws SQLException {
            return createVirtualFileItem(resultSet);
        }
    }

    private static class VirtualFileItem {
        String key;

        String parentKey;

        String name;

        long length;

        String blobkey;
    }
}