eclipse plugin: Add a first draft of the new Dependency Tree

This commit is contained in:
Timotei Dolean 2011-07-05 08:53:30 +00:00
parent 019a37dcb7
commit 95a4b69a5e
3 changed files with 303 additions and 5 deletions

View file

@ -10,10 +10,15 @@ package org.wesnoth.builder;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingDeque;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
@ -33,6 +38,7 @@ import org.wesnoth.preferences.Preferences;
import org.wesnoth.preferences.Preferences.Paths;
import org.wesnoth.preprocessor.PreprocessorUtils;
import org.wesnoth.projects.ProjectCache;
import org.wesnoth.projects.ProjectDependencyNode;
import org.wesnoth.projects.ProjectUtils;
import org.wesnoth.utils.AntUtils;
import org.wesnoth.utils.ResourceUtils;
@ -52,6 +58,8 @@ public class WesnothProjectBuilder extends IncrementalProjectBuilder
{
try
{
createDependencyTree( );
getProject().accept(new ResourceVisitor(monitor));
} catch (CoreException e)
{
@ -66,6 +74,91 @@ public class WesnothProjectBuilder extends IncrementalProjectBuilder
delta.accept(new ResourceDeltaVisitor(monitor));
}
private void createDependencyTree() throws CoreException
{
// start creating the PDT (project dependency tree)
Queue<IContainer> toProcess = new LinkedBlockingDeque<IContainer>( );
List<ProjectDependencyNode> tree = new ArrayList<ProjectDependencyNode>();
ProjectDependencyNode parent = null;
int currentIndex = 0;
toProcess.add( getProject() );
while( toProcess.isEmpty( ) == false ) {
IContainer container = toProcess.poll( );
IResource main_cfg = container.findMember( "_main.cfg" );
if ( main_cfg != null ) {
//TODO process the other children depending on the contents
// of the file
}else {
List<IResource> members = Arrays.asList( container.members( ) ) ;
Collections.sort( members, new WMLFilesComparator( ) );
if ( members.isEmpty( ) )
continue;
ProjectDependencyNode previous = null;
for ( IResource resource : members ) {
System.out.println( resource.toString( ) );
if ( resource instanceof IContainer )
toProcess.add( (IContainer)resource );
else {
String fileName = resource.getName( );
// just config files.
if ( ! fileName.endsWith( ".cfg" ) ||
! ( resource instanceof IFile ))
continue;
ProjectDependencyNode newNode =
new ProjectDependencyNode( (IFile) resource, currentIndex );
currentIndex += ProjectDependencyNode.INDEX_STEP;
if ( previous != null ){
previous.setNext( newNode );
newNode.setPrevious( previous );
} else {
// first node in the current directory -> make it son of parent
if ( parent != null ) {
parent.setSon( newNode );
newNode.setParent( parent );
}
parent = newNode;
}
tree.add( newNode );
previous = newNode;
}
}
}
}
System.out.println("tree:");
if ( !tree.isEmpty( ) ) {
ProjectDependencyNode node = tree.get( 0 );
do {
ProjectDependencyNode leaf = node;
do {
System.out.print( leaf + "; " );
leaf = leaf.getNext( );
} while ( leaf != null );
node = node.getSon( );
System.out.print("\n");
}while ( node != null );
}
else {
System.out.println("Empty");
}
}
@SuppressWarnings("rawtypes")
@Override
protected IProject[] build(int kind, Map args, IProgressMonitor monitor)
@ -120,7 +213,6 @@ public class WesnothProjectBuilder extends IncrementalProjectBuilder
}
monitor.worked(2);
boolean readDefines = true;
if (kind == FULL_BUILD)
{
@ -154,8 +246,10 @@ public class WesnothProjectBuilder extends IncrementalProjectBuilder
{
// we read the defines at the end of the build
// to speed up things (and only if we had any .cfg files processed)
ProjectUtils.getCacheForProject(getProject()).readDefines(true);
ProjectUtils.saveCacheForProject(getProject());
ProjectCache cache = ProjectUtils.getCacheForProject( getProject() );
cache.readDefines( true );
cache.saveCache( );
monitor.worked(10);
}
monitor.done();
@ -304,6 +398,7 @@ public class WesnothProjectBuilder extends IncrementalProjectBuilder
return false;
}
class ResourceDeltaVisitor implements IResourceDeltaVisitor
{
private IProgressMonitor monitor_;
@ -358,6 +453,7 @@ public class WesnothProjectBuilder extends IncrementalProjectBuilder
}
}
class ResourceVisitor implements IResourceVisitor
{
private IProgressMonitor monitor_;
@ -378,4 +474,35 @@ public class WesnothProjectBuilder extends IncrementalProjectBuilder
return checkResource(resource, monitor_, -1, false);
}
}
/**
* This is a WML files comparator, based on the WML parsing rules.
*
* @see http://wiki.wesnoth.org/PreprocessorRef
*/
public static class WMLFilesComparator implements Comparator<IResource> {
@Override
public int compare( IResource o1, IResource o2 )
{
String name1 = o1.getName( );
String name2 = o2.getName( );
// _initial.cfg is always the "lowest"
if ( name1.equals( "_initial.cfg" ) && !( name2.equals( "_initial.cfg" ) ) )
return -1;
if ( name2.equals( "_initial.cfg" ) && !( name1.equals( "_initial.cfg" ) ) )
return 1;
// _final.cfg is always the "highest"
if ( name1.equals( "_final.cfg" ) && !( name2.equals( "_final.cfg" ) ) )
return 1;
if ( name2.equals( "_final.cfg" ) && !( name1.equals( "_final.cfg" ) ) )
return -1;
return name1.compareTo( o2.getName( ) );
}
}
}

