themeinstaller/source/src/com/nokia/tools/themeinstaller/xmlparser/DTDInputSource.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themeinstaller/source/src/com/nokia/tools/themeinstaller/xmlparser/DTDInputSource.java Wed Sep 01 12:32:13 2010 +0100
@@ -0,0 +1,163 @@
+/*
+* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: File Reader for DTD Files. Filters out UTF-8 and 16 byte order
+ * marks.
+ *
+*/
+
+
+package com.nokia.tools.themeinstaller.xmlparser;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.Arrays;
+
+import org.xml.sax.InputSource;
+
+import com.nokia.tools.themeinstaller.installationmanager.InstallationManager;
+
+/**
+ * File Reader for DTD Files. Filters out UTF-8 and 16 byte order marks. Byte
+ * order marks need to be filtered because FileReader can not tolerate BOMs.
+ */
+public class DTDInputSource extends InputSource {
+
+ // CONSTANTS
+ private final static int BUFFER_LENGTH = 3;
+ private final static byte[] BOM_UTF8 = { (byte) 0xEF, (byte) 0xBB,
+ (byte) 0xBF };
+ private final static byte[] BOM_UTF16_BIG = { (byte) 0xFE, (byte) 0xFF };
+ private final static byte[] BOM_UTF16_LIT = { (byte) 0xFF, (byte) 0xFE };
+
+ // DTD File name
+ private String iFileName;
+
+ /**
+ * Constructor.
+ *
+ * @param aFileName
+ * DTD file name
+ * @throws FileNotFoundException
+ * if the file can not be found
+ */
+ public DTDInputSource(String aFileName) throws FileNotFoundException {
+ super( new FileReader( aFileName ) );
+ try {
+ preprocess(aFileName);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ iFileName = aFileName;
+ }
+
+ /**
+ * XML-DTD files should not contain invalid entity references. For example,
+ * %N; is valid while %N is not. This method will validate and correct such
+ * instances. Note: This was introduced because of a defect found in loc to
+ * dtd converter tool. Once loc-dtd tool works fine, this step will not be
+ * required.
+ *
+ * @param fileName
+ * the dtd file that needs correction.
+ * @throws IOException
+ */
+ private void preprocess(String fileName) throws IOException {
+
+
+ /**
+ * We won't use this parameter as of now. If required, use
+ * boolean fixDTD = InstallationManager.isFixDTD();
+ * We may remove this if we find no use in future.
+ */
+ boolean fixDTD = true;
+ if (!fixDTD) {
+ this.setCharacterStream(new FileReader(fileName));
+ return;
+ }
+ long fileLen = (new File(fileName)).length();
+ byte[] fileContents = new byte[(int) fileLen];
+ FileInputStream fis = new FileInputStream(fileName);
+ fis.read(fileContents);
+ fis.close();
+
+ String fileContentsString = new String(fileContents);
+ fileContentsString = fileContentsString.replace("(%N)", "(%N;)");
+ fileContentsString = fileContentsString.replace("(%U)", " (%U;)");
+ fileContentsString = fileContentsString.replace("%0U;", "%U;");
+ fileContentsString = fileContentsString.replace("%U(", "%U;(");
+ fileContentsString = fileContentsString.replace("%0U(", "%U;(");
+ fileContentsString = fileContentsString.replace("%U%N;", "%U;%N;");
+ fileContentsString = fileContentsString.replace("%U%N", "%U;%N;");
+
+ setByteStream(new ByteArrayInputStream(fileContentsString.getBytes()));
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.xml.sax.InputSource#getCharacterStream()
+ */
+ public Reader getCharacterStream() {
+ // Get the reader from the base class
+ Reader reader = super.getCharacterStream();
+
+ // Read the beginning of the file to get the BOM
+ byte[] buffer = new byte[BUFFER_LENGTH];
+ try {
+ // Read 3 bytes
+ for (int i = 0; i < buffer.length; i++) {
+ buffer[i] = (byte) reader.read();
+ }
+
+ int skip = 0;
+
+ // UTF-8 byte order mark (length 3 bytes)
+ if (Arrays.equals(BOM_UTF8, buffer)) {
+ skip = BOM_UTF8.length;
+ }
+ // UTF-16 byte order mark (length 2 bytes)
+ else {
+ byte[] compareBuffer = new byte[BOM_UTF16_BIG.length];
+ System.arraycopy(buffer, 0, compareBuffer, 0,
+ compareBuffer.length);
+
+ // Big and little endian
+ if (Arrays.equals(BOM_UTF16_BIG, compareBuffer)
+ || Arrays.equals(BOM_UTF16_LIT, compareBuffer)) {
+ skip = BOM_UTF16_BIG.length;
+ }
+ }
+
+ // Reset not supported, a new reader must be created
+ FileReader fr = new FileReader(iFileName);
+ fr.skip(skip);
+
+ // Close the old reader
+ reader.close();
+
+ // Set the new reader back to the super class
+ super.setCharacterStream(fr);
+ } catch (Exception e) {
+ // Ignore errors, original (unfiltered) stream will be returned
+ }
+
+ return super.getCharacterStream();
+ }
+
+}