diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/EncodingTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/EncodingTests.java index c9368c8..8baa96a 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/EncodingTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/EncodingTests.java @@ -28,6 +28,7 @@ import org.eclipse.core.runtime.content.IContentDescription; import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.jdt.core.IClasspathAttribute; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaProject; @@ -62,7 +63,7 @@ // Use this static initializer to specify subset for tests // All specified tests which do not belong to the class are skipped... static { -// TESTS_NAMES = new String[] { "testBug110576" }; +// TESTS_NAMES = new String[] { "testBug361356" }; // TESTS_NUMBERS = new int[] { 2, 12 }; // TESTS_RANGE = new int[] { 16, -1 }; } @@ -1217,7 +1218,256 @@ getWorkspaceRoot().setDefaultCharset(wkspEncoding, null); } } - + public void testBug361356() throws Exception { + String oldEncoding = this.encodingProject.getDefaultCharset(); + try{ + String encoding = "Shift-JIS"; + if (wkspEncoding.equals(encoding)) + getWorkspaceRoot().setDefaultCharset("UTF-8", null); + this.encodingProject.setDefaultCharset("UTF-8", null); + IJavaProject project = this.createJavaProject("Encoding2", new String[] {""}, ""); + IFile zipFile = (IFile) this.encodingProject.findMember("testShiftJIS.zip"); //$NON-NLS-1$ + IFile sourceFile = (IFile) this.encodingProject.findMember("src/testShiftJIS/A.java"); + + IClasspathEntry[] entries = this.encodingJavaProject.getRawClasspath(); + IClasspathEntry newEntry = null; + for (int index = 0; index < entries.length; index++) { + IClasspathEntry entry = entries[index]; + if (entry.getPath().toOSString().endsWith("testShiftJIS.jar")) { + newEntry = entries[index]; + } + } + + IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING, encoding); + project.setRawClasspath(new IClasspathEntry[]{JavaCore.newLibraryEntry(newEntry.getPath(), new Path("/Encoding/src"), null, null, new IClasspathAttribute[]{attribute}, false)}, null); + sourceFile.setCharset(null, null); + + IPackageFragmentRoot root = getPackageFragmentRoot("Encoding2", "testShiftJIS.jar"); + ISourceReference sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class"); + assertNotNull(sourceRef); + String source = sourceRef.getSource(); + assertNotNull(source); + String encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding)); + char[] charArray = encodedContents.toCharArray(); + encodedContents = new String(CharOperation.remove(charArray, '\r')); + charArray = source.toCharArray(); + source = new String(CharOperation.remove(charArray, '\r')); + assertTrue("Sources should be decoded the same way", encodedContents.equals(source)); + + attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING, "UTF-8"); + project.setRawClasspath(new IClasspathEntry[]{JavaCore.newLibraryEntry(newEntry.getPath(), new Path("/Encoding/src"), null, null, new IClasspathAttribute[]{attribute}, false)}, null); + sourceFile.setCharset(encoding, null); + + root = getPackageFragmentRoot("Encoding2", "testShiftJIS.jar"); + sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class"); + assertNotNull(sourceRef); + source = sourceRef.getSource(); + assertNotNull(source); + encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding)); + charArray = encodedContents.toCharArray(); + encodedContents = new String(CharOperation.remove(charArray, '\r')); + charArray = source.toCharArray(); + source = new String(CharOperation.remove(charArray, '\r')); + assertTrue("Sources should be decoded the same way", encodedContents.equals(source)); + + attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING, encoding); + project.setRawClasspath(new IClasspathEntry[]{JavaCore.newLibraryEntry(newEntry.getPath(), new Path("/Encoding/testShiftJIS.zip"), null, null, new IClasspathAttribute[]{attribute}, false)}, null); + zipFile.setCharset(null, null); + + root = getPackageFragmentRoot("Encoding2", "testShiftJIS.jar"); + sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class"); + assertNotNull(sourceRef); + source = sourceRef.getSource(); + assertNotNull(source); + encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding)); + charArray = encodedContents.toCharArray(); + encodedContents = new String(CharOperation.remove(charArray, '\r')); + charArray = source.toCharArray(); + source = new String(CharOperation.remove(charArray, '\r')); + assertTrue("Sources should be decoded the same way", encodedContents.equals(source)); + + attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING, "UTF-8"); + project.setRawClasspath(new IClasspathEntry[]{JavaCore.newLibraryEntry(newEntry.getPath(), new Path("/Encoding/testShiftJIS.zip"), null, null, new IClasspathAttribute[]{attribute}, false)}, null); + zipFile.setCharset(encoding, null); + + root = getPackageFragmentRoot("Encoding2", "testShiftJIS.jar"); + sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class"); + assertNotNull(sourceRef); + source = sourceRef.getSource(); + assertNotNull(source); + encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding)); + charArray = encodedContents.toCharArray(); + encodedContents = new String(CharOperation.remove(charArray, '\r')); + charArray = source.toCharArray(); + source = new String(CharOperation.remove(charArray, '\r')); + assertTrue("Sources should be decoded the same way", encodedContents.equals(source)); + + } + finally { + this.encodingProject.setDefaultCharset(oldEncoding, null); + deleteProject("Encoding2"); + getWorkspaceRoot().setDefaultCharset(wkspEncoding, null); + } + } + public void testBug361356a() throws Exception { + String oldEncoding = this.encodingProject.getDefaultCharset(); + try{ + String encoding = "Shift-JIS"; + if (wkspEncoding.equals(encoding)) + getWorkspaceRoot().setDefaultCharset("UTF-8", null); + this.encodingProject.setDefaultCharset("UTF-8", null); + IJavaProject project = this.createJavaProject("Encoding2", new String[] {""}, ""); + IFile zipFile = (IFile) this.encodingProject.findMember("testShiftJIS.zip"); //$NON-NLS-1$ + IFile sourceFile = (IFile) this.encodingProject.findMember("src/testShiftJIS/A.java"); + + IClasspathEntry[] entries = this.encodingJavaProject.getRawClasspath(); + IClasspathEntry newEntry = null; + for (int index = 0; index < entries.length; index++) { + IClasspathEntry entry = entries[index]; + if (entry.getPath().toOSString().endsWith("testShiftJIS.jar")) { + newEntry = entries[index]; + } + } + + IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING, encoding); + attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING, encoding); + project.setRawClasspath(new IClasspathEntry[]{JavaCore.newLibraryEntry(newEntry.getPath(), new Path("/Encoding/testShiftJIS.zip"), null, null, new IClasspathAttribute[]{attribute}, false)}, null); + zipFile.setCharset(null, null); + + IPackageFragmentRoot root = getPackageFragmentRoot("Encoding2", "testShiftJIS.jar"); + ISourceReference sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class"); + assertNotNull(sourceRef); + String source = sourceRef.getSource(); + assertNotNull(source); + String encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding)); + char[] charArray = encodedContents.toCharArray(); + encodedContents = new String(CharOperation.remove(charArray, '\r')); + charArray = source.toCharArray(); + source = new String(CharOperation.remove(charArray, '\r')); + assertTrue("Sources should be decoded the same way", encodedContents.equals(source)); + + attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING, "UTF-8"); + project.setRawClasspath(new IClasspathEntry[]{JavaCore.newLibraryEntry(newEntry.getPath(), new Path("/Encoding/testShiftJIS.zip"), null, null, new IClasspathAttribute[]{attribute}, false)}, null); + zipFile.setCharset(encoding, null); + + root = getPackageFragmentRoot("Encoding2", "testShiftJIS.jar"); + sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class"); + assertNotNull(sourceRef); + source = sourceRef.getSource(); + assertNotNull(source); + encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding)); + charArray = encodedContents.toCharArray(); + encodedContents = new String(CharOperation.remove(charArray, '\r')); + charArray = source.toCharArray(); + source = new String(CharOperation.remove(charArray, '\r')); + assertTrue("Sources should be decoded the same way", encodedContents.equals(source)); + } + finally { + this.encodingProject.setDefaultCharset(oldEncoding, null); + deleteProject("Encoding2"); + getWorkspaceRoot().setDefaultCharset(wkspEncoding, null); + } + } + public void testBug361356b() throws Exception { + String oldEncoding = this.encodingProject.getDefaultCharset(); + File externalSourceZip = null; + File externalSource = null; + try{ + String encoding = "Shift-JIS"; + if (wkspEncoding.equals(encoding)) + getWorkspaceRoot().setDefaultCharset("UTF-8", null); + this.encodingProject.setDefaultCharset("UTF-8", null); + IJavaProject project = this.createJavaProject("Encoding2", new String[] {""}, ""); + IFile sourceFile = (IFile) this.encodingProject.findMember("src/testShiftJIS/A.java"); + + File internalSourceZip = new File(getWorkspacePath(), "/Encoding/testShiftJIS.zip"); + externalSourceZip = new File(getExternalPath(), "testShiftJIS.zip"); + File internalSource = new File(getWorkspacePath(), "/Encoding/src"); + externalSource = new File(getExternalPath(), "testShiftJIS"); + + copyDirectory(internalSource, externalSource); + copy(internalSourceZip, externalSourceZip); + + IClasspathEntry[] entries = this.encodingJavaProject.getRawClasspath(); + IClasspathEntry newEntry = null; + for (int index = 0; index < entries.length; index++) { + IClasspathEntry entry = entries[index]; + if (entry.getPath().toOSString().endsWith("testShiftJIS.jar")) { + newEntry = entries[index]; + } + } + + IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING, encoding); + attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING, encoding); + project.setRawClasspath(new IClasspathEntry[]{JavaCore.newLibraryEntry(newEntry.getPath(), new Path(getExternalResourcePath("testShiftJIS.zip")), null, null, new IClasspathAttribute[]{attribute}, false)}, null); + + IPackageFragmentRoot root = getPackageFragmentRoot("Encoding2", "testShiftJIS.jar"); + ISourceReference sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class"); + assertNotNull(sourceRef); + String source = sourceRef.getSource(); + assertNotNull(source); + String encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding)); + char[] charArray = encodedContents.toCharArray(); + encodedContents = new String(CharOperation.remove(charArray, '\r')); + charArray = source.toCharArray(); + source = new String(CharOperation.remove(charArray, '\r')); + assertTrue("Sources should be decoded the same way", encodedContents.equals(source)); + + attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING, "UTF-8"); + project.setRawClasspath(new IClasspathEntry[]{JavaCore.newLibraryEntry(newEntry.getPath(), new Path(getExternalResourcePath("testShiftJIS.zip")), null, null, new IClasspathAttribute[]{attribute}, false)}, null); + + root = getPackageFragmentRoot("Encoding2", "testShiftJIS.jar"); + sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class"); + assertNotNull(sourceRef); + source = sourceRef.getSource(); + assertNotNull(source); + encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding)); + charArray = encodedContents.toCharArray(); + encodedContents = new String(CharOperation.remove(charArray, '\r')); + charArray = source.toCharArray(); + source = new String(CharOperation.remove(charArray, '\r')); + assertFalse("Sources should not be decoded the same way", encodedContents.equals(source)); + + attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING, encoding); + project.setRawClasspath(new IClasspathEntry[]{JavaCore.newLibraryEntry(newEntry.getPath(), new Path(getExternalResourcePath("testShiftJIS")), null, null, new IClasspathAttribute[]{attribute}, false)}, null); + sourceFile.setCharset(null, null); + + root = getPackageFragmentRoot("Encoding2", "testShiftJIS.jar"); + sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class"); + assertNotNull(sourceRef); + source = sourceRef.getSource(); + assertNotNull(source); + encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding)); + charArray = encodedContents.toCharArray(); + encodedContents = new String(CharOperation.remove(charArray, '\r')); + charArray = source.toCharArray(); + source = new String(CharOperation.remove(charArray, '\r')); + assertTrue("Sources should be decoded the same way", encodedContents.equals(source)); + + attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING, "UTF-8"); + project.setRawClasspath(new IClasspathEntry[]{JavaCore.newLibraryEntry(newEntry.getPath(), new Path(getExternalResourcePath("testShiftJIS")), null, null, new IClasspathAttribute[]{attribute}, false)}, null); + sourceFile.setCharset(encoding, null); + + root = getPackageFragmentRoot("Encoding2", "testShiftJIS.jar"); + sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class"); + assertNotNull(sourceRef); + source = sourceRef.getSource(); + assertNotNull(source); + encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding)); + charArray = encodedContents.toCharArray(); + encodedContents = new String(CharOperation.remove(charArray, '\r')); + charArray = source.toCharArray(); + source = new String(CharOperation.remove(charArray, '\r')); + assertFalse("Sources should not be decoded the same way", encodedContents.equals(source)); + } + finally { + if (externalSourceZip != null) externalSourceZip.delete(); + if (externalSource != null) deleteExternalResource("testShiftJIS"); + this.encodingProject.setDefaultCharset(oldEncoding, null); + deleteProject("Encoding2"); + getWorkspaceRoot().setDefaultCharset(wkspEncoding, null); + } + } private void verifyUtf8BOM(IFile file) throws CoreException { assertNull("File should not have any explicit charset", file.getCharset(false)); IContentDescription contentDescription = file.getContentDescription(); diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathAttribute.java index 685c1a3..3aa09da 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathAttribute.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathAttribute.java @@ -70,6 +70,22 @@ String INDEX_LOCATION_ATTRIBUTE_NAME = "index_location"; //$NON-NLS-1$ /** + * Constant for the name of the encoding to be used for source attachments. + *
The value of this attribute has to be a string representation of a valid encoding. The encoding + * for a source attachment is determined in the following order:
+ * + *org.eclipse.core.resources.IFile#getCharset(false)
"true"
or "false"
.
* When not present, "false"
is assumed.
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java
index 810a6b2..41f66ec 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java
@@ -1271,6 +1271,15 @@
return false;
}
+ public String getSourceAttachmentEncoding() {
+ for (int i = 0, length = this.extraAttributes.length; i < length; i++) {
+ IClasspathAttribute attribute = this.extraAttributes[i];
+ if (IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING.equals(attribute.getName()))
+ return attribute.getValue();
+ }
+ return null;
+ }
+
/**
* Returns the kind of a PackageFragmentRoot
from its String
form.
*/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java
index 9fb59c6..c1e54a0 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java
@@ -154,11 +154,15 @@
return computeChildren(info, underlyingResource);
}
-SourceMapper createSourceMapper(IPath sourcePath, IPath rootPath) {
+SourceMapper createSourceMapper(IPath sourcePath, IPath rootPath) throws JavaModelException {
+ IClasspathEntry entry = ((JavaProject) getParent()).getClasspathEntryFor(getPath());
+ String encoding = (entry== null) ? null : ((ClasspathEntry) entry).getSourceAttachmentEncoding();
SourceMapper mapper = new SourceMapper(
sourcePath,
rootPath == null ? null : rootPath.toOSString(),
- getJavaProject().getOptions(true)); // cannot use workspace options if external jar is 1.5 jar and workspace options are 1.4 options
+ getJavaProject().getOptions(true),// cannot use workspace options if external jar is 1.5 jar and workspace options are 1.4 options
+ encoding);
+
return mapper;
}
/*
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java
index b2302d6..c1c3e86 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java
@@ -250,6 +250,7 @@
*Options to be used
*/
String encoding;
+ String defaultEncoding;
Map options;
/**
@@ -261,15 +262,19 @@
this.areRootPathsComputed = false;
}
+ public SourceMapper(IPath sourcePath, String rootPath, Map options) {
+ this(sourcePath, rootPath, options, null);
+ }
/**
* Creates a SourceMapper
that locates source in the zip file
* at the given location in the specified package fragment root.
*/
- public SourceMapper(IPath sourcePath, String rootPath, Map options) {
+ public SourceMapper(IPath sourcePath, String rootPath, Map options, String encoding) {
this.areRootPathsComputed = false;
this.options = options;
+ this.encoding = encoding;
try {
- this.encoding = ResourcesPlugin.getWorkspace().getRoot().getDefaultCharset();
+ this.defaultEncoding = ResourcesPlugin.getWorkspace().getRoot().getDefaultCharset();
} catch (CoreException e) {
// use no encoding
}
@@ -1020,9 +1025,16 @@
IResource res = ((IContainer)target).findMember(fullName);
if (res instanceof IFile) {
try {
- source = org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray((IFile)res);
+ // Order of preference: charSet supplied, this.encoding or this.defaultEncoding in that order
+ try {
+ charSet = ((IFile) res).getCharset(this.encoding == null);
+ } catch (CoreException e) {
+ // Ignore
+ }
+ source = org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray((IFile) res,
+ charSet == null ? (this.encoding == null ? this.defaultEncoding : this.encoding) : charSet);
} catch (JavaModelException e) {
- // ignore
+ // Ignore
}
}
} else {
@@ -1030,7 +1042,7 @@
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=303511
// For a resource inside the workspace, use the encoding set on the resource
if (target instanceof IFile)
- charSet = ((IFile)target).getCharset();
+ charSet = ((IFile)target).getCharset(this.encoding == null);
} catch (CoreException e) {
// Ignore
}
@@ -1414,7 +1426,8 @@
try {
byte[] bytes = Util.getZipEntryByteContent(entry, zip);
if (bytes != null) {
- return Util.bytesToChar(bytes, charSet == null ? this.encoding : charSet);
+ // Order of preference: charSet supplied, this.encoding or this.defaultEncoding in that order
+ return Util.bytesToChar(bytes, charSet == null ? (this.encoding == null ? this.defaultEncoding : this.encoding) : charSet);
}
} catch (IOException e) {
// ignore