You are viewing a plain text version of this content. The canonical link for it is here.
Posted to batik-commits@xmlgraphics.apache.org by ca...@apache.org on 2007/11/29 00:11:12 UTC

svn commit: r599191 - in /xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor: ./ XMLContext.java XMLDocument.java XMLEditorKit.java XMLScanner.java XMLTextEditor.java XMLToken.java XMLView.java

Author: cam
Date: Wed Nov 28 15:11:11 2007
New Revision: 599191

URL: http://svn.apache.org/viewvc?rev=599191&view=rev
Log:
Syntax highlighting XML text editor component contribution.  Thanks Tonny!

Submitted by: Tonny Kohar <tonny.kohar (at) gmail.com>

Added:
    xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor/
    xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor/XMLContext.java
    xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor/XMLDocument.java
    xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor/XMLEditorKit.java
    xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor/XMLScanner.java
    xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor/XMLTextEditor.java
    xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor/XMLToken.java
    xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor/XMLView.java

Added: xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor/XMLContext.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor/XMLContext.java?rev=599191&view=auto
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor/XMLContext.java (added)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor/XMLContext.java Wed Nov 28 15:11:11 2007
@@ -0,0 +1,165 @@
+/*
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+package org.apache.batik.util.gui.xmleditor;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.util.Map;
+import java.util.HashMap;
+
+import javax.swing.text.StyleContext;
+
+/**
+ * A pool of styles and their associated resources
+ *
+ * @author <a href="mailto:tonny@kiyut.com">Tonny Kohar</a>
+ * @version $Id$
+ */
+public class XMLContext extends StyleContext {
+
+    //public static String DEFAULT_SYNTAX          = "DEFAULT_SYNTAX";
+    public static final String XML_DECLARATION_STYLE  = "xml_declaration";
+    public static final String DOCTYPE_STYLE          = "doctype";
+    public static final String COMMENT_STYLE          = "comment";
+    public static final String ELEMENT_STYLE          = "element";
+    public static final String CHARACTER_DATA_STYLE   = "character_data";
+    public static final String ATTRIBUTE_NAME_STYLE   = "attribute_name";
+    public static final String ATTRIBUTE_VALUE_STYLE  = "attribute_value";
+    public static final String CDATA_STYLE            = "cdata";
+    
+    /** Map<String, Color> */
+    protected Map syntaxForegroundMap = null;
+    
+    /** Map<String, Font> */
+    protected Map syntaxFontMap = null;
+    
+    
+    public XMLContext() {
+        // initialize the default syntax highlight
+        // could be integrated with Application Preferences
+        
+        String syntaxName;
+        Font font;
+        Color fontForeground;
+        syntaxFontMap = new HashMap();
+        syntaxForegroundMap = new HashMap();        
+
+        Font defaultFont = new Font("Monospaced", Font.PLAIN, 12);
+        
+        syntaxName = XMLContext.DEFAULT_STYLE;
+        font = defaultFont;
+        fontForeground = Color.BLACK;
+        syntaxFontMap.put(syntaxName, font);
+        syntaxForegroundMap.put(syntaxName, fontForeground);
+        
+        syntaxName = XMLContext.XML_DECLARATION_STYLE;
+        font = defaultFont.deriveFont(Font.BOLD);
+        fontForeground = new Color(0, 0, 124);
+        syntaxFontMap.put(syntaxName, font);
+        syntaxForegroundMap.put(syntaxName, fontForeground);
+
+        syntaxName = XMLContext.DOCTYPE_STYLE;
+        font = defaultFont.deriveFont(Font.BOLD);
+        fontForeground = new Color(0, 0, 124);
+        syntaxFontMap.put(syntaxName, font);
+        syntaxForegroundMap.put(syntaxName, fontForeground);
+        
+        syntaxName = XMLContext.COMMENT_STYLE;
+        font = defaultFont;
+        fontForeground = new Color(128, 128, 128);
+        syntaxFontMap.put(syntaxName, font);
+        syntaxForegroundMap.put(syntaxName, fontForeground);
+        
+        syntaxName = XMLContext.ELEMENT_STYLE;
+        font = defaultFont;
+        fontForeground = new Color(0, 0, 255);
+        syntaxFontMap.put(syntaxName, font);
+        syntaxForegroundMap.put(syntaxName, fontForeground);
+
+        syntaxName = XMLContext.CHARACTER_DATA_STYLE;
+        font = defaultFont;
+        fontForeground = Color.BLACK;
+        syntaxFontMap.put(syntaxName, font);
+        syntaxForegroundMap.put(syntaxName, fontForeground);
+
+        syntaxName = XMLContext.ATTRIBUTE_NAME_STYLE;
+        font = defaultFont;
+        fontForeground = new Color(0, 124, 0);
+        syntaxFontMap.put(syntaxName, font);
+        syntaxForegroundMap.put(syntaxName, fontForeground);
+
+        syntaxName = XMLContext.ATTRIBUTE_VALUE_STYLE;
+        font = defaultFont;
+        fontForeground = new Color(153, 0, 107);
+        syntaxFontMap.put(syntaxName, font);
+        syntaxForegroundMap.put(syntaxName, fontForeground);
+
+        syntaxName = XMLContext.CDATA_STYLE;
+        font = defaultFont;
+        fontForeground = new Color(124, 98, 0);
+        syntaxFontMap.put(syntaxName, font);
+        syntaxForegroundMap.put(syntaxName, fontForeground);
+    }
+    
+    
+    
+    public Color getSyntaxForeground(int ctx) {
+        String name = getSyntaxName(ctx);
+        Color color = (Color)syntaxForegroundMap.get(name);
+        return color;
+    }
+    
+    public Font getSyntaxFont(int ctx) {
+        String name = getSyntaxName(ctx);
+        Font font = (Font)syntaxFontMap.get(name);
+        return font;
+    }
+    
+    public String getSyntaxName(int ctx) {
+        String name = CHARACTER_DATA_STYLE;
+        switch (ctx) {
+            case XMLScanner.XML_DECLARATION_CONTEXT:
+                name = XML_DECLARATION_STYLE;
+                break;
+            case XMLScanner.DOCTYPE_CONTEXT:
+                name = DOCTYPE_STYLE;
+                break;
+            case XMLScanner.COMMENT_CONTEXT:
+                name = COMMENT_STYLE;
+                break;
+            case XMLScanner.ELEMENT_CONTEXT:
+                name = ELEMENT_STYLE;
+                break;
+            case XMLScanner.ATTRIBUTE_NAME_CONTEXT:
+                name = ATTRIBUTE_NAME_STYLE;
+                break;
+            case XMLScanner.ATTRIBUTE_VALUE_CONTEXT:
+                name = ATTRIBUTE_VALUE_STYLE;
+                break;
+            case XMLScanner.CDATA_CONTEXT:
+                name = CDATA_STYLE;
+                break;
+            default:
+                // should not go here, just incase
+                name = DEFAULT_STYLE;
+                break;
+        }
+        return name;
+    }
+}