View file

@ -40,8 +40,10 @@ public class ProjectCache
private File wesnothFile_;
private File definesFile_;
private Map<String, ConfigFile> configFiles_;
private Map<String, Define> defines_;
private Map< String, ConfigFile > configFiles_;
private Map< String, Define > defines_;
private Map< String, ProjectDependencyNode > depedencyTree_;
private IProject project_;
@ -51,6 +53,8 @@ public class ProjectCache
configFiles_ = new HashMap<String, ConfigFile>();
defines_ = new HashMap<String, Define>(0);
depedencyTree_ = new HashMap<String, ProjectDependencyNode>();
propertiesTimetamp_ = 0;
properties_ = new DialogSettings("project"); //$NON-NLS-1$

View file

@ -0,0 +1,167 @@
/*******************************************************************************
* Copyright (c) 2011 by Timotei Dolean <timotei21@gmail.com>
*
* 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
*******************************************************************************/
package org.wesnoth.projects;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.QualifiedName;
import org.wesnoth.Constants;
import org.wesnoth.Logger;
/**
* This class represents a node
* in the Project's Depedency tree,
* which is constructed on a full build of the project.
*
* Alternatively, a tree node is created
* when a new resource is added.
*/
public class ProjectDependencyNode
{
/**
* This integer represents the default step between 2 file indexes.
* Since int it's on 4 bytes, it can hold values between
* -2,147,483,648 and 2,147,483,647.
*
* With an increment of 10k, we could have 2*214,748 config files.
*/
public static final int INDEX_STEP = 10000;
protected static final QualifiedName PDT_INDEX = new QualifiedName( Constants.PLUGIN_ID, "pdt_index" ); //$NON-NLS-1$
private ProjectDependencyNode previous_;
private ProjectDependencyNode next_;
private ProjectDependencyNode parent_;
private ProjectDependencyNode son_;
private IFile file_;
private int index_;
public ProjectDependencyNode( IFile file, int index )
{
previous_ = next_ = parent_ = son_ = null;
file_ = file;
setIndex( index );
}
/**
* Gets this node's file
* @return A IFile resource
*/
public IFile getFile()
{
return file_;
}
/**
* Returns the index of this node in the whole dependency tree node
* @return
*/
public int getIndex()
{
return index_;
}
/**
* Sets a new index for this node
* @param index The index to set
*/
public void setIndex( int index )
{
index_ = index;
try {
file_.setPersistentProperty( PDT_INDEX, Integer.toString( index ) );
}
catch ( CoreException e ) {
Logger.getInstance( ).logException( e );
}
}
/**
* Gets the parent of this node
* @return A node or null if there is no parent
*/
public ProjectDependencyNode getParent()
{
return parent_;
}
/**
* Sets a new parent for this node
* @param parent The parent to set
*/
public void setParent( ProjectDependencyNode parent )
{
parent_ = parent;
}
/**
* Gets the son of this node
* @return A node or null if there is no parent
*/
public ProjectDependencyNode getSon()
{
return son_;
}
/**
* Sets a new son node for this node
* @param son The new son node to set
*/
public void setSon( ProjectDependencyNode son )
{
son_ = son;
}
/**
* Gets the node before the current node
* @return A node or null if there is no parent
*/
public ProjectDependencyNode getPrevious()
{
return previous_;
}
/**
* Sets a new previous node for this node
* @param previous The new previous node to set
*/
public void setPrevious( ProjectDependencyNode previous )
{
previous_ = previous;
}
/**
* Gets the node after the current node
* @return A node or null if there is no parent
*/
public ProjectDependencyNode getNext()
{
return next_;
}
/**
* Sets a new next node for this node
* @param next The new next node to set
*/
public void setNext( ProjectDependencyNode next )
{
next_ = next;
}
@Override
public String toString()
{
return ( file_ == null ? "" : file_.getProjectRelativePath( ).toString( ) ) + "_" + index_;
}
}