Created
April 10, 2012 13:49
-
-
Save digulla/2351505 to your computer and use it in GitHub Desktop.
Refactored org.cloudsmith.geppetto.pp.dsl.ui.preferences.AbstractRebuildingPreferencePage
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Copyright (c) 2011 Cloudsmith Inc. and other contributors, as listed below. | |
* 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: | |
* Cloudsmith | |
* Aaron Digulla | |
*/ | |
package com.pany.dsl.ui.preferences; | |
import org.eclipse.core.resources.IProject; | |
import org.eclipse.core.runtime.jobs.Job; | |
import org.eclipse.jface.preference.IPreferenceStore; | |
import org.eclipse.jface.util.IPropertyChangeListener; | |
import org.eclipse.jface.util.PropertyChangeEvent; | |
import org.eclipse.xtext.ui.editor.preferences.AbstractPreferencePage; | |
/** | |
* Adds behavior to the abstract preference page that checks if a single preference id has | |
* changed, and if so, triggers a clean build of the project. | |
* | |
*/ | |
public abstract class AbstractRebuildingPreferencePage extends AbstractPreferencePage { | |
private IPropertyChangeListener rebuildListener; | |
private IPreferenceStore usedPreferenceStore; | |
@Override | |
public void dispose() { | |
if(isPropertyPage()) { | |
if(rebuildListener != null) | |
usedPreferenceStore.removePropertyChangeListener(rebuildListener); | |
} | |
super.dispose(); | |
} | |
/** Return true if the project must be rebuilt when the specified property changes */ | |
protected abstract boolean rebuildForChangeOf( String propertyName ); | |
@Override | |
protected void updateFieldEditors(boolean enabled) { | |
super.updateFieldEditors(enabled); | |
if(isPropertyPage()) { | |
if(rebuildListener == null) { | |
rebuildListener = new IPropertyChangeListener() { | |
@Override | |
public void propertyChange(PropertyChangeEvent event) { | |
if(rebuildForChangeOf(event.getProperty())) { | |
Job job = createBuildJob(); | |
job.schedule(); | |
} | |
} | |
}; | |
} | |
// protect against getting different store instances (happens at least when debugging). | |
IPreferenceStore store = getPreferenceStore(); | |
if(store != usedPreferenceStore) { | |
if(usedPreferenceStore != null) | |
usedPreferenceStore.removePropertyChangeListener(rebuildListener); | |
usedPreferenceStore = store; | |
store.addPropertyChangeListener(rebuildListener); | |
} | |
} | |
} | |
/** Create a job to rebuild the project */ | |
protected abstract Job createBuildJob(); | |
public IProject getProject() { | |
return (IProject) getElement(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Copyright (c) 2011 Cloudsmith Inc. and other contributors, as listed below. | |
* 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: | |
* Cloudsmith | |
* Aaron Digulla | |
*/ | |
package com.pany.dsl.ui.preferences; | |
import java.util.List; | |
import org.eclipse.core.resources.IFile; | |
import org.eclipse.core.resources.IProject; | |
import org.eclipse.core.resources.IWorkspace; | |
import org.eclipse.core.resources.IncrementalProjectBuilder; | |
import org.eclipse.core.resources.ResourcesPlugin; | |
import org.eclipse.core.runtime.CoreException; | |
import org.eclipse.core.runtime.IProgressMonitor; | |
import org.eclipse.core.runtime.IStatus; | |
import org.eclipse.core.runtime.OperationCanceledException; | |
import org.eclipse.core.runtime.Status; | |
import org.eclipse.core.runtime.SubProgressMonitor; | |
import org.eclipse.core.runtime.jobs.Job; | |
import org.eclipse.osgi.util.TextProcessor; | |
import com.pany.dsl.DslException; | |
public class DslBuildJob extends Job { | |
private final IProject project; | |
private DslResourceLocator locator; | |
public DslBuildJob(String name, IProject project, DslResourceLocator locator) { | |
super(name); | |
this.project = project; | |
this.locator = locator; | |
} | |
public boolean isCoveredBy(DslBuildJob other) { | |
if (other.project == null) { | |
return true; | |
} | |
return project != null && project.equals(other.project); | |
} | |
@Override | |
protected IStatus run(IProgressMonitor monitor) { | |
synchronized (getClass()) { | |
if (monitor.isCanceled()) { | |
return Status.CANCEL_STATUS; | |
} | |
cancelExistingJobs(); | |
} | |
try { | |
if (project != null) { | |
buildSingleProject( monitor ); | |
} else { | |
buildAllProjects( monitor ); | |
} | |
} catch (CoreException e) { | |
return e.getStatus(); | |
} catch (OperationCanceledException e) { | |
return Status.CANCEL_STATUS; | |
} finally { | |
monitor.done(); | |
} | |
return Status.OK_STATUS; | |
} | |
private void buildAllProjects( IProgressMonitor monitor ) throws CoreException { | |
monitor.beginTask(Messages.DslBuildJob_Build_All, 2); | |
IWorkspace workspace = ResourcesPlugin.getWorkspace(); | |
touchAllDslResource( workspace, new SubProgressMonitor( monitor, 1 ) ); | |
ResourcesPlugin.getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, | |
new SubProgressMonitor(monitor, 1)); | |
} | |
private void buildSingleProject( IProgressMonitor monitor ) throws CoreException { | |
monitor.beginTask( getName(), 3 ); | |
touchAllDslResources( project, new SubProgressMonitor( monitor, 1 ) ); | |
ResourcesPlugin.getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, | |
new SubProgressMonitor(monitor, 1)); | |
project.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, new SubProgressMonitor(monitor, 1)); | |
} | |
private void cancelExistingJobs() { | |
Job[] buildJobs = Job.getJobManager().find(ResourcesPlugin.FAMILY_MANUAL_BUILD); | |
for (int i = 0; i < buildJobs.length; i++) { | |
if (buildJobs[i] != this && buildJobs[i] instanceof DslBuildJob) { | |
DslBuildJob job = (DslBuildJob) buildJobs[i]; | |
if (job.isCoveredBy(this)) { | |
buildJobs[i].cancel(); | |
} | |
} | |
} | |
} | |
private void touchAllDslResource( IWorkspace workspace, IProgressMonitor monitor ) { | |
IProject[] projects = workspace.getRoot().getProjects(); | |
IProgressMonitor perProjectMonitor = new SubProgressMonitor( monitor, projects.length ); | |
for( IProject project : projects ) { | |
if( ! project.isOpen() ) { | |
continue; | |
} | |
touchAllDslResources( project, new SubProgressMonitor( perProjectMonitor, 1 ) ); | |
} | |
} | |
private void touchAllDslResources( IProject project, IProgressMonitor monitor ) { | |
final List<IFile> files = locator.findDslResources( project ); | |
IFile file = null; | |
try { | |
monitor.beginTask( String.format( | |
Messages.DslBuildJob_Touching_resources, | |
TextProcessor.process(project.getName(), ":.")), //$NON-NLS-1$ | |
files.size()); | |
for( int i=0; i<files.size(); i++ ) { | |
file = files.get( i ); | |
file.touch( new SubProgressMonitor( monitor, 1 ) ); | |
} | |
} catch( CoreException e ) { | |
throw new DslException( "Error touching " + file, e ); //$NON-NLS-1$ | |
} finally { | |
monitor.done(); | |
} | |
} | |
@Override | |
public boolean belongsTo(Object family) { | |
return ResourcesPlugin.FAMILY_MANUAL_BUILD == family; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Copyright (c) 2011 Cloudsmith Inc. and other contributors, as listed below. | |
* 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: | |
* Cloudsmith | |
* Aaron Digulla | |
*/ | |
package com.pany.dsl.ui.preferences; | |
import java.util.List; | |
import org.apache.log4j.Logger; | |
import org.eclipse.core.resources.IContainer; | |
import org.eclipse.core.resources.IFile; | |
import org.eclipse.core.resources.IProject; | |
import org.eclipse.core.resources.IResource; | |
import org.eclipse.core.resources.IResourceVisitor; | |
import org.eclipse.core.runtime.CoreException; | |
import org.eclipse.core.runtime.IPath; | |
import org.eclipse.jdt.core.IJavaProject; | |
import org.eclipse.jdt.core.JavaCore; | |
import org.eclipse.jdt.core.JavaModelException; | |
import com.pany.dsl.DslException; | |
import com.google.common.collect.Lists; | |
public class DslResourceLocator { | |
private static Logger log = Logger.getLogger( DslResourceLocator.class ); | |
public List<IFile> findDslResources( IContainer parent ) { | |
final List<IFile> files = Lists.newArrayList(); | |
if( null == parent ) { | |
return files; | |
} | |
final IPath out = getOutputLocation( parent ); | |
// System.out.println( "out=" + out ); | |
IResourceVisitor visitor = new IResourceVisitor() { | |
@Override | |
public boolean visit( IResource resource ) throws CoreException { | |
if( resource.getType() == IResource.FILE ) { | |
IFile file = (IFile) resource; | |
if( includeFile( file ) ) { | |
files.add( file ); | |
} | |
} else if (resource.getType() == IResource.FOLDER ) { | |
IPath path = resource.getProjectRelativePath(); | |
// System.out.println( "path=" + path ); | |
if( out != null && out.isPrefixOf( path ) ) { | |
return false; | |
} | |
} | |
return true; | |
} | |
}; | |
try { | |
parent.accept( visitor ); | |
} catch( CoreException e ) { | |
throw new DslException( "Error getting list of files from " + parent.getFullPath(), e ); //$NON-NLS-1$ | |
} | |
return files; | |
} | |
protected boolean includeFile( IFile file ) { | |
return file.getName().endsWith( ".i18n" ); //$NON-NLS-1$ | |
} | |
private IPath getOutputLocation( IContainer parent ) { | |
IPath result = null; | |
if( parent instanceof IProject ) { | |
IProject project = (IProject) parent; | |
if( hasJavaNature( project ) ) { | |
IJavaProject javaProject = JavaCore.create( project ); | |
try { | |
result = javaProject.getOutputLocation(); | |
result = result.makeRelativeTo( javaProject.getPath() ); | |
} catch( JavaModelException e ) { | |
// Should not happen | |
log.error( "Unable to determine output location of Java project " + project.getProject().getName(), e ); //$NON-NLS-1$ | |
} | |
} | |
} | |
return result; | |
} | |
// TODO I couldn't find a public API to do this check | |
@SuppressWarnings( "restriction" ) | |
protected boolean hasJavaNature( IProject project ) { | |
return org.eclipse.jdt.internal.core.JavaProject.hasJavaNature( project ); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment