summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGloria Yadira Torrealba Melendez2014-06-19 19:11:00 (EDT)
committerIan Trimble2014-06-19 19:11:00 (EDT)
commit4340e4a32f9e0899d54a034fba665f78c1e82d6d (patch)
tree07460c7cc3a0687218abd8b6c780d7e6f95703a8
parentf4a1d0d2b40fff5a41b66990485b14bbb5282ee2 (diff)
downloadwebtools.jsf-4340e4a32f9e0899d54a034fba665f78c1e82d6d.zip
webtools.jsf-4340e4a32f9e0899d54a034fba665f78c1e82d6d.tar.gz
webtools.jsf-4340e4a32f9e0899d54a034fba665f78c1e82d6d.tar.bz2
Bug 431752 - incorrectly determines the encoding of a ISO-8859-1 file asv201406191615R3_2_5_patches
UTF-8
-rw-r--r--jsf/plugins/org.eclipse.jst.jsf.core/META-INF/MANIFEST.MF2
-rw-r--r--jsf/plugins/org.eclipse.jst.jsf.core/plugin.xml18
-rw-r--r--jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/internal/contenttype/AbstractContentDescriberForFacelets.java218
-rw-r--r--jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/internal/contenttype/ContentDescriberForFacelet.java20
-rw-r--r--jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/internal/contenttype/ContentDescriberForFaceletCompositeComponent.java19
5 files changed, 260 insertions, 17 deletions
diff --git a/jsf/plugins/org.eclipse.jst.jsf.core/META-INF/MANIFEST.MF b/jsf/plugins/org.eclipse.jst.jsf.core/META-INF/MANIFEST.MF
index 92c94e5..9ce802b 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.core/META-INF/MANIFEST.MF
+++ b/jsf/plugins/org.eclipse.jst.jsf.core/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %plugin.name
Bundle-SymbolicName: org.eclipse.jst.jsf.core; singleton:=true
-Bundle-Version: 1.3.7.qualifier
+Bundle-Version: 1.3.8.qualifier
Bundle-Activator: org.eclipse.jst.jsf.core.internal.JSFCorePlugin
Bundle-Vendor: %plugin.provider
Bundle-Localization: plugin
diff --git a/jsf/plugins/org.eclipse.jst.jsf.core/plugin.xml b/jsf/plugins/org.eclipse.jst.jsf.core/plugin.xml
index 2acc735..329e3c4 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.core/plugin.xml
+++ b/jsf/plugins/org.eclipse.jst.jsf.core/plugin.xml
@@ -495,36 +495,22 @@
point="org.eclipse.core.contenttype.contentTypes">
<content-type
base-type="org.eclipse.wst.html.core.htmlsource"
- default-charset="UTF-8"
file-extensions="xhtml"
id="jsf.facelet"
name="%Facelet.name"
priority="high">
<describer
- class="org.eclipse.jst.jsf.core.internal.contenttype.XMLDocumentElementAttributeContentDescriber">
- <parameter
- name="xmlns:.*"
- value=".*jsf.*">
- </parameter>
- <parameter
- name="xmlns:.*"
- value=".*faces.*">
- </parameter>
+ class="org.eclipse.jst.jsf.core.internal.contenttype.ContentDescriberForFacelet">
</describer>
</content-type>
<content-type
base-type="jsf.facelet"
- default-charset="UTF-8"
file-extensions="xhtml"
id="jsf.facelet.composite"
name="%FaceletComposite.name"
priority="high">
<describer
- class="org.eclipse.jst.jsf.core.internal.contenttype.XMLDocumentElementAttributeContentDescriber">
- <parameter
- name="xmlns:.*"
- value="http://java.sun.com/jsf/composite">
- </parameter>
+ class="org.eclipse.jst.jsf.core.internal.contenttype.ContentDescriberForFaceletCompositeComponent">
</describer>
</content-type>
</extension>
diff --git a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/internal/contenttype/AbstractContentDescriberForFacelets.java b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/internal/contenttype/AbstractContentDescriberForFacelets.java
new file mode 100644
index 0000000..b1bf8ed
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/internal/contenttype/AbstractContentDescriberForFacelets.java
@@ -0,0 +1,218 @@
+package org.eclipse.jst.jsf.core.internal.contenttype;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.nio.charset.Charset;
+import java.util.Arrays;
+import java.util.regex.Pattern;
+
+import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.core.runtime.content.IContentDescriber;
+import org.eclipse.core.runtime.content.IContentDescription;
+import org.eclipse.core.runtime.content.ITextContentDescriber;
+import org.eclipse.wst.html.core.internal.contenttype.HTMLResourceEncodingDetector;
+import org.eclipse.wst.sse.core.internal.encoding.EncodingMemento;
+import org.eclipse.wst.sse.core.internal.encoding.IContentDescriptionExtended;
+import org.eclipse.wst.sse.core.internal.encoding.IResourceCharsetDetector;
+import org.eclipse.wst.sse.core.utils.StringUtils;
+import org.eclipse.wst.xml.core.internal.parser.XMLTokenizer;
+import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
+
+/**
+ * Copied from ContentDescriberForHTML, since that class is final but we need to add description
+ * criteria.
+ */
+
+public abstract class AbstractContentDescriberForFacelets implements ITextContentDescriber {
+
+ /**
+ * Get the patterns to match against value of namespace attributes (of the document element).
+ * @return Array of Pattern instances to match against value of namespace attributes (of the
+ * document element).
+ */
+ protected abstract Pattern[] getNSValuePatterns();
+
+ final private static QualifiedName[] SUPPORTED_OPTIONS = {IContentDescription.CHARSET, IContentDescription.BYTE_ORDER_MARK, IContentDescriptionExtended.DETECTED_CHARSET, IContentDescriptionExtended.UNSUPPORTED_CHARSET, IContentDescriptionExtended.APPROPRIATE_DEFAULT};
+
+ public int describe(InputStream contents, IContentDescription description) throws IOException {
+ int result = IContentDescriber.INDETERMINATE;
+ byte[] bom = null;
+ if (description != null) {
+ calculateSupportedOptions(contents, description);
+ Object value = description.getProperty(IContentDescription.BYTE_ORDER_MARK);
+ if (value instanceof byte[]) {
+ bom = (byte[])value;
+ }
+ } else {
+ contents.reset();
+ bom = getByteOrderMark(contents);
+ }
+ Object value =
+ (description != null ? description.getProperty(IContentDescription.CHARSET) : null);
+ String charsetName = null;
+ if (value != null) {
+ charsetName = value.toString();
+ } else {
+ if (Arrays.equals(IContentDescription.BOM_UTF_16BE, bom)) {
+ charsetName = "UTF-16BE"; //$NON-NLS-1$
+ } else if (Arrays.equals(IContentDescription.BOM_UTF_16LE, bom)) {
+ charsetName = "UTF-16LE"; //$NON-NLS-1$
+ } else {
+ charsetName = "UTF-8"; //$NON-NLS-1$
+ }
+ }
+ contents.reset();
+ result = checkCriteria(new InputStreamReader(contents, Charset.forName(charsetName)));
+ return result;
+ }
+
+ public int describe(Reader contents, IContentDescription description) throws IOException {
+ int result = IContentDescriber.INDETERMINATE;
+ if (description != null) {
+ calculateSupportedOptions(contents, description);
+ }
+ contents.reset();
+ result = checkCriteria(contents);
+ return result;
+ }
+
+ public QualifiedName[] getSupportedOptions() {
+ return SUPPORTED_OPTIONS;
+ }
+
+ private void calculateSupportedOptions(InputStream contents, IContentDescription description) throws IOException {
+ if (isRelevent(description)) {
+ IResourceCharsetDetector detector = getDetector();
+ detector.set(contents);
+ handleCalculations(description, detector);
+ }
+ }
+
+ private void calculateSupportedOptions(Reader contents, IContentDescription description) throws IOException {
+ if (isRelevent(description)) {
+ IResourceCharsetDetector detector = getDetector();
+ detector.set(contents);
+ handleCalculations(description, detector);
+ }
+ }
+
+ private IResourceCharsetDetector getDetector() {
+ return new HTMLResourceEncodingDetector();
+ }
+
+ @SuppressWarnings("deprecation")
+ private void handleCalculations(IContentDescription description, IResourceCharsetDetector detector) throws IOException {
+ EncodingMemento encodingMemento = ((HTMLResourceEncodingDetector) detector).getEncodingMemento();
+ Object detectedByteOrderMark = encodingMemento.getUnicodeBOM();
+ if (detectedByteOrderMark != null) {
+ Object existingByteOrderMark = description.getProperty(IContentDescription.BYTE_ORDER_MARK);
+ if (!detectedByteOrderMark.equals(existingByteOrderMark)) {
+ description.setProperty(IContentDescription.BYTE_ORDER_MARK, detectedByteOrderMark);
+ }
+ }
+
+ if (!encodingMemento.isValid()) {
+ description.setProperty(IContentDescriptionExtended.UNSUPPORTED_CHARSET, encodingMemento.getInvalidEncoding());
+ description.setProperty(IContentDescriptionExtended.APPROPRIATE_DEFAULT, encodingMemento.getAppropriateDefault());
+ }
+
+ Object detectedCharset = encodingMemento.getDetectedCharsetName();
+ Object javaCharset = encodingMemento.getJavaCharsetName();
+
+ if (detectedCharset != null) {
+ description.setProperty(IContentDescriptionExtended.DETECTED_CHARSET, detectedCharset);
+ }
+
+ if (javaCharset != null) {
+ Object existingCharset = description.getProperty(IContentDescription.CHARSET);
+ if (!javaCharset.equals(existingCharset)) {
+ Object defaultCharset = detector.getSpecDefaultEncoding();
+ if (defaultCharset != null) {
+ if (!defaultCharset.equals(javaCharset)) {
+ description.setProperty(IContentDescription.CHARSET, javaCharset);
+ }
+ } else {
+ description.setProperty(IContentDescription.CHARSET, javaCharset);
+ }
+ }
+ }
+
+ }
+
+ private boolean isRelevent(IContentDescription description) {
+ boolean result = false;
+ if (description != null) {
+ if (description.isRequested(IContentDescription.BYTE_ORDER_MARK)) {
+ result = true;
+ } else if (description.isRequested(IContentDescription.CHARSET)) {
+ result = true;
+ } else if (description.isRequested(IContentDescriptionExtended.APPROPRIATE_DEFAULT)) {
+ result = true;
+ } else if (description.isRequested(IContentDescriptionExtended.DETECTED_CHARSET)) {
+ result = true;
+ } else if (description.isRequested(IContentDescriptionExtended.UNSUPPORTED_CHARSET)) {
+ result = true;
+ }
+ }
+ return result;
+ }
+
+ private int checkCriteria(Reader contents) throws IOException {
+ final Pattern[] nsValuePatterns = getNSValuePatterns();
+ if (nsValuePatterns == null || nsValuePatterns.length == 0) {
+ return INVALID;
+ }
+ final Pattern nsNamePattern = Pattern.compile("xmlns:.*"); //$NON-NLS-1$
+
+ String attributeName = null;
+ String attributeValue = null;
+
+ XMLTokenizer tokenizer = new XMLTokenizer(contents);
+
+ String token = tokenizer.primGetNextToken();
+ while (token != null &&
+ !DOMRegionContext.XML_TAG_CLOSE.equals(token) &&
+ !DOMRegionContext.XML_EMPTY_TAG_CLOSE.equals(token)) {
+
+ if (DOMRegionContext.XML_TAG_ATTRIBUTE_NAME.equals(token)) {
+ attributeName = tokenizer.yytext();
+ }
+ else if (DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE.equals(token)) {
+ attributeValue = StringUtils.strip(tokenizer.yytext());
+ for (int i = 0; i < nsValuePatterns.length; i++) {
+ if (nsNamePattern.matcher(attributeName).matches()) {
+ if (nsValuePatterns[i].matcher(attributeValue).matches()) {
+ return VALID;
+ }
+ }
+ }
+ }
+ token = tokenizer.primGetNextToken();
+ }
+ return INVALID;
+ }
+
+ private static byte[] getByteOrderMark(InputStream contents) throws IOException {
+ int first = contents.read();
+ if (first == 0xEF) {
+ // look for the UTF-8 Byte Order Mark (BOM)
+ int second = contents.read();
+ int third = contents.read();
+ if (second == 0xBB && third == 0xBF)
+ return IContentDescription.BOM_UTF_8;
+ }
+ else if (first == 0xFE) {
+ // look for the UTF-16 BOM
+ if (contents.read() == 0xFF)
+ return IContentDescription.BOM_UTF_16BE;
+ }
+ else if (first == 0xFF) {
+ if (contents.read() == 0xFE)
+ return IContentDescription.BOM_UTF_16LE;
+ }
+ return null;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/internal/contenttype/ContentDescriberForFacelet.java b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/internal/contenttype/ContentDescriberForFacelet.java
new file mode 100644
index 0000000..1d07269
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/internal/contenttype/ContentDescriberForFacelet.java
@@ -0,0 +1,20 @@
+package org.eclipse.jst.jsf.core.internal.contenttype;
+
+import java.util.regex.Pattern;
+
+/**
+ * Content Describer for a "facelet" (document element has an xmlns attribute with a value that
+ * matches ".*jsf.*" or ".*faces.*").
+ *
+ */
+public class ContentDescriberForFacelet extends AbstractContentDescriberForFacelets {
+
+ @Override
+ protected Pattern[] getNSValuePatterns() {
+ return new Pattern[] {
+ Pattern.compile(".*jsf.*"), //$NON-NLS-1$
+ Pattern.compile(".*faces.*") //$NON-NLS-1$
+ };
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/internal/contenttype/ContentDescriberForFaceletCompositeComponent.java b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/internal/contenttype/ContentDescriberForFaceletCompositeComponent.java
new file mode 100644
index 0000000..0f26be6
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/internal/contenttype/ContentDescriberForFaceletCompositeComponent.java
@@ -0,0 +1,19 @@
+package org.eclipse.jst.jsf.core.internal.contenttype;
+
+import java.util.regex.Pattern;
+
+/**
+ * Content Describer for a "facelet composite component" (document element has an xmlns attribute
+ * with a value that matches "http://java.sun.com/jsf/composite").
+ *
+ */
+public class ContentDescriberForFaceletCompositeComponent extends AbstractContentDescriberForFacelets {
+
+ @Override
+ protected Pattern[] getNSValuePatterns() {
+ return new Pattern[] {
+ Pattern.compile("http://java.sun.com/jsf/composite") //$NON-NLS-1$
+ };
+ }
+
+}