| /** |
| * 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); |
| } |
| } |
| |
| } |