/*******************************************************************************
 * Copyright (c) 2000, 2005 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.compare.examples.xml;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;

import java.text.MessageFormat;

import java.util.ArrayList;
import java.util.HashMap;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.LocatorImpl;

import org.eclipse.core.runtime.CoreException;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Position;

import org.eclipse.compare.IEditableContent;
import org.eclipse.compare.IEncodedStreamContentAccessor;
import org.eclipse.compare.IStreamContentAccessor;
import org.eclipse.compare.structuremergeviewer.Differencer;
import org.eclipse.compare.structuremergeviewer.IDiffContainer;
import org.eclipse.compare.structuremergeviewer.IStructureComparator;
import org.eclipse.compare.structuremergeviewer.IStructureCreator;

/**
 * This structure analyzer builds a parse tree of an XML document found in a
 * <code>IByteContentAccessor</code> input by calling getStructure(Object)
 */
public class XMLStructureCreator implements IStructureCreator {

    protected static final boolean DEBUG_MODE= false;
    
    public static final String DEFAULT_NAME= XMLCompareMessages.XMLStructureCreator_pluginname; 

    public static final String USE_UNORDERED= XMLCompareMessages.XMLStructureCreator_unordered; 
    public static final String USE_ORDERED= XMLCompareMessages.XMLStructureCreator_ordered; 
    public static final String DEFAULT_IDMAP= USE_ORDERED;

    public static final String TYPE_ELEMENT= "element"; //$NON-NLS-1$
    public static final String TYPE_TEXT= "text"; //$NON-NLS-1$
    public static final String TYPE_ATTRIBUTE= "attribute"; //$NON-NLS-1$

    // for signatures
    public static final String ROOT_ID= "root"; //$NON-NLS-1$
    public static final char SIGN_SEPARATOR= '>';//'.'
    public static final char SIGN_ENCLOSING= '$';
    public static final String SIGN_ELEMENT= SIGN_ENCLOSING + TYPE_ELEMENT + SIGN_ENCLOSING;
    public static final String SIGN_TEXT= SIGN_ENCLOSING + TYPE_TEXT + SIGN_ENCLOSING;
    public static final String SIGN_ATTRIBUTE= SIGN_ENCLOSING + TYPE_ATTRIBUTE + SIGN_ENCLOSING;
    
    public static final String IDMAP_UNORDERED= XMLCompareMessages.XMLStructureCreator_idmap_unordered; 
    public static final char ID_SEPARATOR= '<';
    public static final char ID_TYPE_BODY= '<';

    private XMLNode fcurrentParent;
    private String fsignature;
    private Document fdoc;
    private boolean ignoreBodies= false;
    private HashMap fIdMapsInternal;
    private HashMap fIdMaps;
    private HashMap fIdExtensionToName;
    private HashMap fOrderedElementsInternal;
    private HashMap fOrderedElements;
    private HashMap idMap;
    private ArrayList fOrdered;
    private String fIdMapToUse;
    private boolean fUseIdMap;
    private String fFileExt;
    private boolean fFirstCall= true;
    private boolean fRemoveWhiteSpace;

    protected class XMLHandler extends DefaultHandler {

        protected Locator prevlocator; //previous locator
        protected Locator locator; //current locator

        @Override
		public void setDocumentLocator(Locator locator0) {
            this.locator= locator0;
        }

        // DocumentHandler methods
        
        /* Processing instruction. */
        @Override
		public void processingInstruction(String target, String data) {

            //    	System.out.println("target: " + target);
            //    	System.out.println("data: " + data);
            //        System.out.print("<?");
            //        System.out.print(target);
            //        if (data != null && data.length() > 0) {
            //            System.out.print(' ');
            //            System.out.print(data);
            //        }
            //        System.out.print("?>");
            //        System.out.flush();
            prevlocator= new LocatorImpl(locator);
        }

        /** Start document. */
        @Override
		public void startDocument() {
            prevlocator= new LocatorImpl(locator);
        }

