1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.log4j.chainsaw;
19
20 import org.apache.log4j.chainsaw.filter.FilterModel;
21 import org.apache.log4j.rule.RuleFactory;
22 import org.apache.log4j.spi.LoggingEventFieldResolver;
23
24 import javax.swing.*;
25 import javax.swing.text.JTextComponent;
26 import java.awt.*;
27 import java.awt.event.*;
28
29
30
31
32
33
34
35 public class ExpressionRuleContext extends KeyAdapter {
36 RuleFactory factory = RuleFactory.getInstance();
37 LoggingEventFieldResolver resolver = LoggingEventFieldResolver.getInstance();
38 JPopupMenu contextMenu = new JPopupMenu();
39 JList list = new JList();
40 FilterModel filterModel;
41 JScrollPane scrollPane = new JScrollPane(list);
42 final JTextComponent textComponent;
43 private DefaultListModel fieldModel = new DefaultListModel();
44 private DefaultListModel operatorModel = new DefaultListModel();
45
46 public ExpressionRuleContext(
47 final FilterModel filterModel, final JTextComponent textComponent) {
48 this.filterModel = filterModel;
49 this.textComponent = textComponent;
50 fieldModel.addElement("LOGGER");
51 fieldModel.addElement("LEVEL");
52 fieldModel.addElement("CLASS");
53 fieldModel.addElement("FILE");
54 fieldModel.addElement("LINE");
55 fieldModel.addElement("METHOD");
56 fieldModel.addElement("MSG");
57 fieldModel.addElement("NDC");
58 fieldModel.addElement("EXCEPTION");
59 fieldModel.addElement("TIMESTAMP");
60 fieldModel.addElement("THREAD");
61 fieldModel.addElement("PROP.");
62
63 operatorModel.addElement("&&");
64 operatorModel.addElement("||");
65 operatorModel.addElement("!");
66 operatorModel.addElement("!=");
67 operatorModel.addElement("==");
68 operatorModel.addElement("~=");
69 operatorModel.addElement("LIKE");
70 operatorModel.addElement("EXISTS");
71 operatorModel.addElement("<");
72 operatorModel.addElement(">");
73 operatorModel.addElement("<=");
74 operatorModel.addElement(">=");
75
76
77 list.setVisibleRowCount(13);
78
79 PopupListener popupListener = new PopupListener();
80 textComponent.addMouseListener(popupListener);
81
82 list.addKeyListener(
83 new KeyAdapter() {
84 public void keyPressed(KeyEvent e) {
85 if (e.getKeyCode() == KeyEvent.VK_ENTER) {
86 String value = list.getSelectedValue().toString();
87 String contextKey = getContextKey();
88 if (contextKey != null && (!(contextKey.endsWith(".")))) {
89 value = "'" + value + "'";
90 }
91
92 updateField(value);
93 contextMenu.setVisible(false);
94 }
95 }
96 });
97
98 list.addMouseListener(
99 new MouseAdapter() {
100 public void mouseClicked(MouseEvent e) {
101 if (e.getClickCount() == 2) {
102 String value = list.getSelectedValue().toString();
103 String contextKey = getContextKey();
104 if (contextKey != null && (!(contextKey.endsWith(".")))) {
105 value = "'" + value + "'";
106 }
107
108 updateField(value);
109 contextMenu.setVisible(false);
110 }
111 }
112 });
113
114 contextMenu.insert(scrollPane, 0);
115 }
116
117 private void updateField(String value) {
118 if (textComponent.getSelectedText() == null) {
119 if (!(value.endsWith("."))) {
120 value = value + " ";
121 }
122 }
123
124 textComponent.replaceSelection(value);
125 }
126
127 public void keyPressed(KeyEvent e) {
128 if (
129 (e.getKeyCode() == KeyEvent.VK_SPACE)
130 && (e.getModifiers() == InputEvent.CTRL_MASK)) {
131 displayContext();
132 }
133 }
134
135 public void displayContext() {
136 String lastField = getContextKey();
137
138 if (lastField != null) {
139 ListModel model = filterModel.getContainer().getModel(lastField);
140 if (model == null) {
141 return;
142 }
143 list.setModel(model);
144 list.setSelectedIndex(0);
145
146 Point p = textComponent.getCaret().getMagicCaretPosition();
147 contextMenu.doLayout();
148 contextMenu.show(textComponent, p.x, (p.y + (textComponent.getHeight() - 5)));
149 list.requestFocus();
150 } else {
151 if (isOperatorContextValid()) {
152 list.setModel(operatorModel);
153 list.setSelectedIndex(0);
154
155 Point p = textComponent.getCaret().getMagicCaretPosition();
156 contextMenu.doLayout();
157 contextMenu.show(textComponent, p.x, (p.y + (textComponent.getHeight() - 5)));
158 list.requestFocus();
159 } else if (isFieldContextValid()) {
160 list.setModel(fieldModel);
161 list.setSelectedIndex(0);
162
163 Point p = textComponent.getCaret().getMagicCaretPosition();
164
165 if (p == null) {
166 p = new Point(
167 textComponent.getLocation().x,
168 (textComponent.getLocation().y - textComponent.getHeight() + 5));
169 }
170 contextMenu.doLayout();
171 contextMenu.show(textComponent, p.x, (p.y + (textComponent.getHeight() - 5)));
172 list.requestFocus();
173 }
174 }
175 }
176
177 private boolean isFieldContextValid() {
178 String text = textComponent.getText();
179 int currentPosition = textComponent.getSelectionStart();
180
181 return ((currentPosition == 0)
182 || (text.charAt(currentPosition - 1) == ' '));
183 }
184
185 private String getContextKey() {
186 String field = getField();
187
188 if (field == null) {
189 field = getSubField();
190 }
191
192 return field;
193 }
194
195 private boolean isOperatorContextValid() {
196 String text = textComponent.getText();
197
198 int currentPosition = textComponent.getSelectionStart();
199
200 if ((currentPosition < 1) || (text.charAt(currentPosition - 1) != ' ')) {
201 return false;
202 }
203
204 int lastFieldPosition = text.lastIndexOf(" ", currentPosition - 1);
205
206 if (lastFieldPosition == -1) {
207 return false;
208 }
209
210 int lastFieldStartPosition =
211 Math.max(0, text.lastIndexOf(" ", lastFieldPosition - 1));
212 String field =
213 text.substring(lastFieldStartPosition, lastFieldPosition).toUpperCase()
214 .trim();
215
216 return resolver.isField(field);
217
218 }
219
220
221
222
223 private String getField() {
224 String text = textComponent.getText();
225
226 int currentPosition = textComponent.getSelectionStart();
227
228 if ((currentPosition < 1) || (text.charAt(currentPosition - 1) != ' ')) {
229 return null;
230 }
231
232 int symbolPosition = text.lastIndexOf(" ", currentPosition - 1);
233
234 if (symbolPosition < 0) {
235 return null;
236 }
237
238 int lastFieldPosition = text.lastIndexOf(" ", symbolPosition - 1);
239
240 if (lastFieldPosition < 0) {
241 return null;
242 }
243
244 int lastFieldStartPosition =
245 Math.max(0, text.lastIndexOf(" ", lastFieldPosition - 1));
246 String lastSymbol =
247 text.substring(lastFieldPosition + 1, symbolPosition).trim();
248
249 String lastField =
250 text.substring(lastFieldStartPosition, lastFieldPosition).trim();
251
252 if (
253 factory.isRule(lastSymbol)
254 && filterModel.getContainer().modelExists(lastField)) {
255 return lastField;
256 }
257
258 return null;
259 }
260
261
262
263 private String getSubField() {
264 int currentPosition = textComponent.getSelectionStart();
265 String text = textComponent.getText();
266
267 if (text.substring(0, currentPosition).toUpperCase().endsWith("PROP.")) {
268 return "PROP.";
269 }
270 return null;
271 }
272
273 class PopupListener extends MouseAdapter {
274 PopupListener() {
275 }
276
277 public void mousePressed(MouseEvent e) {
278 checkPopup(e);
279 }
280
281 public void mouseReleased(MouseEvent e) {
282 checkPopup(e);
283 }
284
285 private void checkPopup(MouseEvent e) {
286 if (e.isPopupTrigger()) {
287 displayContext();
288 }
289 }
290 }
291 }