blob: 58afa6e7cba1218a21504112567cce943794294a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*
*******************************************************************************/
package org.eclipse.jst.jsp.css.core.internal.contenttype;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
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.jst.jsp.core.internal.contenttype.JSPResourceEncodingDetector;
import org.eclipse.jst.jsp.core.internal.provisional.contenttype.IContentDescriptionForJSP;
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;
public class ContentDescriberForJSPedCSS implements ITextContentDescriber {
private final static QualifiedName[] SUPPORTED_OPTIONS = {IContentDescription.CHARSET, IContentDescription.BYTE_ORDER_MARK, IContentDescriptionExtended.DETECTED_CHARSET, IContentDescriptionExtended.UNSUPPORTED_CHARSET, IContentDescriptionExtended.APPROPRIATE_DEFAULT, IContentDescriptionForJSP.CONTENT_TYPE_ATTRIBUTE, IContentDescriptionForJSP.LANGUAGE_ATTRIBUTE};
/*
* (non-Javadoc)
*
* @see org.eclipse.core.runtime.content.IContentDescriber#describe(java.io.InputStream,
* org.eclipse.core.runtime.content.IContentDescription)
*/
public int describe(InputStream contents, IContentDescription description) throws IOException {
int result = IContentDescriber.INVALID;
// if discription is null, we are just being asked to
// assess contents validity
if (description != null) {
result = calculateSupportedOptions(contents, description);
}
else {
result = determineValidity(contents);
}
return result;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.runtime.content.ITextContentDescriber#describe(java.io.Reader,
* org.eclipse.core.runtime.content.IContentDescription)
*/
public int describe(Reader contents, IContentDescription description) throws IOException {
int result = IContentDescriber.INVALID;
// if discription is null, we are just being asked to
// assess contents validity
if (description != null) {
result = calculateSupportedOptions(contents, description);
}
else {
result = determineValidity(contents);
}
return result;
}
public QualifiedName[] getSupportedOptions() {
return SUPPORTED_OPTIONS;
}
private int calculateSupportedOptions(InputStream contents, IContentDescription description) throws IOException {
int result = IContentDescriber.INDETERMINATE;
if (isRelevent(description)) {
IResourceCharsetDetector detector = getDetector();
detector.set(contents);
handleCalculations(description, detector);
result = IContentDescriber.VALID;
}
return result;
}
/**
* @param contents
* @param description
* @throws IOException
*/
private int calculateSupportedOptions(Reader contents, IContentDescription description) throws IOException {
int result = IContentDescriber.INDETERMINATE;
if (isRelevent(description)) {
IResourceCharsetDetector detector = getDetector();
detector.set(contents);
handleCalculations(description, detector);
result = IContentDescriber.VALID;
}
return result;
}
private IResourceCharsetDetector getDetector() {
return new JSPResourceEncodingDetector();
}
private void handleCalculations(IContentDescription description, IResourceCharsetDetector detector) throws IOException {
// handle standard ones first, to be sure detector processes
handleStandardCalculations(description, detector);
// now do those specific for JSPs
// note: detector should always be of correct instance, but we'll
// check, for now.
if (detector instanceof JSPResourceEncodingDetector) {
JSPResourceEncodingDetector jspDetector = (JSPResourceEncodingDetector) detector;
String language = jspDetector.getLanguage();
if (language != null && language.length() > 0) {
description.setProperty(IContentDescriptionForJSP.LANGUAGE_ATTRIBUTE, language);
}
String contentTypeAttribute = jspDetector.getContentType();
if (contentTypeAttribute != null && contentTypeAttribute.length() > 0) {
description.setProperty(IContentDescriptionForJSP.CONTENT_TYPE_ATTRIBUTE, contentTypeAttribute);
}
}
}
private void handleDetectedSpecialCase(IContentDescription description, Object detectedCharset, Object javaCharset) {
if (detectedCharset != null) {
// Once we detected a charset, we should set the property even
// though it's the same as javaCharset
// because there are clients that rely on this property to
// determine if the charset is actually detected in file or not.
description.setProperty(IContentDescriptionExtended.DETECTED_CHARSET, detectedCharset);
}
}
/**
* @param description
* @param detector
* @throws IOException
*/
private void handleStandardCalculations(IContentDescription description, IResourceCharsetDetector detector) throws IOException {
// note: if we're asked for one, we set them all. I need to be sure if
// called
// mulitiple times (one for each, say) that we don't waste time
// processing same
// content again.
EncodingMemento encodingMemento = ((JSPResourceEncodingDetector) detector).getEncodingMemento();
// TODO: I need to verify to see if this BOM work is always done
// by text type.
Object detectedByteOrderMark = encodingMemento.getUnicodeBOM();
if (detectedByteOrderMark != null) {
Object existingByteOrderMark = description.getProperty(IContentDescription.BYTE_ORDER_MARK);
// not sure why would ever be different, so if is different, may
// need to "push" up into base.
if (!detectedByteOrderMark.equals(existingByteOrderMark))
description.setProperty(IContentDescription.BYTE_ORDER_MARK, detectedByteOrderMark);
}
if (!encodingMemento.isValid()) {
// note: after setting here, its the mere presence of
// IContentDescriptionExtended.UNSUPPORTED_CHARSET
// in the resource's description that can be used to determine if
// invalid
// in those cases, the "detected" property contains an
// "appropriate default" to use.
description.setProperty(IContentDescriptionExtended.UNSUPPORTED_CHARSET, encodingMemento.getInvalidEncoding());
description.setProperty(IContentDescriptionExtended.APPROPRIATE_DEFAULT, encodingMemento.getAppropriateDefault());
}
Object detectedCharset = encodingMemento.getDetectedCharsetName();
Object javaCharset = encodingMemento.getJavaCharsetName();
// we always include detected, if its different than java
handleDetectedSpecialCase(description, detectedCharset, javaCharset);
if (javaCharset != null) {
Object existingCharset = description.getProperty(IContentDescription.CHARSET);
if (javaCharset.equals(existingCharset)) {
handleDetectedSpecialCase(description, detectedCharset, javaCharset);
}
else {
// we may need to add what we found, but only need to add
// if different from the default.
Object defaultCharset = detector.getSpecDefaultEncoding();
if (defaultCharset != null) {
if (!defaultCharset.equals(javaCharset)) {
description.setProperty(IContentDescription.CHARSET, javaCharset);
}
}
else {
// assuming if there is no spec default, we always need to
// add, I'm assuming
description.setProperty(IContentDescription.CHARSET, javaCharset);
}
}
}
}
/**
* @param description
* @return
*/
private boolean isRelevent(IContentDescription description) {
boolean result = false;
if (description == null)
result = false;
else 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;
else if (description.isRequested(IContentDescriptionForJSP.CONTENT_TYPE_ATTRIBUTE))
result = true;
return result;
}
private int determineValidity(InputStream inputStream) {
return IContentDescriber.INDETERMINATE;
}
private int determineValidity(Reader reader) {
return IContentDescriber.INDETERMINATE;
}
}