blob: 580bcfa40219cb624995dceae1ae74bd7ce2be30 [file] [log] [blame]
/**
* Copyright (c) 2008 Borland Software Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Alexander Shatalin (Borland) - initial API and implementation
*/
package org.eclipse.gmf.internal.xpand.migration.ui;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.gmf.internal.xpand.ResourceManager;
import org.eclipse.gmf.internal.xpand.RootManager;
import org.eclipse.gmf.internal.xpand.migration.MigrationException;
import org.eclipse.gmf.internal.xpand.migration.XpandMigrationFacade;
import org.eclipse.gmf.internal.xpand.migration.XtendMigrationFacade;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
public class MigrationVisitor extends AbstractMigrationVisitor {
static final String CHARSET = "UTF8";
private int rootPathSegmentCount;
private IFolder dstFolder;
private IFolder dstNativeExtFolder;
private RootManager rootManager;
private IJavaProject javaProject;
private IProject project;
private List<CharSequence> nativeLibraryDeclarations = new ArrayList<CharSequence>();
private BuildPropertiesManager buildPropertiesManager;
public MigrationVisitor(IContainer rootContainer, IFolder templatesOutputFolder, RootManager rootManager, IProgressMonitor progressMonitor) {
this(rootContainer, templatesOutputFolder, null, null, rootManager, null, progressMonitor);
}
public MigrationVisitor(IContainer rootContainer, IFolder templatesOutputFolder, IFolder nativeExtensionsRoot, IProject project, RootManager rootManager, BuildPropertiesManager buildPropertiesManager, IProgressMonitor progressMonitor) {
super(progressMonitor);
rootPathSegmentCount = rootContainer.getProjectRelativePath().segmentCount();
dstFolder = templatesOutputFolder;
dstNativeExtFolder = nativeExtensionsRoot;
this.rootManager = rootManager;
this.project = project;
this.buildPropertiesManager = buildPropertiesManager;
}
public List<CharSequence> getNativeLibraryDeclarations() {
return nativeLibraryDeclarations;
}
@Override
protected void visitContainer(IContainer resource) throws CoreException {
IPath relativePath = getRelativePath(resource);
IFolder folder = dstFolder.getFolder(relativePath);
folder.create(true, true, createSubProgressMonitor("Migrating " + resource.getProjectRelativePath().toString()));
if (relativePath.isEmpty()) {
folder.setDefaultCharset(CHARSET, null);
}
}
@Override
protected void visitOtherResource(IFile resource) throws CoreException {
resource.copy(dstFolder.getFullPath().append(getRelativePath(resource)), true, createSubProgressMonitor("Copying " + resource.getProjectRelativePath().toString()));
}
@Override
protected void visitXpandResource(IFile resource) throws CoreException {
IProgressMonitor subMonitor = createSubProgressMonitor("Migrating " + resource.getProjectRelativePath().toString());
dstFolder.getFile(getRelativePath(resource)).create(migrateXpandResource(resource), true, subMonitor);
}
private InputStream migrateXpandResource(IFile srcFile) throws CoreException {
String templateFullName = rootManager.getTemplateFullName(srcFile);
ResourceManager resourceManager = rootManager.getResourceManager(srcFile);
XpandMigrationFacade migrationFacade = new XpandMigrationFacade(resourceManager, templateFullName);
try {
String updatedResourceContent = migrationFacade.migrateXpandResource();
return new ByteArrayInputStream(updatedResourceContent.getBytes(CHARSET));
} catch (MigrationException ex) {
throw createCoreException(new XpandResourceMigrationException(ex, srcFile));
} catch (UnsupportedEncodingException ex) {
throw createCoreException(ex);
}
}
@Override
protected void visitXtendResource(IFile resource) throws CoreException {
try {
String templateFullName = rootManager.getTemplateFullName(resource);
ResourceManager resourceManager = rootManager.getResourceManager(resource);
XtendMigrationFacade migrationFacade = new XtendMigrationFacade(resourceManager, templateFullName);
IProgressMonitor subMonitor = createSubProgressMonitor("Migrating xtend extensions from " + resource.getProjectRelativePath().toString());
dstFolder.getFile(getRelativePath(resource).removeFileExtension().addFileExtension(MigrateXtendResource.QVTO_EXTENSION)).create(
new ByteArrayInputStream(migrationFacade.migrateXtendResource().toString().getBytes(CHARSET)), true, subMonitor);
subMonitor = createSubProgressMonitor("Migrating native extensions from " + resource.getProjectRelativePath().toString());
StringBuilder nativeLibraryClassBody = migrationFacade.getNativeLibraryClassBody();
if (nativeLibraryClassBody != null) {
nativeLibraryDeclarations.add(migrationFacade.getNativeLibraryXmlDeclaration());
createNativeLibraryClass(migrationFacade.getNativeLibraryPackageName(), migrationFacade.getNativeLibraryClassName(), nativeLibraryClassBody, subMonitor);
} else {
subMonitor.done();
}
} catch (UnsupportedEncodingException e) {
throw createCoreException(e);
} catch (MigrationException e) {
throw createCoreException(new XpandResourceMigrationException(e, resource));
}
}
private void createNativeLibraryClass(String nativeLibraryPackageName, String nativeLibraryClassName, StringBuilder nativeLibraryClassBody, IProgressMonitor subMonitor) throws CoreException,
UnsupportedEncodingException {
IFolder pkg = getNativeExtSourcesFolder().getFolder(new Path(nativeLibraryPackageName.replaceAll("\\.", "/")));
createFolder(pkg);
IFile javaClassFile = pkg.getFile(nativeLibraryClassName + ".java");
javaClassFile.create(new ByteArrayInputStream(nativeLibraryClassBody.toString().getBytes(pkg.getDefaultCharset())), true, subMonitor);
}
private void createFolder(IFolder folder) throws CoreException {
if (!folder.exists()) {
IContainer parent = folder.getParent();
if (parent instanceof IFolder) {
createFolder((IFolder) parent);
}
folder.create(true, true, null);
}
}
private IPath getRelativePath(IResource resource) {
return resource.getProjectRelativePath().removeFirstSegments(rootPathSegmentCount);
}
private IProgressMonitor createSubProgressMonitor(String taskName) {
SubProgressMonitor spm = new SubProgressMonitor(getProgressMonitor(), 1);
spm.setTaskName(taskName);
return spm;
}
private IFolder getNativeExtSourcesFolder() throws CoreException {
assert dstNativeExtFolder != null;
if (!dstNativeExtFolder.exists()) {
dstNativeExtFolder.create(true, true, createSubProgressMonitor("Creating folder: " + dstNativeExtFolder.getName()));
IClasspathEntry[] rawClasspath = getJavaProject().getRawClasspath();
IClasspathEntry[] newRawClasspath = new IClasspathEntry[rawClasspath.length + 1];
System.arraycopy(rawClasspath, 0, newRawClasspath, 0, rawClasspath.length);
newRawClasspath[rawClasspath.length] = JavaCore.newSourceEntry(dstNativeExtFolder.getFullPath());
getJavaProject().setRawClasspath(newRawClasspath, createSubProgressMonitor("Setting classpath"));
assert buildPropertiesManager != null;
buildPropertiesManager.addSourceFolder(dstNativeExtFolder);
}
return dstNativeExtFolder;
}
private IJavaProject getJavaProject() throws CoreException {
if (javaProject == null) {
IProjectDescription descr = project.getDescription();
IClasspathEntry[] rawClasspath = null;
if (!descr.hasNature(JavaCore.NATURE_ID)) {
String[] oldNatures = descr.getNatureIds();
String[] newNatures = new String[oldNatures.length + 1];
System.arraycopy(oldNatures, 0, newNatures, 0, oldNatures.length);
newNatures[oldNatures.length] = JavaCore.NATURE_ID;
descr.setNatureIds(newNatures);
project.setDescription(descr, null);
rawClasspath = new IClasspathEntry[] { JavaCore.newLibraryEntry(JavaCore.getClasspathVariable("JRE_LIB"), null, null) };
}
javaProject = JavaCore.create(project);
if (rawClasspath != null) {
javaProject.setRawClasspath(rawClasspath, null);
}
}
return javaProject;
}
/**
* This method should be called in at end of resource visiting process to
* consume optional progress monitor steps reserved for on-demand native
* extensions source folder creation
*/
public void done() {
if (!dstNativeExtFolder.exists()) {
getProgressMonitor().worked(2);
}
}
}