X-Git-Url: http://git.phpeclipse.com
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaModelManager.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaModelManager.java
index 6652089..04597a0 100644
--- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaModelManager.java
+++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaModelManager.java
@@ -11,10 +11,14 @@
package net.sourceforge.phpdt.internal.core;
import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
import java.io.DataInputStream;
+import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileOutputStream;
import java.io.IOException;
+import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
@@ -25,16 +29,22 @@ import java.util.WeakHashMap;
import java.util.zip.ZipFile;
import net.sourceforge.phpdt.core.ElementChangedEvent;
+import net.sourceforge.phpdt.core.IClasspathEntry;
import net.sourceforge.phpdt.core.ICompilationUnit;
import net.sourceforge.phpdt.core.IElementChangedListener;
import net.sourceforge.phpdt.core.IJavaElement;
import net.sourceforge.phpdt.core.IJavaElementDelta;
+import net.sourceforge.phpdt.core.IJavaModel;
import net.sourceforge.phpdt.core.IJavaProject;
+import net.sourceforge.phpdt.core.IPackageFragment;
+import net.sourceforge.phpdt.core.IPackageFragmentRoot;
import net.sourceforge.phpdt.core.IWorkingCopy;
-import net.sourceforge.phpdt.core.JavaCore;
import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.core.JavaCore;
import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil;
import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpdt.internal.core.builder.PHPBuilder;
+import net.sourceforge.phpdt.internal.core.util.Util;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
@@ -49,16 +59,33 @@ import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IPluginDescriptor;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.core.runtime.Status;
+import net.sourceforge.phpdt.internal.core.DefaultWorkingCopyOwner;
+
+import net.sourceforge.phpdt.internal.core.DeltaProcessingState;
+
+import net.sourceforge.phpdt.internal.core.DeltaProcessor;
+
+import net.sourceforge.phpdt.core.IParent;
+import net.sourceforge.phpdt.internal.core.JavaElementInfo;
+
+import net.sourceforge.phpdt.core.IProblemRequestor;
+import net.sourceforge.phpdt.core.WorkingCopyOwner;
+import net.sourceforge.phpdt.core.compiler.IProblem;
+import net.sourceforge.phpdt.internal.core.CompilationUnit;
+import net.sourceforge.phpdt.internal.core.JavaElement;
+import net.sourceforge.phpdt.internal.core.JavaElementDeltaBuilder;
+import net.sourceforge.phpdt.internal.core.JavaModelManager.PerWorkingCopyInfo;
+
/**
* The JavaModelManager
manages instances of IJavaModel
.
* IElementChangedListener
s register with the JavaModelManager
,
@@ -81,7 +108,7 @@ public class JavaModelManager implements ISaveParticipant {
public static HashMap PreviousSessionVariables = new HashMap(5);
public static HashSet OptionNames = new HashSet(20);
public final static String CP_VARIABLE_PREFERENCES_PREFIX = PHPeclipsePlugin.PLUGIN_ID+".classpathVariable."; //$NON-NLS-1$
-// public final static String CP_CONTAINER_PREFERENCES_PREFIX = JavaCore.PLUGIN_ID+".classpathContainer."; //$NON-NLS-1$
+// public final static String CP_CONTAINER_PREFERENCES_PREFIX = PHPCore.PLUGIN_ID+".classpathContainer."; //$NON-NLS-1$
public final static String CP_ENTRY_IGNORE = "####"; //$NON-NLS-1$
/**
@@ -134,41 +161,46 @@ public class JavaModelManager implements ISaveParticipant {
public final static IWorkingCopy[] NoWorkingCopy = new IWorkingCopy[0];
/**
+ * Table from WorkingCopyOwner to a table of ICompilationUnit (working copy handle) to PerWorkingCopyInfo.
+ * NOTE: this object itself is used as a lock to synchronize creation/removal of per working copy infos
+ */
+ protected Map perWorkingCopyInfos = new HashMap(5);
+ /**
* Returns whether the given full path (for a package) conflicts with the output location
* of the given project.
*/
-// public static boolean conflictsWithOutputLocation(IPath folderPath, JavaProject project) {
-// try {
-// IPath outputLocation = project.getOutputLocation();
-// if (outputLocation == null) {
-// // in doubt, there is a conflict
-// return true;
-// }
-// if (outputLocation.isPrefixOf(folderPath)) {
-// // only allow nesting in project's output if there is a corresponding source folder
-// // or if the project's output is not used (in other words, if all source folders have their custom output)
-// IClasspathEntry[] classpath = project.getResolvedClasspath(true);
-// boolean isOutputUsed = false;
-// for (int i = 0, length = classpath.length; i < length; i++) {
-// IClasspathEntry entry = classpath[i];
-// if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
-// if (entry.getPath().equals(outputLocation)) {
-// return false;
-// }
-// if (entry.getOutputLocation() == null) {
-// isOutputUsed = true;
-// }
-// }
-// }
-// return isOutputUsed;
-// }
-// return false;
-// } catch (JavaModelException e) {
-// // in doubt, there is a conflict
-// return true;
-// }
-// }
-//
+ public static boolean conflictsWithOutputLocation(IPath folderPath, JavaProject project) {
+ try {
+ IPath outputLocation = project.getOutputLocation();
+ if (outputLocation == null) {
+ // in doubt, there is a conflict
+ return true;
+ }
+ if (outputLocation.isPrefixOf(folderPath)) {
+ // only allow nesting in project's output if there is a corresponding source folder
+ // or if the project's output is not used (in other words, if all source folders have their custom output)
+ IClasspathEntry[] classpath = project.getResolvedClasspath(true);
+ boolean isOutputUsed = false;
+ for (int i = 0, length = classpath.length; i < length; i++) {
+ IClasspathEntry entry = classpath[i];
+ if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
+ if (entry.getPath().equals(outputLocation)) {
+ return false;
+ }
+ if (entry.getOutputLocation() == null) {
+ isOutputUsed = true;
+ }
+ }
+ }
+ return isOutputUsed;
+ }
+ return false;
+ } catch (JavaModelException e) {
+ // in doubt, there is a conflict
+ return true;
+ }
+ }
+
// public static IClasspathContainer containerGet(IJavaProject project, IPath containerPath) {
// Map projectContainers = (Map)Containers.get(project);
// if (projectContainers == null){
@@ -276,8 +308,8 @@ public class JavaModelManager implements ISaveParticipant {
if (file.getFileExtension() != null) {
String name = file.getName();
-// if (Util.isValidCompilationUnitName(name))
- if (PHPFileUtil.isPHPFile(file))
+ if (PHPFileUtil.isValidPHPUnitName(name))
+ //if (PHPFileUtil.isPHPFile(file))
return createCompilationUnitFrom(file, project);
// if (Util.isValidClassFileName(name))
// return createClassFileFrom(file, project);
@@ -304,16 +336,14 @@ public class JavaModelManager implements ISaveParticipant {
if (project == null) {
project = JavaCore.create(folder.getProject());
}
-// TODO khartlage temp-del
-// IJavaElement element = determineIfOnClasspath(folder, project);
-// if (conflictsWithOutputLocation(folder.getFullPath(), (JavaProject)project)
-// || (folder.getName().indexOf('.') >= 0
-// && !(element instanceof IPackageFragmentRoot))) {
-// return null; // only package fragment roots are allowed with dot names
-// } else {
-// return element;
-// }
-return null;
+ IJavaElement element = determineIfOnClasspath(folder, project);
+ if (conflictsWithOutputLocation(folder.getFullPath(), (JavaProject)project)
+ || (folder.getName().indexOf('.') >= 0
+ && !(element instanceof IPackageFragmentRoot))) {
+ return null; // only package fragment roots are allowed with dot names
+ } else {
+ return element;
+ }
}
/**
@@ -326,7 +356,7 @@ return null;
// return null;
// }
// if (project == null) {
-// project = JavaCore.create(file.getProject());
+// project = PHPCore.create(file.getProject());
// }
// IPackageFragment pkg = (IPackageFragment) determineIfOnClasspath(file, project);
// if (pkg == null) {
@@ -350,22 +380,18 @@ return null;
if (project == null) {
project = JavaCore.create(file.getProject());
}
-// TODO khartlage temp-del
-// IPackageFragment pkg = (IPackageFragment) determineIfOnClasspath(file, project);
-// if (pkg == null) {
-
+ IPackageFragment pkg = (IPackageFragment) determineIfOnClasspath(file, project);
+ if (pkg == null) {
// not on classpath - make the root its folder, and a default package
-// IPackageFragmentRoot root = project.getPackageFragmentRoot(file.getParent());
-// pkg = root.getPackageFragment(IPackageFragment.DEFAULT_PACKAGE_NAME);
-//
-// if (VERBOSE){
-// System.out.println("WARNING : creating unit element outside classpath ("+ Thread.currentThread()+"): " + file.getFullPath()); //$NON-NLS-1$//$NON-NLS-2$
-// }
-// }
-// return pkg.getCompilationUnit(file.getName());
-return null;
+ IPackageFragmentRoot root = project.getPackageFragmentRoot(file.getParent());
+ pkg = root.getPackageFragment(IPackageFragment.DEFAULT_PACKAGE_NAME);
+
+ if (VERBOSE){
+ System.out.println("WARNING : creating unit element outside classpath ("+ Thread.currentThread()+"): " + file.getFullPath()); //$NON-NLS-1$//$NON-NLS-2$
+ }
+ }
+ return pkg.getCompilationUnit(file.getName());
}
-
/**
* Creates and returns a handle for the given JAR file, its project being the given project.
* The Java model associated with the JAR's project may be
@@ -378,7 +404,7 @@ return null;
// return null;
// }
// if (project == null) {
-// project = JavaCore.create(file.getProject());
+// project = PHPCore.create(file.getProject());
// }
//
// // Create a jar package fragment root only if on the classpath
@@ -402,50 +428,51 @@ return null;
* the package fragment the given resource is located in, or null
* if the given resource is not on the classpath of the given project.
*/
-// public static IJavaElement determineIfOnClasspath(
-// IResource resource,
-// IJavaProject project) {
-//
-// IPath resourcePath = resource.getFullPath();
-// try {
-// IClasspathEntry[] entries =
-// Util.isJavaFileName(resourcePath.lastSegment())
-// ? project.getRawClasspath() // JAVA file can only live inside SRC folder (on the raw path)
-// : ((JavaProject)project).getResolvedClasspath(true);
-//
-// for (int i = 0; i < entries.length; i++) {
-// IClasspathEntry entry = entries[i];
-// if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) continue;
-// IPath rootPath = entry.getPath();
-// if (rootPath.equals(resourcePath)) {
-// return project.getPackageFragmentRoot(resource);
-// } else if (rootPath.isPrefixOf(resourcePath) && !Util.isExcluded(resource, ((ClasspathEntry)entry).fullExclusionPatternChars())) {
-// // given we have a resource child of the root, it cannot be a JAR pkg root
-// IPackageFragmentRoot root = ((JavaProject) project).getFolderPackageFragmentRoot(rootPath);
-// if (root == null) return null;
-// IPath pkgPath = resourcePath.removeFirstSegments(rootPath.segmentCount());
-// if (resource.getType() == IResource.FILE) {
-// // if the resource is a file, then remove the last segment which
-// // is the file name in the package
-// pkgPath = pkgPath.removeLastSegments(1);
-//
-// // don't check validity of package name (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=26706)
+ public static IJavaElement determineIfOnClasspath(
+ IResource resource,
+ IJavaProject project) {
+
+ IPath resourcePath = resource.getFullPath();
+ try {
+ IClasspathEntry[] entries =
+ net.sourceforge.phpdt.internal.compiler.util.Util.isJavaFileName(resourcePath.lastSegment())
+ ? project.getRawClasspath() // JAVA file can only live inside SRC folder (on the raw path)
+ : ((JavaProject)project).getResolvedClasspath(true);
+
+ for (int i = 0; i < entries.length; i++) {
+ IClasspathEntry entry = entries[i];
+ if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) continue;
+ IPath rootPath = entry.getPath();
+ if (rootPath.equals(resourcePath)) {
+ return project.getPackageFragmentRoot(resource);
+ } else if (rootPath.isPrefixOf(resourcePath) && !Util.isExcluded(resource, ((ClasspathEntry)entry).fullExclusionPatternChars())) {
+ // given we have a resource child of the root, it cannot be a JAR pkg root
+ IPackageFragmentRoot root = ((JavaProject) project).getFolderPackageFragmentRoot(rootPath);
+ if (root == null) return null;
+ IPath pkgPath = resourcePath.removeFirstSegments(rootPath.segmentCount());
+ if (resource.getType() == IResource.FILE) {
+ // if the resource is a file, then remove the last segment which
+ // is the file name in the package
+ pkgPath = pkgPath.removeLastSegments(1);
+
+ // don't check validity of package name (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=26706)
// String pkgName = pkgPath.toString().replace('/', '.');
-// return root.getPackageFragment(pkgName);
-// } else {
-// String pkgName = Util.packageName(pkgPath);
-// if (pkgName == null || JavaConventions.validatePackageName(pkgName).getSeverity() == IStatus.ERROR) {
-// return null;
-// }
-// return root.getPackageFragment(pkgName);
-// }
-// }
-// }
-// } catch (JavaModelException npe) {
-// return null;
-// }
-// return null;
-// }
+ String pkgName = pkgPath.toString();
+ return root.getPackageFragment(pkgName);
+ } else {
+ String pkgName = Util.packageName(pkgPath);
+ if (pkgName == null){// || JavaConventions.validatePackageName(pkgName).getSeverity() == IStatus.ERROR) {
+ return null;
+ }
+ return root.getPackageFragment(pkgName);
+ }
+ }
+ }
+ } catch (JavaModelException npe) {
+ return null;
+ }
+ return null;
+ }
/**
* The singleton manager
@@ -455,13 +482,20 @@ return null;
/**
* Infos cache.
*/
-// protected JavaModelCache cache = new JavaModelCache();
+ protected JavaModelCache cache = new JavaModelCache();
+ /*
+ * Temporary cache of newly opened elements
+ */
+ private ThreadLocal temporaryCache = new ThreadLocal();
/**
* Set of elements which are out of sync with their buffers.
*/
protected Map elementsOutOfSynchWithBuffers = new HashMap(11);
-
+ /**
+ * Holds the state used for delta processing.
+ */
+ public DeltaProcessingState deltaState = new DeltaProcessingState();
/**
* Turns delta firing on/off. By default it is on.
*/
@@ -493,7 +527,7 @@ return null;
/**
* Used to convert IResourceDelta
s into IJavaElementDelta
s.
*/
- public final DeltaProcessor deltaProcessor = new DeltaProcessor(this);
+// public final DeltaProcessor deltaProcessor = new DeltaProcessor(this);
/**
* Used to update the JavaModel for IJavaElementDelta
s.
*/
@@ -525,8 +559,8 @@ return null;
public IProject project;
public Object savedState;
public boolean triedRead;
-// public IClasspathEntry[] classpath;
-// public IClasspathEntry[] lastResolvedClasspath;
+ public IClasspathEntry[] classpath;
+ public IClasspathEntry[] lastResolvedClasspath;
public Map resolvedPathToRawEntries; // reverse map from resolved path to raw entries
public IPath outputLocation;
public Preferences preferences;
@@ -537,6 +571,43 @@ return null;
this.project = project;
}
}
+ public static class PerWorkingCopyInfo implements IProblemRequestor {
+ int useCount = 0;
+ IProblemRequestor problemRequestor;
+ ICompilationUnit workingCopy;
+ public PerWorkingCopyInfo(ICompilationUnit workingCopy, IProblemRequestor problemRequestor) {
+ this.workingCopy = workingCopy;
+ this.problemRequestor = problemRequestor;
+ }
+ public void acceptProblem(IProblem problem) {
+ if (this.problemRequestor == null) return;
+ this.problemRequestor.acceptProblem(problem);
+ }
+ public void beginReporting() {
+ if (this.problemRequestor == null) return;
+ this.problemRequestor.beginReporting();
+ }
+ public void endReporting() {
+ if (this.problemRequestor == null) return;
+ this.problemRequestor.endReporting();
+ }
+ public ICompilationUnit getWorkingCopy() {
+ return this.workingCopy;
+ }
+ public boolean isActive() {
+ return this.problemRequestor != null && this.problemRequestor.isActive();
+ }
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("Info for "); //$NON-NLS-1$
+ buffer.append(((JavaElement)workingCopy).toStringWithAncestors());
+ buffer.append("\nUse count = "); //$NON-NLS-1$
+ buffer.append(this.useCount);
+ buffer.append("\nProblem requestor:\n "); //$NON-NLS-1$
+ buffer.append(this.problemRequestor);
+ return buffer.toString();
+ }
+ }
public static boolean VERBOSE = false;
public static boolean CP_RESOLVE_VERBOSE = false;
public static boolean ZIP_ACCESS_VERBOSE = false;
@@ -557,18 +628,17 @@ return null;
* @see org.eclipse.core.runtime.Preferences.IPropertyChangeListener#propertyChange(PropertyChangeEvent)
*/
public void propertyChange(Preferences.PropertyChangeEvent event) {
-
- String propertyName = event.getProperty();
- if (propertyName.startsWith(CP_VARIABLE_PREFERENCES_PREFIX)) {
- String varName = propertyName.substring(CP_VARIABLE_PREFERENCES_PREFIX.length());
- String newValue = (String)event.getNewValue();
- if (newValue != null && !(newValue = newValue.trim()).equals(CP_ENTRY_IGNORE)) {
- Variables.put(varName, new Path(newValue));
- } else {
- Variables.remove(varName);
- }
- }
-// TODO khartlage temp-del
+// TODO : jsurfer temp-del
+// String propertyName = event.getProperty();
+// if (propertyName.startsWith(CP_VARIABLE_PREFERENCES_PREFIX)) {
+// String varName = propertyName.substring(CP_VARIABLE_PREFERENCES_PREFIX.length());
+// String newValue = (String)event.getNewValue();
+// if (newValue != null && !(newValue = newValue.trim()).equals(CP_ENTRY_IGNORE)) {
+// Variables.put(varName, new Path(newValue));
+// } else {
+// Variables.remove(varName);
+// }
+// }
// if (propertyName.startsWith(CP_CONTAINER_PREFERENCES_PREFIX)) {
// recreatePersistedContainer(propertyName, (String)event.getNewValue(), false);
// }
@@ -578,7 +648,7 @@ return null;
/**
* Line separator to use throughout the JavaModel for any source edit operation
*/
- // public static String LINE_SEPARATOR = System.getProperty("line.separator"); //$NON-NLS-1$
+ public static String LINE_SEPARATOR = System.getProperty("line.separator"); //$NON-NLS-1$
/**
* Constructs a new JavaModelManager
*/
@@ -653,7 +723,8 @@ return null;
*/
public void configurePluginDebugOptions(){
if(JavaCore.getPlugin().isDebugging()){
-// TODO khartlage temp-del
+// TODO jsurfer temp-del
+
String option = Platform.getDebugOption(BUILDER_DEBUG);
// if(option != null) JavaBuilder.DEBUG = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
//
@@ -687,15 +758,60 @@ return null;
// option = Platform.getDebugOption(SELECTION_DEBUG);
// if(option != null) SelectionEngine.DEBUG = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
- option = Platform.getDebugOption(SHARED_WC_DEBUG);
- if(option != null) CompilationUnit.SHARED_WC_VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
-
option = Platform.getDebugOption(ZIP_ACCESS_DEBUG);
if(option != null) JavaModelManager.ZIP_ACCESS_VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
}
}
+ /*
+ * Discards the per working copy info for the given working copy (making it a compilation unit)
+ * if its use count was 1. Otherwise, just decrement the use count.
+ * If the working copy is primary, computes the delta between its state and the original compilation unit
+ * and register it.
+ * Close the working copy, its buffer and remove it from the shared working copy table.
+ * Ignore if no per-working copy info existed.
+ * NOTE: it must be synchronized as it may interact with the element info cache (if useCount is decremented to 0), see bug 50667.
+ * Returns the new use count (or -1 if it didn't exist).
+ */
+ public synchronized int discardPerWorkingCopyInfo(CompilationUnit workingCopy) throws JavaModelException {
+ synchronized(perWorkingCopyInfos) {
+ WorkingCopyOwner owner = workingCopy.owner;
+ Map workingCopyToInfos = (Map)this.perWorkingCopyInfos.get(owner);
+ if (workingCopyToInfos == null) return -1;
+
+ PerWorkingCopyInfo info = (PerWorkingCopyInfo)workingCopyToInfos.get(workingCopy);
+ if (info == null) return -1;
+
+ if (--info.useCount == 0) {
+ // create the delta builder (this remembers the current content of the working copy)
+ JavaElementDeltaBuilder deltaBuilder = null;
+ if (workingCopy.isPrimary()) {
+ deltaBuilder = new JavaElementDeltaBuilder(workingCopy);
+ }
+
+ // remove per working copy info
+ workingCopyToInfos.remove(workingCopy);
+ if (workingCopyToInfos.isEmpty()) {
+ this.perWorkingCopyInfos.remove(owner);
+ }
+
+ // remove infos + close buffer (since no longer working copy)
+ removeInfoAndChildren(workingCopy);
+ workingCopy.closeBuffer();
+
+ // compute the delta if needed and register it if there are changes
+ if (deltaBuilder != null) {
+ deltaBuilder.buildDeltas();
+ if ((deltaBuilder.delta != null) && (deltaBuilder.delta.getAffectedChildren().length > 0)) {
+ getDeltaProcessor().registerJavaModelDelta(deltaBuilder.delta);
+ }
+ }
+
+ }
+ return info.useCount;
+ }
+ }
/**
* @see ISaveParticipant
@@ -865,7 +981,9 @@ return null;
}
-
+ public DeltaProcessor getDeltaProcessor() {
+ return this.deltaState.getDeltaProcessor();
+ }
/**
* Returns the set of elements which are out of synch with their buffers.
*/
@@ -934,9 +1052,9 @@ return null;
/**
* Returns the info for the element.
*/
-// public Object getInfo(IJavaElement element) {
-// return this.cache.getInfo(element);
-// }
+ public Object getInfo(IJavaElement element) {
+ return this.cache.getInfo(element);
+ }
/**
* Returns the handle to the active Java Model.
@@ -1003,16 +1121,39 @@ return null;
}
return info;
}
+ /*
+ * Returns the per-working copy info for the given working copy at the given path.
+ * If it doesn't exist and if create, add a new per-working copy info with the given problem requestor.
+ * If recordUsage, increment the per-working copy info's use count.
+ * Returns null if it doesn't exist and not create.
+ */
+ public PerWorkingCopyInfo getPerWorkingCopyInfo(CompilationUnit workingCopy,boolean create, boolean recordUsage, IProblemRequestor problemRequestor) {
+ synchronized(perWorkingCopyInfos) { // use the perWorkingCopyInfo collection as its own lock
+ WorkingCopyOwner owner = workingCopy.owner;
+ Map workingCopyToInfos = (Map)this.perWorkingCopyInfos.get(owner);
+ if (workingCopyToInfos == null && create) {
+ workingCopyToInfos = new HashMap();
+ this.perWorkingCopyInfos.put(owner, workingCopyToInfos);
+ }
+ PerWorkingCopyInfo info = workingCopyToInfos == null ? null : (PerWorkingCopyInfo) workingCopyToInfos.get(workingCopy);
+ if (info == null && create) {
+ info= new PerWorkingCopyInfo(workingCopy, problemRequestor);
+ workingCopyToInfos.put(workingCopy, info);
+ }
+ if (info != null && recordUsage) info.useCount++;
+ return info;
+ }
+ }
/**
* Returns the name of the variables for which an CP variable initializer is registered through an extension point
*/
-// public static String[] getRegisteredVariableNames(){
-//
-// Plugin jdtCorePlugin = JavaCore.getPlugin();
-// if (jdtCorePlugin == null) return null;
-//
-// ArrayList variableList = new ArrayList(5);
+ public static String[] getRegisteredVariableNames(){
+
+ Plugin jdtCorePlugin = JavaCore.getPlugin();
+ if (jdtCorePlugin == null) return null;
+
+ ArrayList variableList = new ArrayList(5);
// IExtensionPoint extension = jdtCorePlugin.getDescriptor().getExtensionPoint(JavaModelManager.CPVARIABLE_INITIALIZER_EXTPOINT_ID);
// if (extension != null) {
// IExtension[] extensions = extension.getExtensions();
@@ -1024,17 +1165,17 @@ return null;
// }
// }
// }
-// String[] variableNames = new String[variableList.size()];
-// variableList.toArray(variableNames);
-// return variableNames;
-// }
+ String[] variableNames = new String[variableList.size()];
+ variableList.toArray(variableNames);
+ return variableNames;
+ }
/**
* Returns the name of the container IDs for which an CP container initializer is registered through an extension point
*/
// public static String[] getRegisteredContainerIDs(){
//
-// Plugin jdtCorePlugin = JavaCore.getPlugin();
+// Plugin jdtCorePlugin = PHPCore.getPlugin();
// if (jdtCorePlugin == null) return null;
//
// ArrayList containerIDList = new ArrayList(5);
@@ -1059,11 +1200,21 @@ return null;
*/
private File getSerializationFile(IProject project) {
if (!project.exists()) return null;
- IPluginDescriptor descr= JavaCore.getJavaCore().getDescriptor();
- IPath workingLocation= project.getPluginWorkingLocation(descr);
+ IPath workingLocation = project.getWorkingLocation(JavaCore.PLUGIN_ID);
return workingLocation.append("state.dat").toFile(); //$NON-NLS-1$
}
-
+ /*
+ * Returns the temporary cache for newly opened elements for the current thread.
+ * Creates it if not already created.
+ */
+ public HashMap getTemporaryCache() {
+ HashMap result = (HashMap)this.temporaryCache.get();
+ if (result == null) {
+ result = new HashMap();
+ this.temporaryCache.set(result);
+ }
+ return result;
+ }
/**
* Returns the open ZipFile at the given location. If the ZipFile
* does not yet exist, it is created, opened, and added to the cache
@@ -1123,11 +1274,16 @@ return null;
}
}
}
-
+ /*
+ * Returns whether there is a temporary cache for the current thread.
+ */
+ public boolean hasTemporaryCache() {
+ return this.temporaryCache.get() != null;
+ }
// public void loadVariablesAndContainers() throws CoreException {
//
// // backward compatibility, consider persistent property
-// QualifiedName qName = new QualifiedName(JavaCore.PLUGIN_ID, "variables"); //$NON-NLS-1$
+// QualifiedName qName = new QualifiedName(PHPCore.PLUGIN_ID, "variables"); //$NON-NLS-1$
// String xmlString = ResourcesPlugin.getWorkspace().getRoot().getPersistentProperty(qName);
//
// try {
@@ -1173,7 +1329,7 @@ return null;
// }
//
// // load variables and containers from preferences into cache
-// Preferences preferences = JavaCore.getPlugin().getPluginPreferences();
+// Preferences preferences = PHPCore.getPlugin().getPluginPreferences();
//
// // only get variable from preferences not set to their default
// String[] propertyNames = preferences.propertyNames();
@@ -1270,19 +1426,48 @@ return null;
* Returns the info for this element without
* disturbing the cache ordering.
*/ // TODO: should be synchronized, could answer unitialized info or if cache is in middle of rehash, could even answer distinct element info
-// protected Object peekAtInfo(IJavaElement element) {
-// return this.cache.peekAtInfo(element);
-// }
+ protected Object peekAtInfo(IJavaElement element) {
+ return this.cache.peekAtInfo(element);
+ }
/**
* @see ISaveParticipant
*/
public void prepareToSave(ISaveContext context) throws CoreException {
}
-// protected void putInfo(IJavaElement element, Object info) {
-// this.cache.putInfo(element, info);
-// }
-
+
+ protected void putInfo(IJavaElement element, Object info) {
+ this.cache.putInfo(element, info);
+ }
+ /*
+ * Puts the infos in the given map (keys are IJavaElements and values are JavaElementInfos)
+ * in the Java model cache in an atomic way.
+ * First checks that the info for the opened element (or one of its ancestors) has not been
+ * added to the cache. If it is the case, another thread has opened the element (or one of
+ * its ancestors). So returns without updating the cache.
+ */
+ protected synchronized void putInfos(IJavaElement openedElement, Map newElements) {
+ // remove children
+ Object existingInfo = this.cache.peekAtInfo(openedElement);
+ if (openedElement instanceof IParent && existingInfo instanceof JavaElementInfo) {
+ IJavaElement[] children = ((JavaElementInfo)existingInfo).getChildren();
+ for (int i = 0, size = children.length; i < size; ++i) {
+ JavaElement child = (JavaElement) children[i];
+ try {
+ child.close();
+ } catch (JavaModelException e) {
+ // ignore
+ }
+ }
+ }
+
+ Iterator iterator = newElements.keySet().iterator();
+ while (iterator.hasNext()) {
+ IJavaElement element = (IJavaElement)iterator.next();
+ Object info = newElements.get(element);
+ this.cache.putInfo(element, info);
+ }
+ }
/**
* Reads the build state for the relevant project.
*/
@@ -1298,11 +1483,10 @@ return null;
String kind= in.readUTF();
if (!kind.equals("STATE")) //$NON-NLS-1$
throw new IOException(Util.bind("build.wrongFileFormat")); //$NON-NLS-1$
-// TODO khartlage temp-del
-// if (in.readBoolean())
-// return JavaBuilder.readState(project, in);
-// if (JavaBuilder.DEBUG)
-// System.out.println("Saved state thinks last build failed for " + project.getName()); //$NON-NLS-1$
+ if (in.readBoolean())
+ return PHPBuilder.readState(project, in);
+ if (PHPBuilder.DEBUG)
+ System.out.println("Saved state thinks last build failed for " + project.getName()); //$NON-NLS-1$
} finally {
in.close();
}
@@ -1409,10 +1593,44 @@ return null;
}
}
-// protected void removeInfo(IJavaElement element) {
-// this.cache.removeInfo(element);
+// PROTECTED VOID REMOVEINFO(IJAVAELEMENT ELEMENT) {
+// THIS.CACHE.REMOVEINFO(ELEMENT);
// }
-
+ /*
+ * Removes all cached info for the given element (including all children)
+ * from the cache.
+ * Returns the info for the given element, or null if it was closed.
+ */
+ public synchronized Object removeInfoAndChildren(JavaElement element) throws JavaModelException {
+ Object info = this.cache.peekAtInfo(element);
+ if (info != null) {
+ boolean wasVerbose = false;
+ try {
+ if (VERBOSE) {
+ System.out.println("CLOSING Element ("+ Thread.currentThread()+"): " + element.toStringWithAncestors()); //$NON-NLS-1$//$NON-NLS-2$
+ wasVerbose = true;
+ VERBOSE = false;
+ }
+ element.closing(info);
+ if (element instanceof IParent && info instanceof JavaElementInfo) {
+ IJavaElement[] children = ((JavaElementInfo)info).getChildren();
+ for (int i = 0, size = children.length; i < size; ++i) {
+ JavaElement child = (JavaElement) children[i];
+ child.close();
+ }
+ }
+ this.cache.removeInfo(element);
+ if (wasVerbose) {
+ System.out.println("-> Package cache size = " + this.cache.pkgSize()); //$NON-NLS-1$
+ System.out.println("-> Openable cache filling ratio = " + NumberFormat.getInstance().format(this.cache.openableFillingRatio()) + "%"); //$NON-NLS-1$//$NON-NLS-2$
+ }
+ } finally {
+ JavaModelManager.VERBOSE = wasVerbose;
+ }
+ return info;
+ }
+ return null;
+ }
public void removePerProjectInfo(JavaProject javaProject) {
synchronized(perProjectInfo) { // use the perProjectInfo collection as its own lock
IProject project = javaProject.getProject();
@@ -1422,7 +1640,12 @@ return null;
}
}
}
-
+ /*
+ * Resets the temporary cache for newly created elements to null.
+ */
+ public void resetTemporaryCache() {
+ this.temporaryCache.set(null);
+ }
/**
* @see ISaveParticipant
*/
@@ -1435,49 +1658,48 @@ return null;
if (context.getKind() == ISaveContext.SNAPSHOT) return;
// save built state
- // TODO khartlage temp-del
-// if (info.triedRead) saveBuiltState(info);
+ if (info.triedRead) saveBuiltState(info);
}
/**
* Saves the built state for the project.
*/
-// private void saveBuiltState(PerProjectInfo info) throws CoreException {
-// if (JavaBuilder.DEBUG)
-// System.out.println(Util.bind("build.saveStateProgress", info.project.getName())); //$NON-NLS-1$
-// File file = getSerializationFile(info.project);
-// if (file == null) return;
-// long t = System.currentTimeMillis();
-// try {
-// DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
-// try {
-// out.writeUTF(JavaCore.PLUGIN_ID);
-// out.writeUTF("STATE"); //$NON-NLS-1$
-// if (info.savedState == null) {
-// out.writeBoolean(false);
-// } else {
-// out.writeBoolean(true);
-// JavaBuilder.writeState(info.savedState, out);
-// }
-// } finally {
-// out.close();
-// }
-// } catch (RuntimeException e) {
-// try {file.delete();} catch(SecurityException se) {}
-// throw new CoreException(
-// new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, Platform.PLUGIN_ERROR,
-// Util.bind("build.cannotSaveState", info.project.getName()), e)); //$NON-NLS-1$
-// } catch (IOException e) {
-// try {file.delete();} catch(SecurityException se) {}
-// throw new CoreException(
-// new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, Platform.PLUGIN_ERROR,
-// Util.bind("build.cannotSaveState", info.project.getName()), e)); //$NON-NLS-1$
-// }
-// if (JavaBuilder.DEBUG) {
-// t = System.currentTimeMillis() - t;
-// System.out.println(Util.bind("build.saveStateComplete", String.valueOf(t))); //$NON-NLS-1$
-// }
-// }
+ private void saveBuiltState(PerProjectInfo info) throws CoreException {
+ if (PHPBuilder.DEBUG)
+ System.out.println(Util.bind("build.saveStateProgress", info.project.getName())); //$NON-NLS-1$
+ File file = getSerializationFile(info.project);
+ if (file == null) return;
+ long t = System.currentTimeMillis();
+ try {
+ DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
+ try {
+ out.writeUTF(JavaCore.PLUGIN_ID);
+ out.writeUTF("STATE"); //$NON-NLS-1$
+ if (info.savedState == null) {
+ out.writeBoolean(false);
+ } else {
+ out.writeBoolean(true);
+ PHPBuilder.writeState(info.savedState, out);
+ }
+ } finally {
+ out.close();
+ }
+ } catch (RuntimeException e) {
+ try {file.delete();} catch(SecurityException se) {}
+ throw new CoreException(
+ new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, Platform.PLUGIN_ERROR,
+ Util.bind("build.cannotSaveState", info.project.getName()), e)); //$NON-NLS-1$
+ } catch (IOException e) {
+ try {file.delete();} catch(SecurityException se) {}
+ throw new CoreException(
+ new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, Platform.PLUGIN_ERROR,
+ Util.bind("build.cannotSaveState", info.project.getName()), e)); //$NON-NLS-1$
+ }
+ if (PHPBuilder.DEBUG) {
+ t = System.currentTimeMillis() - t;
+ System.out.println(Util.bind("build.saveStateComplete", String.valueOf(t))); //$NON-NLS-1$
+ }
+ }
/**
* @see ISaveParticipant
@@ -1587,14 +1809,14 @@ return null;
// if (this.deltaProcessor.indexManager != null){ // no more indexing
// this.deltaProcessor.indexManager.shutdown();
// }
-// try {
-// IJavaModel model = this.getJavaModel();
-// if (model != null) {
+ try {
+ IJavaModel model = this.getJavaModel();
+ if (model != null) {
-// model.close();
-// }
-// } catch (JavaModelException e) {
-// }
+ model.close();
+ }
+ } catch (JavaModelException e) {
+ }
}
/**
@@ -1666,4 +1888,30 @@ return null;
preferences.setValue(variableKey, variableString);
JavaCore.getPlugin().savePluginPreferences();
}
+ /*
+ * Returns all the working copies which have the given owner.
+ * Adds the working copies of the primary owner if specified.
+ * Returns null if it has none.
+ */
+ public ICompilationUnit[] getWorkingCopies(WorkingCopyOwner owner, boolean addPrimary) {
+ synchronized(perWorkingCopyInfos) {
+ ICompilationUnit[] primaryWCs = addPrimary && owner != DefaultWorkingCopyOwner.PRIMARY
+ ? getWorkingCopies(DefaultWorkingCopyOwner.PRIMARY, false)
+ : null;
+ Map workingCopyToInfos = (Map)perWorkingCopyInfos.get(owner);
+ if (workingCopyToInfos == null) return primaryWCs;
+ int primaryLength = primaryWCs == null ? 0 : primaryWCs.length;
+ int size = workingCopyToInfos.size(); // note size is > 0 otherwise pathToPerWorkingCopyInfos would be null
+ ICompilationUnit[] result = new ICompilationUnit[primaryLength + size];
+ if (primaryWCs != null) {
+ System.arraycopy(primaryWCs, 0, result, 0, primaryLength);
+ }
+ Iterator iterator = workingCopyToInfos.values().iterator();
+ int index = primaryLength;
+ while(iterator.hasNext()) {
+ result[index++] = ((JavaModelManager.PerWorkingCopyInfo)iterator.next()).getWorkingCopy();
+ }
+ return result;
+ }
+ }
}