package org.applause.lang.ui.wizard;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.applause.lang.ui.builder.MobilePlatform;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.emf.ecore.resource.impl.ExtensibleURIConverterImpl;
import org.eclipse.xtext.ui.util.PluginProjectFactory;
import org.eclipse.xtext.ui.util.ProjectFactory;
import org.eclipse.xtext.ui.wizard.AbstractProjectCreator;
import org.eclipse.xtext.util.StringInputStream;
import com.google.common.collect.ImmutableList;
import com.google.inject.Inject;
import com.google.inject.Provider;
public class CustomApplauseProjectCreator extends AbstractProjectCreator {
private static final String MODEL_ROOT = "model";
private static final List<String> ALL_FOLDERS = ImmutableList.of();
@Inject
private Provider<PluginProjectFactory> projectFactoryProvider;
@Inject
private Provider<ProjectFactory> platformProjectFactoryProvider;
@Override
protected ProjectFactory createProjectFactory() {
return projectFactoryProvider.get();
}
protected ProjectFactory createPlatformProjectFactory() {
return platformProjectFactoryProvider.get();
}
@Override
protected String getModelFolderName() {
return MODEL_ROOT;
}
@Override
protected List<String> getAllFolders() {
return ALL_FOLDERS;
}
protected ApplauseDslProjectInfo getApplauseProjectInfo() {
return (ApplauseDslProjectInfo)getProjectInfo();
}
@Override
protected void execute(final IProgressMonitor monitor) throws CoreException, InvocationTargetException,
InterruptedException {
SubMonitor subMonitor = SubMonitor.convert(
monitor,
getCreateModelProjectMessage(),
getApplauseProjectInfo().numberOfPlatforms() + 1);
IProject project = createModelProject(subMonitor.newChild(1));
for(MobilePlatform platform : getApplauseProjectInfo().getSelectedPlatforms()) {
createPlatformProject(platform, subMonitor.newChild(1));
}
IFile modelFile = getModelFile(project);
setResult(modelFile);
}
private IProject createModelProject(SubMonitor monitor) throws CoreException {
ProjectFactory factory = createProjectFactory();
configureProjectFactory(factory);
IProject modelProject = factory.createProject(monitor, null);
createModel(modelProject, monitor);
return modelProject;
}
private void createModel(final IProject project, final SubMonitor monitor) throws CoreException {
InputStream contents = this.getClass().getClassLoader().getResourceAsStream("/templateproject/project.zip");
enhancePlatformProject(project, contents, monitor);
}
protected ProjectFactory configureProjectFactoryForPlatformProject(ProjectFactory factory, MobilePlatform platform) {
factory.setProjectName(getProjectInfo().getProjectName() + platform.getProjectNameSuffix());
factory.addReferencedProjects(getReferencedProjects());
factory.addProjectNatures(getProjectNatures());
factory.addBuilderIds(getBuilders());
return factory;
}
private IProject createPlatformProject(MobilePlatform platform, SubMonitor monitor) {
ProjectFactory factory = createPlatformProjectFactory();
configureProjectFactoryForPlatformProject(factory, platform);
IProject platformProject = factory.createProject(monitor, null);
enhancePlatformProject(platformProject, platform, monitor);
return platformProject;
}
private void enhancePlatformProject(IProject project, MobilePlatform platform, SubMonitor monitor) {
ExtensibleURIConverterImpl uriConverter = new ExtensibleURIConverterImpl();
try {
InputStream stream = uriConverter.createInputStream(platform.getTemplateProjectURI());
enhancePlatformProject(project, stream, monitor);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private void enhancePlatformProject(IProject project, InputStream stream, SubMonitor monitor) {
try {
ZipInputStream zipStream = new ZipInputStream(stream);
ZipEntry entry;
while ((entry = zipStream.getNextEntry()) != null) {
String name = entry.getName();
if(name.contains("__MACOSX/"))
continue;
name = replaceTemplate(name);
if (entry.isDirectory()) {
IFolder folder = project.getFolder(name);
if (!folder.exists()) {
folder.create(true, true, monitor);
}
} else {
IFile file = project.getFile(name);
// PFR: PNGs, GIfs and ZIPs will not be filtered. Poor man's binary detection :-/
if (entry.getName().endsWith(".png") || entry.getName().endsWith(".gif") || entry.getName().endsWith(".jar")) {
File destFile = file.getLocation().toFile();
FileOutputStream output = FileUtils.openOutputStream(destFile);
IOUtils.copy(zipStream, output);
}
else {
String content;
content = replaceTemplate(IOUtils.toString(zipStream, "UTF-8"));
if (file.exists()) {
file.delete(true, monitor);
}
file.create(new StringInputStream(content), true, monitor);
}
}
}
project.refreshLocal(IResource.DEPTH_INFINITE, monitor);
} catch (CoreException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
IOUtils.closeQuietly(stream);
}
}
private String replaceTemplate(String str) {
String projectName = getProjectInfo().getProjectName();
String capitalizedProjectName = projectName.equals("_template_") ? "_Template_" : StringUtils.capitalize(projectName);
str = str.replace("itemisApp", projectName);
str = str.replace("ItemisApp", capitalizedProjectName);
str = str.replace("de.itemis.itemisapp.R", "de.itemis." + projectName.toLowerCase() + ".R");
return str;
}
}