Java tutorial
/* * 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; } }