View | Details | Raw Unified | Return to bug 303511 | Differences between
and this patch

Collapse All | Expand All

(-)model/org/eclipse/jdt/internal/core/SourceMapper.java (-10 / +39 lines)
Lines 27-32 Link Here
27
import org.eclipse.core.resources.IContainer;
27
import org.eclipse.core.resources.IContainer;
28
import org.eclipse.core.resources.IFile;
28
import org.eclipse.core.resources.IFile;
29
import org.eclipse.core.resources.IFolder;
29
import org.eclipse.core.resources.IFolder;
30
import org.eclipse.core.resources.IProject;
30
import org.eclipse.core.resources.IResource;
31
import org.eclipse.core.resources.IResource;
31
import org.eclipse.core.resources.ResourcesPlugin;
32
import org.eclipse.core.resources.ResourcesPlugin;
32
import org.eclipse.core.runtime.CoreException;
33
import org.eclipse.core.runtime.CoreException;
Lines 868-879 Link Here
868
869
869
		char[] source = null;
870
		char[] source = null;
870
871
872
		IProject project = pkgFrag.getPackageFragmentRoot().getJavaProject().getProject();
871
		JavaModelManager javaModelManager = JavaModelManager.getJavaModelManager();
873
		JavaModelManager javaModelManager = JavaModelManager.getJavaModelManager();
