com.nokia.carbide.templatewizard.processes.CopyFiles.java Source code

Java tutorial

Introduction

Here is the source code for com.nokia.carbide.templatewizard.processes.CopyFiles.java

Source

/*
* Copyright (c) 2006, 2008 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description: 
*
*/

package com.nokia.carbide.templatewizard.processes;

import com.nokia.carbide.template.engine.ITemplate;
import com.nokia.carbide.templatewizard.Messages;
import com.nokia.carbide.templatewizard.TemplateWizardPlugin;
import com.nokia.carbide.templatewizard.process.AbstractProjectProcess;
import com.nokia.carbide.templatewizard.process.IParameter;
import com.nokia.cpp.internal.api.utils.core.*;
import com.nokia.cpp.internal.api.utils.ui.FilesListDialog;
import com.nokia.cpp.internal.api.utils.ui.WorkbenchUtils;

import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.MessageFormat;
import java.util.*;

/**
 * Process used in templates to files in a project.<p>
 * See the documentation for Creating Wizard Templates.
 */
public class CopyFiles extends AbstractProjectProcess {

    protected static final String UPPER_SUFFIX = "$upper"; //$NON-NLS-1$
    protected static final String LOWER_SUFFIX = "$lower"; //$NON-NLS-1$
    protected static final String TITLE_SUFFIX = "$title"; //$NON-NLS-1$
    protected static final String TITLELOWER_SUFFIX = "$titlelower"; //$NON-NLS-1$
    /**
     * @since 2.1
     */
    protected static final String C_ESCAPED_SUFFIX = "$c_escaped"; //$NON-NLS-1$
    protected static final String SOURCE_PATH_ATTRIBUTE = "sourcePath"; //$NON-NLS-1$
    protected static final String TARGET_PATH_ATTRIBUTE = "targetPath"; //$NON-NLS-1$
    protected static final String SUBSTITUTE_ATTRIBUTE = "substitute"; //$NON-NLS-1$
    protected static final String OVERWRITE_ATTRIBUTE = "overwrite"; //$NON-NLS-1$

    protected static final String FILE_PARAMETER = "file"; //$NON-NLS-1$

    private static final String NO_PROJECT_ERROR = Messages.getString("CopyFiles.NoProjectError"); //$NON-NLS-1$
    private static final String COPY_FILE_ERROR = Messages.getString("CopyFiles.CopyFileError"); //$NON-NLS-1$

    protected IProject project;
    protected URL baseSourceUrl;
    protected Map templateValues;

    private static interface IConvert {
        String convert(String value);
    }

    private static class SuffixOperator {
        private final String suffix;
        private final IConvert convert;

        public SuffixOperator(String suffix, IConvert convert) {
            this.suffix = suffix;
            this.convert = convert;
        }

        public IConvert getConvert() {
            return convert;
        }

        public boolean hasSuffix(String s) {
            return s.endsWith(suffix);
        }

        public String getRoot(String s) {
            return s.substring(0, s.length() - suffix.length());
        }
    }

    private static SuffixOperator[] suffixOperators = { new SuffixOperator(UPPER_SUFFIX, new IConvert() {
        public String convert(String value) {
            return value.toUpperCase();
        }
    }), new SuffixOperator(LOWER_SUFFIX, new IConvert() {
        public String convert(String value) {
            return value.toLowerCase();
        }
    }), new SuffixOperator(TITLE_SUFFIX, new IConvert() {
        public String convert(String value) {
            char c = Character.toUpperCase(value.charAt(0));
            return "" + c + value.substring(1); //$NON-NLS-1$
        }
    }), new SuffixOperator(TITLELOWER_SUFFIX, new IConvert() {
        public String convert(String value) {
            return TextUtils.titleCase(value.toLowerCase());
        }
    }), new SuffixOperator(C_ESCAPED_SUFFIX, new IConvert() {
        public String convert(String value) {
            return TextUtils.escape(value, '\"');
        }
    }) };