        /* Start element. */
        @Override
		public void startElement(String uri, String local, String raw, Attributes attrs) {
            XMLNode currentElement;

            /* add root node for this element */

            if (XMLStructureCreator.DEBUG_MODE) {
                if (locator != null && prevlocator != null) {
                    System.out.println("prevlocator: line " + prevlocator.getLineNumber() + "  column " + prevlocator.getColumnNumber() + "  id " + prevlocator.getPublicId()); //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
                    System.out.println("locator: line " + locator.getLineNumber() + "  column " + locator.getColumnNumber() + "  id " + locator.getPublicId()); //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
                }
            }

            try {
                if (XMLStructureCreator.DEBUG_MODE)
                    System.out.println("Node where children field accessed: " + fcurrentParent.getId()); //$NON-NLS-1$
                XMLChildren currentParent= (XMLChildren) fcurrentParent;
                currentParent.children++;
                String elementId;
                String elementName;
                IRegion r= fdoc.getLineInformation(prevlocator.getLineNumber() - 1);

                String parentSig= fsignature;
                fsignature= fsignature + raw + SIGN_SEPARATOR;

                if (isUseIdMap() && idMap.containsKey(fsignature)) {
                    String attrName= (String) idMap.get(fsignature);
                    elementId= raw + Character.valueOf(ID_SEPARATOR) + attrs.getValue(attrName);
                    elementName= raw + " [" + attrName + "=" + attrs.getValue(attrName) + "]"; //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
                } else {
                    if (!currentParent.childElements.containsKey(raw)) {
                        currentParent.childElements.put(raw, Integer.valueOf(1));
                    } else {
                        currentParent.childElements.put(raw, Integer.valueOf(((Integer) currentParent.childElements.get(raw)).intValue() + 1));
                    }
                    elementId= raw + Character.valueOf(ID_SEPARATOR) + "[" + currentParent.childElements.get(raw) + "]"; //$NON-NLS-2$ //$NON-NLS-1$
                    elementName= MessageFormat.format("{0} [{1}]", raw, currentParent.childElements.get(raw).toString()); //$NON-NLS-1$
                }
                int start= r.getOffset() + prevlocator.getColumnNumber() - 1;
                if (start < 0)
                    start= 0;
                currentElement= new XMLChildren(TYPE_ELEMENT, elementId, elementId, (fsignature + SIGN_ELEMENT), fdoc, start, 0);
                currentElement.setName(elementName);
                if (isUseIdMap() && idMap.containsKey(fsignature))
                    currentElement.setUsesIDMAP(true);
                if (fOrdered != null && fOrdered.contains(parentSig))
                    currentElement.setIsOrderedChild(true);

                fcurrentParent.addChild(currentElement);
                currentElement.setParent(fcurrentParent);
                fcurrentParent= currentElement;
                if (XMLStructureCreator.DEBUG_MODE)
                    System.out.println("\nAdded Element " + raw + "  with offset " + r.getOffset()); //$NON-NLS-2$ //$NON-NLS-1$
                if (XMLStructureCreator.DEBUG_MODE)
                    System.out.println("fcurrentParent1: " + fcurrentParent.getId()); //$NON-NLS-1$

                if (attrs != null) {
                    if (XMLStructureCreator.DEBUG_MODE)
                        System.out.println("attrs != null, fcurrentParent is " + fcurrentParent.getId()); //$NON-NLS-1$
                    //attrs = sortAttributes(attrs);
                    int len= attrs.getLength();
                    int element_lines_length_size;
                    int[] element_lines_length;
                    int column_offset;
                    String element_string;
                    if (fcurrentParent.getParent().getId().equals(ROOT_ID)) {
                        element_lines_length_size= locator.getLineNumber() - prevlocator.getLineNumber();
                        element_lines_length= new int[element_lines_length_size];
                        column_offset= 0;
                        element_string= ""; //$NON-NLS-1$
                        for (int i_ell= 0; i_ell < element_lines_length.length; i_ell++) {
                            IRegion attr_r= fdoc.getLineInformation(i_ell + prevlocator.getLineNumber());
                            element_lines_length[i_ell]= fdoc.get(attr_r.getOffset(), attr_r.getLength()).length() + 1;
                            element_string= element_string + fdoc.get(attr_r.getOffset(), attr_r.getLength()) + " "; //$NON-NLS-1$
                        }
                    } else {
                        element_lines_length_size= locator.getLineNumber() - prevlocator.getLineNumber() + 1;
                        //if (element_lines_length_size < 1)
                        // element_lines_length_size = 1;
                        element_lines_length= new int[element_lines_length_size];
                        IRegion first_line= fdoc.getLineInformation(prevlocator.getLineNumber() - 1);
                        column_offset= prevlocator.getColumnNumber() - 1;
                        int first_line_relevant_offset= first_line.getOffset() + column_offset;
                        int first_line_relevant_length= first_line.getLength() - column_offset;
                        element_string= fdoc.get(first_line_relevant_offset, first_line_relevant_length) + " "; //$NON-NLS-1$
                        element_lines_length[0]= element_string.length();
                        for (int i_ell= 1; i_ell < element_lines_length.length; i_ell++) {
                            IRegion attr_r= fdoc.getLineInformation(i_ell + prevlocator.getLineNumber() - 1);
                            element_lines_length[i_ell]= fdoc.get(attr_r.getOffset(), attr_r.getLength()).length() + 1;
                            element_string= element_string + fdoc.get(attr_r.getOffset(), attr_r.getLength()) + " "; //$NON-NLS-1$
                        }
                    }

                    for (int i_attr= 0; i_attr < len; i_attr++) {
                        String attr_name= attrs.getQName(i_attr);
                        String attr_value= attrs.getValue(i_attr);

                        /*
                         * find range of attribute in doc; manually parses the
                         * line
                         */
                        boolean found= false;
                        int first_quotes= -1;
                        int second_quotes= -1;
                        int id_index= -1;
                        while (!found) {
                            first_quotes= element_string.indexOf("\"", second_quotes + 1); //$NON-NLS-1$
                            second_quotes= element_string.indexOf("\"", first_quotes + 1); //$NON-NLS-1$
                            String value;
                            try {
                                value= element_string.substring(first_quotes + 1, second_quotes);
                            } catch (Exception e) {
                                value= ""; //$NON-NLS-1$
                            }
                            if (value.equals("")) //$NON-NLS-1$
                                found= true;
                            else if (value.equals(attr_value)) {
                                id_index= element_string.lastIndexOf(attr_name, first_quotes - 1);
                                boolean wrong= false;
                                boolean found_equal= false;
                                for (int i_char= id_index + attr_name.length(); i_char < first_quotes && !wrong; i_char++) {
                                    if (element_string.charAt(i_char) == '=')
                                        if (!found_equal)
                                            found_equal= true;
                                        else
                                            wrong= true;
                                    else if (!Character.isWhitespace(element_string.charAt(i_char)))
                                        wrong= true;
                                }
                                if (!wrong)
                                    found= true;
                            }
                        }
                        //id_index has one char missing for every line (the
                        // final cr)
                        int line_of_index= 0;
                        for (line_of_index= 0; id_index > element_lines_length[line_of_index] - 1; line_of_index++)
                            id_index-= (element_lines_length[line_of_index]);
                        if (line_of_index == 0)
                            id_index+= column_offset;
                        if (fcurrentParent.getParent().getId().equals(ROOT_ID))
                            line_of_index+= prevlocator.getLineNumber();
                        else
                            line_of_index+= prevlocator.getLineNumber() - 1;
                        //index at line line_of_index, line offset id_index
                        int line_of_end_of_value= 0;
                        int end_of_value_index= second_quotes;
                        for (line_of_end_of_value= 0; end_of_value_index > element_lines_length[line_of_end_of_value] - 1; line_of_end_of_value++)
                            end_of_value_index-= (element_lines_length[line_of_end_of_value]);
                        if (line_of_end_of_value == 0)
                            end_of_value_index+= column_offset;
                        if (fcurrentParent.getParent().getId().equals(ROOT_ID))
                            line_of_end_of_value+= prevlocator.getLineNumber();
                        else
                            line_of_end_of_value+= prevlocator.getLineNumber() - 1;
                        //end of value at line line_of_end_of_value, line
                        // offset end_of_value_index

                        int attr_start_doc_offset= fdoc.getLineInformation(line_of_index).getOffset() + id_index;
                        //int attr_length_doc_offset =
                        // fdoc.getLineInformation(line_of_value).getOffset()+value_index+attr_value.length()+1+(line_of_end_of_value-line_of_index)
                        // - attr_start_doc_offset;
                        int attr_length_doc_offset= fdoc.getLineInformation(line_of_end_of_value).getOffset() + end_of_value_index + 1 - attr_start_doc_offset;
                        currentElement= new XMLNode(TYPE_ATTRIBUTE, attr_name, attr_value, (fsignature + attr_name + SIGN_SEPARATOR + SIGN_ATTRIBUTE), fdoc, attr_start_doc_offset, attr_length_doc_offset);
                        currentElement.setName(attr_name);
                        fcurrentParent.addChild(currentElement);
                        currentElement.setParent(fcurrentParent);
                        if (XMLStructureCreator.DEBUG_MODE)
                            System.out.println("added attribute " + currentElement.getId() + " with value >" + currentElement.getValue() + "<" + " to element " + fcurrentParent.getId() + " which has parent " + fcurrentParent.getParent().getId()); //$NON-NLS-5$ //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
                    }
                }
            } catch (BadLocationException ex) {
                if (XMLStructureCreator.DEBUG_MODE)
                    System.out.println("BadLocationException in startElement(...) " + ex); //$NON-NLS-1$
                currentElement= new XMLChildren(TYPE_ELEMENT, raw + "_(" + ((XMLChildren) fcurrentParent).children + ")", raw + "_(" + ((XMLChildren) fcurrentParent).children + ")", (fsignature + SIGN_ELEMENT), fdoc, 0, 0); //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
            }
            if (XMLStructureCreator.DEBUG_MODE)
                System.out.println("At the end of startElement(...), fcurrentParent is " + fcurrentParent.getId()); //$NON-NLS-1$
            prevlocator= new LocatorImpl(locator);
        }

