eclipse plugin: Major overhaul for the ProjectCache.

Use the java's built-in serialize/deserialize mechanism
instead of manually doing save/loading.
This commit is contained in:
Timotei Dolean 2011-07-26 15:30:29 +00:00
parent f7a0b20a64
commit 90e2a794eb
11 changed files with 123 additions and 218 deletions

View file

@ -239,9 +239,9 @@ public class WMLProposalProvider extends AbstractWMLProposalProvider
@Override
public String apply( WMLVariable from )
{
if ( from.getScopeStartIndex( ) <= dependencyIndex_ &&
dependencyIndex_ <= from.getScopeEndIndex( ) )
return from.getName( );
// if ( from.getScopeStartIndex( ) <= dependencyIndex_ &&
// dependencyIndex_ <= from.getScopeEndIndex( ) )
// return from.getName( );
return null;
}
} );

View file

@ -8,17 +8,18 @@
*******************************************************************************/
package org.wesnoth.projects;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.io.StreamCorruptedException;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.resources.IProject;
import org.eclipse.jface.dialogs.DialogSettings;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.wesnoth.Constants;
import org.wesnoth.Logger;
import org.wesnoth.builder.DependencyListBuilder;
@ -26,36 +27,30 @@ import org.wesnoth.preferences.Preferences;
import org.wesnoth.preprocessor.Define;
import org.wesnoth.preprocessor.PreprocessorUtils;
import org.wesnoth.utils.ResourceUtils;
import org.wesnoth.utils.WorkspaceUtils;
import org.wesnoth.wml.core.WMLConfig;
import org.wesnoth.wml.core.WMLVariable;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
/**
* A class that stores some project specific infos
* for current session.
* Some of the fields of this cache can be saved to disk
* @see ProjectCache#saveCache()
*/
public class ProjectCache
public class ProjectCache implements Serializable
{
private long propertiesTimestamp_;
private static final long serialVersionUID = -3173930983967880699L;
private long definesTimestamp_;
private DialogSettings properties_;
private File wesnothFile_;
private File definesFile_;
private File treeCacheFile_;
private transient File wesnothFile_;
private transient File definesFile_;
private transient IProject project_;
private transient Map< String, Define > defines_;
private Map<String, String> properties_;
private Map< String, WMLConfig > configFiles_;
private Map< String, Define > defines_;
private DependencyListBuilder dependTree_;
private Multimap<String, WMLVariable> variables_;
private IProject project_;
private Map<String, WMLVariable> variables_;
public ProjectCache(IProject project)
{
@ -63,108 +58,23 @@ public class ProjectCache
configFiles_ = new HashMap<String, WMLConfig>( );
defines_ = new HashMap<String, Define>( );
variables_ = ArrayListMultimap.create( );
variables_ = new HashMap<String, WMLVariable>( );
properties_ = new HashMap<String, String>( );
dependTree_ = new DependencyListBuilder( project_ );
propertiesTimestamp_ = 0;
properties_ = new DialogSettings("project"); //$NON-NLS-1$
definesTimestamp_ = -1;
wesnothFile_ = new File(project.getLocation().toOSString() +
"/.wesnoth"); //$NON-NLS-1$
definesFile_ = new File (PreprocessorUtils.getInstance().getMacrosLocation( project ));
treeCacheFile_ = new File ( WorkspaceUtils.getProjectTemporaryFolder( project ) + "/_TREE_CACHE_.bin" ); //$NON-NLS-1$
ResourceUtils.createWesnothFile(wesnothFile_.getAbsolutePath(), false);
readProperties(true);
readDefines(true);
wesnothFile_ = new File ( project.getLocation().toOSString() + "/.wesnoth" ); //$NON-NLS-1$
definesFile_ = new File ( PreprocessorUtils.getInstance().getMacrosLocation( project ));
}
/**
* Reads the properties from the file only if the
* file changed.
* @param force True to skip checking for modifications
* Gets the properties map for this project.
* @return A map with properties of the project
*/
private void readProperties(boolean force)
public Map<String, String> getProperties()
{
if (force == false &&
wesnothFile_.lastModified() <= propertiesTimestamp_)
return;
try
{
ResourceUtils.createWesnothFile(wesnothFile_.getAbsolutePath(), false);
try
{
properties_.load( wesnothFile_.getAbsolutePath() );
}
catch(ClassCastException ex)
{
// backward compatiblity
// we already have an xml format used by Properties.
// convert it to DialogSettings
ResourceUtils.createWesnothFile(wesnothFile_.getAbsolutePath(), true);
properties_.load( wesnothFile_.getAbsolutePath() );
}
if (properties_.getSection("configs") != null) //$NON-NLS-1$
{
for(IDialogSettings config : properties_.getSection("configs").getSections()) //$NON-NLS-1$
{
if (config.getName().startsWith("config") == false) //$NON-NLS-1$
continue;
WMLConfig tmp = new WMLConfig(config.get("filename")); //$NON-NLS-1$
tmp.ScenarioId = config.get( "scenario_id" ); //$NON-NLS-1$
tmp.CampaignId = config.get( "campaign_id" ); //$NON-NLS-1$
configFiles_.put(config.get("filename"), tmp); //$NON-NLS-1$
}
}
if ( properties_.getSection( "variables" ) != null ){
for(IDialogSettings variable : properties_.getSection("variables").getSections()) //$NON-NLS-1$
{
if (variable.getName().startsWith("var") == false) //$NON-NLS-1$
continue;
variables_.put( variable.get( "name" ),
new WMLVariable(variable.get("name"), //$NON-NLS-1$
variable.get("location"), //$NON-NLS-1$
variable.getInt("offset"),
variable.getInt( "startIndex" ),
variable.getInt( "endIndex" ))); //$NON-NLS-1$
}
}
// unserialize the tree builder
if ( treeCacheFile_.exists( ) ) {
FileInputStream inStream = new FileInputStream( treeCacheFile_ );
ObjectInputStream deserializer = new ObjectInputStream( inStream );
dependTree_.deserialize( deserializer );
}
propertiesTimestamp_ = wesnothFile_.lastModified();
}
catch (Exception e)
{
Logger.getInstance().logException(e);
propertiesTimestamp_ = 0; // force to re-read the file
}
}
/**
* Gets the properties store for the associated Project.
* If the store doesn't exist it will be created.
* This method ensures it will get the latest up-to-date '.wesnoth' file
* @return
*/
public DialogSettings getProperties()
{
readProperties(false);
return properties_;
}
@ -200,11 +110,49 @@ public class ProjectCache
* Returns the variables found in this project
* @return A multimap containing all the variables
*/
public Multimap<String, WMLVariable> getVariables()
public Map<String, WMLVariable> getVariables()
{
return variables_;
}
/**
* Loads this class from the {@code .wesnoth} file and
* loads the other cached files
*/
public void loadCache( )
{
ResourceUtils.createWesnothFile( wesnothFile_.getAbsolutePath(), false );
try
{
try
{
FileInputStream inputStream = new FileInputStream( wesnothFile_ );
ObjectInputStream deserializer = new ObjectInputStream( inputStream );
ProjectCache cache = ( ProjectCache ) deserializer.readObject( );
configFiles_ = cache.configFiles_;
dependTree_ = cache.dependTree_;
}
// invalid file contents. just save this instance to it.
catch ( EOFException e) {
saveCache( );
}
catch (StreamCorruptedException e) {
saveCache( );
}
catch(ClassCastException ex) {
saveCache( );
}
}
catch (Exception e)
{
Logger.getInstance().logException(e);
}
readDefines(true);
}
/**
* Saves the cache to disk.
* Saves:
@ -215,45 +163,12 @@ public class ProjectCache
public boolean saveCache()
{
ResourceUtils.createWesnothFile(wesnothFile_.getAbsolutePath(), false);
try
{
// save config files info
int configCnt = 0;
IDialogSettings configsSection = properties_.addNewSection("configs"); //$NON-NLS-1$
for(WMLConfig config : configFiles_.values())
{
IDialogSettings configSection = configsSection.addNewSection("config" + configCnt); //$NON-NLS-1$
configSection.put("scenario_id", config.ScenarioId); //$NON-NLS-1$
configSection.put("campaign_id", config.CampaignId); //$NON-NLS-1$
configSection.put("filename", config.getFilename()); //$NON-NLS-1$
++configCnt;
}
IDialogSettings variablesSection = properties_.addNewSection("variables"); //$NON-NLS-1$
int varCnt = 0;
for(WMLVariable var : variables_.values( ))
{
IDialogSettings varSection = variablesSection.addNewSection("var" + varCnt); //$NON-NLS-1$
varSection.put("name", var.getName()); //$NON-NLS-1$
varSection.put("location", var.getLocation()); //$NON-NLS-1$
varSection.put("offset", var.getOffset()); //$NON-NLS-1$
varSection.put( "startIndex", var.getScopeStartIndex( ) );
varSection.put( "endIndex", var.getScopeEndIndex( ) );
++varCnt;
}
// store properties
properties_.save( wesnothFile_.getAbsolutePath() );
propertiesTimestamp_ = wesnothFile_.lastModified();
// save the PDT tree
ResourceUtils.createNewFile( treeCacheFile_.getAbsolutePath( ) );
FileOutputStream outStream = new FileOutputStream( treeCacheFile_ );
ObjectOutputStream serializer = new ObjectOutputStream( outStream );
serializer.writeObject( dependTree_ );
serializer.close( );
FileOutputStream outputStream = new FileOutputStream( wesnothFile_ );
ObjectOutputStream serializer = new ObjectOutputStream( outputStream );
serializer.writeObject( this );
return true;
}
@ -266,24 +181,22 @@ public class ProjectCache
/**
* Reads the defines files for this project
* @param force skip checking for last modified timestamp
* @param force Read the defines even if the defines file's contents
* haven't changed since last time read.
*/
public void readDefines(boolean force)
{
if (force == false &&
definesFile_.lastModified() <= definesTimestamp_)
definesFile_.lastModified() <= definesTimestamp_)
return;
if (definesFile_.exists() == false)
return;
defines_ = Define.readDefines(definesFile_.getAbsolutePath());
definesTimestamp_ = definesFile_.lastModified( );
}
public void setDefines(Map<String, Define> defines)
{
defines_ = defines;
}
/**
* Returns the defines associated with this project
* @return
@ -326,13 +239,12 @@ public class ProjectCache
*/
public void clear()
{
properties_ = new DialogSettings("project"); //$NON-NLS-1$
properties_ = new HashMap<String, String>();
configFiles_.clear( );
defines_.clear( );
dependTree_ = new DependencyListBuilder( project_ );
propertiesTimestamp_ = -1;
definesTimestamp_ = -1;
saveCache( );

View file

@ -18,7 +18,6 @@ import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.dialogs.DialogSettings;
import org.wesnoth.Constants;
import org.wesnoth.Logger;
import org.wesnoth.Messages;
@ -41,13 +40,10 @@ public class ProjectUtils
}
/**
* Gets the properties store for specified project.
* If the store doesn't exist it will be created.
* This will return null if it has been an exception
* This method ensures it will get the latest up-to-date '.wesnoth' file
* @param project the project
* Gets the properties map for this project.
* @return A map with properties of the project
*/
public static DialogSettings getPropertiesForProject(IProject project)
public static Map<String, String> getPropertiesForProject(IProject project)
{
return getCacheForProject(project).getProperties();
}
@ -64,21 +60,12 @@ public class ProjectUtils
if (cache == null)
{
cache = new ProjectCache(project);
cache.loadCache( );
projectCache_.put(project,cache);
}
return cache;
}
/**
* Saves the current properties of the specified project on the filesystem.
* If the file/properties don't exist they will be created
* @param project
*/
public static void saveCacheForProject(IProject project)
{
getCacheForProject(project).saveCache();
}
/**
* Creates a new wesnoth project with the specified name
* and on the specified location on disk

View file

@ -27,4 +27,10 @@ public class Pair<T, K>
public static <U,V> Pair<U,V> create( U first, V second) {
return new Pair<U, V> ( first, second );
}
@Override
public String toString()
{
return "( " + First.toString( ) + "; " + Second.toString( ) + " )";
}
}

View file

@ -46,7 +46,6 @@ import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.jface.dialogs.DialogSettings;
import org.eclipse.swt.SWT;
import org.wesnoth.Constants;
import org.wesnoth.Logger;
@ -242,7 +241,6 @@ public class ResourceUtils
(force == false && wesnothFile.exists() == false))
{
createNewFile(wesnothFile.getAbsolutePath());
new DialogSettings("project").save(path); //$NON-NLS-1$
}
}
catch (Exception e) {

View file

@ -127,7 +127,7 @@ public class CampaignNewWizard extends NewWizardTemplate
// store some campaign-related info
ProjectUtils.getPropertiesForProject(currentProject).put("difficulties", page2_.getDifficulties()); //$NON-NLS-1$
ProjectUtils.saveCacheForProject(currentProject);
ProjectUtils.getCacheForProject( currentProject ).saveCache( );
monitor.done();
}

View file

@ -14,6 +14,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Map;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
@ -23,7 +24,6 @@ import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.dialogs.DialogSettings;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
@ -73,7 +73,7 @@ public class ScenarioNewWizard extends NewWizardTemplate
if (selectionContainer_ != null)
{
DialogSettings props = ProjectUtils.getPropertiesForProject(selectionContainer_.getProject());
Map<String, String> props = ProjectUtils.getPropertiesForProject(selectionContainer_.getProject());
if (props.get("difficulties") != null) //$NON-NLS-1$
{
page1_ = new ScenarioPage1();

View file

@ -8,8 +8,9 @@
*******************************************************************************/
package org.wesnoth.wizards.scenario;
import java.util.Map;
import org.eclipse.core.resources.IContainer;
import org.eclipse.jface.dialogs.DialogSettings;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
@ -48,8 +49,9 @@ public class ScenarioPage1 extends NewWizardPageTemplate
IContainer selContainer = getWizard().getSelectionContainer();
if (selContainer != null)
{
DialogSettings prefs =
Map<String, String> prefs =
ProjectUtils.getPropertiesForProject(selContainer.getProject());
if (prefs.get("difficulties") != null) //$NON-NLS-1$
{
String[] difficulties = prefs.get("difficulties").split(","); //$NON-NLS-1$ //$NON-NLS-2$

View file

@ -124,7 +124,7 @@ public class SimpleWMLParser
ICompositeNode node = NodeModelUtils.getNode( context ) ;
variable.setLocation( file_.getLocation( ).toOSString( ) );
variable.setScopeStartIndex( ResourceUtils.getDependencyIndex( file_ ) );
// variable.setScopeStartIndex( ResourceUtils.getDependencyIndex( file_ ) );
variable.setOffset( node.getTotalOffset( ) );
if ( context instanceof WMLKey ) {

View file

@ -8,13 +8,17 @@
*******************************************************************************/
package org.wesnoth.wml.core;
import java.io.Serializable;
/**
* A class that stores WML config file specific information
*/
public class WMLConfig
public class WMLConfig implements Serializable
{
public String ScenarioId;
private static final long serialVersionUID = -4722231494864404935L;
public String ScenarioId;
/**
* True if there was a [scenario] tag present in the file.
*

View file

@ -8,17 +8,24 @@
*******************************************************************************/
package org.wesnoth.wml.core;
import java.io.Serializable;
import java.util.List;
import org.wesnoth.utils.Pair;
/**
* Represents a WML Variable
*/
public class WMLVariable
public class WMLVariable implements Serializable
{
private String name_;
private static final long serialVersionUID = 5293113569770337870L;
private String name_;
private String location_;
private int offset_;
private boolean isArray_;
private int scopeStartIndex_;
private int scopeEndIndex_;
private List< Pair<Integer, Integer> > scopes_;
public WMLVariable()
{
@ -26,19 +33,10 @@ public class WMLVariable
}
public WMLVariable( String name, String location, int offset )
{
this( name, location, offset, Integer.MIN_VALUE, Integer.MAX_VALUE );
}
public WMLVariable( String name, String location, int offset,
int startIndex, int endIndex )
{
name_ = name;
location_ = location;
offset_ = offset;
scopeStartIndex_ = startIndex;
scopeEndIndex_ = endIndex;
}
public String getName()
@ -74,29 +72,27 @@ public class WMLVariable
isArray_ = isArray;
}
public int getScopeEndIndex()
public List<Pair<Integer, Integer>> getScopes()
{
return scopeEndIndex_;
}
public int getScopeStartIndex()
{
return scopeStartIndex_;
}
public void setScopeEndIndex( int scopeEndIndex )
{
scopeEndIndex_ = scopeEndIndex;
}
public void setScopeStartIndex( int scopeStartIndex )
{
scopeStartIndex_ = scopeStartIndex;
return scopes_;
}
@Override
public String toString()
{
return "Variable - Name: " + name_ +
"; Location:" + location_ +
"; Offset:" + offset_ +
"; Scope: " + scopeStartIndex_ + " -> " + scopeEndIndex_;
StringBuilder res = new StringBuilder( );
res.append( "Variable - Name: " + name_ );
res.append( "; Location:" + location_ );
res.append( "; Offset:" + offset_ );
if ( ! scopes_.isEmpty( ) ) {
res.append( "; Scopes: " );
for ( Pair<Integer,Integer> scope : scopes_ ) {
res.append( scope );
}
}
return res.toString( );
}
}