/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package ro.nextreports.designer; import org.jdesktop.swingx.JXPanel; import org.jdesktop.swingx.JXList; import ro.nextreports.designer.querybuilder.ParameterManager; import ro.nextreports.designer.ui.sqleditor.Editor; import ro.nextreports.designer.util.I18NSupport; import javax.swing.*; import javax.swing.border.TitledBorder; import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.List; import java.util.Collections; import java.util.Comparator; import java.util.Set; import java.text.Collator; import ro.nextreports.engine.util.NameType; import ro.nextreports.engine.exporter.util.variable.VariableFactory; import ro.nextreports.engine.exporter.util.variable.Variable; import ro.nextreports.engine.exporter.ResultExporter; import ro.nextreports.engine.queryexec.QueryParameter; /** * User: mihai.panaitescu * Date: 30-Apr-2010 * Time: 13:54:34 */ public class ExpressionPanel extends JXPanel { //@todo i18n public static String STRING_TYPE = "String"; public static String DATE_TYPE = "Date"; public static String NUMERIC_TYPE = "Numeric"; public static String BOOLEAN_TYPE = "Boolean"; private Dimension scrDim = new Dimension(180, 106); private Dimension smallScrDim = new Dimension(80, 100); private Dimension editorDim = new Dimension(540, 300); private JXList columnList; private DefaultListModel columnModel = new DefaultListModel(); private JScrollPane scrColumn; private JXList functionList; private DefaultListModel functionModel = new DefaultListModel(); private JScrollPane scrFunction; private JXList variableList; private DefaultListModel variableModel = new DefaultListModel(); private JScrollPane scrVariable; private JXList parameterList; private DefaultListModel parameterModel = new DefaultListModel(); private JScrollPane scrParameter; private JXList operatorList; private DefaultListModel operatorModel = new DefaultListModel(); private JScrollPane scrOperator; private Editor editor; private JScrollPane scrEditor; private JTextField nameText; public ExpressionPanel(boolean isStatic, boolean isFooter, String bandName) { this(isStatic, isFooter, bandName, true); } public ExpressionPanel(boolean isStatic, boolean isHeaderOrFooter, String bandName, boolean showName) { if (!isStatic) { addColumns(); } if (isHeaderOrFooter) { addFunctions(bandName); } addVariables(); addParameters(); addOperators(); initUI(isStatic, isHeaderOrFooter, showName); } private void initUI(boolean isStatic, boolean isHeaderOrFooter, boolean showName) { setLayout(new GridBagLayout()); if (!isStatic) { columnList = new JXList(columnModel); columnList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); columnList.setCellRenderer(new ColumnCellRenderer()); columnList.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 2) { int position = editor.getEditorPanel().getEditorPane().getCaretPosition(); String old = editor.getText(); int index = columnList.locationToIndex(e.getPoint()); NameType nt = (NameType) columnModel.getElementAt(index); String col = nt.getName().replaceAll("\\s", ResultExporter.SPACE_REPLACEMENT); editor.setText(newExpression(old, position, col, "C")); } } }); scrColumn = new JScrollPane(columnList, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); scrColumn.setPreferredSize(scrDim); scrColumn.setMinimumSize(scrDim); scrColumn.setBorder(new TitledBorder(I18NSupport.getString("expression.columns"))); } if (isHeaderOrFooter && (functionModel.size() > 0)) { functionList = new JXList(functionModel); functionList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); functionList.setCellRenderer(new FunctionCellRenderer()); functionList.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 2) { int position = editor.getEditorPanel().getEditorPane().getCaretPosition(); String old = editor.getText(); int index = functionList.locationToIndex(e.getPoint()); String f = (String) functionModel.getElementAt(index); editor.setText(newExpression(old, position, f, "F")); } } }); scrFunction = new JScrollPane(functionList, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); scrFunction.setPreferredSize(scrDim); scrFunction.setMinimumSize(scrDim); scrFunction.setBorder(new TitledBorder(I18NSupport.getString("expression.functions"))); } variableList = new JXList(variableModel); variableList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); variableList.setCellRenderer(new VariableCellRenderer()); variableList.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 2) { int position = editor.getEditorPanel().getEditorPane().getCaretPosition(); String old = editor.getText(); int index = variableList.locationToIndex(e.getPoint()); Variable variable = (Variable) variableModel.getElementAt(index); editor.setText(newExpression(old, position, variable.getName(), "V")); } } }); scrVariable = new JScrollPane(variableList, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); scrVariable.setPreferredSize(scrDim); scrVariable.setMinimumSize(scrDim); scrVariable.setBorder(new TitledBorder(I18NSupport.getString("expression.variables"))); parameterList = new JXList(parameterModel); parameterList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); parameterList.setCellRenderer(new ParameterCellRenderer()); parameterList.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 2) { int position = editor.getEditorPanel().getEditorPane().getCaretPosition(); String old = editor.getText(); int index = parameterList.locationToIndex(e.getPoint()); QueryParameter parameter = (QueryParameter) parameterModel.getElementAt(index); editor.setText(newExpression(old, position, parameter.getName(), "P")); } } }); scrParameter = new JScrollPane(parameterList, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); scrParameter.setPreferredSize(scrDim); scrParameter.setMinimumSize(scrDim); scrParameter.setBorder(new TitledBorder(I18NSupport.getString("expression.parameters"))); operatorList = new JXList(operatorModel); operatorList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); operatorList.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 2) { int position = editor.getEditorPanel().getEditorPane().getCaretPosition(); String old = editor.getText(); int index = operatorList.locationToIndex(e.getPoint()); String operator = (String) operatorModel.getElementAt(index); editor.setText(newExpressionOperator(old, position, operator)); } } }); scrOperator = new JScrollPane(operatorList, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); scrOperator.setPreferredSize(smallScrDim); scrOperator.setMinimumSize(smallScrDim); scrOperator.setBorder(new TitledBorder(I18NSupport.getString("expression.operators"))); editor = new Editor(); scrEditor = new JScrollPane(editor, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); scrEditor.setPreferredSize(editorDim); scrEditor.setMinimumSize(editorDim); scrEditor.setBorder(new TitledBorder(I18NSupport.getString("expression.editor"))); nameText = new JTextField(); nameText.requestFocusInWindow(); JPanel namePanel = new JPanel(); namePanel.setLayout(new BoxLayout(namePanel, BoxLayout.X_AXIS)); namePanel.add(new JLabel(I18NSupport.getString("expression.name"))); namePanel.add(Box.createHorizontalStrut(5)); namePanel.add(nameText); if (showName) { add(namePanel, new GridBagConstraints(0, 0, 1, 1, 0.1, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); } int index = 1; if (!isStatic) { add(scrColumn, new GridBagConstraints(0, 1, 1, 1, 0.1, 1.0, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0, 5, 5, 5), 0, 0)); index++; } if (isHeaderOrFooter && (functionModel.size() > 0)) { add(scrFunction, new GridBagConstraints(0, index, 1, 1, 0.1, 1.0, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0, 5, 5, 5), 0, 0)); index++; } add(scrVariable, new GridBagConstraints(0, index, 1, 1, 0.1, 1.0, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0, 5, 5, 5), 0, 0)); int gridHeight = index; if (!parameterModel.isEmpty()) { gridHeight = index+1; add(scrParameter, new GridBagConstraints(0, gridHeight, 1, 1, 0.1, 1.0, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0, 5, 5, 5), 0, 0)); } add(scrOperator, new GridBagConstraints(1, 1, 1, gridHeight, 0.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.VERTICAL, new Insets(5, 0, 5, 5), 0, 0)); add(scrEditor, new GridBagConstraints(2, 1, 1, gridHeight, 1.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(5, 0, 5, 5), 0, 0)); } class ColumnCellRenderer extends DefaultListCellRenderer { public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { JLabel comp = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); if (value != null) { NameType column = (NameType) value; String type = NUMERIC_TYPE; if ("java.lang.String".equals(column.getType())) { type = STRING_TYPE; } else if ("java.util.Date".equals(column.getType())) { type = DATE_TYPE; } else if ("java.lang.Boolean".equals(column.getType())) { type = BOOLEAN_TYPE; } comp.setText("<html>$C_" + column.getName() + " <font color=\"#cccccc\">(" + type + ")</font></html>"); // value = column.getName(); // list.setToolTipText(value.toString()); } return comp; } } class VariableCellRenderer extends DefaultListCellRenderer { public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { JLabel comp = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); if (value != null) { Variable variable = (Variable) value; String type = STRING_TYPE; if (variable.getName().equals(Variable.DATE_VARIABLE)) { type = DATE_TYPE; } else if (variable.getName().equals(Variable.ROW_VARIABLE)) { type = NUMERIC_TYPE; } else if (variable.getName().equals(Variable.GROUP_ROW_VARIABLE)) { type = NUMERIC_TYPE; } else if (variable.getName().equals(Variable.PRODUCT_VARIABLE)) { type = STRING_TYPE; } else if (variable.getName().equals(Variable.USER_VARIABLE)) { type = STRING_TYPE; } else if (variable.getName().equals(Variable.EMPTY_DATA_VARIABLE)) { type = BOOLEAN_TYPE; } comp.setText("<html>$V_" + variable.getName() + " <font color=\"#cccccc\">(" + type + ")</font></html>"); } return comp; } } class ParameterCellRenderer extends DefaultListCellRenderer { public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { JLabel comp = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); if (value != null) { QueryParameter parameter = (QueryParameter) value; String type = NUMERIC_TYPE; if ("java.lang.String".equals(parameter.getValueClassName())) { type = STRING_TYPE; } else if ("java.lang.Boolean".equals(parameter.getValueClassName())) { type = BOOLEAN_TYPE; } else if ("java.util.Date".equals(parameter.getValueClassName())) { type = DATE_TYPE; } comp.setText("<html>$P_" + parameter.getName() + " <font color=\"#cccccc\">(" + type + ")</font></html>"); } return comp; } } class FunctionCellRenderer extends DefaultListCellRenderer { public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { JLabel comp = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); if (value != null) { String func = (String) value; String type = NUMERIC_TYPE; comp.setText("<html>$F_" + func + " <font color=\"#cccccc\">(" + type + ")</font></html>"); } return comp; } } private void addColumns() { String sql = Globals.getMainFrame().getQueryBuilderPanel().getUserSql(); List<NameType> columns = null; try { columns = ReportLayoutUtil.getAllColumnsForReport(sql); Collections.sort(columns, new Comparator<NameType>() { public int compare(NameType o1, NameType o2) { return Collator.getInstance().compare(o1.getName(), o2.getName()); } }); for (NameType nt : columns) { columnModel.addElement(nt); } } catch (Exception e) { e.printStackTrace(); } } private void addFunctions(String bandName) { Set<String> functions = LayoutHelper.getReportLayout().getFunctions(bandName); for (String f : functions) { functionModel.addElement(f); } } private void addVariables() { List<Variable> variables = VariableFactory.getVariables(); Collections.sort(variables, new Comparator<Variable>() { public int compare(Variable o1, Variable o2) { return Collator.getInstance().compare(o1.getName(), o2.getName()); } }); for (Variable v : variables) { variableModel.addElement(v); } } private void addParameters() { List<QueryParameter> parameters = ParameterManager.getInstance().getParameters(); Collections.sort(parameters, new Comparator<QueryParameter>() { public int compare(QueryParameter o1, QueryParameter o2) { return Collator.getInstance().compare(o1.getName(), o2.getName()); } }); for (QueryParameter param : parameters) { parameterModel.addElement(param); } } private void addOperators() { operatorModel.addElement("+"); operatorModel.addElement("-"); operatorModel.addElement("*"); operatorModel.addElement("/ (div)"); operatorModel.addElement("% (mod)"); operatorModel.addElement("&& (and)"); operatorModel.addElement("|| (or)"); operatorModel.addElement("! (not)"); operatorModel.addElement("== (eq)"); operatorModel.addElement("!= (ne)"); operatorModel.addElement("< (lt)"); operatorModel.addElement("<= (le)"); operatorModel.addElement("> (gt)"); operatorModel.addElement(">= (ge)"); operatorModel.addElement("&"); operatorModel.addElement("|"); operatorModel.addElement("^"); operatorModel.addElement("~"); operatorModel.addElement("if..else.."); } private String newExpression(String oldExpression, int position, String element, String index) { String prefix = oldExpression.substring(0, position); if (!prefix.endsWith(" ")) { prefix = prefix + " "; } String sufix = oldExpression.substring(position); if (!sufix.startsWith(" ")) { sufix = " " + sufix; } return prefix + "$" + index + "_" + element + sufix; } private String newExpressionOperator(String oldExpression, int position, String operator) { String prefix = oldExpression.substring(0, position); if (!prefix.endsWith(" ")) { prefix = prefix + " "; } String sufix = oldExpression.substring(position); if (!sufix.startsWith(" ")) { sufix = " " + sufix; } int index = operator.indexOf("("); if (index > 0) { operator = operator.substring(0, index-1); } if (operator.startsWith("if")) { operator = "if ( ) { ; } else { ; }"; } return prefix + operator + sufix; } public String getExpression(){ return editor.getText(); } public void setExpression(String expression) { editor.setText(expression); } public String getExpressionName() { return nameText.getText(); } public void setExpressionName(String expressionName) { nameText.setText(expressionName); if (!expressionName.equals("")) { nameText.setEditable(false); } } }