View | Details | Raw Unified | Return to bug 103839
Collapse All | Expand All

(-)model/org/eclipse/jdt/internal/core/JavaModelManager.java (-4 / +490 lines)
Lines 11-17 Link Here
11
package org.eclipse.jdt.internal.core;
11
package org.eclipse.jdt.internal.core;
12
12
13
import java.io.*;
13
import java.io.*;
14
import java.text.MessageFormat;
14
import java.util.*;
15
import java.util.*;
16
import java.util.Map.Entry;
15
import java.util.zip.ZipFile;
17
import java.util.zip.ZipFile;
16
18
17
import javax.xml.parsers.DocumentBuilder;
19
import javax.xml.parsers.DocumentBuilder;
Lines 104-110 Link Here
104
	public final static String CP_ENTRY_IGNORE = "##<cp entry ignore>##"; //$NON-NLS-1$
106
	public final static String CP_ENTRY_IGNORE = "##<cp entry ignore>##"; //$NON-NLS-1$
105
	public final static IPath CP_ENTRY_IGNORE_PATH = new Path(CP_ENTRY_IGNORE);
107
	public final static IPath CP_ENTRY_IGNORE_PATH = new Path(CP_ENTRY_IGNORE);
106
	
108
	
107
	private final static int VARIABLES_AND_CONTAINERS_FILE_VERSION = 1;
109
	private final static int VARIABLES_AND_CONTAINERS_FILE_VERSION = 2;