        /* Characters. */
        @Override
		public void characters(char ch[], int start, int length) {
            if (!ignoreBodies) {
                //			String chars = (new String(ch, start, length)).trim();
                String chars= new String(ch, start, length);
                if (XMLStructureCreator.DEBUG_MODE)
                    System.out.println("characters: >" + chars + "<"); //$NON-NLS-2$ //$NON-NLS-1$
                if (XMLStructureCreator.DEBUG_MODE)
                    System.out.println("Body Location: line " + locator.getLineNumber() + "  column " + locator.getColumnNumber()); //$NON-NLS-2$ //$NON-NLS-1$

                //if text contains only white space, it will be ignored.
                if (!trimWhiteSpace(chars).equals("")) { //$NON-NLS-1$
                    if (XMLStructureCreator.DEBUG_MODE)
                        System.out.println("Adding body"); //$NON-NLS-1$
                    try {
                        IRegion r= fdoc.getLineInformation(locator.getLineNumber() - 1);
                        //location returns the END of the characters
                        //offset of BEGINNING of characters:
                        int offset= r.getOffset() + locator.getColumnNumber() - 1 - length;
                        fcurrentParent.bodies++;
                        String body_value= new String(ch, start, length);
                        if (fRemoveWhiteSpace) {
                            body_value= removeWhiteSpace(body_value);
                        }
                        XMLNode bodynode= new XMLNode(TYPE_TEXT, "body_(" + fcurrentParent.bodies + ")", body_value, (fsignature + SIGN_TEXT), fdoc, offset, length); //$NON-NLS-2$ //$NON-NLS-1$
                        bodynode.setName(MessageFormat.format("{0} ({1})", XMLCompareMessages.XMLStructureCreator_body, Integer.toString(fcurrentParent.bodies)));  //$NON-NLS-1$
                        fcurrentParent.addChild(bodynode);
                        bodynode.setParent(fcurrentParent);
                        if (XMLStructureCreator.DEBUG_MODE)
                            System.out.println("Created body " + fcurrentParent.bodies //$NON-NLS-1$
                                    + " with offset " + offset + " and length " + length //$NON-NLS-2$ //$NON-NLS-1$
                                    + " with parent " + bodynode.getParent().getId()); //$NON-NLS-1$
                        //bodies as id attributes
                        String popsig= fcurrentParent.getParent().getSignature(); //signature of parent of
                        // parent
                        popsig= popsig.substring(0, popsig.lastIndexOf(SIGN_ELEMENT));
                        if (isUseIdMap() && fcurrentParent.bodies == 1 && idMap.containsKey(popsig)) {
                            String pid= fcurrentParent.getId();//id of parent
                            String pelementname= pid.substring(0, pid.indexOf("<")); //name of parent element //$NON-NLS-1$
                            if (((String) idMap.get(popsig)).equals(ID_TYPE_BODY + pelementname)) {
                                XMLNode pop= fcurrentParent.getParent();
                                String popid= pop.getId();
                                String popelementname= popid.substring(0, popid.indexOf("<")); //$NON-NLS-1$
                                pop.setId(popelementname + "<" + body_value); //$NON-NLS-1$
                                pop.setOrigId(popelementname + "<" + body_value); //$NON-NLS-1$
                                pop.setName(MessageFormat.format("{0} [{1}={2}]", popelementname, pelementname, body_value)); //$NON-NLS-1$
                                pop.setUsesIDMAP(true);
                            }
                        }
                    } catch (BadLocationException ex) {
                        if (XMLStructureCreator.DEBUG_MODE)
                            System.out.println("BadLocationException in characters(...) " + ex); //$NON-NLS-1$
                        fcurrentParent.addChild(new XMLNode(TYPE_TEXT, "body_(" + fcurrentParent.bodies + ")", new String(ch, start, length), (fsignature + SIGN_TEXT), fdoc, 0, 0)); //$NON-NLS-2$ //$NON-NLS-1$
                    }
                }
            }
            prevlocator= new LocatorImpl(locator);
        }

