Imediava's Blog

Just another WordPress.com site

Restore files from local history with Eclipse API

If you work with Eclipse you probably know that it keeps a copy of every modification made to a file. This is thanks to a backup system Eclipse guys call the Local history. This system is a really useful feature that can be a real lifesaver in some cases. It’s true that the copies are only kept for a relatively short period of time, but that can be configured by changing the Eclipse preferences.

However my interest is not to talk about its features, but to explain how the Local history system can be used when developing Eclipse plugins to implement undo capabilities for your actions.

Suppose your plugin has an action that modifies more than one file of an user’s project and you want to provide the user with the chance to undo that action. In that case, just by reverting every modified file to the state it had before the action’s date using the local history you would have an undo system ready. As simple as that. There is no need to develop the opposite action or to store manually the system state to go back to it.

An example of restoring a file to the it’s inmediately previous state in the local history is the following one coded with GroovyMonkey:

/*
 * Menu: Remove Markers
 * Script-Path: /GroovyMonkeyScripts/monkey/historial_ficheros.gm
 * Kudos: ERVIN
 * License: EPL 1.0
 * DOM: http://groovy-monkey.sourceforge.net/update/plugins/net.sf.groovyMonkey.dom
 */

import org.eclipse.core.resources.*
import org.eclipse.jdt.core.JavaCore
import org.eclipse.jdt.core.IPackageFragmentRoot
import org.eclipse.core.runtime.Path

workspace.root.projects.each { project ->

   //selects only the java projects
   if (project.isOpen() && project.isNatureEnabled("org.eclipse.jdt.core.javanature")){
 	   javaProject = JavaCore.create(project)
	   roots = javaProject.getPackageFragments()
	   
	   // Filters the source code packages
	   .findAll{ fragment -> fragment.getKind() == IPackageFragmentRoot.K_SOURCE}
	   
	   .each { fragment ->
	 	    fragment.compilationUnits.each {
			    file = it.resource
			    file.setContents(file.getHistory(null)[0].
                                         contents,IFile.KEEP_HISTORY, null)
			    file.refreshLocal(IResource.DEPTH_INFINITE, null)
	 	    }
		
	   }
	 
   }
}

Basically what this code does is: it takes all the open Java Projects in Eclipse, and restore the content of every source code file to the last state in their history.

The most interesting part of the snippet are the two following lines:


file.setContents(file.getHistory(null)[0].
                       contents,IFile.KEEP_HISTORY, null)

file.refreshLocal(IResource.DEPTH_INFINITE, null)


The first line takes the first element from the file’s history. Since the getHistory() method returns an ordered array, the first element corresponds to the last state of the file in it’s history. Then it takes the last state’s content and assigns it to the file, thus restoring the file’s content to it’s previous state.

The second line is just in charge of making Eclipse aware of the file’s change.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: