/*
* 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.common.base.Charsets;
import com.google.common.io.CharStreams;
import com.google.dart.tools.core.DartCore;
import com.google.dart.tools.core.generator.Stagehand.StagehandTuple;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* An abstract template class to create sample applications.
*
* @coverage dart.tools.core.generator
*/
public class AbstractSample implements Comparable<AbstractSample> {
private static Stagehand stagehand = new Stagehand();
private static List<AbstractSample> cachedSamples;
/**
* Get all the known samples. This method can be slow.
*
* @return all the known samples
*/
public static List<AbstractSample> getAllSamples() {
if (cachedSamples != null) {
return cachedSamples;
}
boolean doUpgradeCheck = true;
if (!stagehand.isInstalled()) {
doUpgradeCheck = false;
stagehand.install();
}
List<StagehandTuple> samples = null;
try {
samples = stagehand.getAvailableSamples();
} catch (StagehandException e) {
List<AbstractSample> tempResults = new ArrayList<AbstractSample>();
tempResults.add(new CommandLineSample());
tempResults.add(new PackageSample());
tempResults.add(new WebAppSample());
return tempResults;
}
// Make sure we're on a reasonably latest version of Stagehand.
if (doUpgradeCheck) {
new Thread() {
@Override
public void run() {
stagehand.upgrade();
}
}.start();
}
cachedSamples = new ArrayList<AbstractSample>();
// TODO(devoncarew): Remove this when/if a chrome app sample is in stagehand.
cachedSamples.add(new ChromePackagedAppSample());
for (StagehandTuple sample : samples) {
cachedSamples.add(new StagehandSample(
stagehand,
sample.id,
sample.label,
sample.description,
sample.entrypoint));
}
Collections.sort(cachedSamples);
return cachedSamples;
}
private String title;
private String description;
private List<String[]> templates = new ArrayList<String[]>();
protected String mainFile;
public AbstractSample(String title, String description) {
this.title = title;
this.description = description;
}
@Override
public int compareTo(AbstractSample other) {
return getTitle().compareToIgnoreCase(other.getTitle());
}
public IFile generateInto(IContainer container, String sampleName) throws CoreException {
Map<String, String> variables = new HashMap<String, String>();
variables.put("{name}", sampleName);
variables.put("{name.lower}", sampleName.toLowerCase());
variables.put("{name.title}", toTitleCase(sampleName));
for (String[] template : templates) {
String path = substitute(template[0], variables);
String contents = substitute(template[1], variables);
try {
if (contents.startsWith("@") && !contents.endsWith(".png")) {
contents = substitute(getResourceAsString(contents.substring(1)), variables);
}
} catch (IOException e) {
throw new CoreException(new Status(IStatus.ERROR, DartCore.PLUGIN_ID, e.toString(), e));
}
if (path.startsWith(".settings")) {
createFile(container.getProject(), path, contents);
} else {
createFile(container, path, contents);
}
}
if (mainFile != null) {
IResource resource = container.findMember(substitute(mainFile, variables));
if (resource instanceof IFile) {
return (IFile) resource;
} else {
return null;
}
} else {
return null;
}
}
public String getDescription() {
return description;
}
public String getTitle() {
return title;
}
public boolean isValidProjectName(String name) {
return !name.equalsIgnoreCase(getTitle());
}
public boolean shouldBeDefault() {
return false;
}
@Override
public String toString() {
return getTitle();
}
protected void setMainFile(String mainFile) {
this.mainFile = mainFile;
}
protected void setTemplates(List<String[]> templates) {
this.templates = templates;
}
private IFile createFile(IContainer container, String path, String contents) throws CoreException {
IFile file = container.getFile(new Path(path));
if (file.getParent() instanceof IFolder) {
createFolder((IFolder) file.getParent(), false, true, null);
}
InputStream in;
if (contents.startsWith("@")) {
in = getClass().getResourceAsStream(contents.substring(1));
} else {
in = new ByteArrayInputStream(contents.getBytes(Charsets.UTF_8));
}
file.create(in, false, null);
return file;
}
private void createFolder(IFolder folder, boolean force, boolean local, IProgressMonitor monitor)
throws CoreException {
if (!folder.exists()) {
IContainer parent = folder.getParent();
if (parent instanceof IFolder) {
createFolder((IFolder) parent, force, local, null);
}
folder.create(force, local, monitor);
}
}
private String getResourceAsString(String resourceName) throws IOException {
InputStream in = getClass().getResourceAsStream(resourceName);
if (in == null) {
return "";
} else {
Reader reader = new InputStreamReader(in, Charsets.UTF_8);
return CharStreams.toString(reader);
}
}
private String substitute(String str, Map<String, String> variables) {
for (String var : variables.keySet()) {
int index = str.indexOf(var);
String replacement = variables.get(var);
while (index != -1) {
str = str.substring(0, index) + replacement + str.substring(index + var.length());
index = str.indexOf(var);
}
}
return str;
}
private String toTitleCase(String str) {
if (str.length() < 2) {
return str.toUpperCase();
} else {
return str.substring(0, 1).toUpperCase() + str.substring(1).replaceAll("_", " ");
}
}
}