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