This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 193557
Collapse All | Expand All

(-)a/db.sql.editor/nbproject/project.xml (-9 / +27 lines)
Lines 50-55 Link Here
50
            <code-name-base>org.netbeans.modules.db.sql.editor</code-name-base>
50
            <code-name-base>org.netbeans.modules.db.sql.editor</code-name-base>
51
            <module-dependencies>
51
            <module-dependencies>
52
                <dependency>
52
                <dependency>
53
                    <code-name-base>org.netbeans.modules.csl.api</code-name-base>
54
                    <build-prerequisite/>
55
                    <compile-dependency/>
56
                    <run-dependency>
57
                        <release-version>2</release-version>
58
                        <specification-version>2.27</specification-version>
59
                    </run-dependency>
60
                </dependency>
61
                <dependency>
53
                    <code-name-base>org.netbeans.modules.db</code-name-base>
62
                    <code-name-base>org.netbeans.modules.db</code-name-base>
54
                    <build-prerequisite/>
63
                    <build-prerequisite/>
55
                    <compile-dependency/>
64
                    <compile-dependency/>
Lines 102-116 Link Here
102
                    </run-dependency>
111
                    </run-dependency>
103
                </dependency>
112
                </dependency>
104
                <dependency>
113
                <dependency>
105
                    <code-name-base>org.netbeans.modules.editor.deprecated.pre65formatting</code-name-base>
106
                    <build-prerequisite/>
107
                    <compile-dependency/>
108
                    <run-dependency>
109
                        <release-version>0-1</release-version>
110
                        <specification-version>1.0</specification-version>
111
                    </run-dependency>
112
                </dependency>
113
                <dependency>
114
                    <code-name-base>org.netbeans.modules.editor.lib</code-name-base>
114
                    <code-name-base>org.netbeans.modules.editor.lib</code-name-base>
115
                    <build-prerequisite/>
115
                    <build-prerequisite/>
116
                    <compile-dependency/>
116
                    <compile-dependency/>
Lines 120-125 Link Here
120
                    </run-dependency>
120
                    </run-dependency>
121
                </dependency>
121
                </dependency>
122
                <dependency>
122
                <dependency>
123
                    <code-name-base>org.netbeans.modules.editor.lib2</code-name-base>
124
                    <build-prerequisite/>
125
                    <compile-dependency/>
126
                    <run-dependency>
127
                        <release-version>1</release-version>
128
                        <specification-version>1.60</specification-version>
129
                    </run-dependency>
130
                </dependency>
131
                <dependency>
132
                    <code-name-base>org.netbeans.modules.editor.mimelookup</code-name-base>
133
                    <build-prerequisite/>
134
                    <compile-dependency/>
135
                    <run-dependency>
136
                        <release-version>1</release-version>
137
                        <specification-version>1.26</specification-version>
138
                    </run-dependency>
139
                </dependency>
140
                <dependency>
123
                    <code-name-base>org.netbeans.modules.lexer</code-name-base>
141
                    <code-name-base>org.netbeans.modules.lexer</code-name-base>
124
                    <build-prerequisite/>
142
                    <build-prerequisite/>
125
                    <compile-dependency/>
143
                    <compile-dependency/>
(-)a/db.sql.editor/src/org/netbeans/modules/db/sql/editor/Bundle.properties (-4 lines)
Lines 42-51 Link Here
42
42
43
OPTIONS_sql=SQL Editor
43
OPTIONS_sql=SQL Editor
44
44
45
#SQLIndentEngineBeanInfo
46
LBL_SQLIndentEngine=SQL Indentation Engine
47
HINT_SQLIndentEngine=Indentation Engine for SQL files
48
49
#SQLEditorProviderImpl
45
#SQLEditorProviderImpl
50
#{0} = command number
46
#{0} = command number
51
#PARTI18N - only localize "SQL Command" and do not add anything after ".sql"
47
#PARTI18N - only localize "SQL Command" and do not add anything after ".sql"
(-)a/db.sql.editor/src/org/netbeans/modules/db/sql/editor/SQLEditorKit.java (-140 lines)
Lines 1-140 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2011 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * Contributor(s):
28
 *
29
 * The Original Software is NetBeans. The Initial Developer of the Original
30
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
31
 * Microsystems, Inc. All Rights Reserved.
32
 *
33
 * If you wish your version of this file to be governed by only the CDDL
34
 * or only the GPL Version 2, indicate your decision by adding
35
 * "[Contributor] elects to include this software in this distribution
36
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
37
 * single choice of license, a recipient has the option to distribute
38
 * your version of this file under either the CDDL, the GPL Version 2 or
39
 * to extend the choice of license to its licensees as provided above.
40
 * However, if you add GPL Version 2 code and therefore, elected the GPL
41
 * Version 2 license, then the option applies only if the new code is
42
 * made subject to such option by the copyright holder.
43
 */
44
45
package org.netbeans.modules.db.sql.editor;
46
47
import javax.swing.Action;
48
import javax.swing.text.BadLocationException;
49
import javax.swing.text.Caret;
50
import javax.swing.text.Document;
51
import javax.swing.text.TextAction;
52
import org.netbeans.api.lexer.TokenSequence;
53
import org.netbeans.editor.BaseDocument;
54
import org.netbeans.editor.Syntax;
55
import org.netbeans.editor.SyntaxSupport;
56
import org.netbeans.modules.db.sql.editor.completion.SQLCompletionEnv;
57
import org.netbeans.modules.db.sql.lexer.SQLTokenId;
58
import org.netbeans.modules.editor.NbEditorKit;
59
60
/**
61
 * This class implements the editor kit for text/x-sql files
62
 * in the editor
63
 *
64
 * @author Jesse Beaumont
65
 * @author Andrei Badea
66
 */
67
public class SQLEditorKit extends NbEditorKit {
68
69
    public static final String MIME_TYPE = "text/x-sql"; // NOI18N
70
71
    /**
72
     * Creates a new instance of SQLEditorKit
73
     */
74
    public SQLEditorKit() {
75
    }
76
77
    /**
78
     * Create a syntax object suitable for highlighting SQL syntax
79
     */
80
    @Override
81
    public Syntax createSyntax(Document doc) {
82
        return new SQLSyntax();
83
    }
84
85
    /** Create syntax support */
86
    @Override
87
    public SyntaxSupport createSyntaxSupport(BaseDocument doc) {
88
        return new SQLSyntaxSupport(doc);
89
    }
90
91
    @Override
92
    protected Action[] createActions() {
93
        Action[] superActions = super.createActions();
94
        Action[] sqlActions = new Action[] {
95
            new SQLDefaultKeyTypedAction(),
96
            new ToggleCommentAction("-- ") // NOI18N
97
        };
98
        return TextAction.augmentList(superActions, sqlActions);
99
    }
100
101
    /**
102
     * Retrieves the content type for this editor kit
103
     */
104
    @Override
105
    public String getContentType() {
106
        return MIME_TYPE;
107
    }
108
109
    public static class SQLDefaultKeyTypedAction extends ExtDefaultKeyTypedAction {
110
111
        @Override
112
        protected void insertString(BaseDocument doc, int caretOffset, Caret caret, String str, boolean overwrite) throws BadLocationException {
113
            char insertedChar = str.charAt(0);
114
            if (insertedChar == '\"' || insertedChar == '\'') {  //NOI18N
115
                if (canCompleteQuote(doc, caretOffset)) {
116
                    // add pair quote
117
                    super.insertString(doc, caretOffset, caret, String.valueOf(insertedChar) + insertedChar, overwrite);
118
                    caret.setDot(caretOffset + 1);
119
                    return;
120
                }
121
            }
122
            super.insertString(doc, caretOffset, caret, str, overwrite);
123
        }
124
125
        /** Returns true if completion of quote is wanted, i.e. cursor is
126
         * on token boundary and previous token is dot or whitespace. */
127
        private static boolean canCompleteQuote(BaseDocument doc, int caretOffset) {
128
            SQLCompletionEnv env = SQLCompletionEnv.forDocument(doc, caretOffset);
129
            TokenSequence<SQLTokenId> seq = env.getTokenSequence();
130
            if (seq.move(caretOffset) == 0 && seq.movePrevious()) {
131
                switch (seq.token().id()) {
132
                    case WHITESPACE:
133
                    case DOT:
134
                        return true;
135
                }
136
            }
137
            return false;
138
        }
139
    }
140
}
(-)a/db.sql.editor/src/org/netbeans/modules/db/sql/editor/SQLFormatter.java (-90 lines)
Lines 1-90 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * Contributor(s):
28
 *
29
 * The Original Software is NetBeans. The Initial Developer of the Original
30
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
31
 * Microsystems, Inc. All Rights Reserved.
32
 *
33
 * If you wish your version of this file to be governed by only the CDDL
34
 * or only the GPL Version 2, indicate your decision by adding
35
 * "[Contributor] elects to include this software in this distribution
36
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
37
 * single choice of license, a recipient has the option to distribute
38
 * your version of this file under either the CDDL, the GPL Version 2 or
39
 * to extend the choice of license to its licensees as provided above.
40
 * However, if you add GPL Version 2 code and therefore, elected the GPL
41
 * Version 2 license, then the option applies only if the new code is
42
 * made subject to such option by the copyright holder.
43
 */
44
45
package org.netbeans.modules.db.sql.editor;
46
47
import java.io.IOException;
48
import java.io.Writer;
49
import javax.swing.text.BadLocationException;
50
import javax.swing.text.JTextComponent;
51
import org.netbeans.editor.BaseDocument;
52
import org.netbeans.editor.Syntax;
53
import org.netbeans.editor.ext.ExtFormatter;
54
55
/**
56
 * Formatter for SQL
57
 *
58
 * @author Jesse Beaumont
59
 */
60
public class SQLFormatter extends ExtFormatter {
61
    
62
    /** 
63
     * Creates a new instance of SQLFormater 
64
     */
65
    public SQLFormatter(Class kitClass) {
66
        super(kitClass);        
67
    }
68
    
69
    /**
70
     * Determines whether the specified syntax is supported by this formatter
71
     */
72
    protected boolean acceptSyntax(Syntax syntax) {
73
	return (syntax instanceof SQLSyntax);
74
    }
75
        
76
    /**
77
     * Reformats a portion of the document
78
     */
79
    public Writer reformat(BaseDocument doc, int startOffset, int endOffset, boolean indentOnly) 
80
    throws BadLocationException, IOException {
81
	return super.reformat(doc, startOffset, endOffset,  indentOnly);
82
    }
83
    
84
    /**
85
     * Reformats a block of text
86
     */
87
    public int[] getReformatBlock(JTextComponent target, String typedText) {
88
        return super.getReformatBlock(target, typedText);
89
    }
90
}
(-)a/db.sql.editor/src/org/netbeans/modules/db/sql/editor/SQLIndentEngine.java (-75 lines)
Lines 1-75 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * Contributor(s):
28
 *
29
 * The Original Software is NetBeans. The Initial Developer of the Original
30
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
31
 * Microsystems, Inc. All Rights Reserved.
32
 *
33
 * If you wish your version of this file to be governed by only the CDDL
34
 * or only the GPL Version 2, indicate your decision by adding
35
 * "[Contributor] elects to include this software in this distribution
36
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
37
 * single choice of license, a recipient has the option to distribute
38
 * your version of this file under either the CDDL, the GPL Version 2 or
39
 * to extend the choice of license to its licensees as provided above.
40
 * However, if you add GPL Version 2 code and therefore, elected the GPL
41
 * Version 2 license, then the option applies only if the new code is
42
 * made subject to such option by the copyright holder.
43
 */
44
45
package org.netbeans.modules.db.sql.editor;
46
47
import org.netbeans.editor.ext.ExtFormatter;
48
import org.netbeans.modules.db.sql.editor.SQLFormatter;
49
import org.netbeans.modules.editor.FormatterIndentEngine;
50
import org.openide.util.NbBundle;
51
52
/**
53
 * Implements an indentation engine for SQL
54
 *
55
 * @author Jesse Beaumont
56
 * @author Andrei Badea
57
 */
58
public class SQLIndentEngine extends FormatterIndentEngine {
59
    
60
    static final long serialVersionUID = -2095935054411935707L;
61
    
62
    /** 
63
     * Creates a new instance of SQLIndentEngine 
64
     */
65
    public SQLIndentEngine() {
66
        setAcceptedMimeTypes(new String[] { SQLEditorKit.MIME_TYPE });
67
    }
68
69
    /**
70
     * Creates a suitable formatter for handling SQL
71
     */
72
    protected ExtFormatter createFormatter() {
73
        return new SQLFormatter(SQLEditorKit.class);
74
    }
75
}
(-)a/db.sql.editor/src/org/netbeans/modules/db/sql/editor/SQLIndentEngineBeanInfo.java (-95 lines)
Lines 1-95 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * Contributor(s):
28
 *
29
 * The Original Software is NetBeans. The Initial Developer of the Original
30
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
31
 * Microsystems, Inc. All Rights Reserved.
32
 *
33
 * If you wish your version of this file to be governed by only the CDDL
34
 * or only the GPL Version 2, indicate your decision by adding
35
 * "[Contributor] elects to include this software in this distribution
36
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
37
 * single choice of license, a recipient has the option to distribute
38
 * your version of this file under either the CDDL, the GPL Version 2 or
39
 * to extend the choice of license to its licensees as provided above.
40
 * However, if you add GPL Version 2 code and therefore, elected the GPL
41
 * Version 2 license, then the option applies only if the new code is
42
 * made subject to such option by the copyright holder.
43
 */
44
45
package org.netbeans.modules.db.sql.editor;
46
47
import java.beans.BeanDescriptor;
48
import java.util.MissingResourceException;
49
import org.netbeans.modules.editor.FormatterIndentEngineBeanInfo;
50
import org.netbeans.modules.editor.NbEditorUtilities;
51
import org.openide.util.NbBundle;
52
53
/**
54
 * The BeanInfo descriptor for the SQLIndentEngine
55
 *
56
 * @author Jesse Beaumont
57
 */
58
public class SQLIndentEngineBeanInfo extends FormatterIndentEngineBeanInfo {
59
60
    private BeanDescriptor beanDescriptor;
61
62
    /**
63
     * Get the bean descriptor
64
     */
65
    public BeanDescriptor getBeanDescriptor () {
66
        if (beanDescriptor == null) {
67
            beanDescriptor = new BeanDescriptor(getBeanClass());
68
            beanDescriptor.setDisplayName(getMessage("LBL_SQLIndentEngine"));
69
            beanDescriptor.setShortDescription(getMessage("HINT_SQLIndentEngine"));
70
            beanDescriptor.setValue("global", Boolean.TRUE); // NOI18N
71
        }
72
        return beanDescriptor;
73
    }
74
75
    /**
76
     * Get the class of the bean described by this bean info
77
     */
78
    protected Class getBeanClass() {
79
        return SQLIndentEngine.class;
80
    }
81
82
    /**
83
     * Look up a resource bundle message, if it is not found locally defer to 
84
     * the super implementation
85
     */
86
    protected String getMessage(String key) {
87
        try {
88
            return NbBundle.getMessage(SQLIndentEngineBeanInfo.class, key);
89
        } catch (MissingResourceException e) {
90
            return super.getString(key);
91
        }
92
    }
93
94
}
95
(-)a/db.sql.editor/src/org/netbeans/modules/db/sql/editor/SQLSettingsInitializer.java (-65 lines)
Lines 1-65 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * Contributor(s):
28
 *
29
 * The Original Software is NetBeans. The Initial Developer of the Original
30
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
31
 * Microsystems, Inc. All Rights Reserved.
32
 *
33
 * If you wish your version of this file to be governed by only the CDDL
34
 * or only the GPL Version 2, indicate your decision by adding
35
 * "[Contributor] elects to include this software in this distribution
36
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
37
 * single choice of license, a recipient has the option to distribute
38
 * your version of this file under either the CDDL, the GPL Version 2 or
39
 * to extend the choice of license to its licensees as provided above.
40
 * However, if you add GPL Version 2 code and therefore, elected the GPL
41
 * Version 2 license, then the option applies only if the new code is
42
 * made subject to such option by the copyright holder.
43
 */
