/******************************************************************************
* Copyright (c) 2010-2013, Linagora
*
* 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:
* Linagora - initial API and implementation
*******************************************************************************/
package com.ebmwebsourcing.petals.common.internal.provisional.refactoring;
import java.io.File;
import java.util.regex.Pattern;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.CompositeChange;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.TextFileChange;
import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
import org.eclipse.ltk.core.refactoring.participants.IConditionChecker;
import org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant;
import org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor;
import org.eclipse.ltk.core.refactoring.participants.SharableParticipants;
import org.eclipse.ltk.core.refactoring.participants.ValidateEditChecker;
import org.eclipse.ltk.core.refactoring.resource.RenameResourceChange;
import com.ebmwebsourcing.petals.common.internal.provisional.utils.PetalsConstants;
import com.ebmwebsourcing.petals.common.internal.provisional.utils.PetalsRefactoringUtils;
/**
* A refactoring processor for Petals Maven projects.
* <p>
* This processor supports participants (e.g. for the service
* projects, where the service-name may have to be changed in the
* jbi.xml and the WSDL).
* </p>
*
* @author Vincent Zurczak - EBM WebSourcing
*/
public class MavenProjectRefactoringProcessor extends RefactoringProcessor {
private MavenProjectRefactoringInfo info;
private final MavenProjectRefactoringExtension[] extensions;
/**
* Constructor.
* @param extensions
*/
public MavenProjectRefactoringProcessor( MavenProjectRefactoringExtension... extensions ) {
if( extensions == null )
this.extensions = new MavenProjectRefactoringExtension[ 0 ];
else
this.extensions = extensions;
}
/*
* (non-Javadoc)
* @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor
* #checkFinalConditions(org.eclipse.core.runtime.IProgressMonitor,
* org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext)
*/
@Override
public RefactoringStatus checkFinalConditions(
IProgressMonitor pm,
CheckConditionsContext context )
throws CoreException, OperationCanceledException {
RefactoringStatus status = new RefactoringStatus();
pm.beginTask( "Scanning files...", 30 );
try {
// Make sure this renaming won't result in conflicts
IProject p = ResourcesPlugin.getWorkspace().getRoot().getProject( this.info.getNewName());
if( p.exists())
status.addFatalError( "There is already a project called " + this.info.getNewName() + "." );
else {
File f = this.info.getProject().getLocation().toFile().getParentFile();
if( new File( f, this.info.getNewName()).exists())
status.addFatalError( "There is already a file with this name at this location." );
}
pm.worked( 20 );
// Check the extensions
for( MavenProjectRefactoringExtension extension : this.extensions ) {
if( status.isOK())
extension.checkFinalConditions( pm, status, context );
}
// Validate the impacted files (POM)
if( status.isOK() && context != null ) {
IConditionChecker checker = context.getChecker( ValidateEditChecker.class );
ValidateEditChecker editChecker = (ValidateEditChecker) checker;
editChecker.addFile( this.info.getProject().getFile( PetalsConstants.LOC_POM_FILE ));
}
} finally {
pm.done();
}
return status;
}
/*
* (non-Javadoc)
* @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor
* #checkInitialConditions(org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
public RefactoringStatus checkInitialConditions( IProgressMonitor pm )
throws CoreException, OperationCanceledException {
RefactoringStatus status = new RefactoringStatus();
if( this.info.getProject() == null )
status.addFatalError( "The project cannot be null." );
else if( ! this.info.getProject().exists())
status.addFatalError( this.info.getProject().getName() + " does not exist." );
else if( ! this.info.getProject().isAccessible())
status.addFatalError( "The project must be open." );
else if( ! this.info.getProject().getFile( PetalsConstants.LOC_POM_FILE ).exists())
status.addFatalError( "This project does not contain a Maven POM." );
else {
for( MavenProjectRefactoringExtension extension : this.extensions ) {
extension.checkInitialConditions( pm, status );
if( ! status.isOK())
break;
}
}
return status;
}
/*
* (non-Javadoc)
* @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor
* #createChange(org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
public Change createChange( IProgressMonitor pm )
throws CoreException, OperationCanceledException {
CompositeChange compositeChange = new CompositeChange( "Refactoring of " + this.info.getProject().getName() );
try {
pm.beginTask( "Collecting changes...", 40 + this.extensions.length * 10 );
// A file change contains a tree of edits, first add the root of them
IFile pomFile = this.info.getProject().getFile( PetalsConstants.LOC_POM_FILE );
TextFileChange textFileChange = PetalsRefactoringUtils.buildTextFileChange(
pomFile,
Pattern.quote( this.info.getProject().getName()),
null,
null,
this.info.getNewName());
if( textFileChange != null )
compositeChange.add( textFileChange );
pm.worked( 20 );
// Add the partipant's changes
for( MavenProjectRefactoringExtension extension : this.extensions ) {
if( extension.isEnabled()) {
Change participantChange = extension.createChange( pm );
if( participantChange instanceof CompositeChange )
compositeChange.merge((CompositeChange) participantChange );
else if( participantChange != null )
compositeChange.add( participantChange );
pm.worked( 10 );
}
}
// Update the project name
RenameResourceChange resourceChange = new RenameResourceChange(
this.info.getProject().getFullPath(),
this.info.getNewName());
compositeChange.add( resourceChange );
pm.worked( 20 );
} finally {
pm.done();
}
return compositeChange;
}
/*
* (non-Javadoc)
* @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor
* #getElements()
*/
@Override
public Object[] getElements() {
return new Object[] { this.info.getProject()};
}
/*
* (non-Javadoc)
* @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor
* #getIdentifier()
*/
@Override
public String getIdentifier() {
return getClass().getName();
}
/*
* (non-Javadoc)
* @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor
* #getProcessorName()
*/
@Override
public String getProcessorName() {
return "Refactoring for Petals Maven projects";
}
/*
* (non-Javadoc)
* @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor
* #isApplicable()
*/
@Override
public boolean isApplicable() throws CoreException {
return true;
}
/*
* (non-Javadoc)
* @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor
* #loadParticipants(org.eclipse.ltk.core.refactoring.RefactoringStatus,
* org.eclipse.ltk.core.refactoring.participants.SharableParticipants)
*/
@Override
public RefactoringParticipant[] loadParticipants(
RefactoringStatus status,
SharableParticipants sharedParticipants )
throws CoreException {
return new RefactoringParticipant[ 0 ];
}
/**
* @param info the info to set
*/
public void setInfo( MavenProjectRefactoringInfo info ) {
this.info = info;
for( MavenProjectRefactoringExtension extension : this.extensions )
extension.setInfo( info );
}
}