Added: xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor/XMLDocument.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor/XMLDocument.java?rev=599191&view=auto
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor/XMLDocument.java (added)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor/XMLDocument.java Wed Nov 28 15:11:11 2007
@@ -0,0 +1,174 @@
+/*
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+package org.apache.batik.util.gui.xmleditor;
+
+import javax.swing.text.AttributeSet;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Element;
+import javax.swing.text.PlainDocument;
+
+/**
+ * A document that can be marked up using XML style.
+ *
+ * @author <a href="mailto:tonny@kiyut.com">Tonny Kohar</a>
+ * @version $Id$
+ */
+public class XMLDocument extends PlainDocument {
+
+    protected XMLScanner lexer;
+    protected XMLContext context;
+    
+    protected XMLToken cacheToken = null;
+    
+    public XMLDocument() {
+        this(new XMLContext());
+    }
+
+    /** Creates a new instance of XMLDocument 
+     * @param context XMLContext
+     */
+    public XMLDocument(XMLContext context) {
+        //super(context);
+        this.context = context;
+        lexer = new XMLScanner();
+    }
+    
+    /** Return XMLToken
+     * @param pos position
+     * @return XMLToken
+     */
+    public XMLToken getScannerStart(int pos) throws BadLocationException {
+        int ctx = XMLScanner.CHARACTER_DATA_CONTEXT;
+        int offset = 0;
+        int tokenOffset = 0;
+        
+        if (cacheToken != null) {
+            if (cacheToken.getStartOffset() > pos) {
+                cacheToken = null;
+            } else {
+                ctx = cacheToken.getContext();
+                offset = cacheToken.getStartOffset();
+                tokenOffset = offset;
+                
+                Element element = getDefaultRootElement();
+                int line1 = element.getElementIndex(pos);
+                int line2 = element.getElementIndex(offset);
+                
+                //if (pos - offset <= 1800 ) {
+                if (line1 - line2 < 50) {
+                    return cacheToken;
+                }
+            }
+        }
+        
+        String str = getText(offset, pos - offset);
+        lexer.setString(str);
+        lexer.reset();
+        
+        // read until pos
+        int lastCtx = ctx;
+        int lastOffset = offset;
+        while (offset < pos) {
+            lastOffset = offset;
+            lastCtx = ctx;
+            
+            offset = lexer.scan(ctx) + tokenOffset;
+            ctx = lexer.getScanValue();
+        }
+        cacheToken = new XMLToken(lastCtx, lastOffset, offset);
+        return cacheToken;
+    }
+    
+    /** {@inheritDoc} */
+    public void insertString(int offset, String str, AttributeSet a)
+            throws BadLocationException {
+
+        super.insertString(offset, str, a);
+        
+        if (cacheToken != null) {
+            if (cacheToken.getStartOffset() >= offset) {
+                cacheToken = null;
+            }
+        }
+        
+    }
+    
+    /** {@inheritDoc} */
+    public void remove(int offs, int len) throws BadLocationException {
+        super.remove(offs, len);
+        
+        if (cacheToken != null) {
+            if (cacheToken.getStartOffset() >= offs) {
+                cacheToken = null;
+            }
+        }
+    }
+    
+    /**
+     * Find the first occurrence of the specified String starting at the specified index.
+     * @param str String to find
+     * @param fromIndex
+     * @param caseSensitive true or false
+     * @return the offset if the string argument occurs as a substring, otherwise return -1
+     * @throws BadLocationException if fromIndex was not a valid part of the document
+     */
+    public int find(String str, int fromIndex, boolean caseSensitive)
+            throws BadLocationException {
+
+        int offset = -1;
+        int startOffset = -1;
+        int len = 0;
+        int charIndex = 0;
+        
+        Element rootElement = getDefaultRootElement();
+        
+        int elementIndex = rootElement.getElementIndex(fromIndex);
+        if (elementIndex < 0) { return offset; }
+        
+        // set the initial charIndex
+        charIndex = fromIndex -
+            rootElement.getElement(elementIndex).getStartOffset();
+        
+        for (int i = elementIndex; i < rootElement.getElementCount(); i++) {
+            Element element = rootElement.getElement(i);
+            startOffset = element.getStartOffset();
+            if (element.getEndOffset() > getLength()) {
+               len = getLength() - startOffset;
+            } else {
+                len = element.getEndOffset() - startOffset;
+            }
+            
+            String text = getText(startOffset, len);
+            
+            if (!caseSensitive) {
+                text = text.toLowerCase();
+                str = str.toLowerCase();
+            }
+            
+            charIndex = text.indexOf(str, charIndex);
+            if (charIndex != -1) {
+                offset = startOffset + charIndex;
+                break;
+            }
+            charIndex = 0;  // reset the charIndex
+        }
+        
+        return offset;
+    }
+}

