package com.mobilesorcery.sdk.product.intro.actions; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Map; import java.util.Properties; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.IJobChangeEvent; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.runtime.jobs.JobChangeAdapter; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.intro.IIntroManager; import org.eclipse.ui.intro.IIntroPart; import org.eclipse.ui.intro.IIntroSite; import org.eclipse.ui.intro.config.IIntroAction; import org.eclipse.ui.progress.WorkbenchJob; import com.mobilesorcery.sdk.core.MoSyncProject; import com.mobilesorcery.sdk.core.MoSyncTool; import com.mobilesorcery.sdk.core.SectionedPropertiesFile; import com.mobilesorcery.sdk.core.SectionedPropertiesFile.Section; import com.mobilesorcery.sdk.ui.ImportProjectsRunnable; /** * An action that imports examples into the current workspace, and closes the * welcome screen. * * @author Mattias F */ public class ImportExamplesAction implements IIntroAction { /** * Represents a job that imports all examples into the current workspace. * * @author Mattias */ private final class ImportExamplesProjectJob extends WorkbenchJob { private String type; private ImportExamplesProjectJob(String name) { super(name); } @Override public IStatus runInUIThread(IProgressMonitor monitor) { File examplesDir = MoSyncTool.getDefault() .getMoSyncExamplesDirectory().toFile(); File exampleManifestFile = new File(examplesDir, "examples.list"); if (!exampleManifestFile.exists()) { return Status.OK_STATUS; } try { String type = getType(); /* Parse examples list */ Map<String, String> exampleMap = parseExampleManifest(type, exampleManifestFile); /* Do not import examples that we already have in the workspace */ removeExistingExamples(exampleMap); /* * If there are any examples left to import, add them to the * example lists */ ArrayList<File> projectFiles = new ArrayList<File>(); ArrayList<String> preferredProjectNames = new ArrayList<String>(); addExamples(type, exampleMap, projectFiles, preferredProjectNames); /* Create the import job */ File projectFileArray[] = projectFiles.toArray(new File[0]); String preferredProjectNameArray[] = preferredProjectNames .toArray(new String[0]); ImportProjectsRunnable importer = new ImportProjectsRunnable( projectFileArray, preferredProjectNameArray, ImportProjectsRunnable.COPY_ALL_FILES | ImportProjectsRunnable.USE_NEW_PROJECT_IF_AVAILABLE); importer.useNewCopyFilter(); Job job = importer.createJob(true); closeWelcomeWhenDone(job); } catch (Exception e) { return new Status(IStatus.ERROR, "com.mobilesorcery.sdk.product", "Could not import examples", e); } return Status.OK_STATUS; } /** * Parses the example manifest file. * @param type * * @param exampleManifestFile * @return A map from example names to their path. * @throws IOException */ private Map<String, String> parseExampleManifest( String type, File exampleManifestFile) throws IOException { SectionedPropertiesFile exampleManifest = SectionedPropertiesFile .parse(exampleManifestFile); Section exampleSection = exampleManifest .getFirstSection(type); if (exampleSection == null) { throw new IOException("No examples of type: " + type); } return exampleSection.getEntriesAsMap(); } /** * Removes the examples that already exists in the current workspace, * from the list of examples to be imported. * * @param exampleMap * Map of example names to directories. */ private void removeExistingExamples(Map<String, String> exampleMap) { IWorkspaceRoot wsRoot = ResourcesPlugin.getWorkspace().getRoot(); IProject[] alreadyImportedProjects = wsRoot.getProjects(); for (int i = 0; i < alreadyImportedProjects.length; i++) { IProject project = alreadyImportedProjects[i]; exampleMap.remove(project.getName()); } } /** * Adds the examples with full paths to the given lists. * * @param exampleMap * Map of example names to directories. * @param projectFiles * Output list of absolute paths to example projects. * @param preferredProjectNames * Output list of preferred project names. */ private void addExamples(String type, Map<String, String> exampleMap, ArrayList<File> projectFiles, ArrayList<String> preferredProjectNames) { if (exampleMap.isEmpty()) { return; } for (String newExample : exampleMap.keySet()) { String newExampleDir = exampleMap.get(newExample); IPath newExampleFullDir = MoSyncTool.getDefault() .getMoSyncExamplesDirectory().append(type).append(newExampleDir); projectFiles.add(newExampleFullDir.append( MoSyncProject.MOSYNC_PROJECT_META_DATA_FILENAME) .toFile()); preferredProjectNames.add(newExample); } } public void setType(String type) { this.type = type; } public String getType() { return type == null ? "cpp" : type; } } /** * Makes the given job close the welcome screen when it is done. * * @param job * The job that should close the welcome screen upon completion. */ private void closeWelcomeWhenDone(Job job) { /* Close the welcome screen. */ final IIntroManager im = PlatformUI.getWorkbench().getIntroManager(); job.addJobChangeListener(new JobChangeAdapter() { @Override public void done(IJobChangeEvent event) { im.getIntro().getIntroSite().getShell().getDisplay() .asyncExec(new Runnable() { @Override public void run() { IIntroPart part = im.getIntro(); im.closeIntro(part); } }); } }); } /** * @see IIntroAction.run. */ @Override public void run(IIntroSite site, Properties params) { ImportExamplesProjectJob job = new ImportExamplesProjectJob( "Importing example projects"); String type = params.getProperty("type"); job.setType(type); job.setUser(true); job.schedule(); } }