44
45
package org.netbeans.modules.db.sql.editor;
46
47
import java.util.Collections;
48
import java.util.List;
49
import org.openide.text.IndentEngine;
50
51
/**
52
 * Initializes the SQL Settings
53
 *
54
 * @author Jesse Beaumont, Andrei Badea
55
 */
56
public class SQLSettingsInitializer {
57
58
    public static List getTokenContext() {
59
        return Collections.singletonList(SQLTokenContext.context);
60
    }
61
    
62
    public static IndentEngine getIndentEngine() {
63
        return new SQLIndentEngine();
64
    }
65
}
(-)a/db.sql.editor/src/org/netbeans/modules/db/sql/editor/SQLSyntax.java (-520 lines)
Lines 1-520 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * Contributor(s):
28
 *
29
 * The Original Software is NetBeans. The Initial Developer of the Original
30
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2010 Sun
31
 * Microsystems, Inc. All Rights Reserved.
32
 *
33
 * If you wish your version of this file to be governed by only the CDDL
34
 * or only the GPL Version 2, indicate your decision by adding
35
 * "[Contributor] elects to include this software in this distribution
36
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
37
 * single choice of license, a recipient has the option to distribute
38
 * your version of this file under either the CDDL, the GPL Version 2 or
39
 * to extend the choice of license to its licensees as provided above.
40
 * However, if you add GPL Version 2 code and therefore, elected the GPL
41
 * Version 2 license, then the option applies only if the new code is
42
 * made subject to such option by the copyright holder.
43
 */
44
45
package org.netbeans.modules.db.sql.editor;
46
47
import org.netbeans.editor.Syntax;
48
import org.netbeans.editor.TokenID;
49
import org.netbeans.modules.db.api.sql.SQLKeywords;
50
51
/**
52
 * This class implements SQL syntax recognition
53
 *
54
 * @author Jesse Beaumont, Andrei Badea
55
 */
56
public class SQLSyntax extends Syntax {
57
58
    private static final int ISI_WHITESPACE = 2; // inside white space
59
    private static final int ISI_LINE_COMMENT = 4; // inside line comment --
60
    private static final int ISI_BLOCK_COMMENT = 5; // inside block comment /* ... */
61
    private static final int ISI_STRING = 6; // inside string constant
62
    private static final int ISI_STRING_A_QUOTE = 7; // inside string constant after '
63
    private static final int ISI_IDENTIFIER = 10; // inside identifier
64
    private static final int ISA_SLASH = 11; // slash char
65
    private static final int ISA_OPERATOR = 12; // after '=', '/', '+'
66
    private static final int ISA_MINUS = 13;
67
    private static final int ISA_STAR = 20; // after '*'
68
    private static final int ISA_STAR_I_BLOCK_COMMENT_END = 21; // after '*' in a block comment
69
    private static final int ISA_EXCLAMATION = 26; // after '!'
70
    private static final int ISA_ZERO = 27; // after '0'
71
    private static final int ISI_INT = 28; // integer number
72
    private static final int ISI_DOUBLE = 30; // double number
73
    private static final int ISA_DOT = 33; // after '.'
74
    private static final int ISA_COMMA = 34; // after ','
75
    private static final int ISA_SEMICOLON = 35; //after ';'
76
    private static final int ISA_LPAREN = 36; //after (
77
    private static final int ISA_RPAREN = 37; //after )
78
    private static final int ISA_BACK_SLASH_IN_STRING = 38; // after \ in string
79
    private static final int ISA_HASH = 39; // '#' char
80
81
    private int startQuoteChar = -1;
82
83
    /** 
84
     * Creates a new instance of SQLSyntax 
85
     */
86
    public SQLSyntax() {
87
        tokenContextPath = SQLTokenContext.contextPath;
88
    }
89
    
90
    /**
91
     * Parse the next token
92
     */
93
    @Override
94
    protected TokenID parseToken() {
95
        char actChar; //the current character
96
97
        //while we still have stuff to parse, do so
98
        while(offset < stopOffset) {
99
            actChar = buffer[offset];
100
101
            //do the appropriate stuff based on what state the parser is in
102
            switch (state) {
103
                //the initial state (start of a new token)
104
                case INIT:
105
                    switch (actChar) {
106
                        case '\'': // NOI18N
107
                            state = ISI_STRING;
108
                            break;
109
                        case '/':
110
                            state = ISA_SLASH;
111
                            break;
112
                        case '#':
113
                                state = ISA_HASH;
114
                            break;
115
                        case '=':
116
                        case '>':
117
                        case '<':
118
                        case '+':
119
                        case ',':
120
                        case ')':
121
                        case '(':
122
                        case ';':
123
                        case '*':
124
                        case '!':
125
                            offset++;
126
                            state = INIT;
127
                            return SQLTokenContext.OPERATOR;
128
                        case '-':
129
                            state = ISA_MINUS;
130
                            break;
131
                        case '0':
132
                            state = ISA_ZERO;
133
                            break;
134
                        case '.':
135
                            state = ISA_DOT;
136
                            break;
137
                        default:
138
                            // Check for whitespace
139
                            if (Character.isWhitespace(actChar)) {
140
                                state = ISI_WHITESPACE;
141
                                break;
142
                            }
143
144
                            // Check for digit
145
                            if (Character.isDigit(actChar)) {
146
                                state = ISI_INT;
147
                                break;
148
                            }
149
150
                            // otherwise it's an identifier
151
                            state = ISI_IDENTIFIER;
152
                            if (isStartQuoteChar(actChar)) {
153
                                startQuoteChar = actChar;
154
                            }
155
                            break;
156
                    }
157
                    break;
158
                //if we are currently in a whitespace token
159
                case ISI_WHITESPACE: // white space
160
                    if (!Character.isWhitespace(actChar)) {
161
                        state = INIT;
162
                        return SQLTokenContext.WHITESPACE;
163
                    }
164
                    break;
165
166
                //if we are currently in a line comment
167
                case ISI_LINE_COMMENT:
168
                    if (actChar == '\n') {
169
                        state = INIT;
170
                        return SQLTokenContext.LINE_COMMENT;
171
                    }
172
                    break;
173
174
                //if we are currently in a block comment
175
                case ISI_BLOCK_COMMENT:
176
                    if(actChar =='*') {
177
                        state = ISA_STAR_I_BLOCK_COMMENT_END;
178
                    }
179
                    break;
180
                
181
                //if we are currently in a string literal
182
                case ISI_STRING:
183
                    switch (actChar) {
184
                        case '\\': // NOI18N
185
                            // escape possible single quote #152325
186
                            state = ISA_BACK_SLASH_IN_STRING;
187
                            break;
188
                        case '\'': // NOI18N
189
                            offset++;
190
                            state = INIT;
191
                            return SQLTokenContext.STRING;
192
                    }
193
                    break;
194
195
                // If we are after a back slash (\) in string.
196
                case ISA_BACK_SLASH_IN_STRING:
197
                    state = ISI_STRING;
198
                    break;
199
200
                //if we are currently in an identifier (e.g. a variable name)
201
                case ISI_IDENTIFIER:
202
                    if (startQuoteChar != -1) {
203
                        if (!isEndQuoteChar(startQuoteChar, actChar)) {
204
                            break;
205
                        } else {
206
                            offset++;
207
                        }
208
                    } else {
209
                        if (Character.isLetterOrDigit(actChar) || actChar == '_' || actChar == '#') {
210
                            break;
211
                        }
212
                    }
213
                    state = INIT;
214
                    startQuoteChar = -1;
215
                    TokenID tid = matchKeyword(buffer, tokenOffset, offset - tokenOffset);
216
                    if (tid != null) {
217
                        return tid;
218
                    } else {
219
                        return SQLTokenContext.IDENTIFIER;
220
                    }
221
222
                //if we are after a slash (/)
223
                case ISA_SLASH:
224
                    switch (actChar) {
225
                        case '*':
226
                            state = ISI_BLOCK_COMMENT;
227
                            break;
228
                        default:
229
                            state = INIT;
230
                            return SQLTokenContext.OPERATOR;
231
                    }
232
                    break;
233
234
                //if we are after a -
235
                case ISA_MINUS:
236
                    switch (actChar) {
237
                        case '-':
238
                            state = ISI_LINE_COMMENT;
239
                            break;
240
                        default:
241
                            state = INIT;
242
                            return SQLTokenContext.OPERATOR;
243
                    }
244
                    break;
245
                
246
                //if we are after a #
247
                case ISA_HASH:
248
                    if (Character.isWhitespace(actChar)) {
249
                        // only in MySQL # starts line comment
250
                        state = ISI_LINE_COMMENT;
251
                        if (actChar == '\n') {
252
                            return SQLTokenContext.LINE_COMMENT;
253
                        }
254
                    } else {
255
                        // otherwise it can be identifier (issue 172904)
256
                        if (offset > 1) {
257
                            state = ISI_IDENTIFIER;
258
                        } else {
259
                            state = ISI_LINE_COMMENT;
260
                        }
261
                    }
262
                    break;
263
264
                //if we are in the middle of a possible block comment end token
265
                case ISA_STAR_I_BLOCK_COMMENT_END:
266
                    switch (actChar) {
267
                        case '/':
268
                            offset++;
269
                            state = INIT;
270
                            return SQLTokenContext.BLOCK_COMMENT;
271
                        default:
272
                            offset--;
273
                            state = ISI_BLOCK_COMMENT;
274
                            break;
275
                    }
276
                    break;
277
                       
278
                //if we are after a 0
279
                case ISA_ZERO:
280
                    switch (actChar) {
281
                        case '.':
282
                            state = ISI_DOUBLE;
283
                            break;
284
                        default:
285
                            if (Character.isDigit(actChar)) { 
286
                                state = ISI_INT;
287
                                break;
288
                            } else {
289
                                state = INIT;
290
                                return SQLTokenContext.INT_LITERAL;
291
                            }
292
                    }
293
                    break;
294
295
                //if we are after an integer
296
                case ISI_INT:
297
                    switch (actChar) {
298
                        case '.':
299
                            state = ISI_DOUBLE;
300
                            break;
301
                        default:
302
                            if (Character.isDigit(actChar)) { 
303
                                state = ISI_INT;
304
                                break;
305
                            } else {
306
                                state = INIT;
307
                                return SQLTokenContext.INT_LITERAL;
308
                            }
309
                    }
310
                    break;
311
312
                //if we are in the middle of what we believe is a floating point
313
                //number
314
                case ISI_DOUBLE:
315
                    if (actChar >= '0' && actChar <= '9') {
316
                        state = ISI_DOUBLE;
317
                        break;
318
                    } else {
319
                        state = INIT;
320
                        return SQLTokenContext.DOUBLE_LITERAL;
321
                    }
322
323
                //if we are after a period
324
                case ISA_DOT:
325
                    if (Character.isDigit(actChar)) {
326
                        state = ISI_DOUBLE;
327
                    } else { // only single dot
328
                        state = INIT;
329
                        return SQLTokenContext.DOT;
330
                    }
331
                    break;
332
333
            } // end of switch(state)
334
335
            offset++;
336
        } // end of while(offset...)
337
338
        /* 
339
         * At this stage there's no more text in the scanned buffer.
340
         * Scanner first checks whether this is completely the last
341
         * available buffer.
342
         */
343
        if (lastBuffer) {
344
            switch(state) {
345
            case ISI_WHITESPACE:
346
                state = INIT;
347
                    return SQLTokenContext.WHITESPACE;
348
            case ISI_IDENTIFIER:
349
                state = INIT;
350
                startQuoteChar = -1;
351
                TokenID tid = 
352
                        matchKeyword(buffer, tokenOffset, offset - tokenOffset);
353
                if(tid != null) {
354
                    return tid;
355
                }
356
                else {
357
                    return SQLTokenContext.IDENTIFIER;
358
                }
359
            case ISI_LINE_COMMENT:
360
                // stay in line-comment state
361
                return SQLTokenContext.LINE_COMMENT; 
362
            case ISI_BLOCK_COMMENT:
363
            case ISA_STAR_I_BLOCK_COMMENT_END:
364
                // stay in block-comment state
365
                return SQLTokenContext.BLOCK_COMMENT; 
366
            case ISI_STRING:
367
            case ISA_BACK_SLASH_IN_STRING:
368
                return SQLTokenContext.INCOMPLETE_STRING;
369
            case ISA_ZERO:
370
            case ISI_INT:
371
                state = INIT;
372
                return SQLTokenContext.INT_LITERAL; 
373
            case ISI_DOUBLE:
374
                state = INIT;
375
                return SQLTokenContext.DOUBLE_LITERAL; 
376
            case ISA_DOT:
377
                state = INIT;
378
                return SQLTokenContext.DOT; 
379
            case ISA_SLASH:
380
                state = INIT;
381
                return SQLTokenContext.OPERATOR; 
382
            }
383
        }
384
385
        /* 
386
         * At this stage there's no more text in the scanned buffer, but
387
         * this buffer is not the last so the 
388
         * scan will continue on another buffer.
389
         * The scanner tries to minimize the amount of characters
390
         * that will be prescanned in the next buffer by returning the token
391
         * where possible.
392
         */
393
394
        switch (state) {
395
            case ISI_WHITESPACE:
396
                    return SQLTokenContext.WHITESPACE; 
397
        }
398
399
        return null; // nothing found
400
    }
401
402
    /**
403
     * Returns the state name for the state id
404
     */
405
    @Override
406
    public String getStateName(int stateNumber) {
407
        switch(stateNumber) {
408
        case ISI_WHITESPACE:
409
            return "ISI_WHITESPACE"; // NOI18N
410
        case ISI_LINE_COMMENT:
411
            return "ISI_LINE_COMMENT"; // NOI18N
412
        case ISI_BLOCK_COMMENT:
413
            return "ISI_BLOCK_COMMENT"; // NOI18N
414
        case ISI_STRING:
415
            return "ISI_STRING"; // NOI18N
416
        case ISI_STRING_A_QUOTE:
417
            return "ISI_STRING_A_QUOTE"; // NOI18N
418
        case ISI_IDENTIFIER:
419
            return "ISI_IDENTIFIER"; // NOI18N
420
        case ISA_SLASH:
421
            return "ISA_SLASH"; // NOI18N
422
        case ISA_OPERATOR:
423
            return "ISA_OPERATOR"; // NOI18N
424
        case ISA_MINUS:
425
            return "ISA_MINUS"; // NOI18N
426
        case ISA_STAR:
427
            return "ISA_STAR"; // NOI18N
428
        case ISA_STAR_I_BLOCK_COMMENT_END:
429
            return "ISA_STAR_I_BLOCK_COMMENT_END"; // NOI18N
430
        case ISA_ZERO:
431
            return "ISA_ZERO"; // NOI18N
432
        case ISI_INT:
433
            return "ISI_INT"; // NOI18N
434
        case ISI_DOUBLE:
435
            return "ISI_DOUBLE"; // NOI18N
436
        case ISA_DOT:
437
            return "ISA_DOT"; // NOI18N
438
        case ISA_COMMA:
439
            return "ISA_COMMA"; // NOI18N
440
441
        default:
442
            return super.getStateName(stateNumber);
443
        }
444
    }
445
446
    @Override
447
    public void loadInitState() {
448
        startQuoteChar = -1;
449
        super.loadInitState();
450
    }
451
452
    @Override
453
    public StateInfo createStateInfo() {
454
        return new SQLStateInfo();
455
    }
456
457
    @Override
458
    public void loadState(StateInfo stateInfo) {
459
        startQuoteChar = ((SQLStateInfo) stateInfo).getStartQuoteChar();
460
        super.loadState(stateInfo);
461
    }
462
463
    @Override
464
    public void storeState(StateInfo stateInfo) {
465
        ((SQLStateInfo)stateInfo).setStartQuoteChar(startQuoteChar);
466
        super.storeState(stateInfo);
467
    }
468
469
    @Override
470
    public int compareState(StateInfo stateInfo) {
471
        if (stateInfo != null) {
472
            if (((SQLStateInfo)stateInfo).getStartQuoteChar() == startQuoteChar) {
473
                return super.compareState(stateInfo);
474
            }
475
        }
476
        return DIFFERENT_STATE;
477
    }
478
479
    private static boolean isStartQuoteChar(int start) {
480
        return start == '\"' || // SQL-99
481
               start == '`' ||  // MySQL
482
               start == '[';    // MS SQL Server
483
    }
484
485
486
    private static boolean isEndQuoteChar(int start, int end) {
487
        return start == '\"' && end == start || // SQL-99
488
               start == '`' && end == start ||  // MySQL
489
               start == '[' && end == ']';      // MS SQL Server
490
    }
491
492
    /**
493
     * Tries to match the specified sequence of characters to a SQL
494
     * keyword.
495
     *
496
     * @return the KEYWORD id or null if no match was found
497
     */
498
    public TokenID matchKeyword(char[] buffer, int offset, int len) {
499
        String keywordCandidate = new String(buffer, offset, len);
500
        
501
        if (SQLKeywords.isSQL99Keyword(keywordCandidate.toUpperCase(), true)) {
502
            return SQLTokenContext.KEYWORD;
503
        }
504
        
505
        return null;
506
    }
507
508
    private static final class SQLStateInfo extends BaseStateInfo {
509
510
        private int startQuoteChar;
511
512
        public int getStartQuoteChar() {
513
            return startQuoteChar;
514
        }
515
516
        public void setStartQuoteChar(int startQuoteChar) {
517
            this.startQuoteChar = startQuoteChar;
518
        }
519
    }
520
}
(-)a/db.sql.editor/src/org/netbeans/modules/db/sql/editor/SQLSyntaxSupport.java (-74 lines)
Lines 1-74 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * Contributor(s):
28
 *
29
 * The Original Software is NetBeans. The Initial Developer of the Original
30
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
31
 * Microsystems, Inc. All Rights Reserved.
32
 *
33
 * If you wish your version of this file to be governed by only the CDDL
34
 * or only the GPL Version 2, indicate your decision by adding
35
 * "[Contributor] elects to include this software in this distribution
36
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
37
 * single choice of license, a recipient has the option to distribute
38
 * your version of this file under either the CDDL, the GPL Version 2 or
39
 * to extend the choice of license to its licensees as provided above.
40
 * However, if you add GPL Version 2 code and therefore, elected the GPL
41
 * Version 2 license, then the option applies only if the new code is
42
 * made subject to such option by the copyright holder.
43
 */
44
45
package org.netbeans.modules.db.sql.editor;
46
47
import javax.swing.text.BadLocationException;
48
import javax.swing.text.JTextComponent;
49
import org.netbeans.editor.BaseDocument;
50
import org.netbeans.editor.TokenID;
51
import org.netbeans.editor.ext.ExtSyntaxSupport;
52
import org.openide.DialogDisplayer;
53
import org.openide.NotifyDescriptor;
54
55
/**
56
 *
57
 * @author Jesse Beaumont
58
 */
59
public class SQLSyntaxSupport extends ExtSyntaxSupport {
60
61
    public SQLSyntaxSupport(BaseDocument doc) {
62
        super(doc);
63
    }
64
65
    /**
66
     * Get the array of token IDs that denote the comments.
67
     */
68
    public TokenID[] getCommentTokens() {
69
        return new TokenID[] {
70
            SQLTokenContext.BLOCK_COMMENT,
71
            SQLTokenContext.LINE_COMMENT
72
        };
73
    }
74
}
(-)a/db.sql.editor/src/org/netbeans/modules/db/sql/editor/SQLTokenContext.java (-127 lines)
Lines 1-127 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * Contributor(s):
28
 *
29
 * The Original Software is NetBeans. The Initial Developer of the Original
30
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2009 Sun
31
 * Microsystems, Inc. All Rights Reserved.
32
 *
33
 * If you wish your version of this file to be governed by only the CDDL
34
 * or only the GPL Version 2, indicate your decision by adding
35
 * "[Contributor] elects to include this software in this distribution
36
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
37
 * single choice of license, a recipient has the option to distribute
38
 * your version of this file under either the CDDL, the GPL Version 2 or
39
 * to extend the choice of license to its licensees as provided above.
40
 * However, if you add GPL Version 2 code and therefore, elected the GPL
41
 * Version 2 license, then the option applies only if the new code is
42
 * made subject to such option by the copyright holder.
43
 */
44
45
package org.netbeans.modules.db.sql.editor;
46
47
import java.util.logging.Level;
48
import java.util.logging.Logger;
49
import org.netbeans.editor.BaseTokenCategory;
50
import org.netbeans.editor.BaseTokenID;
51
import org.netbeans.editor.TokenContext;
52
import org.netbeans.editor.TokenContextPath;
53
54
/**
55
* SQL token-context defines token-ids and token-categories
56
* used in SQL language.
57
*
58
* @author Jesse Beaumont based on code by Miloslav Metelka
59
*/
60
61
public class SQLTokenContext extends TokenContext {
62
63
    // Numeric-ids for token categories
64
    public static final int ERRORS_ID = 0; // errors
65
66
    // Numeric-ids for token-ids
67
    public static final int WHITESPACE_ID = ERRORS_ID + 1; // inside white space
68
    public static final int LINE_COMMENT_ID = WHITESPACE_ID + 1; // inside line comment --
69
    public static final int BLOCK_COMMENT_ID = LINE_COMMENT_ID + 1; // inside block comment /* ... */
70
    public static final int STRING_ID = BLOCK_COMMENT_ID + 1; // inside string constant
71
    public static final int INCOMPLETE_STRING_ID = STRING_ID + 1; // inside string constant after '
72
    public static final int IDENTIFIER_ID = INCOMPLETE_STRING_ID + 1; // inside identifier
73
    public static final int OPERATOR_ID = IDENTIFIER_ID + 1; // slash char
74
    public static final int INVALID_COMMENT_END_ID = OPERATOR_ID + 1; // after '0'
75
    public static final int INT_LITERAL_ID = INVALID_COMMENT_END_ID + 1; // integer number
76
    public static final int DOUBLE_LITERAL_ID = INT_LITERAL_ID + 1; // double number
77
    public static final int DOT_ID = DOUBLE_LITERAL_ID + 1; // after '.'
78
    public static final int KEYWORD_ID = DOT_ID + 1;
79
    
80
    // Token categories
81
    public static final BaseTokenCategory ERRORS = 
82
            new BaseTokenCategory("errors", ERRORS_ID); // NOI18N
83
    
84
    // Token-ids
85
    public static final BaseTokenID WHITESPACE = 
86
            new BaseTokenID( "whitespace", WHITESPACE_ID ); // NOI18N
87
    public static final BaseTokenID LINE_COMMENT = 
88
            new BaseTokenID( "line-comment", LINE_COMMENT_ID ); // NOI18N
89
    public static final BaseTokenID BLOCK_COMMENT = 
90
            new BaseTokenID( "block-comment", BLOCK_COMMENT_ID ); // NOI18N
91
    public static final BaseTokenID STRING = 
92
            new BaseTokenID( "string-literal", STRING_ID ); // NOI18N
93
    public static final BaseTokenID INCOMPLETE_STRING = 
94
            new BaseTokenID( "incomplete-string-literal", INCOMPLETE_STRING_ID, ERRORS ); // NOI18N
95
    public static final BaseTokenID IDENTIFIER = 
96
            new BaseTokenID( "identifier", IDENTIFIER_ID ); // NOI18N
97
    public static final BaseTokenID OPERATOR = 
98
            new BaseTokenID( "operator", OPERATOR_ID ); // NOI18N
99
    public static final BaseTokenID INVALID_COMMENT_END = 
100
            new BaseTokenID( "invalid-comment-end", INVALID_COMMENT_END_ID, ERRORS ); // NOI18N
101
    public static final BaseTokenID INT_LITERAL = 
102
            new BaseTokenID( "int-literal", INT_LITERAL_ID ); // NOI18N
103
    public static final BaseTokenID DOUBLE_LITERAL = 
104
            new BaseTokenID( "double-literal", DOUBLE_LITERAL_ID ); // NOI18N
105
    public static final BaseTokenID DOT = 
106
            new BaseTokenID( "dot", DOT_ID ); // NOI18N
107
    public static final BaseTokenID KEYWORD = 
108
            new BaseTokenID( "keyword", KEYWORD_ID ); // NOI18N
109
        
110
    // Context instance declaration
111
    public static final SQLTokenContext context = new SQLTokenContext();
112
    public static final TokenContextPath contextPath = context.getContextPath();
113
114
    /**
115
     * Constructs a new SQLTokenContext
116
     */
117
    private SQLTokenContext() {
118
        super("sql-"); // NOI18N
119
120
        try {
121
            addDeclaredTokenIDs();
122
        } catch (Exception e) {
123
            Logger.getLogger (SQLTokenContext.class.getName ()).log (Level.INFO, e.getLocalizedMessage (), e);
124
        }
125
126
    }
127
}
(-)a/db.sql.editor/src/org/netbeans/modules/db/sql/editor/SQLTypedTextInterceptor.java (+164 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.db.sql.editor;
43
44
import javax.swing.text.BadLocationException;
45
import javax.swing.text.Document;
46
import org.netbeans.api.editor.mimelookup.MimeRegistration;
47
import org.netbeans.api.editor.mimelookup.MimeRegistrations;
48
import org.netbeans.api.lexer.TokenSequence;
49
import org.netbeans.editor.BaseDocument;
50
import org.netbeans.modules.db.sql.editor.completion.SQLCompletionEnv;
51
import org.netbeans.modules.db.sql.lexer.SQLLexer;
52
import org.netbeans.modules.db.sql.lexer.SQLTokenId;
53
import org.netbeans.spi.editor.typinghooks.TypedTextInterceptor;
54
55
public class SQLTypedTextInterceptor implements TypedTextInterceptor {
56
57
    @MimeRegistrations({
58
        @MimeRegistration(mimeType = "text/x-sql", service = TypedTextInterceptor.Factory.class)
59
    })
60
    public static class Factory implements TypedTextInterceptor.Factory {
61
62
        @Override
63
        public TypedTextInterceptor createTypedTextInterceptor(org.netbeans.api.editor.mimelookup.MimePath mimePath) {
64
            return new SQLTypedTextInterceptor();
65
        }
66
    }
67
68
    @Override
69
    public boolean beforeInsert(Context context) throws BadLocationException {
70
        return false;
71
    }
72
73
    @Override
74
    public void insert(MutableContext context) throws BadLocationException {
75
    }
76
77
    @Override
78
    public void afterInsert(final Context context) throws BadLocationException {
79
        final Document doc = context.getDocument();
80
81
        Runnable r = new Runnable() {
82
            public void run() {
83
                int caretOffset = context.getOffset();
84
                String str = context.getText();
85
86
                Character nextChar;
87
                
88
                try {
89
                    nextChar = doc.getText(caretOffset + str.length(),
90
                            1).charAt(0);
91
                } catch (BadLocationException ex) {
92
                    nextChar = null;
93
                }
94
                
95
                if (!str.isEmpty()) {
96
                    char insertedChar = str.charAt(str.length() - 1);
97
                    if ( (SQLLexer.isStartIdentifierQuoteChar(insertedChar)
98
                            && (nextChar == null || Character.isWhitespace(nextChar) || nextChar.equals('.')))
99
                            || 
100
                         (SQLLexer.isStartStringQuoteChar(insertedChar) 
101
                            && (nextChar == null || Character.isWhitespace(nextChar)))
102
                            ) {  //NOI18N
103
                        if (canCompleteQuote(doc, caretOffset)) {
104
                            try {
105
                                // add pair quote
106
                                doc.insertString(caretOffset + str.length(), String.valueOf((char) SQLLexer.getMatchingQuote(insertedChar)), null);
107
                                context.getComponent().getCaret().setDot(caretOffset + str.length());
108
                            } catch (BadLocationException ex) {
109
                            }
110
                        }
111
                    } else if (insertedChar == '(' && (nextChar == null || Character.isWhitespace(nextChar))) {
112
                        if (canCompleteBrace(doc, caretOffset)) {
113
                            try {
114
                                // add pair quote
115
                                doc.insertString(caretOffset + str.length(), ")", null);
116
                                context.getComponent().getCaret().setDot(caretOffset + str.length());
117
                            } catch (BadLocationException ex) {
118
                            }
119
                        }
120
                    }
121
                }
122
            }
123
        };
124
        
125
        if(doc instanceof BaseDocument) {
126
            ((BaseDocument) doc).runAtomic(r);
127
        } else {
128
            r.run();
129
        }
130
    }
131
132
    /**
133
     * Returns true if completion of quote is wanted, i.e. cursor is on token
134
     * boundary and previous token is dot or whitespace.
135
     */
136
    private static boolean canCompleteQuote(Document doc, int caretOffset) {
137
        SQLCompletionEnv env = SQLCompletionEnv.forDocument(doc, caretOffset);
138
        TokenSequence<SQLTokenId> seq = env.getTokenSequence();
139
        if (seq.move(caretOffset) == 0 && seq.movePrevious()) {
140
            switch (seq.token().id()) {
141
                case WHITESPACE:
142
                case DOT:
143
                    return true;
144
            }
145
        }
146
        return false;
147
    }
148
149
    private static boolean canCompleteBrace(Document doc, int caretOffset) {
150
        SQLCompletionEnv env = SQLCompletionEnv.forDocument(doc, caretOffset);
151
        TokenSequence<SQLTokenId> seq = env.getTokenSequence();
152
        if (seq.move(caretOffset) == 0 && seq.movePrevious()) {
153
            switch (seq.token().id()) {
154
                case WHITESPACE:
155
                    return true;
156
            }
157
        }
158
        return false;
159
    }
160
161
    @Override
162
    public void cancelled(Context context) {
163
    }
164
}
(-)a/db.sql.editor/src/org/netbeans/modules/db/sql/editor/resources/NetBeans-SQL-preferences.xml (-51 lines)
Lines 1-51 Link Here
1
<?xml version="1.0"?>
2
<!--
3
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4
5
Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
6
7
Oracle and Java are registered trademarks of Oracle and/or its affiliates.
8
Other names may be trademarks of their respective owners.
9
10
11
The contents of this file are subject to the terms of either the GNU
12
General Public License Version 2 only ("GPL") or the Common
13
Development and Distribution License("CDDL") (collectively, the
14
"License"). You may not use this file except in compliance with the
15
License. You can obtain a copy of the License at
16
http://www.netbeans.org/cddl-gplv2.html
17
or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
18
specific language governing permissions and limitations under the
19
License.  When distributing the software, include this License Header
20
Notice in each file and include the License file at
21
nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
22
particular file as subject to the "Classpath" exception as provided
23
by Oracle in the GPL Version 2 section of the License file that
24
accompanied this code. If applicable, add the following below the
25
License Header, with the fields enclosed by brackets [] replaced by
26
your own identifying information:
27
"Portions Copyrighted [year] [name of copyright owner]"
28
29
Contributor(s):
30
31
The Original Software is NetBeans. The Initial Developer of the Original
32
Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
33
Microsystems, Inc. All Rights Reserved.
34
35
If you wish your version of this file to be governed by only the CDDL
36
or only the GPL Version 2, indicate your decision by adding
37
"[Contributor] elects to include this software in this distribution
38
under the [CDDL or GPL Version 2] license." If you do not indicate a
39
single choice of license, a recipient has the option to distribute
40
your version of this file under either the CDDL, the GPL Version 2 or
41
to extend the choice of license to its licensees as provided above.
42
However, if you add GPL Version 2 code and therefore, elected the GPL
43
Version 2 license, then the option applies only if the new code is
44
made subject to such option by the copyright holder.
45
-->
46
<!DOCTYPE editor-preferences PUBLIC "-//NetBeans//DTD Editor Preferences 1.0//EN" "http://www.netbeans.org/dtds/EditorPreferences-1_0.dtd">
47
48
<editor-preferences>
49
    <entry name="token-context-list" value="org.netbeans.modules.db.sql.editor.SQLSettingsInitializer.getTokenContext" javaType="methodvalue" />
50
    <entry name="indentEngine" value="org.netbeans.modules.db.sql.editor.SQLSettingsInitializer.getIndentEngine" javaType="methodvalue" />
51
</editor-preferences>
(-)a/db.sql.editor/src/org/netbeans/modules/db/sql/editor/resources/SQLIndentEngine.settings (-10 lines)
Lines 1-10 Link Here
1
<?xml version="1.0"?>
2
<!DOCTYPE settings PUBLIC "-//NetBeans//DTD Session settings 1.0//EN" "http://www.netbeans.org/dtds/sessionsettings-1_0.dtd">
3
<settings version="1.0">
4
    <module name="org.netbeans.modules.db.sql.editor"/>
5
    <instanceof class="org.openide.ServiceType"/>
6
    <instanceof class="org.openide.text.IndentEngine"/>
7
    <instanceof class="org.netbeans.modules.editor.FormatterIndentEngine"/>
8
    <instanceof class="org.netbeans.modules.db.sql.editor.SQLIndentEngine"/>
9
    <instance class="org.netbeans.modules.db.sql.editor.SQLIndentEngine"/>
10
</settings>
(-)a/db.sql.editor/src/org/netbeans/modules/db/sql/editor/resources/layer.xml (-18 lines)
Lines 45-57 Link Here
45
-->
45
-->
46
<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.0//EN" "http://www.netbeans.org/dtds/filesystem-1_0.dtd">
46
<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.0//EN" "http://www.netbeans.org/dtds/filesystem-1_0.dtd">
47
<filesystem>
47
<filesystem>
48
    <folder name="Services">
49
        <folder name="IndentEngine">
50
            <file name="org-netbeans-modules-db-sql-editor-resources-SQLIndentEngine.settings" url="SQLIndentEngine.settings">
51
            </file>
52
        </folder>
53
    </folder>
54
55
    <folder name="Actions">
48
    <folder name="Actions">
56
        <folder name="System">
49
        <folder name="System">
57
            <file name="org-netbeans-modules-db-sql-editor-ui-actions-RunSQLAction.instance">
50
            <file name="org-netbeans-modules-db-sql-editor-ui-actions-RunSQLAction.instance">
Lines 80-101 Link Here
80
        <folder name="text">
73
        <folder name="text">
81
            <folder name="x-sql">
74
            <folder name="x-sql">
82
                <attr name="SystemFileSystem.localizingBundle" stringvalue="org.netbeans.modules.db.sql.editor.resources.Bundle"/>
75
                <attr name="SystemFileSystem.localizingBundle" stringvalue="org.netbeans.modules.db.sql.editor.resources.Bundle"/>
83
                <file name="EditorKit.instance">
84
                    <attr name="instanceClass" stringvalue="org.netbeans.modules.db.sql.editor.SQLEditorKit"/>
85
                    <attr name="instanceOf" stringvalue="javax.swing.text.EditorKit,org.netbeans.modules.db.sql.editor.SQLEditorKit"/>
86
                    <attr name="beaninfo" boolvalue="false"/>
87
                </file>
88
76
89
                <folder name="CompletionProviders">
77
                <folder name="CompletionProviders">
90
                    <file name="org-netbeans-modules-db-sql-editor-completion-SQLCompletionProvider.instance"/>
78
                    <file name="org-netbeans-modules-db-sql-editor-completion-SQLCompletionProvider.instance"/>
91
                </folder>
79
                </folder>
92
80
93
                <folder name="Preferences">
94
                    <folder name="Defaults">
95
                        <file name="org-netbeans-modules-db-sql-editor-preferences.xml" url="NetBeans-SQL-preferences.xml"/>
96
                    </folder>
97
                </folder>
98
99
                <folder name="FontsColors">
81
                <folder name="FontsColors">
100
                    <folder name="NetBeans">
82
                    <folder name="NetBeans">
101
                        <folder name="Defaults">
83
                        <folder name="Defaults">
(-)a/db.sql.editor/src/org/netbeans/modules/db/sql/lexer/SQLLanguageConfig.java (+67 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.db.sql.lexer;
43
44
import org.netbeans.api.lexer.Language;
45
import org.netbeans.modules.csl.spi.DefaultLanguageConfig;
46
import org.netbeans.modules.csl.spi.LanguageRegistration;
47
48
@LanguageRegistration(mimeType="text/x-sql")
49
public class SQLLanguageConfig extends DefaultLanguageConfig {
50
51
    @Override
52
    public Language<SQLTokenId> getLexerLanguage() {
53
        return SQLTokenId.language();
54
    }
55
56
    @Override
57
    public String getDisplayName() {
58
        return "SQL";
59
    }
60
61
    @Override
62
    public String getLineCommentPrefix() {
63
        return "-- ";
64
    }
65
    
66
    
67
}
(-)a/db.sql.editor/src/org/netbeans/modules/db/sql/lexer/SQLLexer.java (-7 / +18 lines)
Lines 128-134 Link Here
128
                            }
128
                            }
129
129
130
                            // Otherwise it's an identifier.
130
                            // Otherwise it's an identifier.
131
                            if (isStartQuoteChar(actChar)) {
131
                            if (isStartIdentifierQuoteChar(actChar)) {
132
                                startQuoteChar = actChar;
132
                                startQuoteChar = actChar;
133
                            }
133
                            }
134
                            state = State.ISI_IDENTIFIER;
134
                            state = State.ISI_IDENTIFIER;
Lines 182-188 Link Here
182
                // or a keyword.
182
                // or a keyword.
183
                case ISI_IDENTIFIER:
183
                case ISI_IDENTIFIER:
184
                    if (startQuoteChar != -1) {
184
                    if (startQuoteChar != -1) {
185
                        if (!isEndQuoteChar(startQuoteChar, actChar)) {
185
                        if (!isEndIdentifierQuoteChar(startQuoteChar, actChar)) {
186
                            break;
186
                            break;
187
                        }
187
                        }
188
                    } else {
188
                    } else {
Lines 377-392 Link Here
377
    public void release() {
377
    public void release() {
378
    }
378
    }
379
379
380
    private static boolean isStartQuoteChar(int start) {
380
    public static boolean isStartStringQuoteChar(int start) {
381
        return start == '\'';  // SQL-99 string
382
    }
383
    
384
    public static boolean isStartIdentifierQuoteChar(int start) {
381
        return start == '\"' || // SQL-99
385
        return start == '\"' || // SQL-99
382
                start == '`' || // MySQL
386
                start == '`' || // MySQL
383
                start == '[';    // MS SQL Server
387
                start == '[';    // MS SQL Server
384
    }
388
    }
389
    
390
    public static int getMatchingQuote(int start) {
391
        switch(start) {
392
            case '[':
393
                return ']';
394
            default:
395
                return start;
396
        }
397
    }
385
398
386
    private static boolean isEndQuoteChar(int start, int end) {
399
    public static boolean isEndIdentifierQuoteChar(int start, int end) {
387
        return start == '\"' && end == start || // SQL-99
400
        return end == getMatchingQuote(start);
388
                start == '`' && end == start || // MySQL
389
                start == '[' && end == ']';      // MS SQL Server
390
    }
401
    }
391
402
392
    private static SQLTokenId testKeyword(CharSequence value) {
403
    private static SQLTokenId testKeyword(CharSequence value) {
(-)a/db.sql.editor/src/org/netbeans/modules/db/sql/lexer/SQLTokenId.java (-17 / +14 lines)
Lines 61-83 Link Here
61
 * @author Andrei Badea
61
 * @author Andrei Badea
62
 */
62
 */
63
public enum SQLTokenId implements TokenId {
63
public enum SQLTokenId implements TokenId {
64
64
    WHITESPACE("sql-whitespace"), // NOI18N
65
    // XXX prefix with "sql-" for compat reasons?
65
    LINE_COMMENT("sql-line-comment"), // NOI18N
66
66
    BLOCK_COMMENT("sql-block-comment"), // NOI18N
67
    WHITESPACE("whitespace"), // NOI18N
67
    STRING("sql-string-literal"), // NOI18N
68
    LINE_COMMENT("line-comment"), // NOI18N
68
    INCOMPLETE_STRING("sql-string-literal"), // NOI18N
69
    BLOCK_COMMENT("block-comment"), // NOI18N
69
    IDENTIFIER("sql-identifier"), // NOI18N
70
    STRING("string-literal"), // NOI18N
70
    OPERATOR("sql-operator"), // NOI18N
71
    INCOMPLETE_STRING("incomplete-string-literal"), // NOI18N
71
    LPAREN("sql-operator"), // NOI18N
72
    IDENTIFIER("identifier"), // NOI18N
72
    RPAREN("sql-operator"), // NOI18N
73
    OPERATOR("operator"), // NOI18N
73
    DOT("sql-dot"), // NOI18N
74
    LPAREN("operator"), // NOI18N
74
    COMMA("sql-operator"), //  // NOI18N XXX or have own category?
75
    RPAREN("operator"), // NOI18N
75
    INT_LITERAL("sql-int-literal"),  // NOI18N
76
    DOT("dot"), // NOI18N
76
    DOUBLE_LITERAL("sql-double-literal"), // NOI18N
77
    COMMA("operator"), //  // NOI18N XXX or have own category?
77
    KEYWORD("sql-keyword"); // NOI18N
78
    INT_LITERAL("int-literal"),  // NOI18N
79
    DOUBLE_LITERAL("double-literal"), // NOI18N
80
    KEYWORD("keyword"); // NOI18N
81
78
82
    private final String primaryCategory;
79
    private final String primaryCategory;
83
80
(-)a/db.sql.editor/test/unit/src/org/netbeans/modules/db/sql/editor/SQLSyntaxTest.java (-185 lines)
Lines 1-185 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * Contributor(s):
28
 *
29
 * The Original Software is NetBeans. The Initial Developer of the Original
30
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2010 Sun
31
 * Microsystems, Inc. All Rights Reserved.
32
 *
33
 * If you wish your version of this file to be governed by only the CDDL
34
 * or only the GPL Version 2, indicate your decision by adding
35
 * "[Contributor] elects to include this software in this distribution
36
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
37
 * single choice of license, a recipient has the option to distribute
38
 * your version of this file under either the CDDL, the GPL Version 2 or
39
 * to extend the choice of license to its licensees as provided above.
40
 * However, if you add GPL Version 2 code and therefore, elected the GPL
41
 * Version 2 license, then the option applies only if the new code is
42
 * made subject to such option by the copyright holder.
43
 */
44
45
package org.netbeans.modules.db.sql.editor;
46
47
import java.util.Arrays;
48
import java.util.Iterator;
49
import org.netbeans.editor.Syntax;
50
import org.netbeans.editor.TokenID;
51
import org.netbeans.junit.NbTestCase;
52
53
/**
54
 *
55
 * @author Andrei Badea, Jiri Skrivanek
56
 */
57
public class SQLSyntaxTest extends NbTestCase {
58
59
    public SQLSyntaxTest(String testName) {
60
        super(testName);
61
    }
62
63
    public void testNumberLiteralsEndWithFirstNonDigitCharIssue67379() {
64
        assertTokens("10-20.3-3", new TokenID[] {
65
            SQLTokenContext.INT_LITERAL,
66
            SQLTokenContext.OPERATOR,
67
            SQLTokenContext.DOUBLE_LITERAL,
68
            SQLTokenContext.OPERATOR,
69
            SQLTokenContext.INT_LITERAL,
70
        });
71
72
        assertTokens("10foo", new TokenID[] {
73
            SQLTokenContext.INT_LITERAL,
74
            SQLTokenContext.IDENTIFIER,
75
        });
76
    }
77
78
    public void testLast() {
79
        SQLSyntax s = new SQLSyntax();
80
        String sql = "`ident";
81
        s.load(null, sql.toCharArray(), 0, sql.length(), true, sql.length());
82
        assertEquals(SQLTokenContext.IDENTIFIER, s.nextToken());
83
        sql = "select foo bar baz";
84
        s.load(null, sql.toCharArray(), 0, sql.length(), true, sql.length());
85
        assertEquals(SQLTokenContext.KEYWORD, s.nextToken());
86
    }
87
88
    public void testEscapeSingleQuote() {
89
        assertTokens("'Frank\\'s Book'", SQLTokenContext.STRING);
90
        assertTokens("'Frank''s Book'", SQLTokenContext.STRING, SQLTokenContext.STRING);
91
        assertTokens("'Frank\\s Book'", SQLTokenContext.STRING);
92
        assertTokens("'Frank\\", SQLTokenContext.INCOMPLETE_STRING);
93
        assertTokens("'Frank\\'", SQLTokenContext.INCOMPLETE_STRING);
94
    }
95
96
    public void testSlash() {
97
        assertTokens("((EndTime-StartTime)/2)*5", new TokenID[] {
98
            SQLTokenContext.OPERATOR,
99
            SQLTokenContext.OPERATOR,
100
            SQLTokenContext.IDENTIFIER,
101
            SQLTokenContext.OPERATOR,
102
            SQLTokenContext.IDENTIFIER,
103
            SQLTokenContext.OPERATOR,
104
            SQLTokenContext.OPERATOR,
105
            SQLTokenContext.INT_LITERAL,
106
            SQLTokenContext.OPERATOR,
107
            SQLTokenContext.OPERATOR,
108
            SQLTokenContext.INT_LITERAL,
109
        });
110
    }
111
112
    public void testComments() {
113
        assertTokens("select /* block comment */ * from #notLineComment -- line comment",
114
            SQLTokenContext.KEYWORD,
115
            SQLTokenContext.WHITESPACE,
116
            SQLTokenContext.BLOCK_COMMENT,
117
            SQLTokenContext.WHITESPACE,
118
            SQLTokenContext.OPERATOR,
119
            SQLTokenContext.WHITESPACE,
120
            SQLTokenContext.KEYWORD,
121
            SQLTokenContext.WHITESPACE,
122
            SQLTokenContext.IDENTIFIER,
123
            SQLTokenContext.WHITESPACE,
124
            SQLTokenContext.LINE_COMMENT);
125
        // https://netbeans.org/bugzilla/show_bug.cgi?id=172904
126
        assertTokens("# MySQL Line Comment", SQLTokenContext.LINE_COMMENT);
127
        // https://netbeans.org/bugzilla/show_bug.cgi?id=181020
128
        assertTokens("# my line comment \nselect * from mytable",
129
                SQLTokenContext.LINE_COMMENT,
130
                SQLTokenContext.WHITESPACE,
131
                SQLTokenContext.KEYWORD,
132
                SQLTokenContext.WHITESPACE,
133
                SQLTokenContext.OPERATOR,
134
                SQLTokenContext.WHITESPACE,
135
                SQLTokenContext.KEYWORD,
136
                SQLTokenContext.WHITESPACE,
137
                SQLTokenContext.IDENTIFIER
138
                );
139
        // https://netbeans.org/bugzilla/show_bug.cgi?id=191188
140
        assertTokens("select * from mytable where id# = 1",
141
            SQLTokenContext.KEYWORD,
142
            SQLTokenContext.WHITESPACE,
143
            SQLTokenContext.OPERATOR,
144
            SQLTokenContext.WHITESPACE,
145
            SQLTokenContext.KEYWORD,
146
            SQLTokenContext.WHITESPACE,
147
            SQLTokenContext.IDENTIFIER,
148
            SQLTokenContext.WHITESPACE,
149
            SQLTokenContext.KEYWORD,
150
            SQLTokenContext.WHITESPACE,
151
            SQLTokenContext.IDENTIFIER,
152
            SQLTokenContext.WHITESPACE,
153
            SQLTokenContext.OPERATOR,
154
            SQLTokenContext.WHITESPACE,
155
            SQLTokenContext.INT_LITERAL);
156
    }
157
158
    
159
    public void testHashInIdentifier() {
160
        assertTokens("id# = 1", SQLTokenContext.IDENTIFIER, SQLTokenContext.WHITESPACE, SQLTokenContext.OPERATOR, SQLTokenContext.WHITESPACE, SQLTokenContext.INT_LITERAL);
161
    }
162
163
    private void assertTokens(String m, TokenID... tokens) {
164
        Syntax s = new SQLSyntax();
165
        s.load(null, m.toCharArray(), 0, m.length(), true, m.length());
166
        
167
        TokenID token = null;
168
        Iterator<TokenID> i = Arrays.asList(tokens).iterator();
169
        do {
170
            token = s.nextToken();
171
            if (token != null) {
172
                if (!i.hasNext()) {
173
                    fail("More tokens returned than expected.");
174
                } else {
175
                    assertSame("Tokens differ", i.next(), token);
176
                }
177
            } else {
178
                assertFalse("More tokens expected than returned.", i.hasNext());
179
            }
180
            if (token != null) {
181
                log(token.getName());
182
            }
183
        } while (token != null);
184
    }
185
}

Return to bug 193557