Added: xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor/XMLEditorKit.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor/XMLEditorKit.java?rev=599191&view=auto
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor/XMLEditorKit.java (added)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor/XMLEditorKit.java Wed Nov 28 15:11:11 2007
@@ -0,0 +1,93 @@
+/*
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+package org.apache.batik.util.gui.xmleditor;
+
+import javax.swing.text.DefaultEditorKit;
+import javax.swing.text.Document;
+import javax.swing.text.Element;
+import javax.swing.text.View;
+import javax.swing.text.ViewFactory;
+
+/**
+ * This is the set of things needed by a text component to be a reasonably
+ * functioning editor for xml type document.
+ *
+ * @author <a href="mailto:tonny@kiyut.com">Tonny Kohar</a>
+ * @version $Id$
+ */
+public class XMLEditorKit extends DefaultEditorKit {
+
+    public static final String XML_MIME_TYPE = "text/xml";
+    
+    protected XMLContext context;
+    protected ViewFactory factory = null;
+    
+    /** Creates a new instance of XMLEditorKit */
+    public XMLEditorKit() {
+        super();
+        factory = new XMLViewFactory();
+        context = new XMLContext();
+    }
+    
+    public XMLContext getStylePreferences() {
+        return context;
+    }
+    
+    public void setStylePreferences(XMLContext prefs) {
+        context = prefs;
+    }
+    
+    
+    /**
+     * Get the MIME type of the data that this
+     * kit represents support for.  This kit supports
+     * the type <code>text/xml</code>.
+     */
+    public String getContentType() {
+        return XML_MIME_TYPE;
+    }
+    
+    /** {@inheritDoc} */
+    public Object clone() {
+        XMLEditorKit kit = new XMLEditorKit();
+        kit.context = context;
+        return kit;
+    }
+    
+    /** {@inheritDoc} */
+    public Document createDefaultDocument() {
+        XMLDocument doc = new XMLDocument(context);
+        return doc;
+    }
+    
+    /** {@inheritDoc} */
+    public ViewFactory getViewFactory() {
+        return factory;
+    }
+    
+    /**
+     * A simple view factory implementation.
+     */
+    protected class XMLViewFactory implements ViewFactory {
+        // Creates the XML View.
+        public View create(Element elem) {
+            return new XMLView(context, elem);
+        }
+    }
+}

