You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2009/03/11 12:56:51 UTC

svn commit: r752430 - in /cayenne/main/trunk: ./ framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/ framework/cayenne-modeler/src/main/java/org/apache/caye...

Author: aadamchik
Date: Wed Mar 11 11:56:50 2009
New Revision: 752430

URL: http://svn.apache.org/viewvc?rev=752430&view=rev
Log:
CAY-1164 Implement EJBQL query support in the Modeler

patch by Olga Tkachova implementing our own text pane with syntax hihglighting

Added:
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/EditorKit.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/JCayenneTextPane.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/TextPaneView.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/TextPaneViewFactory.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/UnderlineHighlighterForText.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/style/
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/style/SyntaxStyle.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/style/TextPaneStyleMap.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/style/TextPaneStyleTypes.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/syntax/
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/syntax/EJBQLSyntaxConstant.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/syntax/SQLSyntaxConstants.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/syntax/SyntaxConstant.java
Modified:
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EjbqlQueryScriptsTab.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/CayenneWidgetFactory.java
    cayenne/main/trunk/pom.xml

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EjbqlQueryScriptsTab.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EjbqlQueryScriptsTab.java?rev=752430&r1=752429&r2=752430&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EjbqlQueryScriptsTab.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EjbqlQueryScriptsTab.java Wed Mar 11 11:56:50 2009
@@ -20,7 +20,6 @@
 
 import java.awt.BorderLayout;
 import javax.swing.JPanel;
-import javax.swing.JScrollPane;
 import javax.swing.event.DocumentEvent;
 import javax.swing.event.DocumentListener;
 import javax.swing.text.BadLocationException;
@@ -31,87 +30,43 @@
 import org.apache.cayenne.modeler.util.CayenneWidgetFactory;
 import org.apache.cayenne.query.EJBQLQuery;
 import org.apache.cayenne.query.Query;
+import org.apache.cayenne.swing.components.textpane.JCayenneTextPane;
 import org.apache.cayenne.util.Util;
-import org.syntax.jedit.JEditTextArea;
-import org.syntax.jedit.KeywordMap;
-import org.syntax.jedit.tokenmarker.PLSQLTokenMarker;
-import org.syntax.jedit.tokenmarker.SQLTokenMarker;
-import org.syntax.jedit.tokenmarker.Token;
-import org.syntax.jedit.tokenmarker.TokenMarker;
-
-import com.jgoodies.forms.builder.PanelBuilder;
-import com.jgoodies.forms.layout.CellConstraints;
-import com.jgoodies.forms.layout.FormLayout;
 
-
-public class EjbqlQueryScriptsTab extends JPanel implements DocumentListener{
+public class EjbqlQueryScriptsTab extends JPanel implements DocumentListener {
 
     protected ProjectController mediator;
-    
-    static final TokenMarker SQL_TEMPLATE_MARKER;
-    static {
-        KeywordMap map = PLSQLTokenMarker.getKeywordMap();
-        
-        //adding more keywords
-        map.add("FIRST", Token.KEYWORD1);
-        map.add("LIMIT", Token.KEYWORD1);
-        map.add("OFFSET", Token.KEYWORD1);
-        map.add("TOP", Token.KEYWORD1);
-        
-        //adding velocity template highlighing
-        map.add("#bind", Token.KEYWORD2);
-        map.add("#bindEqual", Token.KEYWORD2);
-        map.add("#bindNotEqual", Token.KEYWORD2);
-        map.add("#bindObjectEqual", Token.KEYWORD2);
-        map.add("#bindObjectNotEqual", Token.KEYWORD2);
-        map.add("#chain", Token.KEYWORD2);
-        map.add("#chunk", Token.KEYWORD2);
-        map.add("#end", Token.KEYWORD2);
-        map.add("#result", Token.KEYWORD2);
-        
-        SQL_TEMPLATE_MARKER = new SQLTokenMarker(map);
-    }
-    
+
     /**
      * JEdit text component for highlighing SQL syntax (see CAY-892)
      */
-    protected JEditTextArea scriptArea;
- 
+    protected JCayenneTextPane scriptArea;
+    protected JPanel panelArea;
     private boolean updateDisabled;
-    
+
     public EjbqlQueryScriptsTab(ProjectController mediator) {
         this.mediator = mediator;
         initView();
     }
-    
+
     void displayScript() {
         EJBQLQuery query = getQuery();
         updateDisabled = true;
         scriptArea.setText(query.getEjbqlStatement());
         updateDisabled = false;
-     }
+    }
 
     private void initView() {
- 
-        scriptArea = CayenneWidgetFactory.createJEditTextArea();     
-        scriptArea.setTokenMarker(SQL_TEMPLATE_MARKER);  
+
+        scriptArea = CayenneWidgetFactory.createJEJBQLTextPane();
         scriptArea.getDocument().addDocumentListener(this);
-        CellConstraints cc = new CellConstraints();
-        
-        FormLayout formLayout = new FormLayout(
-                "fill:0dlu:grow", 
-                "fill:0dlu:grow");
-
-        formLayout.maximumLayoutSize(scriptArea);
-        PanelBuilder builder = new PanelBuilder(formLayout);
-      
-        builder.add(new JScrollPane(scriptArea), cc.xy(1,1));
-        
+
         setLayout(new BorderLayout());
-        add(builder.getPanel(), BorderLayout.CENTER); 
+        add(scriptArea, BorderLayout.WEST);
+        add(scriptArea.scrollPane, BorderLayout.CENTER);
+        setVisible(true);
     }
 
-
     public void initFromModel() {
         Query query = mediator.getCurrentQuery();
 
@@ -119,21 +74,20 @@
             setVisible(false);
             return;
         }
-        
-        scriptArea.setEnabled(true);      
+        scriptArea.setEnabled(true);
         displayScript();
-        setVisible(true);    
-   
+        setVisible(true);
+
     }
-    
+
     EJBQLQuery getQuery() {
         Query query = mediator.getCurrentQuery();
         return (query instanceof EJBQLQuery) ? (EJBQLQuery) query : null;
     }