        /* Ignorable whitespace. */
        @Override
		public void ignorableWhitespace(char ch[], int start, int length) {
            //
            //// characters(ch, start, length);
            //// System.out.flush();
            //
            prevlocator= new LocatorImpl(locator);
        }

        /* End element. */
        @Override
		public void endElement(String uri, String local, String raw) {
            if (XMLStructureCreator.DEBUG_MODE)
                System.out.println("\nExiting element " + fcurrentParent.getId()); //$NON-NLS-1$

            if (XMLStructureCreator.DEBUG_MODE)
                System.out.println("prevlocator: line " + prevlocator.getLineNumber() + "  column " + prevlocator.getColumnNumber() + "  id " + prevlocator.getPublicId()); //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
            if (XMLStructureCreator.DEBUG_MODE)
                System.out.println("locator: line " + locator.getLineNumber() + "  column " + locator.getColumnNumber() + "  id " + locator.getPublicId()); //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$

            if (fcurrentParent.getParent() != null) {
                try {
                    IRegion r2= fdoc.getLineInformation(locator.getLineNumber() - 1);
                    Position pos= fcurrentParent.getRange();

                    int elem_length= r2.getOffset() + locator.getColumnNumber() - 1 - pos.getOffset();//length of element from
                    // start tag to end tag
                    fcurrentParent.setLength(elem_length);
                    if (XMLStructureCreator.DEBUG_MODE)
                        System.out.println("pos.getOffset: " + pos.getOffset() + "  elem_length: " + elem_length); //$NON-NLS-2$ //$NON-NLS-1$
                    if (XMLStructureCreator.DEBUG_MODE)
                        System.out.println("fdoc.get(pos.getOffset()+elem_length-5,4): >" + fdoc.get(pos.getOffset() + elem_length - 5, 4) + "<"); //$NON-NLS-2$ //$NON-NLS-1$
                    //if (fdoc.get(pos.getOffset()+elem_length-2,1) != ">")
                    // elem_length-=1;
                    try {
                        fcurrentParent.setValue(fdoc.get(pos.getOffset(), elem_length));
                    } catch (BadLocationException ex) {
                        try {
                            fcurrentParent.setValue(fdoc.get(pos.getOffset(), elem_length - 1));
                        } catch (BadLocationException ex2) {
                            if (XMLStructureCreator.DEBUG_MODE) {
                                System.out.println("BadLocationException in endElement(...) while attempting fcurrentParent.setValue(...): " + ex); //$NON-NLS-1$
                                System.out.println("Attempt to correct BadLocationException failed: " + ex2); //$NON-NLS-1$
                            }
                        }
                    }
                    if (XMLStructureCreator.DEBUG_MODE)
                        System.out.println("Value of " + fcurrentParent.getId() + "  is >" + fcurrentParent.getValue() + "<"); //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$

                    //going from ending element to parent element
                    fcurrentParent= fcurrentParent.getParent();
                    if (XMLStructureCreator.DEBUG_MODE)
                        System.out.println("fcurrentParent = fcurrentParent.getParent();"); //$NON-NLS-1$
                } catch (BadLocationException ex) {
                    if (XMLStructureCreator.DEBUG_MODE) {
                        System.out.println("BadLocationException in endElement(...): " + ex); //$NON-NLS-1$
                        System.out.println("fcurrentParent.getId(): " + fcurrentParent.getId()); //$NON-NLS-1$
                    }
                }
            } else {
                if (XMLStructureCreator.DEBUG_MODE)
                    System.out.println("Error: Cannot reach Parent of Parent"); //$NON-NLS-1$
            }
            if (XMLStructureCreator.DEBUG_MODE)
                System.out.println("fcurrentParent is now " + fcurrentParent.getId()); //$NON-NLS-1$

            prevlocator= new LocatorImpl(locator);
            if (XMLStructureCreator.DEBUG_MODE)
                System.out.println("Signature before cutting: " + fsignature); //$NON-NLS-1$
            int ssi= fsignature.lastIndexOf(SIGN_SEPARATOR);//fsignature
            // separator index
            ssi= fsignature.lastIndexOf(SIGN_SEPARATOR, ssi - 1);//second-last
            // ".", e.g. in
            // root.a.b. to
            // obtain
            // root.a.
            fsignature= fsignature.substring(0, ssi + 1);
            if (XMLStructureCreator.DEBUG_MODE)
                System.out.println("Signature after cutting: " + fsignature); //$NON-NLS-1$
        }

