/*******************************************************************************
 * 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) {
            StringBuffer str= new StringBuffer();

            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 {
            StringBuffer buffer= new StringBuffer();
            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);
        StringBuffer retStr= new StringBuffer();
        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;
    }
}
