1 11 package org.eclipse.core.internal.content; 12 13 import java.io.*; 14 import org.eclipse.core.runtime.QualifiedName; 15 import org.eclipse.core.runtime.content.IContentDescription; 16 import org.eclipse.core.runtime.content.ITextContentDescriber; 17 18 29 public class XMLContentDescriber extends TextContentDescriber implements ITextContentDescriber { 30 private static final QualifiedName[] SUPPORTED_OPTIONS = new QualifiedName[] {IContentDescription.CHARSET, IContentDescription.BYTE_ORDER_MARK}; 31 private static final String ENCODING = "encoding="; private static final String XML_PREFIX = "<?xml "; 34 public int describe(InputStream input, IContentDescription description) throws IOException { 35 byte[] bom = getByteOrderMark(input); 36 String xmlDeclEncoding = "UTF-8"; input.reset(); 38 if (bom != null) { 39 if (bom == IContentDescription.BOM_UTF_16BE) 40 xmlDeclEncoding = "UTF-16BE"; else if (bom == IContentDescription.BOM_UTF_16LE) 42 xmlDeclEncoding = "UTF-16LE"; input.skip(bom.length); 45 if (description != null && description.isRequested(IContentDescription.BYTE_ORDER_MARK)) 47 description.setProperty(IContentDescription.BYTE_ORDER_MARK, bom); 48 } 49 byte[] xmlPrefixBytes = XML_PREFIX.getBytes(xmlDeclEncoding); 50 byte[] prefix = new byte[xmlPrefixBytes.length]; 51 if (input.read(prefix) < prefix.length) 52 return INDETERMINATE; 54 for (int i = 0; i < prefix.length; i++) 55 if (prefix[i] != xmlPrefixBytes[i]) 56 return INDETERMINATE; 58 if (description == null) 59 return VALID; 60 if (description.isRequested(IContentDescription.CHARSET)) { 62 String fullXMLDecl = readFullXMLDecl(input, xmlDeclEncoding); 63 if (fullXMLDecl != null) { 64 String charset = getCharset(fullXMLDecl); 65 if (charset != null && !"UTF-8".equalsIgnoreCase(charset)) description.setProperty(IContentDescription.CHARSET, getCharset(fullXMLDecl)); 68 } 69 } 70 return VALID; 71 } 72 73 private String readFullXMLDecl(InputStream input, String unicodeEncoding) throws IOException { 74 byte[] xmlDecl = new byte[100]; 75 int c = 0; 76 int read = 0; 78 while (read < xmlDecl.length && (c = input.read()) != -1 && c != '?') 79 xmlDecl[read++] = (byte) c; 80 return c == '?' ? new String (xmlDecl, 0, read, unicodeEncoding) : null; 81 } 82 83 public int describe(Reader input, IContentDescription description) throws IOException { 84 BufferedReader reader = new BufferedReader(input); 85 String line = reader.readLine(); 86 if (line == null) 88 return INDETERMINATE; 89 if (!line.startsWith(XML_PREFIX)) 91 return INDETERMINATE; 92 if (description == null) 93 return VALID; 94 if ((description.isRequested(IContentDescription.CHARSET))) 96 description.setProperty(IContentDescription.CHARSET, getCharset(line)); 97 return VALID; 98 } 99 100 private String getCharset(String firstLine) { 101 int encodingPos = firstLine.indexOf(ENCODING); 102 if (encodingPos == -1) 103 return null; 104 char quoteChar = '"'; 105 int firstQuote = firstLine.indexOf(quoteChar, encodingPos); 106 if (firstQuote == -1) { 107 quoteChar = '\''; 108 firstQuote = firstLine.indexOf(quoteChar, encodingPos); 109 } 110 if (firstQuote == -1 || firstLine.length() == firstQuote - 1) 111 return null; 112 int secondQuote = firstLine.indexOf(quoteChar, firstQuote + 1); 113 if (secondQuote == -1) 114 return null; 115 return firstLine.substring(firstQuote + 1, secondQuote); 116 } 117 118 public QualifiedName[] getSupportedOptions() { 119 return SUPPORTED_OPTIONS; 120 } 121 } 122 | Popular Tags |