        //
        // ErrorHandler methods
        //

        /* Warning. */
        @Override
		public void warning(SAXParseException ex) {
            System.err.println("[Warning] " + //$NON-NLS-1$
                    getLocationString(ex) + ": " + //$NON-NLS-1$
                    ex.getMessage());
        }

        /* Error. */
        @Override
		public void error(SAXParseException ex) {
            System.err.println("[Error] " + //$NON-NLS-1$
                    getLocationString(ex) + ": " + //$NON-NLS-1$
                    ex.getMessage());
        }

        /* Fatal error. */
        @Override
		public void fatalError(SAXParseException ex) throws SAXException {
            System.err.println("[Fatal Error] " + //$NON-NLS-1$
                    getLocationString(ex) + ": " + //$NON-NLS-1$
                    ex.getMessage());
            //System.out.println(ex);
            //throw ex;
        }

        /* Returns a string of the location. */
        private String getLocationString(SAXParseException ex) {
            StringBuilder str= new StringBuilder();

            String systemId= ex.getSystemId();
            if (systemId != null) {
                int index= systemId.lastIndexOf('/');
                if (index != -1)
                    systemId= systemId.substring(index + 1);
                str.append(systemId);
            }
            str.append(':');
            str.append(ex.getLineNumber());
            str.append(':');
            str.append(ex.getColumnNumber());

            return str.toString();

        }
    }