Added: xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor/XMLScanner.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor/XMLScanner.java?rev=599191&view=auto
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor/XMLScanner.java (added)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor/XMLScanner.java Wed Nov 28 15:11:11 2007
@@ -0,0 +1,329 @@
+/*
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+package org.apache.batik.util.gui.xmleditor;
+
+import org.apache.batik.xml.XMLUtilities;
+
+/**
+ * XML scanner for parsing xml text
+ *
+ * @author <a href="mailto:tonny@kiyut.com">Tonny Kohar</a>
+ * @version $Id$
+ */
+public class XMLScanner {
+
+    public static final int TEMP_ERROR_CONTEXT = -2;
+    public static final int EOF_CONTEXT = -1;
+    public static final int DEFAULT_CONTEXT = 0;
+    public static final int COMMENT_CONTEXT = 1;
+    public static final int ELEMENT_CONTEXT = 2;
+    public static final int CHARACTER_DATA_CONTEXT = 3;
+    public static final int ATTRIBUTE_NAME_CONTEXT = 4;
+    public static final int ATTRIBUTE_VALUE_CONTEXT = 5;
+    public static final int XML_DECLARATION_CONTEXT = 6;
+    public static final int DOCTYPE_CONTEXT = 7;
+    public static final int ENTITY_CONTEXT = 8;
+    public static final int ELEMENT_DECLARATION_CONTEXT = 9;
+    public static final int CDATA_CONTEXT = 10;
+    public static final int PI_CONTEXT = 11;
+    
+    
+    private int position;
+    private String string;
+    private int current;
+    private int scanValue;
+    private int startOffset;
+    
+    public XMLScanner() {
+        reset();
+    }
+    
+    public void reset() {
+        position = 0;
+        startOffset = 0;
+    }
+    
+    public void setString(String string) {
+        this.string = string;
+    }
+    
+    protected int nextChar() {
+        try {
+            current = (int)string.charAt(position);
+            position++;
+        } catch (Exception ex) {
+            current = -1;
+        }
+        
+        return current;
+    }
+    
+
+    protected int skipSpaces() {
+        do {
+            nextChar();
+        } while (current != -1 && XMLUtilities.isXMLSpace((char)current));
+        return current;
+    }
+    
+    public int getScanValue() {
+        return scanValue;
+    }
+    
+    public int getStartOffset() {
+        return startOffset;
+    }
+    
+    public int scan(int context) {
+        nextChar();
+        switch(context) {
+            case XML_DECLARATION_CONTEXT:
+                scanValue = scanXMLDeclaration();
+                break;
+            case DOCTYPE_CONTEXT:
+                scanValue = scanDOCTYPE();
+                break;
+            case COMMENT_CONTEXT:
+                scanValue = scanComment();
+                break;
+            case ELEMENT_CONTEXT:
+                scanValue = scanElement();
+                break;
+            case ATTRIBUTE_NAME_CONTEXT:
+                scanValue = scanAttributeName();
+                break;
+            case ATTRIBUTE_VALUE_CONTEXT:
+                scanValue = scanAttributeValue();
+                break;
+            case CDATA_CONTEXT:
+                scanValue = scanCDATA();
+                break;
+            default:
+                scanValue = scanCharacterData();
+                break;
+        }
+        return position;
+    }
+    
+    private int scanCharacterData() {
+        while (current != -1) {
+            if (current == '<') {
+                nextChar();
+                if (current == '?') {
+                    position = position - 2;
+                    return XML_DECLARATION_CONTEXT;
+                } else if (current == '!') {
+                    nextChar();
+                    if (current == 'D') {
+                        position = position - 3;
+                        return DOCTYPE_CONTEXT;
+                    } else if (current == '-') {
+                        nextChar();
+                        if (current == '-') {
+                            position = position - 4;
+                            return COMMENT_CONTEXT;
+                        }
+                    } else if (current == '[') {
+                        if (nextChar() == 'C') {
+                            if (nextChar() == 'D') {
+                                if (nextChar() == 'A') {
+                                    if (nextChar() == 'T') {
+                                        if (nextChar() == 'A') {
+                                            if (nextChar() == '[') {
+                                                position = position - 9;
+                                                return CDATA_CONTEXT;
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                } else {
+                    position = position - 2;
+                    return ELEMENT_CONTEXT;
+                }
+            }
+            nextChar();
+        }
+        
+        if (current == -1) {
+            return EOF_CONTEXT;
+        }
+        
+        return CHARACTER_DATA_CONTEXT;
+    }
+    
+    private int scanXMLDeclaration() {
+        position = position + 2;    // to skip the first <?
+        while(current != -1) {
+            if (current == '?') {
+                if (nextChar() == '>') {
+                    return CHARACTER_DATA_CONTEXT;
+                } else {
+                    return TEMP_ERROR_CONTEXT;
+                }
+            }
+            nextChar();
+        }
+        
+        if (current == -1) {
+            return EOF_CONTEXT;
+        }
+        
+        return XML_DECLARATION_CONTEXT;
+    }
+    
+    private int scanDOCTYPE() {
+        position = position + 3;    // to skip the first <!D
+        boolean end = true;
+        while(current != -1) {
+            if (current == '[') {
+                end = false;
+            } else if (current == ']') {
+                end = true;
+            } else if (current == '>' && end == true) {
+                return CHARACTER_DATA_CONTEXT;
+            }
+            nextChar();
+        }
+        
+        if (current == -1) {
+            return EOF_CONTEXT;
+        }
+        
+        return DOCTYPE_CONTEXT;
+    }
+    
+    private int scanComment() {
+        //position = position + 4;    // to skip the first <!--
+        
+        while(current != -1) {
+            if (current == '-') {
+                if (nextChar() == '-') {
+                    if (nextChar() == '>') {
+                        return CHARACTER_DATA_CONTEXT;
+                    }
+                }
+            }
+            nextChar();
+        }
+        
+        if (current == -1) {
+            return EOF_CONTEXT;
+        }
+        
+        
+        return COMMENT_CONTEXT;
+    }
+    
+    /**
+     * Returns the next lexical unit in the context of a start tag.
+     */
+    private int scanElement() {
+        //position = position + 1;    // to skip the first <
+        while (current != -1) {
+            if (current == '>') {
+                return CHARACTER_DATA_CONTEXT;
+            } else if (XMLUtilities.isXMLSpace((char)current)) {
+                return ATTRIBUTE_NAME_CONTEXT;
+            } 
+            
+            nextChar();
+        }
+        
+        if (current == -1) {
+            return EOF_CONTEXT;
+        }
+        
+        return ELEMENT_CONTEXT;
+    }
+    
+    private int scanAttributeName() {
+        while (current != -1) {
+            if (current == '=') {
+                return ATTRIBUTE_VALUE_CONTEXT;
+            } else if (current == '/') {
+                position--;
+                return ELEMENT_CONTEXT;
+            } else if (current == '>') {
+                position--;
+                return ELEMENT_CONTEXT;
+            }
+            nextChar();
+        }
+        
+        if (current == -1) {
+            return EOF_CONTEXT;
+        }
+        
+        return ATTRIBUTE_NAME_CONTEXT;
+    }
+    
+    private int scanAttributeValue() {
+        
+        int delim = '"';
+        
+        // looking for the first delimiter
+        while (current != -1) {
+            if ((current == '"') || (current == '\'')) {
+                delim = current;
+                break;
+            }
+            nextChar();
+        }
+        
+        nextChar();
+        
+        // looking for the second delimiter
+        while (current != -1) {
+            if (current == delim) {
+                return ELEMENT_CONTEXT;
+            }
+            nextChar();
+        }
+        
+        if (current == -1) {
+            return EOF_CONTEXT;
+        }
+        
+        return ATTRIBUTE_VALUE_CONTEXT;
+    }
+    
+    private int scanCDATA() {
+        //position = position + 9;    // to skip the first <![CDATA[
+        
+        while(current != -1) {
+            if (current == ']') {
+                if (nextChar() == ']') {
+                    if (nextChar() == '>') {
+                        return CHARACTER_DATA_CONTEXT;
+                    }
+                }
+            }
+            nextChar();
+        }
+        
+        if (current == -1) {
+            return EOF_CONTEXT;
+        }
+        
+        return CDATA_CONTEXT;
+    }
+}

Added: xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor/XMLTextEditor.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor/XMLTextEditor.java?rev=599191&view=auto
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor/XMLTextEditor.java (added)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor/XMLTextEditor.java Wed Nov 28 15:11:11 2007
@@ -0,0 +1,101 @@
+/*
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+package org.apache.batik.util.gui.xmleditor;
+
+import java.awt.Color;
+import java.awt.Font;
+
+import javax.swing.JEditorPane;
+import javax.swing.event.UndoableEditEvent;
+import javax.swing.event.UndoableEditListener;
+import javax.swing.text.Element;
+import javax.swing.undo.CannotRedoException;
+import javax.swing.undo.CannotUndoException;
+import javax.swing.undo.UndoManager;
+
+/**
+ * Simple Text Component to edit xml document with integrated undo / redo behaviour.
+ * If you looking for how to create editor component with syntax highlight,
+ * just create any JEditorPane and supply it with XMLEditoKit eg:
+ * <pre>
+ * JEditorPane editor = new JEditorPane();
+ * editor.setEditorKitForContentType(XMLEditorKit.XML_MIME_TYPE, new XMLEditorKit();
+ * editor.setContentType(XMLEditorKit.XML_MIME_TYPE);
+ * </pre>
+ *
+ * @author <a href="mailto:tonny@kiyut.com">Tonny Kohar</a>
+ * @version $Id$
+ */
+public class XMLTextEditor extends JEditorPane {
+
+    protected UndoManager undoManager;
+    
+    /** Creates a new instance of XMLEditorPane */
+    public XMLTextEditor() {
+        super();
+        XMLEditorKit kit = new XMLEditorKit();
+        setEditorKitForContentType(XMLEditorKit.XML_MIME_TYPE, kit);
+        setContentType(XMLEditorKit.XML_MIME_TYPE);
+        setBackground(Color.white);
+        setFont(new Font("Monospaced", Font.PLAIN, 12));
+                
+        // add undoable edit
+        undoManager = new UndoManager();
+        UndoableEditListener undoableEditHandler = new UndoableEditListener() {
+            public void undoableEditHappened(UndoableEditEvent e) {
+                undoManager.addEdit(e.getEdit());
+            }
+        };
+        getDocument().addUndoableEditListener(undoableEditHandler);
+    }
+    
+    /** {@inheritDoc} */
+    public void setText(String t) {
+        super.setText(t);
+        
+        undoManager.discardAllEdits();
+    }
+    
+    /** Undo */
+    public void undo() {
+        try {
+            undoManager.undo();
+        } catch (CannotUndoException ex) { }
+    }
+    
+    /** Redo */
+    public void redo() {
+        try {
+            undoManager.redo();
+        } catch (CannotRedoException ex) { }
+    }
+    
+    
+    /** Move the cursor to the specified line
+     * if exception occur cursor not change
+     * @param line the specified line number
+     */
+    public void gotoLine(int line) {
+        Element element =
+            getDocument().getDefaultRootElement().getElement(line);
+        if (element == null) { return; }
+        int pos = element.getStartOffset();
+        setCaretPosition(pos);
+    }
+}

Added: xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor/XMLToken.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor/XMLToken.java?rev=599191&view=auto
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor/XMLToken.java (added)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor/XMLToken.java Wed Nov 28 15:11:11 2007
@@ -0,0 +1,51 @@
+/*
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+package org.apache.batik.util.gui.xmleditor;
+
+/**
+ * XML Token
+ * 
+ * @author <a href="mailto:tonny@kiyut.com">Tonny Kohar</a>
+ * @version $Id$
+ */
+public class XMLToken {
+
+    private int context;
+    private int startOffset;
+    private int endOffset;
+    
+    /** Creates a new instance of XMLToken */
+    public XMLToken(int context, int startOffset, int endOffset) {
+        this.context = context;
+        this.startOffset = startOffset;
+        this.endOffset = endOffset;
+    }
+    
+    public int getContext() {
+        return context;
+    }
+    
+    public int getStartOffset() {
+        return startOffset;
+    }
+    
+    public int getEndOffset() {
+        return endOffset;
+    }
+}

Added: xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor/XMLView.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor/XMLView.java?rev=599191&view=auto
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor/XMLView.java (added)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/util/gui/xmleditor/XMLView.java Wed Nov 28 15:11:11 2007
@@ -0,0 +1,122 @@
+/*
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+package org.apache.batik.util.gui.xmleditor;
+
+import java.awt.Graphics;
+import java.awt.Shape;
+
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Element;
+import javax.swing.text.PlainView;
+import javax.swing.text.Segment;
+import javax.swing.text.Utilities;
+import javax.swing.text.ViewFactory;
+
+/**
+ * View that uses the lexical information to determine the
+ * style characteristics of the text that it renders.  This
+ * simply colorizes the various tokens and assumes a constant
+ * font family and size.
+ *
+ * @author <a href="mailto:tonny@kiyut.com">Tonny Kohar</a>
+ * @version $Id$
+ */
+public class XMLView extends PlainView {
+
+    protected XMLContext context = null;
+    protected XMLScanner lexer = new XMLScanner();
+    protected int tabSize = 4;
+    
+    /**
+     * Construct a simple colorized view of java
+     * text.
+     */
+    public XMLView(XMLContext context, Element elem) {
+        super(elem);
+        this.context = context;
+    }
+    
+    /** {@inheritDoc} */
+    public int getTabSize() {
+        return tabSize;
+    }
+    
+    /** {@inheritDoc} */
+    protected int drawUnselectedText(Graphics g, int x, int y, int p0, int p1)
+            throws BadLocationException {
+
+        XMLDocument doc = (XMLDocument)getDocument();
+        XMLToken token = doc.getScannerStart(p0);
+        
+        String str = doc.getText(token.getStartOffset(),
+                                 (p1-token.getStartOffset()) + 1);
+        
+        lexer.setString(str);
+        lexer.reset();
+        
+        // read until p0
+        int pos = token.getStartOffset();
+        int ctx = token.getContext();
+        int lastCtx = ctx;
+        while (pos < p0) {
+            pos = lexer.scan(ctx) + token.getStartOffset();
+            lastCtx = ctx;
+            ctx = lexer.getScanValue();
+        }
+        int mark = p0;
+        
+        while (pos < p1) {
+            if (lastCtx != ctx) {
+                //syntax = context.getSyntaxName(lastCtx);
+                g.setColor(context.getSyntaxForeground(lastCtx));
+                g.setFont(context.getSyntaxFont(lastCtx));
+                Segment text = getLineBuffer();
+                doc.getText(mark, pos - mark, text);
+                x = Utilities.drawTabbedText(text, x, y, g, this, mark);
+                mark = pos;
+            }
+            
+            pos = lexer.scan(ctx) + token.getStartOffset();
+            lastCtx = ctx;
+            ctx = lexer.getScanValue();
+            
+        }
+        
+        // flush remaining
+        //syntax = context.getSyntaxName(lastCtx);
+        g.setColor(context.getSyntaxForeground(lastCtx));
+        g.setFont(context.getSyntaxFont(lastCtx));
+        Segment text = getLineBuffer();
+        doc.getText(mark, p1 - mark, text);
+        x = Utilities.drawTabbedText(text, x, y, g, this, mark);
+        
+        return x;
+    }
+    
+    /** Overriden to handle multi line node
+     * {@inheritDoc}
+     */
+    protected void updateDamage(javax.swing.event.DocumentEvent changes,
+                                Shape a,
+                                ViewFactory f) {
+        super.updateDamage(changes, a, f);
+        java.awt.Component host = getContainer();
+        host.repaint();
+    }
+}