001/*-------------------------------------------------------------------------+
002|                                                                          |
003| Copyright 2005-2011 the ConQAT Project                                   |
004|                                                                          |
005| Licensed under the Apache License, Version 2.0 (the "License");          |
006| you may not use this file except in compliance with the License.         |
007| You may obtain a copy of the License at                                  |
008|                                                                          |
009|    http://www.apache.org/licenses/LICENSE-2.0                            |
010|                                                                          |
011| Unless required by applicable law or agreed to in writing, software      |
012| distributed under the License is distributed on an "AS IS" BASIS,        |
013| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
014| See the License for the specific language governing permissions and      |
015| limitations under the License.                                           |
016+-------------------------------------------------------------------------*/
017package eu.cqse.check.framework.scanner.highlighting;
018
019import java.awt.Color;
020import java.awt.Font;
021
022import org.conqat.lib.commons.collections.ImmutablePair;
023
024import eu.cqse.check.framework.scanner.ELanguage;
025import eu.cqse.check.framework.scanner.ETokenType;
026import eu.cqse.check.framework.scanner.ETokenType.ETokenClass;
027import eu.cqse.check.framework.scanner.IToken;
028
029/**
030 * Class that determines the style used when displaying source code.
031 */
032public class SourceCodeStyle {
033
034        /** Color used for comments. */
035        private static final Color JAVA_COMMENT_COLOR = new Color(63, 127, 95);
036
037        /** Color used for JavaDoc comments. */
038        private static final Color JAVA_DOCCOMMENT_COLOR = new Color(63, 95, 191);
039
040        /** Color used for Java keywords. */
041        private static final Color JAVA_KEYWORD_COLOR = new Color(127, 0, 85);
042
043        /** Color used for Java literals. */
044        private static final Color JAVA_LITERAL_COLOR = new Color(42, 0, 255);
045
046        /** Color used for C# keywords. */
047        private static final Color CS_KEYWORD_COLOR = new Color(0, 0, 255);
048
049        /** Color used for C# comments. */
050        private static final Color CS_COMMENT_COLOR = new Color(0, 128, 0);
051
052        /** Color used for C# literals. */
053        private static final Color CS_LITERAL_COLOR = new Color(163, 21, 21);
054
055        /** Color used for C# specials. */
056        private static final Color CS_SPECIAL_COLOR = new Color(200, 200, 200);
057
058        /** Color used for C# doc comments. */
059        private static final Color CS_DOCCOMMENT_COLOR = new Color(128, 128, 128);
060
061        /** The default style used. */
062        private static SourceCodeStyle DEFAULT_STYLE = new SourceCodeStyle();
063
064        /**
065         * The style used for Java. As the default style if already Java-like, we
066         * only have to handle JavaDoc comments here.
067         */
068        private static SourceCodeStyle JAVA_STYLE = new SourceCodeStyle() {
069                @Override
070                public ImmutablePair<Color, Integer> getStyle(ETokenType tokenType) {
071                        if (tokenType == ETokenType.DOCUMENTATION_COMMENT) {
072                                return style(JAVA_DOCCOMMENT_COLOR);
073                        }
074
075                        return super.getStyle(tokenType);
076                }
077        };
078
079        /**
080         * The style used for PL/SQL. The only difference is that we highlight
081         * operators the same as keywords.
082         */
083        private static SourceCodeStyle PLSQL_STYLE = new SourceCodeStyle() {
084                @Override
085                public ImmutablePair<Color, Integer> getStyle(ETokenType tokenType) {
086                        if (tokenType.getTokenClass() == ETokenClass.OPERATOR) {
087                                // we use "if" but any keyword will do
088                                return super.getStyle(ETokenType.IF);
089                        }
090                        return super.getStyle(tokenType);
091                }
092        };
093
094        /** The style used for C#. */
095        private static SourceCodeStyle CS_STYLE = new SourceCodeStyle() {
096                @Override
097                public ImmutablePair<Color, Integer> getStyle(ETokenType tokenType) {
098                        if (tokenType == ETokenType.DOCUMENTATION_COMMENT) {
099                                return style(CS_DOCCOMMENT_COLOR);
100                        }
101
102                        switch (tokenType.getTokenClass()) {
103                        case KEYWORD:
104                                return style(CS_KEYWORD_COLOR);
105                        case LITERAL:
106                                return style(CS_LITERAL_COLOR);
107                        case COMMENT:
108                                return style(CS_COMMENT_COLOR);
109                        case SPECIAL:
110                                return style(CS_SPECIAL_COLOR);
111                        default:
112                                return super.getStyle(tokenType);
113                        }
114                }
115        };
116
117        /** The style used for plain text. */
118        private static SourceCodeStyle PLAIN_TEXT_STYLE = new SourceCodeStyle() {
119                @Override
120                public ImmutablePair<Color, Integer> getStyle(ETokenType tokenType) {
121                        return style(Color.BLACK);
122                }
123        };
124
125        /** Constructor. */
126        private SourceCodeStyle() {
127                // empty
128        }
129
130        /**
131         * Returns the color/font style pair for a given token type. The default
132         * implementation provides a generic highlighting roughly following the one
133         * of java.
134         */
135        public ImmutablePair<Color, Integer> getStyle(ETokenType tokenType) {
136                switch (tokenType.getTokenClass()) {
137                case KEYWORD:
138                        return style(JAVA_KEYWORD_COLOR, Font.BOLD);
139                case LITERAL:
140                        return style(JAVA_LITERAL_COLOR);
141                case SYNTHETIC:
142                case ERROR:
143                        return style(Color.RED, Font.BOLD);
144                case COMMENT:
145                        return style(JAVA_COMMENT_COLOR);
146                default:
147                        return style(Color.BLACK);
148                }
149        }
150
151        /** Returns the color/font style pair for a given token. */
152        public ImmutablePair<Color, Integer> getStyle(IToken token) {
153                return getStyle(token.getType());
154        }
155
156        /** Factory method to simplify creation of style pairs. */
157        private static ImmutablePair<Color, Integer> style(Color color) {
158                return style(color, Font.PLAIN);
159        }
160
161        /** Factory method to simplify creation of style pairs. */
162        private static ImmutablePair<Color, Integer> style(Color color, int style) {
163                return new ImmutablePair<Color, Integer>(color, style);
164        }
165
166        /** Returns the style for a given language. */
167        public static SourceCodeStyle get(ELanguage language) {
168                switch (language) {
169                case TEXT:
170                        return PLAIN_TEXT_STYLE;
171                case JAVA:
172                        return JAVA_STYLE;
173                case CS:
174                case VB:
175                        return CS_STYLE;
176                case PLSQL:
177                        return PLSQL_STYLE;
178                default:
179                        return DEFAULT_STYLE;
180                }
181        }
182}