    public XMLStructureCreator() {
        //set default idmap
        fIdMapToUse= DEFAULT_IDMAP;
        fUseIdMap= false;
        XMLPlugin plugin= XMLPlugin.getDefault();
        //if statement required for tests
        if (plugin != null) {
            fIdMaps= plugin.getIdMaps();
            fIdMapsInternal= plugin.getIdMapsInternal();
            fIdExtensionToName= plugin.getIdExtensionToName();
            fOrderedElements= plugin.getOrderedElements();
            fOrderedElementsInternal= plugin.getOrderedElementsInternal();
        }
        fRemoveWhiteSpace= false;
    }

    /*
     * This title will be shown in the title bar of the structure compare pane.
     */
    @Override
	public String getName() {
        return DEFAULT_NAME;
    }

    /*
     * Set File extension of the parsed file. This extension will be used to choose an Id Map scheme.
     */
    public void setFileExtension(String ext) {
        fFileExt= ext;
    }

    /**
     * Initialize the Id Mappings for the Id Mapping Scheme and the Ordered Elements
     * This method must be called before getStructure(Object) is called on the two/three inputs of the compare
     */
    public void initIdMaps() {
        if (fFirstCall && fFileExt != null) {
            fFirstCall= false;
            String fileExtLower= fFileExt.toLowerCase();
            if (fIdExtensionToName.containsKey(fileExtLower))
                setIdMap((String) fIdExtensionToName.get(fileExtLower));
        }

        setUseIdMap();
        fOrdered= null;
        if (!isUseIdMap())
            idMap= null;
        else if (fIdMaps.containsKey(fIdMapToUse)) {
            idMap= (HashMap) fIdMaps.get(fIdMapToUse);
        } else if (fIdMapsInternal.containsKey(fIdMapToUse)) {
            idMap= (HashMap) fIdMapsInternal.get(fIdMapToUse);
        }

        if (fOrderedElements != null)
            fOrdered= (ArrayList) fOrderedElements.get(fIdMapToUse);
        if (fOrdered == null && fOrderedElementsInternal != null)
            fOrdered= (ArrayList) fOrderedElementsInternal.get(fIdMapToUse);
    }