    private static class FileInfo {
        private URL sourceFileURL;
        private IFile targetFile;
        private boolean substitute;

        public FileInfo(URL sourceFileURL, IFile targetFile, boolean substitute) {
            this.sourceFileURL = sourceFileURL;
            this.targetFile = targetFile;
            this.substitute = substitute;
        }

        public URL getSourceFileURL() {
            return sourceFileURL;
        }

        public IFile getTargetFile() {
            return targetFile;
        }

        public boolean substitute() {
            return substitute;
        }

    }

    @Override
    public void process(ITemplate template, List<IParameter> parameters, IProgressMonitor monitor)
            throws CoreException {
        super.process(template, parameters, monitor);

        // get info about each file
        List<FileInfo> infos = new ArrayList<FileInfo>();
        for (IParameter parameter : parameters) {
            if (parameter.getName().equals(FILE_PARAMETER)) {
                infos.add(getFileInfo(parameter));
            }
        }

        // see if any target files exist
        List<IFile> existingFiles = new ArrayList<IFile>();
        for (FileInfo fileInfo : infos) {
            if (FileUtils.exists(fileInfo.targetFile)) {
                existingFiles.add(fileInfo.targetFile);
            }
        }

        List<FileInfo> fileInfosToCopy = new ArrayList<FileInfo>(infos);
        if (!existingFiles.isEmpty()) {
            handleExistingFiles(infos, existingFiles, fileInfosToCopy);
        }

        for (FileInfo fileInfo : fileInfosToCopy) {
            copyFile(fileInfo.getSourceFileURL(), fileInfo.getTargetFile(), fileInfo.substitute(), monitor);
        }
    }

    private void handleExistingFiles(List<FileInfo> infos, final List<IFile> existingFiles,
            List<FileInfo> fileInfosToCopy) {
        boolean overwrite = true;
        String autoOverwrite = projectParameter.getAttributeValue(OVERWRITE_ATTRIBUTE);
        if (autoOverwrite == null && !WorkbenchUtils.isJUnitRunning()) { // should ask
            final int[] result = { IDialogConstants.CANCEL_ID };
            Display.getDefault().syncExec(new Runnable() {
                public void run() {
                    Shell shell = WorkbenchUtils.getActiveShell();
                    String title = Messages.getString("CopyFiles.FilesExistTitle"); //$NON-NLS-1$
                    String message = Messages.getString("CopyFiles.OverwriteFilesQuestion"); //$NON-NLS-1$
                    FilesListDialog dialog = new FilesListDialog(shell, existingFiles, title, message);
                    dialog.setAltButtonLabels(IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL);
                    result[0] = dialog.open();
                }
            });
            overwrite = result[0] == IDialogConstants.OK_ID;
        } else if (autoOverwrite != null) {
            overwrite = Boolean.parseBoolean(autoOverwrite);
        }

        if (!overwrite) {
            fileInfosToCopy.clear();
            for (FileInfo fileInfo : infos) {
                if (!FileUtils.exists(fileInfo.targetFile))
                    fileInfosToCopy.add(fileInfo);
            }
        }
    }

    @Override
    protected void init(ITemplate template, List<IParameter> parameters) throws CoreException {
        super.init(template, parameters);

        IWorkspace workspace = ResourcesPlugin.getWorkspace();
        IWorkspaceRoot root = workspace.getRoot();
        project = root.getProject(getProjectName());
        String error = MessageFormat.format(NO_PROJECT_ERROR, new Object[] { getProjectName() });
        failIfNull(project, error);
        baseSourceUrl = FileUtils.getParentPathURL(template.getTemplateUrl());
        templateValues = template.getTemplateValues();
    }

