/* * Copyright (c) 2012, the Dart project authors. * * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.eclipse.org/legal/epl-v10.html * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package com.google.dart.tools.core.generator; import com.google.dart.tools.core.DartCore; import com.google.dart.tools.core.internal.util.Extensions; import com.google.dart.tools.core.internal.util.ResourceUtil; import com.google.dart.tools.core.internal.util.StatusUtil; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubMonitor; import java.io.File; import java.text.MessageFormat; import java.util.HashMap; /** * Instances of <code>ApplicationGenerator</code> are used to create a new Application in an after * validating the name and location. * * @coverage dart.tools.core.generator */ public class ApplicationGenerator extends AbstractGenerator { public static final String CSS_FILENAME_EXTENSION = ".css"; //$NON-NLS-1$ public static final String HTML_FILENAME_EXTENSION = ".html"; //$NON-NLS-1$ public static final String WEB_SOURCE_DIRECTORY_NAME = "web"; //$NON-NLS-1$ public static final String CMD_LINE_SOURCE_DIRECTORY_NAME = "bin"; //$NON-NLS-1$ public static final String DESCRIPTION = GeneratorMessages.ApplicationGenerator_description; private String applicationName; private String applicationLocation; private boolean isWebApplication; private boolean hasPubSupport; private IFile iApplicationFile = null; private IProject project; /** * Construct a new instance. */ public ApplicationGenerator(IProject project) { this.project = project; } /** * Create the folder to contain the library and the library declaration file * * @param monitor the monitor to which activity is reported */ @Override public void execute(IProgressMonitor monitor) throws CoreException { // Sanity Check Assert.isNotNull(applicationName); Assert.isNotNull(applicationLocation); IStatus status = validate(); if (status.getSeverity() == IStatus.ERROR) { throw new IllegalStateException(status.getMessage()); } String applicationFileName = appendIfNoExtension(applicationName, Extensions.DOT_DART); File applicationFile; if (isWebApplication) { applicationFile = generateWebApplication(monitor, applicationFileName); } else { applicationFile = generateCommandLineApp(monitor, applicationFileName); } if (hasPubSupport) { generatePubspecFile(monitor, applicationFileName); } // The generator creates resources using java.io.File APIs. project.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor()); iApplicationFile = (IFile) ResourceUtil.getResource(applicationFile); } public File getApplicationFile(String fileName) { // Fail fast for null elements Assert.isNotNull(fileName); if (hasPubSupport) { if (isWebApplication) { return new File(applicationLocation + File.separator + WEB_SOURCE_DIRECTORY_NAME + File.separator + fileName); } else { return new File(applicationLocation + File.separator + CMD_LINE_SOURCE_DIRECTORY_NAME + File.separator + fileName); } } return new File(applicationLocation + File.separator + fileName); } public IFile getFile() { return iApplicationFile; } public String getLibraryFileName() { return applicationName; } /** * Answer the file to be created * * @return the file or <code>null</code> if a file cannot be created */ public File getSystemFile(String fileName) { // Fail fast for null elements Assert.isNotNull(fileName); return new File(applicationLocation + File.separator + fileName); } public boolean isWebApplication() { return isWebApplication; } public void setApplicationLocation(String applicationLocation) { this.applicationLocation = applicationLocation; } public void setApplicationName(String applicationName) { this.applicationName = applicationName; } public void setHasPubSupport(boolean hasPubSupport) { this.hasPubSupport = hasPubSupport; } public void setWebApplication(boolean isWebApplication) { this.isWebApplication = isWebApplication; } /** * Checks that the library location and file name are both valid. * * @see #validateLocation() * @see #validateName() * @return IStatus corresponding to any errors/warnings that would make the lib/app invalid */ @Override public IStatus validate() { IStatus status = StatusUtil.getMoreSevere(Status.OK_STATUS, validateLocation()); status = StatusUtil.getMoreSevere(status, validateName()); return status; } private File generateCommandLineApp(IProgressMonitor monitor, String applicationFileName) throws CoreException { SubMonitor subMonitor = SubMonitor.convert( monitor, GeneratorMessages.ApplicationGenerator_message, 100); String className = applicationFileName.substring(0, applicationFileName.indexOf('.')); final HashMap<String, String> substitutions = new HashMap<String, String>(); substitutions.put("className", className); //$NON-NLS-1$ File applicationFile = getApplicationFile(applicationFileName); execute("generated-dart-server.txt", applicationFile, substitutions, monitor); //$NON-NLS-1$ subMonitor.newChild(100); subMonitor.done(); return applicationFile; } private void generatePubspecFile(IProgressMonitor monitor, String applicationFileName) throws CoreException { SubMonitor subMonitor = SubMonitor.convert( monitor, GeneratorMessages.ApplicationGenerator_message, 100); String className = applicationFileName.substring(0, applicationFileName.indexOf('.')); final HashMap<String, String> substitutions = new HashMap<String, String>(); substitutions.put("className", className); //$NON-NLS-1$ File pubspecFile = getSystemFile(DartCore.PUBSPEC_FILE_NAME); execute("generated-pubspec.txt", pubspecFile, substitutions, monitor); //$NON-NLS-1$ subMonitor.newChild(100); subMonitor.done(); } private File generateWebApplication(IProgressMonitor monitor, String applicationFileName) throws CoreException { SubMonitor subMonitor = SubMonitor.convert( monitor, GeneratorMessages.ApplicationGenerator_message, 100); String className = applicationFileName.substring(0, applicationFileName.indexOf('.')); final HashMap<String, String> substitutions = new HashMap<String, String>(); substitutions.put("className", className); //$NON-NLS-1$ substitutions.put("extends", ""); //$NON-NLS-1$ //$NON-NLS-2$ substitutions.put("implements", ""); //$NON-NLS-1$ //$NON-NLS-2$ File applicationFile = getApplicationFile(applicationFileName); execute("generated-dart-class-main.txt", applicationFile, substitutions, monitor); //$NON-NLS-1$ subMonitor.newChild(100); subMonitor.done(); // html file subMonitor = SubMonitor.convert( monitor, GeneratorMessages.ApplicationGenerator_htmlFileMessage, 100); String htmlFileName = appendIfNoExtension(applicationName, HTML_FILENAME_EXTENSION); File iHtmlFile = getApplicationFile(htmlFileName); substitutions.put("title", toTitleCase(className)); substitutions.put("fileName", className); substitutions.put("dartSrcPath", applicationFileName); execute("generated-html.txt", iHtmlFile, substitutions, monitor); //$NON-NLS-1$ // css file subMonitor = SubMonitor.convert( monitor, GeneratorMessages.ApplicationGenerator_htmlFileMessage, 100); String cssFileName = appendIfNoExtension(applicationName, CSS_FILENAME_EXTENSION); File iCssFile = getApplicationFile(cssFileName); execute("generated-css.txt", iCssFile, null, monitor); //$NON-NLS-1$ subMonitor.newChild(100); subMonitor.done(); return applicationFile; } private String toTitleCase(String str) { if (str.length() < 2) { return str.toUpperCase(); } else { return str.substring(0, 1).toUpperCase() + str.substring(1); } } /** * Validate the application location. * * @return {@link Status#OK_STATUS} if the name is valid, or a status indicating an error or * warning. */ private IStatus validateLocation() { // Validate that: // 1) The file is non-empty // 2) The directory is a valid path if (applicationLocation == null || applicationLocation.isEmpty()) { return new Status(IStatus.ERROR, DartCore.PLUGIN_ID, DESCRIPTION); } Path libraryPath = new Path(applicationLocation); if (!libraryPath.isAbsolute() || !libraryPath.isValidPath(applicationLocation)) { return new Status( IStatus.ERROR, DartCore.PLUGIN_ID, GeneratorMessages.ApplicationGenerator_directoryMessage); } return Status.OK_STATUS; } /** * Validate the application name. * * @return {@link Status#OK_STATUS} if the name is valid, or a status indicating an error or * warning. */ private IStatus validateName() { // Validate that: // 1) The file is non-empty; // 2) The file does not contain any whitespace; // 3) The file does not exist yet. // 4) That the file is a valid Dart identifier. if (applicationName == null || applicationName.isEmpty()) { return new Status(IStatus.ERROR, DartCore.PLUGIN_ID, DESCRIPTION); } else if (containsWhitespace(applicationName)) { return new Status( IStatus.ERROR, DartCore.PLUGIN_ID, GeneratorMessages.ApplicationGenerator_noWhiteSpace); } Path path = new Path(applicationLocation); if (path.append(appendIfNoExtension(applicationName, Extensions.DOT_DART)).toFile().exists()) { return new Status(IStatus.ERROR, DartCore.PLUGIN_ID, MessageFormat.format( GeneratorMessages.ApplicationGenerator_fileExists, new Object[] {applicationName + Extensions.DOT_DART})); } if (path.append(appendIfNoExtension(applicationName, HTML_FILENAME_EXTENSION)).toFile().exists()) { return new Status(IStatus.ERROR, DartCore.PLUGIN_ID, MessageFormat.format( GeneratorMessages.ApplicationGenerator_fileExists, new Object[] {applicationName + HTML_FILENAME_EXTENSION})); } if (path.append(appendIfNoExtension(applicationName, CSS_FILENAME_EXTENSION)).toFile().exists()) { return new Status(IStatus.ERROR, DartCore.PLUGIN_ID, MessageFormat.format( GeneratorMessages.ApplicationGenerator_fileExists, new Object[] {applicationName + CSS_FILENAME_EXTENSION})); } IStatus status = DartIdentifierUtil.validateIdentifier(applicationName); if (status != Status.OK_STATUS) { return status; } return Status.OK_STATUS; } }