    /*
     * Returns the XML parse tree of the input.
     */
    @Override
	public IStructureComparator getStructure(Object input) {
        if (XMLStructureCreator.DEBUG_MODE)
            System.out.println("Starting parse"); //$NON-NLS-1$

        if (!(input instanceof IStreamContentAccessor))
            return null;

        IStreamContentAccessor sca= (IStreamContentAccessor) input;

        try {
            // Input parsed with parser.parse(new InputSource(sca.getContents));	

            String contents= readString(sca);
            if (contents == null)
                contents= ""; //$NON-NLS-1$
            fdoc= new Document(contents);

            fsignature= ROOT_ID + SIGN_SEPARATOR;
            XMLChildren root= new XMLChildren(TYPE_ELEMENT, ROOT_ID, "", (fsignature + SIGN_ELEMENT), fdoc, 0, fdoc.getLength()); //$NON-NLS-1$
            fcurrentParent= root;

            XMLHandler handler= new XMLHandler();

            try {
                //            	/* original xerces code
                //            	SAXParser parser = (SAXParser)Class.forName(parserName).newInstance();
                //            	*/
                //				XMLReader parser = XMLReaderFactory.createXMLReader(parserName);
                //				
                //	            parser.setFeature( "http://xml.org/sax/features/validation", setValidation); //$NON-NLS-1$
                //    	        parser.setFeature( "http://xml.org/sax/features/namespaces", setNameSpaces ); //$NON-NLS-1$
                //    	        /*
                //    	        parser.setFeature( "http://apache.org/xml/features/nonvalidating/load-external-dtd", false); //$NON-NLS-1$
                //        	    parser.setFeature( "http://apache.org/xml/features/validation/schema", setSchemaSupport ); //$NON-NLS-1$
                //	            parser.setFeature( "http://apache.org/xml/features/validation/schema-full-checking", setSchemaFullSupport); //$NON-NLS-1$
                //	           	*/
                //	            parser.setContentHandler(handler);
                //	            parser.setErrorHandler(handler);
                //	            
                //	            parser.parse(new InputSource(sca.getContents()));

                SAXParserFactory factory= SAXParserFactory.newInstance();
                factory.setNamespaceAware(true);
                SAXParser parser= factory.newSAXParser();
                parser.parse(new InputSource(new StringReader(contents)), handler);

                if (XMLStructureCreator.DEBUG_MODE)
                    System.out.println("End of parse"); //$NON-NLS-1$
            } catch (SAXParseException e) {
                XMLPlugin.log(e);
                return null;
            } catch (Exception e) {
                //				MessageDialog.openError(XMLPlugin.getActiveWorkbenchShell(),"Error in XML parser","An error occured in the XML parser.\nNo structured compare can be shown");
                XMLPlugin.log(e);
                return null;
            }
            return root;
        } catch (CoreException ex) {
            XMLPlugin.log(ex);
        }
        return null;
    }

    public boolean canSave() {
        return true;
    }

    public boolean canRewriteTree() {
        return false;
    }

    public void rewriteTree(Differencer differencer, IDiffContainer root) {
    		// nothing to do
    }

    @Override
	public void save(IStructureComparator structure, Object input) {
        if (input instanceof IEditableContent && structure instanceof XMLNode) {
            IDocument document= ((XMLNode) structure).getDocument();
            IEditableContent bca= (IEditableContent) input;
			String contents= document.get();
			String encoding= null;
			if (input instanceof IEncodedStreamContentAccessor) {
				try {
					encoding= ((IEncodedStreamContentAccessor)input).getCharset();
				} catch (CoreException e1) {
					// ignore
				}
			}
			if (encoding == null)
				encoding= "UTF-8"; //$NON-NLS-1$
			try {
			    bca.setContent(contents.getBytes(encoding));
			} catch (UnsupportedEncodingException e) {
			    bca.setContent(contents.getBytes());	
			}
		}
	}