    private FileInfo getFileInfo(IParameter parameter) throws CoreException {
        URL sourceFileUrl = getSourceFileUrl(parameter);

        String targetPathStr = getRequiredAttributeFromParameter(parameter, TARGET_PATH_ATTRIBUTE);

        IPath workspacePath = new Path(project.getName()).append(targetPathStr);

        // canonicalize the path in the workspace to ensure the directory names are the same case
        IPath targetPath = FileUtils.getCanonicalWorkspacePath(workspacePath);

        IFile targetFile = project.getWorkspace().getRoot().getFile(targetPath);

        String substituteValue = parameter.getAttributeValue(SUBSTITUTE_ATTRIBUTE);

        // substitute by default
        boolean substitute = substituteValue == null || Boolean.parseBoolean(substituteValue);

        return new FileInfo(sourceFileUrl, targetFile, substitute);
    }

    /**
     * Copy a file from the given source URL to the given workspace file.  This overwrites
     * the target without complaint.
     * @param sourceFileUrl URL for source (file, jar, etc)
     * @param targetFile target file, need not exist
     * @param substitute if true, apply variable substitution to contents
     * @param monitor progress monitor 
     * @throws CoreException if file copying fails
     */
    protected void copyFile(URL sourceFileUrl, IFile targetFile, boolean substitute, IProgressMonitor monitor)
            throws CoreException {
        if (!substitute) {
            try {
                File toFile = targetFile.getLocation().toFile();
                toFile.createNewFile();
                InputStream is = sourceFileUrl.openStream();
                FileUtils.copyFile(is, toFile);
                IFile ifile = FileUtils.convertFileToIFile(toFile);
                if (ifile != null)
                    ifile.refreshLocal(IResource.DEPTH_ZERO, monitor);
            } catch (IOException e) {
                String error = MessageFormat.format(COPY_FILE_ERROR,
                        new Object[] { getProcessName(), e.getLocalizedMessage() });
                fail(error, e);
            }
        } else {
            String input = getSourceAsString(sourceFileUrl);
            VariableSubstitutionEngine substitutionEngine = new VariableSubstitutionEngine(null, null);
            substitutionEngine.setVariableToken('(');
            String output = substitutionEngine.substitute(new IVariableLookupCallback() {
                Map<String, String> cache = new HashMap<String, String>();

                public Object getValue(String var) {
                    if (cache.containsKey(var))
                        return cache.get(var);
                    String key = var;
                    SuffixOperator operator = null;
                    for (int i = 0; i < suffixOperators.length; i++) {
                        SuffixOperator temp = suffixOperators[i];
                        if (temp.hasSuffix(var)) {
                            key = temp.getRoot(var);
                            operator = temp;
                            break;
                        }
                    }
                    String value = (String) templateValues.get(key);
                    if (operator != null)
                        value = operator.getConvert().convert(value);
                    cache.put(var, value);
                    return value;
                }
            }, input);
            output = postProcessContent(output);
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(output.getBytes());
            // allow overwriting when used in subclasses
            if (targetFile.exists())
                targetFile.setContents(byteArrayInputStream, true, true, monitor);
            else
                targetFile.create(byteArrayInputStream, true, monitor);
        }
    }

    /**
     * @param input the content of the file after all replacements made
     * @return the input after any post-processing
     */
    public String postProcessContent(String input) {
        // may be overridden
        return input;
    }

    private String getSourceAsString(URL sourceFileUrl) throws CoreException {
        String string = null;
        try {
            InputStream is = sourceFileUrl.openStream();
            string = new String(FileUtils.readInputStreamContents(is, null));
        } catch (IOException e) {
            String error = MessageFormat.format(COPY_FILE_ERROR,
                    new Object[] { getProcessName(), e.getLocalizedMessage() });
            fail(error, e);
        }
        return string;
    }

    private URL getSourceFileUrl(IParameter parameter) throws CoreException {
        String sourcePathStr = getRequiredAttributeFromParameter(parameter, SOURCE_PATH_ATTRIBUTE);
        try {
            return new URL(baseSourceUrl, sourcePathStr);
        } catch (MalformedURLException e) {
            throw new CoreException(Logging.newStatus(TemplateWizardPlugin.getDefault(), e));
        }
    }

    protected Plugin getPlugin() {
        return TemplateWizardPlugin.getDefault();
    }
}