-    
+
     void setEJBQL(DocumentEvent e) {
         Document doc = e.getDocument();
-     
+
         try {
             setEJBQL(doc.getText(0, doc.getLength()));
         }
@@ -141,7 +95,7 @@
             e1.printStackTrace();
         }
     }
-    
+
     void setEJBQL(String text) {
         EJBQLQuery query = getQuery();
         if (query == null) {
@@ -158,12 +112,12 @@
         // Compare the value before modifying the query - text area
         // will call "verify" even if no changes have occured....
         if (!Util.nullSafeEquals(text, query.getEjbqlStatement())) {
-             query.setEjbqlStatement(text);
-             mediator.fireQueryEvent(new QueryEvent(this, query));
+            query.setEjbqlStatement(text);
+            mediator.fireQueryEvent(new QueryEvent(this, query));
         }
-        
+
     }
- 
+
     public void insertUpdate(DocumentEvent e) {
         changedUpdate(e);
     }
@@ -171,7 +125,7 @@
     public void removeUpdate(DocumentEvent e) {
         changedUpdate(e);
     }
-    
+
     public void changedUpdate(DocumentEvent e) {
         if (!updateDisabled) {
             setEJBQL(e);

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/CayenneWidgetFactory.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/CayenneWidgetFactory.java?rev=752430&r1=752429&r2=752430&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/CayenneWidgetFactory.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/CayenneWidgetFactory.java Wed Mar 11 11:56:50 2009
@@ -40,6 +40,8 @@
 import org.apache.cayenne.modeler.ModelerPreferences;
 import org.apache.cayenne.modeler.util.combo.AutoCompletion;
 import org.apache.cayenne.modeler.util.combo.ComboBoxCellEditor;
+import org.apache.cayenne.swing.components.textpane.JCayenneTextPane;
+import org.apache.cayenne.swing.components.textpane.syntax.EJBQLSyntaxConstant;
 import org.syntax.jedit.DefaultInputHandler;
 import org.syntax.jedit.JEditTextArea;
 
@@ -189,7 +191,18 @@
         
         return area;
     }
+    
+//    public static JSQLTextPane createJSQLTextPane() {
+//        JSQLTextPane area = new JSQLTextPane();
+//        return area;
+//    }
  
+    public static JCayenneTextPane createJEJBQLTextPane() {
+        JCayenneTextPane area = new JCayenneTextPane(new EJBQLSyntaxConstant());
+        return area;
+    }
+ 
+    
     /**
      * Class for enabling Mac OS X keys
      */

Added: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/EditorKit.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/EditorKit.java?rev=752430&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/EditorKit.java (added)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/EditorKit.java Wed Mar 11 11:56:50 2009
@@ -0,0 +1,26 @@
+package org.apache.cayenne.swing.components.textpane;
+
+import javax.swing.text.StyledEditorKit;
+import javax.swing.text.ViewFactory;
+import org.apache.cayenne.swing.components.textpane.syntax.SyntaxConstant;
+
+public class EditorKit extends StyledEditorKit {
+
+    private ViewFactory xmlViewFactory;
+    private String contentType;
+
+    public EditorKit(SyntaxConstant syntaxConstant) {
+        contentType = syntaxConstant.getContentType();
+        xmlViewFactory = new TextPaneViewFactory(syntaxConstant);
+    }
+
+    @Override
+    public ViewFactory getViewFactory() {
+        return xmlViewFactory;
+    }
+
+    @Override
+    public String getContentType() {
+        return contentType;
+    }
+}

Added: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/JCayenneTextPane.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/JCayenneTextPane.java?rev=752430&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/JCayenneTextPane.java (added)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/JCayenneTextPane.java Wed Mar 11 11:56:50 2009
@@ -0,0 +1,263 @@
+package org.apache.cayenne.swing.components.textpane;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Point;
+import java.awt.Rectangle;
+
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextPane;
+import javax.swing.JViewport;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Document;
+import javax.swing.text.Highlighter;
+
+import org.apache.cayenne.swing.components.textpane.syntax.SQLSyntaxConstants;
+import org.apache.cayenne.swing.components.textpane.syntax.SyntaxConstant;
+
+public class JCayenneTextPane extends JPanel {
+
+    protected Highlighter.HighlightPainter painter;
+    private JTextPaneScrollable pane;
+    public JScrollPane scrollPane;
+    public boolean repaint;
+
+    public void setText(String text) {
+        pane.setText(text);
+    }
+
+    public String getText() {
+        return pane.getText();
+    }
+
+    public int getStartPositionInDocument() {
+        return pane.viewToModel(scrollPane.getViewport().getViewPosition());
+        // starting pos
+        // in document
+    }
+
+    public int getEndPositionInDocument() {
+        return pane.viewToModel(new Point(scrollPane.getViewport().getViewPosition().x
+                + pane.getWidth(), scrollPane.getViewport().getViewPosition().y
+                + pane.getHeight()));
+    }
+
+    /**
+     * Return an int containing the wrapped line index at the given position
+     * 
+     * @param int pos
+     * @return int
+     */
+    public int getLineNumber(int pos) {
+        int posLine;
+        int y = 0;
+
+        try {
+            Rectangle caretCoords = pane.modelToView(pos);
+            y = (int) caretCoords.getY();
+        }
+        catch (BadLocationException ex) {
+        }
+
+        int lineHeight = pane.getFontMetrics(pane.getFont()).getHeight();
+        posLine = (y / lineHeight) + 1;
+        return posLine;
+    }
+
+    /**
+     * Return an int position at the given line number and symbol position in this line
+     * 
+     * @param int posInLine
+     * @param int line
+     * @return int
+     * @throws BadLocationException
+     */
+    public int getPosition(int line, int posInLine) throws BadLocationException {
+        // translate lines to offsets
+        int position = -1;
+        int numrows = 1;
+        char[] chararr = pane.getText().toCharArray();
+        for (int i = 0; i < chararr.length; i++) {
+            if (chararr[i] == '\n') {
+                numrows++;
+                if (numrows == line) {
+                    position = i;
+                    break;
+                }
+            }
+        }
+        return position + posInLine;
+    }
+
+    public JCayenneTextPane(SyntaxConstant syntaxConstant) {
+        super();
+
+        setMinimumSize(new Dimension(30, 30));
+        setPreferredSize(new Dimension(30, 30));
+        setMinimumSize(new Dimension(30, 30));
+        setBackground(new Color(245, 238, 238));
+        setBorder(null);
+        pane = new JTextPaneScrollable(new EditorKit(syntaxConstant)) {           
+            public void paint(Graphics g) {
+                super.paint(g);
+                JCayenneTextPane.this.repaint();
+            }
+        };
+
+        pane.setFont(SQLSyntaxConstants.DEFAULT_FONT);
+
+        scrollPane = new JScrollPane(pane);
+
+        this.painter = new UnderlineHighlighterForText.UnderlineHighlightPainter(
+                Color.red);
+
+        pane.getDocument().addDocumentListener(new DocumentListener() {
+
+            public void insertUpdate(DocumentEvent evt) {
+                try {
+                    removeHighlightText();
+                }
+                catch (BadLocationException e) {
+                    e.printStackTrace();
+                }
+
+                try {
+                    if (pane.getText(evt.getOffset(), 1).toString().equals("/")
+                            || pane.getText(evt.getOffset(), 1).toString().equals("*")) {
+                        pane.repaint();
+                    }
+                }
+                catch (BadLocationException e) {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                }
+            }
+
+            public void removeUpdate(DocumentEvent evt) {
+                try {
+                    removeHighlightText();
+                }
+                catch (BadLocationException e) {
+                    e.printStackTrace();
+                }
+
+            }
+
+            public void changedUpdate(DocumentEvent evt) {
+
+            }
+
+        });
+    }
+
+    public void setHighlightText(int lastIndex, int endIndex) throws BadLocationException {
+        Highlighter highlighter = pane.getHighlighter();
+        removeHighlightText(highlighter);
+        highlighter.addHighlight(lastIndex, endIndex, painter);
+    }
+
+    public void setHighlightText(int line, int lastIndex, int size)
+            throws BadLocationException {
+
+        int position = getPosition(line, lastIndex);
+        int positionEnd = position + size;
+        Highlighter highlighter = pane.getHighlighter();
+        removeHighlightText(highlighter);
+        highlighter.addHighlight(position, positionEnd, painter);
+    }
+
+    public void removeHighlightText(Highlighter highlighter) throws BadLocationException {
+
+        Highlighter.Highlight[] highlights = highlighter.getHighlights();
+        for (int i = 0; i < highlights.length; i++) {
+            Highlighter.Highlight h = highlights[i];
+            if (h.getPainter() instanceof UnderlineHighlighterForText.UnderlineHighlightPainter) {
+                highlighter.removeHighlight(h);
+            }
+        }
+    }
+
+    public void removeHighlightText() throws BadLocationException {
+        Highlighter highlighter = pane.getHighlighter();
+        removeHighlightText(highlighter);
+    }
+
+    public void paint(Graphics g) {
+
+        super.paint(g);
+
+        int start = getStartPositionInDocument();
+        int end = getEndPositionInDocument();
+        // end pos in doc
+
+        // translate offsets to lines
+        Document doc = pane.getDocument();
+        int startline = doc.getDefaultRootElement().getElementIndex(start) + 1;
+        int endline = doc.getDefaultRootElement().getElementIndex(end) + 1;
+
+        int fontHeight = g.getFontMetrics(pane.getFont()).getHeight();
+        int fontDesc = g.getFontMetrics(pane.getFont()).getDescent();
+        int starting_y = -1;
+
+        try {
+            starting_y = pane.modelToView(start).y
+                    - scrollPane.getViewport().getViewPosition().y
+                    + fontHeight
+                    - fontDesc;
+        }
+        catch (BadLocationException e1) {
+            e1.printStackTrace();
+        }
+
+        for (int line = startline, y = starting_y; line <= endline; y += fontHeight, line++) {
+            Color color = g.getColor();
+            g.setColor(Color.gray);
+            Font f2 = SQLSyntaxConstants.DEFAULT_FONT;
+            FontMetrics fm2 = getFontMetrics(f2);
+            g.setFont(f2);
+
+            g.drawString(Integer.toString(line), (30 - fm2.stringWidth(Integer
+                    .toString(line))) / 2, y);
+            g.setColor(color);
+        }
+
+    }
+
+    public Document getDocument() {
+        return pane.getDocument();
+    }
+
+    class JTextPaneScrollable extends JTextPane {
+
+        // private static final long serialVersionUID = 6270183148379328084L;
+
+        public JTextPaneScrollable(EditorKit editorKit) {
+            // Set editor kit
+            this.setEditorKitForContentType(editorKit.getContentType(), editorKit);
+            this.setContentType(editorKit.getContentType());
+        }
+
+        @Override
+        public boolean getScrollableTracksViewportWidth() {
+            if (getParent() instanceof JViewport) {
+                JViewport port = (JViewport) getParent();
+                if (port.getWidth() > getUI().getPreferredSize(this).width) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        @Override
+        public void paintComponent(Graphics g) {
+            super.paintComponent(g);
+        }
+    }
+
+}

Added: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/TextPaneView.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/TextPaneView.java?rev=752430&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/TextPaneView.java (added)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/TextPaneView.java Wed Mar 11 11:56:50 2009
@@ -0,0 +1,249 @@
+package org.apache.cayenne.swing.components.textpane;
+
+import java.awt.Graphics;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Element;
+import javax.swing.text.PlainDocument;
+import javax.swing.text.PlainView;
+import javax.swing.text.Segment;
+import javax.swing.text.StyledDocument;
+import javax.swing.text.Utilities;
+
+import org.apache.cayenne.swing.components.textpane.style.TextPaneStyleMap;
+import org.apache.cayenne.swing.components.textpane.style.TextPaneStyleTypes;
+import org.apache.cayenne.swing.components.textpane.style.SyntaxStyle;
+import org.apache.cayenne.swing.components.textpane.syntax.SQLSyntaxConstants;
+import org.apache.cayenne.swing.components.textpane.syntax.SyntaxConstant;
+
+public class TextPaneView extends PlainView {
+
+    private static HashMap<Pattern, SyntaxStyle> patternSyntaxStyle;
+    private static Pattern patternComment;
+    private static Pattern patternCommentStart;
+
+    private static SyntaxStyle syntaxStyleComment;
+    private static HashMap<Pattern, SyntaxStyle> patternValue;
+
+    static {
+        patternSyntaxStyle = new HashMap<Pattern, SyntaxStyle>();
+        patternValue = new HashMap<Pattern, SyntaxStyle>();
+    }
+
+    public TextPaneView(Element elem, SyntaxConstant syntaxConstants) {
+
+        super(elem);
+        getDocument().putProperty(PlainDocument.tabSizeAttribute, 4);
+        TextPaneStyleMap style = new TextPaneStyleMap();
+
+        if (patternSyntaxStyle.size() == 0) {
+
+            String[] keywords = syntaxConstants.getKEYWORDS();
+            String[] keywords2 = syntaxConstants.getKEYWORDS2();
+            String[] operators = syntaxConstants.getOPERATORS();
+            String[] types = syntaxConstants.getTYPES();
+            
+            for (int i = 0; i < keywords.length; i++) {
+                String patern = "(" + keywords[i] + ")";
+                patternSyntaxStyle.put(Pattern.compile(patern, Pattern.UNICODE_CASE
+                        | Pattern.CASE_INSENSITIVE), style.syntaxStyleMap
+                        .get(TextPaneStyleTypes.KEYWORDS));
+            }
+            for (int i = 0; i < keywords2.length; i++) {
+                String patern = "(" + keywords2[i] + ")";
+                patternSyntaxStyle.put(Pattern.compile(patern, Pattern.UNICODE_CASE
+                        | Pattern.CASE_INSENSITIVE), style.syntaxStyleMap
+                        .get(TextPaneStyleTypes.KEYWORDS2));
+            }
+            for (int i = 0; i < operators.length; i++) {
+                String patern = "(" + operators[i] + ")";
+                patternSyntaxStyle.put(Pattern.compile(patern, Pattern.UNICODE_CASE
+                        | Pattern.CASE_INSENSITIVE), style.syntaxStyleMap
+                        .get(TextPaneStyleTypes.KEYWORDS));
+            }           
+            for (int i = 0; i < types.length; i++) {
+                String patern = "(" + types[i] + ")";
+                patternSyntaxStyle.put(Pattern.compile(patern, Pattern.UNICODE_CASE
+                        | Pattern.CASE_INSENSITIVE), style.syntaxStyleMap
+                        .get(TextPaneStyleTypes.TYPE));
+            }
+        }
+
+        if (patternValue.size() == 0) {
+            patternValue.put(
+                    Pattern.compile(SQLSyntaxConstants.NUMBER_TEXT),
+                    style.syntaxStyleMap.get(TextPaneStyleTypes.NUMBER));
+            // patternValue.put(Pattern.compile(SQLSyntaxConstants.STRING_TEXT,
+            // Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE),
+            // style.sqlSyntaxStyleMap.get(SQLStyleTypes.STRING));
+        }
+
+        patternComment = Pattern.compile(
+                SQLSyntaxConstants.COMMENT_TEXT,
+                Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE);
+        patternCommentStart = Pattern.compile(
+                SQLSyntaxConstants.COMMENT_TEXT_START,
+                Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE);
+
+        syntaxStyleComment = style.syntaxStyleMap.get(TextPaneStyleTypes.COMMENT);
+    }
+
+    @Override
+    protected int drawUnselectedText(Graphics graphics, int x, int y, int p0, int p1)
+            throws BadLocationException {
+
+        boolean lineComment = false;
+        HashMap<Integer, Integer> comment = new HashMap<Integer, Integer>();
+        HashMap<Integer, Integer> commentInLine = new HashMap<Integer, Integer>();
+        StyledDocument doc = (StyledDocument) getDocument();
+
+        String text = doc.getText(p0, p1 - p0);
+        Segment segment = getLineBuffer();
+
+        Matcher m = patternComment.matcher(doc.getText(0, doc.getLength()));
+        int maxEnd = 0;
+        while (m.find()) {
+            comment.put(m.start(), m.end());
+            if (maxEnd < m.end()) {
+                maxEnd = m.end();
+            }
+        }
+        Matcher m3 = patternCommentStart.matcher(doc.getText(0, doc.getLength()));
+        while (m3.find()) {
+            if (maxEnd < m3.start()) {
+                comment.put(m3.start(), doc.getLength());
+                break;
+            }
+        }
+
+        int j = 0;
+        for (Map.Entry<Integer, Integer> entry : comment.entrySet()) {
+            if (p0 >= entry.getKey() && p1 <= entry.getValue()) {
+                lineComment = true;
+                break;
+            }
+            else if (p0 <= entry.getKey() && p1 >= entry.getValue()) {
+                commentInLine.put(entry.getKey() - p0, entry.getValue() - p0);
+            }
+            else if (p0 <= entry.getKey()
+                    && p1 >= entry.getKey()
+                    && p1 < entry.getValue()) {
+                commentInLine.put(entry.getKey() - p0, p1 - p0);
+            }
+            else if (p0 <= entry.getValue()
+                    && p1 >= entry.getValue()
+                    && p0 > entry.getKey()) {
+                commentInLine.put(0, entry.getValue() - p0);
+            }
+            j++;
+        }
+
+        SortedMap<Integer, Integer> startMap = new TreeMap<Integer, Integer>();
+        SortedMap<Integer, SyntaxStyle> syntaxStyleMap = new TreeMap<Integer, SyntaxStyle>();
+
+        if (lineComment) {
+            startMap.put(0, text.length());
+            syntaxStyleMap.put(0, syntaxStyleComment);
+        }
+        else {
+            for (Map.Entry<Integer, Integer> entryCommentInLine : commentInLine
+                    .entrySet()) {
+                startMap.put(entryCommentInLine.getKey(), entryCommentInLine.getValue());
+                syntaxStyleMap.put(entryCommentInLine.getKey(), syntaxStyleComment);
+            }
+            // Match all regexes on this snippet, store positions
+            for (Map.Entry<Pattern, SyntaxStyle> entry : patternSyntaxStyle.entrySet()) {
+
+                Matcher matcher = entry.getKey().matcher(text);
+                while (matcher.find()) {
+                    if ((text.length() == matcher.end()
+                            || text.charAt(matcher.end()) == ' ' || text.charAt(matcher
+                            .end()) == '\n')
+                            && (matcher.start() == 0 || text.charAt(matcher.start() - 1) == ' ')) {
+                        boolean inComment = false;
+                        for (Map.Entry<Integer, Integer> entryCommentInLine : commentInLine
+                                .entrySet()) {
+                            if (matcher.start(1) >= entryCommentInLine.getKey()
+                                    && matcher.end() <= entryCommentInLine.getValue()) {
+                                inComment = true;
+                            }
+                        }
+                        if (!inComment) {
+                            startMap.put(matcher.start(), matcher.end());
+                            syntaxStyleMap.put(matcher.start(1), entry.getValue());
+                        }
+                    }
+                }
+            }
+
+            for (Map.Entry<Pattern, SyntaxStyle> entry : patternValue.entrySet()) {
+
+                Matcher matcher = entry.getKey().matcher(text);
+
+                while (matcher.find()) {
+                    if ((text.length() == matcher.end()
+                            || text.charAt(matcher.end()) == ' '
+                            || text.charAt(matcher.end()) == ')' || text.charAt(matcher
+                            .end()) == '\n')
+                            && (matcher.start() == 0
+                                    || text.charAt(matcher.start() - 1) == ' '
+                                    || text.charAt(matcher.start() - 1) == '=' || text
+                                    .charAt(matcher.start() - 1) == '(')) {
+                        boolean inComment = false;
+                        for (Map.Entry<Integer, Integer> entryCommentInLine : commentInLine
+                                .entrySet()) {
+                            if (matcher.start() >= entryCommentInLine.getKey()
+                                    && matcher.end() <= entryCommentInLine.getValue()) {
+                                inComment = true;
+                            }
+                        }
+                        if (!inComment) {
+                            startMap.put(matcher.start(), matcher.end());
+                            syntaxStyleMap.put(matcher.start(), entry.getValue());
+                        }
+                    }
+                }
+            }
+
+        }
+        // TODO: check the map for overlapping parts
+
+        int i = 0;
+
+        // Colour the parts
+        for (Map.Entry<Integer, Integer> entry : startMap.entrySet()) {
+            int start = entry.getKey();
+            int end = entry.getValue();
+
+            if (i < start) {
+                graphics.setColor(SQLSyntaxConstants.DEFAULT_COLOR);
+                graphics.setFont(SQLSyntaxConstants.DEFAULT_FONT);
+                doc.getText(p0 + i, start - i, segment);
+                x = Utilities.drawTabbedText(segment, x, y, graphics, this, i);
+            }
+
+            graphics.setFont(syntaxStyleMap.get(start).getFont());
+            graphics.setColor(syntaxStyleMap.get(start).getColor());
+            i = end;
+            doc.getText(p0 + start, i - start, segment);
+
+            x = Utilities.drawTabbedText(segment, x, y, graphics, this, start);
+        }
+
+        // Paint possible remaining text black
+        if (i < text.length()) {
+            graphics.setColor(SQLSyntaxConstants.DEFAULT_COLOR);
+            graphics.setFont(SQLSyntaxConstants.DEFAULT_FONT);
+            doc.getText(p0 + i, text.length() - i, segment);
+            x = Utilities.drawTabbedText(segment, x, y, graphics, this, i);
+        }
+
+        return x;
+    }
+}

Added: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/TextPaneViewFactory.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/TextPaneViewFactory.java?rev=752430&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/TextPaneViewFactory.java (added)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/TextPaneViewFactory.java Wed Mar 11 11:56:50 2009
@@ -0,0 +1,19 @@
+package org.apache.cayenne.swing.components.textpane;
+
+import javax.swing.text.Element;
+import javax.swing.text.View;
+import javax.swing.text.ViewFactory;
+
+import org.apache.cayenne.swing.components.textpane.syntax.SyntaxConstant;
+
+public class TextPaneViewFactory extends Object implements ViewFactory {
+
+    SyntaxConstant syntaxConstant;
+    public TextPaneViewFactory(SyntaxConstant syntaxConstant) {
+        this.syntaxConstant = syntaxConstant;
+    }
+
+    public View create(Element elem) {
+        return new TextPaneView(elem, syntaxConstant);
+    }
+}

Added: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/UnderlineHighlighterForText.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/UnderlineHighlighterForText.java?rev=752430&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/UnderlineHighlighterForText.java (added)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/UnderlineHighlighterForText.java Wed Mar 11 11:56:50 2009
@@ -0,0 +1,111 @@
+package org.apache.cayenne.swing.components.textpane;
+
+import java.awt.Color;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+import java.awt.Shape;
+
+import javax.swing.text.BadLocationException;
+import javax.swing.text.DefaultHighlighter;
+import javax.swing.text.Highlighter;
+import javax.swing.text.JTextComponent;
+import javax.swing.text.LayeredHighlighter;
+import javax.swing.text.Position;
+import javax.swing.text.View;
+
+public class UnderlineHighlighterForText extends DefaultHighlighter {
+
+    public UnderlineHighlighterForText(Color c) {
+        painter = (c == null ? sharedPainter : new UnderlineHighlightPainter(c));
+    }
+
+    // Convenience method to add a highlight with
+    // the default painter.
+    public Object addHighlight(int p0, int p1) throws BadLocationException {
+        return addHighlight(p0, p1, painter);
+    }
+
+    public void setDrawsLayeredHighlights(boolean newValue) {
+        // Illegal if false - we only support layered highlights
+        if (newValue == false) {
+            throw new IllegalArgumentException(
+                    "UnderlineHighlighterForArea only draws layered highlights");
+        }
+        super.setDrawsLayeredHighlights(true);
+    }
+
+    // Painter for underlined highlights
+    public static class UnderlineHighlightPainter extends LayeredHighlighter.LayerPainter {
+
+        public UnderlineHighlightPainter(Color c) {
+            color = c;
+        }
+
+        public void paint(Graphics g, int offs0, int offs1, Shape bounds, JTextComponent c) {
+            // Do nothing: this method will never be called
+        }
+
+        public Shape paintLayer(
+                Graphics g,
+                int offs0,
+                int offs1,
+                Shape bounds,
+                JTextComponent c,
+                View view) {
+            g.setColor(color == null ? c.getSelectionColor() : color);
+
+            Rectangle alloc = null;
+            if (offs0 == view.getStartOffset() && offs1 == view.getEndOffset()) {
+                if (bounds instanceof Rectangle) {
+                    alloc = (Rectangle) bounds;
+                }
+                else {
+                    alloc = bounds.getBounds();
+                }
+            }
+            else {
+                try {
+                    Shape shape = view.modelToView(
+                            offs0,
+                            Position.Bias.Forward,
+                            offs1,
+                            Position.Bias.Backward,
+                            bounds);
+                    alloc = (shape instanceof Rectangle) ? (Rectangle) shape : shape
+                            .getBounds();
+                }
+                catch (BadLocationException e) {
+                    return null;
+                }
+            }
+
+            FontMetrics fm = c.getFontMetrics(c.getFont());
+            int baseline = alloc.y + alloc.height - fm.getDescent() + 1;
+            int[] masY = {
+                    0, 1, 1, 0, -1, -1
+            };
+
+            int[] x = new int[alloc.width];
+            int[] y = new int[alloc.width];
+
+            for (int i = 0; i < alloc.width; i++) {
+                x[i] = alloc.x + i;
+                y[i] = baseline + masY[i % 6];
+            }
+
+            g.drawPolyline(x, y, alloc.width);
+            return alloc;
+        }
+
+        protected Color color; // The color for the underline
+    }
+
+    // Shared painter used for default highlighting
+    protected static final Highlighter.HighlightPainter sharedPainter = new UnderlineHighlightPainter(
+            null);
+
+    // Painter used for this highlighter
+    protected Highlighter.HighlightPainter painter;
+
+}

Added: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/style/SyntaxStyle.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/style/SyntaxStyle.java?rev=752430&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/style/SyntaxStyle.java (added)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/style/SyntaxStyle.java Wed Mar 11 11:56:50 2009
@@ -0,0 +1,24 @@
+package org.apache.cayenne.swing.components.textpane.style;
+
+import java.awt.Color;
+import java.awt.Font;
+
+public final class SyntaxStyle {
+
+    private Color color;
+    private Font font;
+
+    public SyntaxStyle(Color color, Font fontStyle) {
+        super();
+        this.color = color;
+        this.font = fontStyle;
+    }
+
+    public Font getFont() {
+        return font;
+    }
+
+    public Color getColor() {
+        return color;
+    }
+}

Added: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/style/TextPaneStyleMap.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/style/TextPaneStyleMap.java?rev=752430&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/style/TextPaneStyleMap.java (added)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/style/TextPaneStyleMap.java Wed Mar 11 11:56:50 2009
@@ -0,0 +1,36 @@
+package org.apache.cayenne.swing.components.textpane.style;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.util.HashMap;
+
+import org.apache.cayenne.swing.components.textpane.syntax.SQLSyntaxConstants;
+
+
+
+public class TextPaneStyleMap {
+	
+	public HashMap<TextPaneStyleTypes, SyntaxStyle> syntaxStyleMap = new HashMap<TextPaneStyleTypes, SyntaxStyle>();
+	
+	public TextPaneStyleMap() {
+		Font plainFont = SQLSyntaxConstants.DEFAULT_FONT;
+		Font boldFont = new Font(plainFont.getFamily(), Font.BOLD , plainFont.getSize());
+		Font italicFont = new Font(plainFont.getFamily(), Font.ITALIC, plainFont.getSize());
+		
+		SyntaxStyle keywordsStyle = new SyntaxStyle(Color.blue, boldFont);
+		SyntaxStyle numberStyle = new SyntaxStyle(Color.ORANGE, italicFont);
+		SyntaxStyle typeStyle = new SyntaxStyle(Color.BLUE, boldFont);
+		SyntaxStyle stringStyle = new SyntaxStyle(Color.blue, italicFont);
+		SyntaxStyle commentStyle = new SyntaxStyle(Color.LIGHT_GRAY, italicFont);
+		SyntaxStyle keywords2Style = new SyntaxStyle(Color.MAGENTA, plainFont);
+		
+		syntaxStyleMap.put(TextPaneStyleTypes.KEYWORDS, keywordsStyle);
+		syntaxStyleMap.put(TextPaneStyleTypes.KEYWORDS2, keywords2Style);
+		syntaxStyleMap.put(TextPaneStyleTypes.OPERATORS, keywordsStyle);
+		syntaxStyleMap.put(TextPaneStyleTypes.NUMBER, numberStyle);
+		syntaxStyleMap.put(TextPaneStyleTypes.TYPE, typeStyle);
+		syntaxStyleMap.put(TextPaneStyleTypes.STRING, stringStyle);
+		syntaxStyleMap.put(TextPaneStyleTypes.COMMENT, commentStyle);	
+	}
+
+}

Added: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/style/TextPaneStyleTypes.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/style/TextPaneStyleTypes.java?rev=752430&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/style/TextPaneStyleTypes.java (added)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/style/TextPaneStyleTypes.java Wed Mar 11 11:56:50 2009
@@ -0,0 +1,12 @@
+package org.apache.cayenne.swing.components.textpane.style;
+
+public enum TextPaneStyleTypes {
+
+	KEYWORDS, // Language keywords
+	KEYWORDS2,// Language keywords with style2
+	OPERATORS, // Language operators
+	NUMBER, // numbers in various formats
+	STRING, // String
+	COMMENT, // comments
+	TYPE // Types, usually not keywords, but supported by the language
+}

Added: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/syntax/EJBQLSyntaxConstant.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/syntax/EJBQLSyntaxConstant.java?rev=752430&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/syntax/EJBQLSyntaxConstant.java (added)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/syntax/EJBQLSyntaxConstant.java Wed Mar 11 11:56:50 2009
@@ -0,0 +1,45 @@
+package org.apache.cayenne.swing.components.textpane.syntax;
+
+public class EJBQLSyntaxConstant implements SyntaxConstant{
+	private static String[] KEYWORDS = { "AS", "ABS", "ASC", "AVG", "BETWEEN",
+			"BOTH", "BIT_LENGTH", "CHARACTER_LENGTH", "CHAR_LENGTH", "COUNT",
+			"CONCAT", "CURRENT_TIME", "CURRENT_DATE", "CURRENT_TIMESTAMP",
+			"DELETE", "DESC", "DISTINCT", "EMPTY", "ESCAPE", "FALSE", "FETCH",
+			"FROM", "GROUP", "HAVING", "IS", "INNER", "LOCATE", "LOWER",
+			"LEADING", "LEFT", "LENGTH", "MAX", "MEMBER", "MIN", "MOD", "NEW",
+			"NULL", "OBJECT", "OF", "ORDER", "POSITION", "SELECT", "SOME",
+			"SUM", "SIZE", "SQRT", "SUBSTR", "TRAILING", "TRUE", "TRIM",
+			"UNKNOWN", "UPDATE", "UPPER", "USER", "WHERE", "JOIN" };
+
+	private static String[] KEYWORDS2 = {};
+
+	private static String[] TYPES = {};
+
+	private static String[] OPERATORS = { "ALL", "AND", "ANY", "BETWEEN", "BY",
+			"EXISTS", "IN", "LIKE", "NOT", "NULL", "OR" };
+
+    
+    public String[] getKEYWORDS() {
+        return KEYWORDS;
+    }
+
+    
+    public String[] getKEYWORDS2() {
+        return KEYWORDS2;
+    }
+
+    
+    public String[] getTYPES() {
+        return TYPES;
+    }
+
+    
+    public String[] getOPERATORS() {
+        return OPERATORS;
+    }
+    
+    public String getContentType() {
+        return "text/ejbql";
+    }
+
+}

Added: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/syntax/SQLSyntaxConstants.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/syntax/SQLSyntaxConstants.java?rev=752430&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/syntax/SQLSyntaxConstants.java (added)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/syntax/SQLSyntaxConstants.java Wed Mar 11 11:56:50 2009
@@ -0,0 +1,99 @@
+package org.apache.cayenne.swing.components.textpane.syntax;
+
+
+public class SQLSyntaxConstants implements SyntaxConstant{
+
+	private static String[] KEYWORDS = {
+
+	"ABORT", "ACCESS", "ADD", "ALTER", "ARRAY", "ARRAY_LEN", "AS", "ASC",
+			"ASSERT", "ASSIGN", "AT", "AUDIT", "AUTHORIZATION",
+			"AUTHORIZATION", "AVG", "BASE_TABLE", "BEGIN", "BODY", "CASE",
+			"CHAR", "CHAR_BASE", "CHECK", "CLOSE", "CLUSTER", "CLUSTERS",
+			"COLAUTH", "COLAUTH", "COLUMN", "COMMIT", "COMPRESS", "CONSTANT",
+			"CONSTRAINT", "CONSTRAINT", "COUNT", "CREATE", "CURRENT",
+			"CURRVAL", "CURSOR", "DATABASE", "DATA_BASE", "DATE", "DBA",
+			"DEBUGOFF", "DEBUGON", "DECLARE", "DEFAULT", "DEFINITION", "DELAY",
+			"DELETE", "DESC", "DIGITS", "DISPOSE", "DISTINCT", "DO", "DROP",
+			"DUMP", "ELSE", "ELSIF", "END", "ENTRY", "EXCEPTION",
+			"EXCEPTION_INIT", "EXCLUSIVE", "EXIT", "FALSE", "FETCH", "FILE",
+			"FOR", "FORM", "FROM", "FUNCTION", "GENERIC", "GOTO", "GRANT",
+			"GREATEST", "GROUP", "HAVING", "IDENTIFIED", "IDENTITYCOL", "IF",
+			"IMMEDIATE", "INCREMENT", "INDEX", "INDEXES", "INDICATOR",
+			"INITIAL", "INSERT", "INTERFACE", "INTO", "IS", "LEAST", "LEVEL",
+			"LIMITED", "LOCK", "LONG", "LOOP", "MAX", "MAXEXTENTS", "MIN",
+			"MINUS", "MLSLABEL", "MOD", "MORE", "NEW", "NEXTVAL", "NOAUDIT",
+			"NOCOMPRESS", "NOWAIT", "NULL", "NUMBER_BASE", "OF", "OFFLINE",
+			"ON", "OFF", "ONLINE", "OPEN", "OPTION", "ORDER", "OTHERS", "OUT",
+			"PACKAGE", "PARTITION", "PCTFREE", "PRAGMA", "PRIVATE",
+			"PRIVILEGES", "PROCEDURE", "PUBLIC", "QUOTED_IDENTIFIER", "RAISE",
+			"RANGE", "RECORD", "REF", "RELEASE", "REMR", "RENAME", "RESOURCE",
+			"RETURN", "REVERSE", "REVOKE", "ROLLBACK", "ROW", "ROWLABEL",
+			"ROWNUM", "ROWS", "ROWTYPE", "RUN", "SAVEPOINT", "SCHEMA",
+			"SELECT", "SEPERATE", "SESSION", "SET", "SHARE", "SPACE", "SQL",
+			"SQLCODE", "SQLERRM", "STATEMENT", "STDDEV", "SUBTYPE",
+			"SUCCESSFULL", "SUM", "SYNONYM", "SYSDATE", "TABAUTH", "TABLE",
+			"TABLES", "TASK", "TERMINATE", "THEN", "TO", "TRIGGER", "TRUE",
+			"TYPE", "UID", "UNION", "UNIQUE", "UPDATE", "UPDATETEXT", "USE",
+			"USER", "USING", "VALIDATE", "VALUES", "VARIANCE", "VIEW", "VIEWS",
+			"WHEN", "WHENEVER", "WHERE", "WHILE", "WITH", "WORK", "WRITE",
+			"XOR",
+
+			"UPPER", "VERIFY", "SERVEROUTPUT", "PAGESIZE", "LINESIZE",
+			"ARRAYSIZE", "DBMS_OUTPUT", "PUT_LINE", "ENABLE",
+
+			"FIRST", "LIMIT", "OFFSET", "TOP"
+
+	};
+
+	private static String[] KEYWORDS2 = { "ABS", "ACOS", "ADD_MONTHS", "ASCII",
+			"ASIN", "ATAN", "ATAN2", "CEIL", "CHARTOROWID", "CHR", "CONCAT",
+			"CONVERT", "COS", "COSH", "DECODE", "DEFINE", "FLOOR", "HEXTORAW",
+			"INITCAP", "INSTR", "INSTRB", "LAST_DAY", "LENGTH", "LENGTHB",
+			"LN", "LOG", "LOWER", "LPAD", "LTRIM", "MOD", "MONTHS_BETWEEN",
+			"NEW_TIME", "NEXT_DAY", "NLSSORT", "NSL_INITCAP", "NLS_LOWER",
+			"NLS_UPPER", "NVL", "POWER", "RAWTOHEX", "REPLACE", "ROUND",
+			"ROWIDTOCHAR", "RPAD", "RTRIM", "SIGN", "SOUNDEX", "SIN", "SINH",
+			"SQRT", "SUBSTR", "SUBSTRB", "TAN", "TANH", "TO_CHAR", "TO_DATE",
+			"TO_MULTIBYTE", "TO_NUMBER", "TO_SINGLE_BYTE", "TRANSLATE",
+			"TRUNC", 
+			"#bind", "#bindEqual", "#bindNotEqual", "#bindObjectEqual",
+			"#bindObjectNotEqual", "#chain", "#chunk", "#end", "#result"
+
+	};
+
+	private static String[] TYPES = { "binary", "bit", "blob", "boolean",
+			"char", "character", "DATE", "datetime", "DEC", "decimal",
+			"DOUBLE PRECISION", "float", "image", "int", "integer", "money",
+			"name", "NATURAL", "NATURALN", "NUMBER", "numeric", "nchar",
+			"nvarchar", "ntext", "pls_integer", "POSITIVE", "POSITIVEN", "RAW",
+			"real", "ROWID", "SIGNTYPE", "smalldatetime", "smallint",
+			"smallmoney", "text", "timestamp", "tinyint", "uniqueidentifier",
+			"UROWID", "varbinary", "varchar", "varchar2" };
+
+	private static String[] OPERATORS = { "ALL", "AND", "ANY", "BETWEEN", "BY",
+			"CONNECT", "EXISTS", "IN", "INTERSECT", "LIKE", "NOT", "NULL",
+			"OR", "START", "UNION", "WITH" };
+	
+	public String[] getKEYWORDS() {
+        return KEYWORDS;
+    }
+
+    
+    public String[] getKEYWORDS2() {
+        return KEYWORDS2;
+    }
+
+    
+    public String[] getTYPES() {
+        return TYPES;
+    }
+
+    
+    public String[] getOPERATORS() {
+        return OPERATORS;
+    }
+    
+    public String getContentType() {
+        return "text/sql";
+    }
+}

Added: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/syntax/SyntaxConstant.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/syntax/SyntaxConstant.java?rev=752430&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/syntax/SyntaxConstant.java (added)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/syntax/SyntaxConstant.java Wed Mar 11 11:56:50 2009
@@ -0,0 +1,43 @@
+/*****************************************************************
+ *   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.cayenne.swing.components.textpane.syntax;
+
+import java.awt.Color;
+import java.awt.Font;
+
+public interface SyntaxConstant {
+
+    public static Font DEFAULT_FONT = new Font("Courier", Font.PLAIN, 14);
+    public static Color DEFAULT_COLOR = Color.black;
+    public static String COMMENT_TEXT = "(?:/\\*(?:[^*]|(?:\\*+[^*/]))*\\*+/)|(?://.*)";
+    public static final String COMMENT_TEXT_START = "/\\*.?";
+    public static String STRING_TEXT = "'[^']*'";
+    public static String NUMBER_TEXT = "\\d+";
+
+    public String[] getKEYWORDS();
+
+    public String[] getKEYWORDS2();
+
+    public String[] getTYPES();
+
+    public String[] getOPERATORS();
+    
+    public String getContentType();
+
+}

Modified: cayenne/main/trunk/pom.xml
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/pom.xml?rev=752430&r1=752429&r2=752430&view=diff
==============================================================================
--- cayenne/main/trunk/pom.xml (original)
+++ cayenne/main/trunk/pom.xml Wed Mar 11 11:56:50 2009
@@ -157,15 +157,15 @@
 				<role>PMC, Member</role>
 			</roles>
 			<timezone>+10</timezone>
-		</developer>
-		<developer>
-			<id>andrey</id>
-			<name>Andrey Razumovsky</name>
-			<email>andrey@apache.org</email>
-			<roles>
-				<role>Committer</role>
-			</roles>
-			<timezone>+3</timezone>
+		</developer>
+		<developer>
+			<id>andrey</id>
+			<name>Andrey Razumovsky</name>
+			<email>andrey@apache.org</email>
+			<roles>
+				<role>Committer</role>
+			</roles>
+			<timezone>+3</timezone>
 		</developer>
 	</developers>