    @Override
	public String getContents(Object node, boolean ignoreWhitespace) {
        if (node instanceof XMLNode) {
            String s= ((XMLNode) node).getValue();
            if (ignoreWhitespace)
                s= s.trim();
            return s;
        }
        return null;
    }

    @Override
	public IStructureComparator locate(Object path, Object source) {
        return null;
    }

    static String readString(IStreamContentAccessor sa) throws CoreException {
        InputStream is= sa.getContents();
        String encoding= null;
        if (sa instanceof IEncodedStreamContentAccessor)
            encoding= ((IEncodedStreamContentAccessor) sa).getCharset();
        if (encoding == null)
            encoding= "UTF-8"; //$NON-NLS-1$
        return readString(is, encoding);
    }

    /*
     * Returns null if an error occurred.
     */
    private static String readString(InputStream is, String encoding) {
        if (is == null)
            return null;
        BufferedReader reader= null;
        try {
            StringBuilder buffer= new StringBuilder();
            char[] part= new char[2048];
            int read= 0;
            reader= new BufferedReader(new InputStreamReader(is, encoding));

            while ((read= reader.read(part)) != -1)
                buffer.append(part, 0, read);

            return buffer.toString();

        } catch (IOException ex) {
            // NeedWork
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException ex) {
                    // silently ignored
                }
            }
        }
        return null;
    }

    /* Returns a sorted list of attributes.
     */
    protected Attributes sortAttributes(Attributes attrs) {

        AttributesImpl attributes= new AttributesImpl();
        int len= (attrs != null) ? attrs.getLength() : 0;
        for (int i= 0; i < len; i++) {
            String name= attrs.getQName(i);
            int count= attributes.getLength();
            int j= 0;
            while (j < count) {
                if (name.compareTo(attributes.getQName(j)) < 0)
                    break;
                j++;
            }
            attributes.insertAttributeAt(j, name, attrs.getType(i), attrs.getValue(i));
        }

        return attributes;

    }

    public void setIdMap(String idmap_name) {
        fIdMapToUse= idmap_name;
    }

    /*
     * Returns the name of the IdMap Scheme that will be used to set ids.
     */
    public String getIdMap() {
        return fIdMapToUse;
    }

    public void setUseIdMap() {
        if (fIdMaps != null && fIdMapsInternal != null)
            fUseIdMap= fIdMaps.containsKey(fIdMapToUse) || fIdMapsInternal.containsKey(fIdMapToUse);
    }

    public boolean isUseIdMap() {
        return fUseIdMap;
    }

    public void updateIdMaps() {
        fIdMaps= XMLPlugin.getDefault().getIdMaps();
        fOrderedElements= XMLPlugin.getDefault().getOrderedElements();
    }

    protected boolean isWhiteSpace(char c) {
        return c == '\t' || c == '\n' || c == '\r' || c == ' ';
    }

    protected String removeWhiteSpace(String str) {
        str= trimWhiteSpace(str);
        StringBuilder retStr= new StringBuilder();
        int start= 0, end= 0;
        outer_while: while (true) {
            while (end < str.length() && !isWhiteSpace(str.charAt(end))) {
                end++;
            }
            if (end > str.length())
                break outer_while;
            if (start != 0)
                retStr.append(' ');
            retStr.append(str.substring(start, end));
            end++;
            while (end < str.length() && isWhiteSpace(str.charAt(end))) {
                end++;
            }
            start= end;
        }
        return retStr.toString();
    }

    protected String trimWhiteSpace(String str) {
        int start= 0, end= str.length() - 1;
        while (start < str.length() && isWhiteSpace(str.charAt(start))) {
            start++;
        }
        if (start == str.length())
            return ""; //$NON-NLS-1$
        while (end >= 0 && isWhiteSpace(str.charAt(end))) {
            end--;
        }
        return str.substring(start, end + 1);
    }

    public void setRemoveWhiteSpace(boolean removeWhiteSpace) {
        fRemoveWhiteSpace= removeWhiteSpace;
    }

    public boolean getRemoveWhiteSpace() {
        return fRemoveWhiteSpace;
    }
}