108
110
109
	/**
111
	/**
110
	 * Name of the extension point for contributing classpath variable initializers
112
	 * Name of the extension point for contributing classpath variable initializers
Lines 1930-1937 Link Here
1930
		DataInputStream in = null;
1932
		DataInputStream in = null;
1931
		try {
1933
		try {
1932
			in = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
1934
			in = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
1933
			if (VARIABLES_AND_CONTAINERS_FILE_VERSION == in.readInt()) {
1935
			switch (in.readInt())
1934
				
1936
			{
1937
			  case 2 :
1938
				new VariablesAndContainersLoadHelper(in).load();
1939
				break;
1940
			  case 1 : // backward compatibility, load old format
1935
				// variables
1941
				// variables
1936
				int size = in.readInt();
1942
				int size = in.readInt();
1937
				while (size-- > 0) {
1943
				while (size-- > 0) {
Lines 1986-1991 Link Here
1986
		containersReset(getRegisteredContainerIDs());
1992
		containersReset(getRegisteredContainerIDs());
1987
	}
1993
	}
1988
1994
1995
	private static final class PersistedClasspathContainer implements
1996
			IClasspathContainer {
1997
1998
		private final IPath containerPath;
1999
2000
		private final IClasspathEntry[] entries;
2001
2002
		private final IJavaProject project;
2003
2004
		PersistedClasspathContainer(IJavaProject project, IPath containerPath,
2005
				IClasspathEntry[] entries) {
2006
			super();
2007
			this.containerPath = containerPath;
2008
			this.entries = entries;
2009
			this.project = project;
2010
		}
2011
2012
		public IClasspathEntry[] getClasspathEntries() {
2013
			return entries;
2014
		}
2015
2016
		public String getDescription() {
2017
			return "Persisted container [" + containerPath //$NON-NLS-1$
2018
					+ " for project [" + project.getElementName() //$NON-NLS-1$
2019
					+ "]]"; //$NON-NLS-1$  
2020
		}
2021
2022
		public int getKind() {
2023
			return 0;
2024
		}
2025
2026
		public IPath getPath() {
2027
			return containerPath;
2028
		}
2029
2030
		public String toString() {
2031
			return getDescription();
2032
		}
2033
	}
2034
2035
	private final class VariablesAndContainersLoadHelper {
2036
2037
		private static final int ArrayIncrement = 200;
2038
2039
		private IClasspathEntry[] allClasspathEntries;
2040
		private int allClasspathEntryCount;
2041
2042
		private final Map allPaths; // String -> IPath
2043
2044
		private String[] allStrings;
2045
		private int allStringsCount;
2046
2047
		private final DataInputStream in;
2048
2049
		VariablesAndContainersLoadHelper(DataInputStream in) {
2050
			super();
2051
			this.allClasspathEntries = null;
2052
			this.allClasspathEntryCount = 0;
2053
			this.allPaths = new HashMap();
2054
			this.allStrings = null;
2055
			this.allStringsCount = 0;
2056
			this.in = in;
2057
		}
2058
2059
		void load() throws IOException {
2060
			loadProjects(JavaModelManager.this.getJavaModel());
2061
			loadVariables();
2062
		}
2063
2064
		private IAccessRule loadAccessRule() throws IOException {
2065
			int kind = loadInt();
2066
			IPath pattern = loadPath();
2067
2068
			return new ClasspathAccessRule(pattern, kind);
2069
		}
2070
2071
		private IAccessRule[] loadAccessRules() throws IOException {
2072
			int count = loadInt();
2073
2074
			if (count == 0)
2075
				return ClasspathEntry.NO_ACCESS_RULES;
2076
2077
			IAccessRule[] rules = new IAccessRule[count];
2078
2079
			for (int i = 0; i < count; ++i)
2080
				rules[i] = loadAccessRule();
2081
2082
			return rules;
2083
		}
2084
2085
		private IClasspathAttribute loadAttribute() throws IOException {
2086
			String name = loadString();
2087
			String value = loadString();
2088
2089
			return new ClasspathAttribute(name, value);
2090
		}
2091
2092
		private IClasspathAttribute[] loadAttributes() throws IOException {
2093
			int count = loadInt();
2094
2095
			if (count == 0)
2096
				return ClasspathEntry.NO_EXTRA_ATTRIBUTES;
2097
2098
			IClasspathAttribute[] attributes = new IClasspathAttribute[count];
2099
2100
			for (int i = 0; i < count; ++i)
2101
				attributes[i] = loadAttribute();
2102
2103
			return attributes;
2104
		}
2105
2106
		private boolean loadBoolean() throws IOException {
2107
			return in.readBoolean();
2108
		}
2109
2110
		private IClasspathEntry[] loadClasspathEntries() throws IOException {
2111
			int count = loadInt();
2112
			IClasspathEntry[] entries = new IClasspathEntry[count];
2113
2114
			for (int i = 0; i < count; ++i)
2115
				entries[i] = loadClasspathEntry();
2116
2117
			return entries;
2118
		}
2119
2120
		private IClasspathEntry loadClasspathEntry() throws IOException {
2121
			int id = loadInt();
2122
2123
			if (id < 0 || id > allClasspathEntryCount)
2124
				throw new IOException("Unexpected classpathentry id"); //$NON-NLS-1$
2125
2126
			if (id < allClasspathEntryCount)
2127
				return allClasspathEntries[id];
2128
2129
			int contentKind = loadInt();
2130
			int entryKind = loadInt();
2131
			IPath path = loadPath();
2132
			IPath[] inclusionPatterns = loadPaths();
2133
			IPath[] exclusionPatterns = loadPaths();
2134
			IPath sourceAttachmentPath = loadPath();
2135
			IPath sourceAttachmentRootPath = loadPath();
2136
			IPath specificOutputLocation = loadPath();
2137
			boolean isExported = loadBoolean();
2138
			IAccessRule[] accessRules = loadAccessRules();
2139
			boolean combineAccessRules = loadBoolean();
2140
			IClasspathAttribute[] extraAttributes = loadAttributes();
2141
2142
			IClasspathEntry entry = new ClasspathEntry(contentKind, entryKind,
2143
					path, inclusionPatterns, exclusionPatterns,
2144
					sourceAttachmentPath, sourceAttachmentRootPath,
2145
					specificOutputLocation, isExported, accessRules,
2146
					combineAccessRules, extraAttributes);
2147
2148
			IClasspathEntry[] array = allClasspathEntries;
2149
2150
			if (array == null || id == array.length) {
2151
				array = new IClasspathEntry[id + ArrayIncrement];
2152
2153
				if (id != 0)
2154
					System.arraycopy(allClasspathEntries, 0, array, 0, id);
2155
2156
				allClasspathEntries = array;
2157
			}
2158
2159
			array[id] = entry;
2160
			allClasspathEntryCount = id + 1;
2161
2162
			return entry;
2163
		}
2164
2165
		private void loadContainers(IJavaProject project) throws IOException {
2166
			int count = loadInt();
2167
2168
			for (int i = 0; i < count; ++i) {
2169
				IPath path = loadPath();
2170
				IClasspathEntry[] entries = loadClasspathEntries();
2171
				IClasspathContainer container = new PersistedClasspathContainer(
2172
						project, path, entries);
2173
2174
				JavaModelManager.this.containerPut(project, path, container);
2175
2176
				Map oldContainers = (Map) JavaModelManager.this.previousSessionContainers
2177
						.get(project);
2178
2179
				if (oldContainers == null) {
2180
					oldContainers = new HashMap();
2181
					JavaModelManager.this.previousSessionContainers.put(project,
2182
							oldContainers);
2183
				}
2184
2185
				oldContainers.put(path, container);
2186
			}
2187
		}
2188
2189
		private int loadInt() throws IOException {
2190
			return in.readInt();
2191
		}
2192
2193
		private IPath loadPath() throws IOException {
2194
			if (loadBoolean())
2195
				return null;
2196
2197
			String portableString = loadString();
2198
			IPath path = (IPath) allPaths.get(portableString);
2199
2200
			if (path == null) {
2201
				path = Path.fromPortableString(portableString);
2202
				allPaths.put(portableString, path);
2203
			}
2204
2205
			return path;
2206
		}
2207
2208
		private IPath[] loadPaths() throws IOException {
2209
			int count = loadInt();
2210
			IPath[] pathArray = new IPath[count];
2211
2212
			for (int i = 0; i < count; ++i)
2213
				pathArray[i] = loadPath();
2214
2215
			return pathArray;
2216
		}
2217
2218
		private void loadProjects(IJavaModel model) throws IOException {
2219
			int count = loadInt();
2220
2221
			for (int i = 0; i < count; ++i) {
2222
				String projectName = loadString();
2223
2224
				loadContainers(model.getJavaProject(projectName));
2225
			}
2226
		}
2227
2228
		private String loadString() throws IOException {
2229
			int id = loadInt();
2230
2231
			if (id < 0 || id > allStringsCount)
2232
				throw new IOException("Unexpected string id"); //$NON-NLS-1$
2233
2234
			if (id < allStringsCount)
2235
				return allStrings[id];
2236
2237
			String string = in.readUTF();
2238
			String[] array = allStrings;
2239
2240
			if (array == null || id == array.length) {
2241
				array = new String[id + ArrayIncrement];
2242
2243
				if (id != 0)
2244
					System.arraycopy(allStrings, 0, array, 0, id);
2245
2246
				allStrings = array;
2247
			}
2248
2249
			array[id] = string;
2250
			allStringsCount = id + 1;
2251
2252
			return string;
2253
		}
2254
2255
		private void loadVariables() throws IOException {
2256
			int size = loadInt();
2257
			Map loadedVars = new HashMap(size);
2258
2259
			for (int i = 0; i < size; ++i) {
2260
				String varName = loadString();
2261
				IPath varPath = loadPath();
2262
2263
				if (varPath != null)
2264
					loadedVars.put(varName, varPath);
2265
			}
2266
2267
			JavaModelManager.this.previousSessionVariables.putAll(loadedVars);
2268
			JavaModelManager.this.variables.putAll(loadedVars);
2269
		}
2270
	}
2271
1989
	/**
2272
	/**
1990
	 *  Returns the info for this element without
2273
	 *  Returns the info for this element without
1991
	 *  disturbing the cache ordering.
2274
	 *  disturbing the cache ordering.
Lines 2324-2329 Link Here
2324
		try {
2607
		try {
2325
			out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
2608
			out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
2326
			out.writeInt(VARIABLES_AND_CONTAINERS_FILE_VERSION);
2609
			out.writeInt(VARIABLES_AND_CONTAINERS_FILE_VERSION);
2610
			if (VARIABLES_AND_CONTAINERS_FILE_VERSION == 2)
2611
				new VariablesAndContainersSaveHelper(out).save();
2612
			else if (VARIABLES_AND_CONTAINERS_FILE_VERSION == 1) {
2613
				// old code retained for performance comparisons
2327
			
2614
			
2328
			// variables
2615
			// variables
2329
			out.writeInt(this.variables.size());
2616
			out.writeInt(this.variables.size());
Lines 2384-2390 Link Here
2384
					out.writeBytes(containerString);
2671
					out.writeBytes(containerString);
2385
				}
2672
				}
2386
			}
2673
			}
2387
			
2674
			}
2388
		} catch (IOException e) {
2675
		} catch (IOException e) {
2389
			IStatus status = new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, IStatus.ERROR, "Problems while saving variables and containers", e); //$NON-NLS-1$
2676
			IStatus status = new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, IStatus.ERROR, "Problems while saving variables and containers", e); //$NON-NLS-1$
2390
			throw new CoreException(status);
2677
			throw new CoreException(status);
Lines 2399-2411 Link Here
2399
		}
2686
		}
2400
	}
2687
	}
2401
	
2688
	
2689
	private final class VariablesAndContainersSaveHelper {
2690
2691
		private final Map classpathEntryIds; // IClasspathEntry -> Integer
2692
		private final DataOutputStream out;
2693
		private final Map stringIds; // Strings -> Integer
2694
2695
		VariablesAndContainersSaveHelper(DataOutputStream out) {
2696
			super();
2697
			this.classpathEntryIds = new HashMap();
2698
			this.out = out;
2699
			this.stringIds = new HashMap();
2700
		}
2701
2702
		void save() throws IOException, JavaModelException {
2703
			saveProjects(JavaModelManager.this.getJavaModel().getJavaProjects());
2704
			saveVariables(JavaModelManager.this.variables);
2705
		}
2706
2707
		private void saveAccessRule(IAccessRule rule) throws IOException {
2708
			saveInt(rule.getKind());
2709
			savePath(rule.getPattern());
2710
		}
2711
2712
		private void saveAccessRules(IAccessRule[] rules) throws IOException {
2713
			int count = rules == null ? 0 : rules.length;
2714
2715
			saveInt(count);
2716
			for (int i = 0; i < count; ++i)
2717
				saveAccessRule(rules[i]);
2718
		}
2719
2720
		private void saveAttribute(IClasspathAttribute attribute)
2721
				throws IOException {
2722
			saveString(attribute.getName());
2723
			saveString(attribute.getValue());
2724
		}
2725
2726
		private void saveAttributes(IClasspathAttribute[] attributes)
2727
				throws IOException {
2728
			int count = attributes == null ? 0 : attributes.length;
2729
2730
			saveInt(count);
2731
			for (int i = 0; i < count; ++i)
2732
				saveAttribute(attributes[i]);
2733
		}
2734
2735
		private void saveClasspathEntries(IClasspathEntry[] entries)
2736
				throws IOException {
2737
			int count = entries == null ? 0 : entries.length;
2738
2739
			saveInt(count);
2740
			for (int i = 0; i < count; ++i)
2741
				saveClasspathEntry(entries[i]);
2742
		}
2743
2744
		private void saveClasspathEntry(IClasspathEntry entry)
2745
				throws IOException {
2746
			if (saveNewId(entry, classpathEntryIds)) {
2747
				saveInt(entry.getContentKind());
2748
				saveInt(entry.getEntryKind());
2749
				savePath(entry.getPath());
2750
				savePaths(entry.getInclusionPatterns());
2751
				savePaths(entry.getExclusionPatterns());
2752
				savePath(entry.getSourceAttachmentPath());
2753
				savePath(entry.getSourceAttachmentRootPath());
2754
				savePath(entry.getOutputLocation());
2755
				out.writeBoolean(entry.isExported());
2756
				saveAccessRules(entry.getAccessRules());
2757
				out.writeBoolean(entry.combineAccessRules());
2758
				saveAttributes(entry.getExtraAttributes());
2759
			}
2760
		}
2761
2762
		private void saveContainers(IJavaProject project, Map containerMap)
2763
				throws IOException {
2764
			saveInt(containerMap.size());
2765
2766
			for (Iterator i = containerMap.entrySet().iterator(); i.hasNext();) {
2767
				Entry entry = (Entry) i.next();
2768
				IPath path = (IPath) entry.getKey();
2769
				IClasspathContainer container = (IClasspathContainer) entry
2770
						.getValue();
2771
				IClasspathEntry[] cpEntries = null;
2772
2773
				if (container == null) {
2774
					// container has not been initialized yet, use previous
2775
					// session value
2776
					// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=73969)
2777
					container = JavaModelManager.this.getPreviousSessionContainer(path,
2778
							project);
2779
				}
2780
2781
				if (container != null)
2782
					cpEntries = container.getClasspathEntries();
2783
2784
				savePath(path);
2785
				saveClasspathEntries(cpEntries);
2786
			}
2787
		}
2788
2789
		private void saveInt(int value) throws IOException {
2790
			out.writeInt(value);
2791
		}
2792
2793
		private boolean saveNewId(Object key, Map map) throws IOException {
2794
			Integer id = (Integer) map.get(key);
2795
2796
			if (id == null) {
2797
				int newId = map.size();
2798
2799
				map.put(key, new Integer(newId));
2800
2801
				saveInt(newId);
2802
2803
				return true;
2804
			} else {
2805
				saveInt(id.intValue());
2806
2807
				return false;
2808
			}
2809
		}
2810
2811
		private void savePath(IPath path) throws IOException {
2812
			if (path == null) {
2813
				out.writeBoolean(true);
2814
			} else {
2815
				out.writeBoolean(false);
2816
				saveString(path.toPortableString());
2817
			}
2818
		}
2819
2820
		private void savePaths(IPath[] paths) throws IOException {
2821
			int count = paths == null ? 0 : paths.length;
2822
2823
			saveInt(count);
2824
			for (int i = 0; i < count; ++i)
2825
				savePath(paths[i]);
2826
		}
2827
2828
		private void saveProjects(IJavaProject[] projects) throws IOException,
2829
				JavaModelException {
2830
			int count = projects.length;
2831
2832
			saveInt(count);
2833
2834
			for (int i = 0; i < count; ++i) {
2835
				IJavaProject project = projects[i];
2836
2837
				saveString(project.getElementName());
2838
2839
				Map containerMap = (Map) JavaModelManager.this.containers.get(project);
2840
2841
				if (containerMap == null) {
2842
					containerMap = Collections.EMPTY_MAP;
2843
				} else {
2844
					// clone while iterating
2845
					// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=59638)
2846
					containerMap = new HashMap(containerMap);
2847
				}
2848
2849
				saveContainers(project, containerMap);
2850
			}
2851
		}
2852
2853
		private void saveString(String string) throws IOException {
2854
			if (saveNewId(string, stringIds))
2855
				out.writeUTF(string);
2856
		}
2857
2858
		private void saveVariables(Map map) throws IOException {
2859
			saveInt(map.size());
2860
2861
			for (Iterator i = map.entrySet().iterator(); i.hasNext();) {
2862
				Entry entry = (Entry) i.next();
2863
				String varName = (String) entry.getKey();
2864
				IPath varPath = (IPath) entry.getValue();
2865
2866
				saveString(varName);
2867
				savePath(varPath);
2868
			}
2869
		}
2870
	}
2871
2872
	private void traceVariableAndContainers(String action, long start) {
2873
		if (!VERBOSE)
2874
			return;
2875
2876
		Long delta = new Long(System.currentTimeMillis() - start);
2877
		Long length = new Long(getVariableAndContainersFile().length());
2878
		String pattern = "{0} {1} bytes in variablesAndContainers.dat in {2}ms"; //$NON-NLS-1$
2879
		String message = MessageFormat.format(pattern, new Object[]{action, length, delta});
2880
2881
		System.out.println(message);
2882
	}
2883
2402
	/**
2884
	/**
2403
	 * @see ISaveParticipant
2885
	 * @see ISaveParticipant
2404
	 */