872
		try {
874
		try {
873
			javaModelManager.cacheZipFiles(this); // Cache any zip files we open during this operation
875
			javaModelManager.cacheZipFiles(this); // Cache any zip files we open during this operation
874
876
875
			if (this.rootPath != null) {
877
			if (this.rootPath != null) {
876
				source = getSourceForRootPath(this.rootPath, name);
878
				source = getSourceForRootPath(this.rootPath, name, project);
877
			}
879
			}
878
	
880
	
879
			if (source == null) {
881
			if (source == null) {
Lines 882-888 Link Here
882
					loop: for (Iterator iterator = this.rootPaths.iterator(); iterator.hasNext(); ) {
884
					loop: for (Iterator iterator = this.rootPaths.iterator(); iterator.hasNext(); ) {
883
						String currentRootPath = (String) iterator.next();
885
						String currentRootPath = (String) iterator.next();
884
						if (!currentRootPath.equals(this.rootPath)) {
886
						if (!currentRootPath.equals(this.rootPath)) {
885
							source = getSourceForRootPath(currentRootPath, name);
887
							source = getSourceForRootPath(currentRootPath, name, project);
886
							if (source != null) {
888
							if (source != null) {
887
								// remember right root path
889
								// remember right root path
888
								this.rootPath = currentRootPath;
890
								this.rootPath = currentRootPath;
Lines 901-907 Link Here
901
		return source;
903
		return source;
902
	}
904
	}
903
905
904
	private char[] getSourceForRootPath(String currentRootPath, String name) {
906
	private char[] getSourceForRootPath(String currentRootPath, String name, IProject project) {
905
		String newFullName;
907
		String newFullName;
906
		if (!currentRootPath.equals(IPackageFragmentRoot.DEFAULT_PACKAGEROOT_PATH)) {
908
		if (!currentRootPath.equals(IPackageFragmentRoot.DEFAULT_PACKAGEROOT_PATH)) {
907
			if (currentRootPath.endsWith("/")) { //$NON-NLS-1$
909
			if (currentRootPath.endsWith("/")) { //$NON-NLS-1$
Lines 912-933 Link Here
912
		} else {
914
		} else {
913
			newFullName = name;
915
			newFullName = name;
914
		}
916
		}
915
		return this.findSource(newFullName);
917
		return this.findSource(newFullName, project);
916
	}
918
	}
917
919
918
	public char[] findSource(String fullName) {
920
	public char[] findSource(String fullName, IProject project) {
919
		char[] source = null;
921
		char[] source = null;
920
		Object target = JavaModel.getTarget(this.sourcePath, true);
922
		Object target = JavaModel.getTarget(this.sourcePath, true);
923
		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=303511
924
		// Use the character encoding set by the user than the default one
925
		String charSet = null;
921
		if (target instanceof IContainer) {
926
		if (target instanceof IContainer) {
927
			// For external folders, get use the project's encoding
928
			if (project != null && ExternalFoldersManager.isInternalPathForExternalFolder(((IContainer)target).getFullPath())) {
929
				try {
930
					charSet = project.getDefaultCharset();
931
				} catch (CoreException e) {
932
					// Proceed with null encoding
933
				}
934
			}
922
			IResource res = ((IContainer)target).findMember(fullName);
935
			IResource res = ((IContainer)target).findMember(fullName);
923
			if (res instanceof IFile) {
936
			if (res instanceof IFile) {
924
				try {
937
				try {
925
					source = org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray((IFile)res);
938
					if (charSet == null)
939
						source = org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray((IFile)res);
940
					else 
941
						source = org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray((IFile)res, charSet);
926
				} catch (JavaModelException e) {
942
				} catch (JavaModelException e) {
927
					// ignore
943
					// ignore
928
				}
944
				}
929
			}
945
			}
930
		} else {
946
		} else {
947
			try {
948
				// If the archive (IResource) is available from the workspace, use it's encoding
949
				// Else take it from the project
950
				if (target instanceof IFile)
951
					charSet = ((IFile)target).getCharset();
952
				else if (project != null)
953
					charSet = project.getDefaultCharset();
954
			} catch (CoreException e) {
955
				// Ignore
956
			}
957
			
931
			// try to get the entry
958
			// try to get the entry
932
			ZipEntry entry = null;
959
			ZipEntry entry = null;
933
			ZipFile zip = null;
960
			ZipFile zip = null;
Lines 937-943 Link Here
937
				entry = zip.getEntry(fullName);
964
				entry = zip.getEntry(fullName);
938
				if (entry != null) {
965
				if (entry != null) {
939
					// now read the source code
966
					// now read the source code
940
					source = readSource(entry, zip);
967
					source = readSource(entry, zip, charSet);
941
				}
968
				}
942
			} catch (CoreException e) {
969
			} catch (CoreException e) {
943
				return null;
970
				return null;
Lines 948-954 Link Here
948
		return source;
975
		return source;
949
	}
976
	}
950
977
951
978
	public char[] findSource(String fullName) {
979
		return findSource(fullName, null);
980
	}
952
981
953
	/**
982
	/**
954
	 * Returns the SourceRange for the name of the given element, or
983
	 * Returns the SourceRange for the name of the given element, or
Lines 1275-1285 Link Here
1275
			this.typeDepth = -1;
1304
			this.typeDepth = -1;
1276
		}
1305
		}
1277
	}
1306
	}
1278
	private char[] readSource(ZipEntry entry, ZipFile zip) {
1307
	private char[] readSource(ZipEntry entry, ZipFile zip, String charSet) {
1279
		try {
1308
		try {
1280
			byte[] bytes = Util.getZipEntryByteContent(entry, zip);
1309
			byte[] bytes = Util.getZipEntryByteContent(entry, zip);
1281
			if (bytes != null) {
1310
			if (bytes != null) {
1282
				return Util.bytesToChar(bytes, this.encoding);
1311
				return Util.bytesToChar(bytes, charSet == null ? this.encoding : charSet);
1283
			}
1312
			}
1284
		} catch (IOException e) {
1313
		} catch (IOException e) {
1285
			// ignore
1314
			// ignore
(-)src/org/eclipse/jdt/core/tests/model/EncodingTests.java (+109 lines)
Lines 24-32 Link Here
24
import org.eclipse.core.runtime.CoreException;
24
import org.eclipse.core.runtime.CoreException;
25
import org.eclipse.core.runtime.IProgressMonitor;
25
import org.eclipse.core.runtime.IProgressMonitor;
26
import org.eclipse.core.runtime.NullProgressMonitor;
26
import org.eclipse.core.runtime.NullProgressMonitor;
27
import org.eclipse.core.runtime.Path;
27
import org.eclipse.core.runtime.content.IContentDescription;
28
import org.eclipse.core.runtime.content.IContentDescription;
28
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
29
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
29
import org.eclipse.core.runtime.preferences.InstanceScope;
30
import org.eclipse.core.runtime.preferences.InstanceScope;
31
import org.eclipse.jdt.core.IClasspathEntry;
30
import org.eclipse.jdt.core.ICompilationUnit;
32
import org.eclipse.jdt.core.ICompilationUnit;
31
import org.eclipse.jdt.core.IJavaProject;
33
import org.eclipse.jdt.core.IJavaProject;
32
import org.eclipse.jdt.core.IOpenable;
34
import org.eclipse.jdt.core.IOpenable;
Lines 929-934 Link Here
929
			preferences.flush();
931
			preferences.flush();
930
		}
932
		}
931
	}
933
	}
934
	
935
	/**
936
	 * Bug 303511: Allow to specify encoding for source attachments
937
	 * Test whether the source mapper picks the right encoding for the source attachment as a ZIP in workspace.
938
	 * The encoding could be explicitly set or inherited from the project.
939
	 *
940
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=303511"
941
	 */
942
	public void testBug303511() throws JavaModelException, CoreException {
943
944
		// Set file encoding
945
		String encoding = "Shift-JIS";
946
		IFile zipFile = (IFile) this.encodingProject.findMember("testShiftJIS.zip"); //$NON-NLS-1$
947
		IFile sourceFile = (IFile) this.encodingProject.findMember("src/testShiftJIS/A.java");
948
		
949
		assertNotNull("Cannot find class file!", zipFile);
950
		zipFile.setCharset(encoding, null);
951
952
		// Get class file and compare source (should not be the same as modify charset on zip file has no effect...)
953
		IPackageFragmentRoot root = getPackageFragmentRoot("Encoding", "testShiftJIS.jar");
954
		ISourceReference sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class");
955
		assertNotNull(sourceRef);
956
		String source = sourceRef.getSource();
957
		assertNotNull(source);
958
		String encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding));
959
		assertTrue("Sources should be decoded the same way", encodedContents.equals(source));
960
961
		// Reset zip file encoding
962
		zipFile.setCharset(null, null);
963
		String oldEncoding = this.encodingProject.getDefaultCharset();
964
		this.encodingProject.setDefaultCharset(encoding, null);
965
966
		root = getPackageFragmentRoot("Encoding", "testShiftJIS.jar");
967
		sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class");
968
		assertNotNull(sourceRef);
969
		source = sourceRef.getSource();
970
		assertNotNull(source);
971
		encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding));
972
		assertTrue("Sources should be decoded the same way", encodedContents.equals(source));
973
974
		// Reset zip file encoding
975
		zipFile.setCharset(null, null);
976
		this.encodingProject.setDefaultCharset(oldEncoding, null);
977
	}
978
979
	/**
980
	 * Bug 303511: Allow to specify encoding for source attachments
981
	 * Test whether the source mapper picks the right encoding for an external source attachment
982
	 * The attachment could be an external folder or external archive and have the encoding 
983
	 * explicitly set or inherit from the project. 
984
	 *
985
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=303511"
986
	 */
987
	public void testBug303511a() throws JavaModelException, CoreException {
988
		// Set file encoding
989
		String encoding = "Shift-JIS";
990
		String oldEncoding = this.encodingProject.getDefaultCharset();
991
		String externalPath = this.encodingProject.getLocation().toOSString() + File.separator + "testShiftJIS.zip";
992
		IFile sourceFile = (IFile) this.encodingProject.findMember("src/testShiftJIS/A.java");
993
		
994
		this.encodingProject.setDefaultCharset(encoding, null);
995
		IClasspathEntry[] entries = this.encodingJavaProject.getRawClasspath();
996
		IClasspathEntry oldEntry = null;
997
		for (int index = 0; index < entries.length; index++) {
998
			IClasspathEntry entry = entries[index];
999
			if (entry.getPath().toOSString().endsWith("testShiftJIS.jar")) {
1000
				oldEntry = entry;
1001
				IClasspathEntry newEntry = JavaCore.newLibraryEntry(entry.getPath(), new Path(externalPath), null);
1002
				entries[index] = newEntry; 
1003
			}
1004
		}
1005
		this.encodingJavaProject.setRawClasspath(entries, null);
1006
		this.encodingJavaProject.getResolvedClasspath(true);
1007
		
1008
		// Get class file and compare source (should not be the same as modify charset on zip file has no effect...)
1009
		IPackageFragmentRoot root = getPackageFragmentRoot("Encoding", "testShiftJIS.jar");
1010
		ISourceReference sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class");
1011
		assertNotNull(sourceRef);
1012
		String source = sourceRef.getSource();
1013
		assertNotNull(source);
1014
		String encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding));
1015
		assertTrue("Sources should be decoded the same way", encodedContents.equals(source));
1016
1017
		entries = this.encodingJavaProject.getRawClasspath();
1018
		String sourcePath = this.encodingProject.getLocation().toOSString() + File.separator + "src";
1019
		for (int index = 0; index < entries.length; index++) {
1020
			IClasspathEntry entry = entries[index];
1021
			if (entry.getPath().toOSString().endsWith("testShiftJIS.jar")) {
1022
				IClasspathEntry newEntry = JavaCore.newLibraryEntry(entry.getPath(), new Path(sourcePath), null);
1023
				entries[index] = newEntry; 
1024
			}
1025
		}
1026
		this.encodingJavaProject.setRawClasspath(entries, null);
1027
		this.encodingJavaProject.getResolvedClasspath(true);
1028
		
1029
		entries = this.encodingJavaProject.getRawClasspath();
1030
		for (int index = 0; index < entries.length; index++) {
1031
			IClasspathEntry entry = entries[index];
1032
			if (entry.getPath().toOSString().endsWith("testShiftJIS.jar")) {
1033
				entries[index] = oldEntry;
1034
			}
1035
		}
1036
		this.encodingJavaProject.setRawClasspath(entries, null);
1037
		this.encodingJavaProject.getResolvedClasspath(true);
1038
		refreshExternalArchives(this.encodingJavaProject);
1039
		this.encodingProject.setDefaultCharset(oldEncoding, null);
1040
	}
932
1041
933
	private void verifyUtf8BOM(IFile file) throws CoreException {
1042
	private void verifyUtf8BOM(IFile file) throws CoreException {
934
		assertNull("File should not have any explicit charset", file.getCharset(false));
1043
		assertNull("File should not have any explicit charset", file.getCharset(false));

Return to bug 303511