2886
	 */
2405
	public void saving(ISaveContext context) throws CoreException {
2887
	public void saving(ISaveContext context) throws CoreException {
2406
		
2888
		
2407
	    // save variable and container values on snapshot/full save
2889
	    // save variable and container values on snapshot/full save
2890
		long start = System.currentTimeMillis();
2408
		saveVariablesAndContainers();
2891
		saveVariablesAndContainers();
2892
		traceVariableAndContainers("Saved", start); //$NON-NLS-1$
2409
		
2893
		
2410
		if (context.getKind() == ISaveContext.FULL_SAVE) {
2894
		if (context.getKind() == ISaveContext.FULL_SAVE) {
2411
			// will need delta since this save (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=38658)
2895
			// will need delta since this save (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=38658)
Lines 2589-2595 Link Here
2589
			JavaCore.getPlugin().getPluginPreferences().addPropertyChangeListener(propertyListener);
3073
			JavaCore.getPlugin().getPluginPreferences().addPropertyChangeListener(propertyListener);
2590
3074
2591
			// retrieve variable values
3075
			// retrieve variable values
3076
			long start = System.currentTimeMillis();
2592
			loadVariablesAndContainers();
3077
			loadVariablesAndContainers();
3078
			traceVariableAndContainers("Loaded", start); //$NON-NLS-1$
2593
3079
2594
			final IWorkspace workspace = ResourcesPlugin.getWorkspace();
3080
			final IWorkspace workspace = ResourcesPlugin.getWorkspace();
2595
			workspace.addResourceChangeListener(
3081
			workspace.addResourceChangeListener(

Return to bug 103839