/******************************************************************************* * Copyright 2017 Capital One Services, LLC and Bitwise, Inc. * Licensed 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 hydrograph.ui.dataviewer.filter; import java.io.IOException; import java.sql.SQLException; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.StringTokenizer; import java.util.TreeMap; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.collections.ListUtils; import org.apache.commons.lang.StringUtils; import org.eclipse.jface.fieldassist.AutoCompleteField; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CCombo; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.custom.TableEditor; import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.FocusListener; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.MessageBox; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Text; import org.slf4j.Logger; import com.google.gson.Gson; import hydrograph.ui.common.schema.Field; import hydrograph.ui.common.schema.Fields; import hydrograph.ui.common.util.CustomColorRegistry; import hydrograph.ui.dataviewer.adapters.DataViewerAdapter; import hydrograph.ui.dataviewer.constants.AdapterConstants; import hydrograph.ui.dataviewer.constants.Messages; import hydrograph.ui.dataviewer.utilities.DataViewerUtility; import hydrograph.ui.dataviewer.utilities.ViewDataSchemaHelper; import hydrograph.ui.dataviewer.window.DebugDataViewer; import hydrograph.ui.logging.factory.LogFactory; /** * The Class FilterHelper. * Helper class for Filter Window * @author Bitwise * */ public class FilterHelper { private static final Logger logger = LogFactory.INSTANCE.getLogger(FilterHelper.class); public static final FilterHelper INSTANCE = new FilterHelper(); private DataViewerAdapter dataViewerAdapter; private DebugDataViewer debugDataViewer; private FilterConditionsDialog filterConditionsDialog; private String SCHEMA_FILE_EXTENTION=".xml"; private String localCondition = ""; /** * Sets the local condition. * * @param localCondition * the new local condition */ public void setLocalCondition(String localCondition) { this.localCondition = localCondition; } /** * Sets the remote condition. * * @param remoteCondition * the new remote condition */ public void setRemoteCondition(String remoteCondition) { this.remoteCondition = remoteCondition; } private String remoteCondition; private FilterHelper() { } /** * Gets the type based operator map. * * @return the type based operator map */ public Map<String, String[]> getTypeBasedOperatorMap(){ Map<String, String[]> typeBasedConditionalOperators = new HashMap<String, String[]>(); String[] NUMERIC_CONDITIONS = new String[]{FilterConstants.GREATER_THAN, FilterConstants.FIELD_GREATER_THAN, FilterConstants.LESS_THAN, FilterConstants.FIELD_LESS_THAN, FilterConstants.LESS_THAN_EQUALS, FilterConstants.FIELD_LESS_THAN_EQUALS, FilterConstants.GREATER_THAN_EQUALS,FilterConstants.FIELD_GREATER_THAN_EQUALS, FilterConstants.NOT_EQUALS,FilterConstants.FIELD_NOT_EQUALS, FilterConstants.EQUALS,FilterConstants.FIELD_EQUALS, FilterConstants.IN, FilterConstants.NOT_IN, FilterConstants.BETWEEN, FilterConstants.BETWEEN_FIELD}; typeBasedConditionalOperators.put(FilterConstants.TYPE_STRING, new String[]{FilterConstants.NOT_EQUALS, FilterConstants.EQUALS, FilterConstants.LIKE, FilterConstants.NOT_LIKE, FilterConstants.IN, FilterConstants.NOT_IN}); typeBasedConditionalOperators.put(FilterConstants.TYPE_BOOLEAN, new String[]{FilterConstants.NOT_EQUALS, FilterConstants.EQUALS}); typeBasedConditionalOperators.put(FilterConstants.TYPE_INTEGER, NUMERIC_CONDITIONS); typeBasedConditionalOperators.put(FilterConstants.TYPE_DATE, NUMERIC_CONDITIONS); typeBasedConditionalOperators.put(FilterConstants.TYPE_BIGDECIMAL, NUMERIC_CONDITIONS); typeBasedConditionalOperators.put(FilterConstants.TYPE_LONG, NUMERIC_CONDITIONS); typeBasedConditionalOperators.put(FilterConstants.TYPE_SHORT, NUMERIC_CONDITIONS); typeBasedConditionalOperators.put(FilterConstants.TYPE_FLOAT, NUMERIC_CONDITIONS); typeBasedConditionalOperators.put(FilterConstants.TYPE_DOUBLE, NUMERIC_CONDITIONS); return typeBasedConditionalOperators; } /** * Gets the text box value 1 listener. * * @param conditionsList * the conditions list * @param fieldsAndTypes * the fields and types * @param fieldNames * the field names * @param saveButton * the save button * @param displayButton * the display button * @return the text box value 1 listener */ public Listener getTextBoxValue1Listener(final List<Condition> conditionsList, final Map<String, String> fieldsAndTypes, final String[] fieldNames, final Button saveButton, final Button displayButton) { Listener listener = new Listener() { @Override public void handleEvent(Event event) { Text text = (Text)event.widget; int index = (int) text.getData(FilterConstants.ROW_INDEX); Condition filterConditions = conditionsList.get(index); filterConditions.setValue1(text.getText()); validateText(text, filterConditions.getFieldName(), fieldsAndTypes, filterConditions.getConditionalOperator()); toggleSaveDisplayButton(conditionsList, fieldsAndTypes, fieldNames, saveButton, displayButton); } }; return listener; } /** * Gets the text box value 2 listener. * * @param conditionsList * the conditions list * @param fieldsAndTypes * the fields and types * @param fieldNames * the field names * @param saveButton * the save button * @param displayButton * the display button * @return the text box value 2 listener */ public Listener getTextBoxValue2Listener(final List<Condition> conditionsList, final Map<String, String> fieldsAndTypes, final String[] fieldNames, final Button saveButton, final Button displayButton) { Listener listener = new Listener() { @Override public void handleEvent(Event event) { Text text = (Text)event.widget; int index = (int) text.getData(FilterConstants.ROW_INDEX); Condition filterConditions = conditionsList.get(index); filterConditions.setValue2(text.getText()); validateText(text, filterConditions.getFieldName(), fieldsAndTypes,filterConditions.getConditionalOperator()); toggleSaveDisplayButton(conditionsList, fieldsAndTypes, fieldNames, saveButton, displayButton); } }; return listener; } /** * Gets the local condition. * * @return the local condition */ public String getLocalCondition() { return localCondition; } /** * Gets the remote condition. * * @return the remote condition */ public String getRemoteCondition() { return remoteCondition; } private void toggleSaveDisplayButton(final List<Condition> conditionsList, final Map<String, String> fieldsAndTypes, final String[] fieldNames, final Button saveButton, final Button displayButton) { if(FilterValidator.INSTANCE.isAllFilterConditionsValid(conditionsList, fieldsAndTypes, fieldNames,debugDataViewer)){ saveButton.setEnabled(true); displayButton.setEnabled(true); } else{ saveButton.setEnabled(false); displayButton.setEnabled(false); } } /** * Gets the field name selection listener. * * @param tableViewer * the table viewer * @param conditionsList * the conditions list * @param fieldsAndTypes * the fields and types * @param fieldNames * the field names * @param saveButton * the save button * @param displayButton * the display button * @return the field name selection listener */ public SelectionListener getFieldNameSelectionListener(final TableViewer tableViewer, final List<Condition> conditionsList, final Map<String, String> fieldsAndTypes, final String[] fieldNames, final Button saveButton, final Button displayButton) { SelectionListener listener = new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { CCombo source = (CCombo) e.getSource(); int index = (int) source.getData(FilterConstants.ROW_INDEX); Condition filterConditions = conditionsList.get(index); String fieldName = source.getText(); filterConditions.setFieldName(fieldName); if(StringUtils.isNotBlank(fieldName)){ String fieldType = fieldsAndTypes.get(fieldName); TableItem item = tableViewer.getTable().getItem(index); CCombo conditionalCombo = (CCombo) item.getData(FilterConditionsDialog.CONDITIONAL_OPERATORS); String[] items = FilterHelper.INSTANCE.getTypeBasedOperatorMap().get(fieldType); //if the current item is not in the item list, reset it if(!Arrays.asList(items).contains(conditionalCombo.getText())){ conditionalCombo.setText(""); } conditionalCombo.setItems(items); new AutoCompleteField(conditionalCombo, new CComboContentAdapter(), conditionalCombo.getItems()); } validateCombo(source); toggleSaveDisplayButton(conditionsList, fieldsAndTypes, fieldNames, saveButton, displayButton); } @Override public void widgetDefaultSelected(SelectionEvent e) {} }; return listener; } /** * Gets the field name modify listener. * * @param tableViewer * the table viewer * @param conditionsList * the conditions list * @param fieldsAndTypes * the fields and types * @param fieldNames * the field names * @param saveButton * the save button * @param displayButton * the display button * @return the field name modify listener */ public ModifyListener getFieldNameModifyListener(final TableViewer tableViewer, final List<Condition> conditionsList, final Map<String, String> fieldsAndTypes, final String[] fieldNames, final Button saveButton, final Button displayButton) { ModifyListener listener = new ModifyListener() { @Override public void modifyText(ModifyEvent e) { CCombo source = (CCombo) e.getSource(); int index = (int) source.getData(FilterConstants.ROW_INDEX); Condition filterConditions = conditionsList.get(index); String fieldName = source.getText(); filterConditions.setFieldName(fieldName); if(StringUtils.isNotBlank(fieldName)){ String fieldType = fieldsAndTypes.get(fieldName); TableItem item = tableViewer.getTable().getItem(index); CCombo conditionalCombo = (CCombo) item.getData(FilterConditionsDialog.CONDITIONAL_OPERATORS); if(conditionalCombo != null && StringUtils.isNotBlank(fieldType)){ conditionalCombo.setText(filterConditions.getConditionalOperator()); conditionalCombo.setItems(FilterHelper.INSTANCE.getTypeBasedOperatorMap().get(fieldType)); new AutoCompleteField(conditionalCombo, new CComboContentAdapter(), conditionalCombo.getItems()); } } validateCombo(source); toggleSaveDisplayButton(conditionsList, fieldsAndTypes, fieldNames, saveButton, displayButton); } }; return listener; } /** * Gets the conditional operator selection listener. * * @param conditionsList * the conditions list * @param fieldsAndTypes * the fields and types * @param fieldNames * the field names * @param saveButton * the save button * @param displayButton * the display button * @return the conditional operator selection listener */ public SelectionListener getConditionalOperatorSelectionListener(final List<Condition> conditionsList, final Map<String, String> fieldsAndTypes, final String[] fieldNames, final Button saveButton, final Button displayButton) { SelectionListener listener = new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { CCombo source = (CCombo) e.getSource(); TableItem tableItem = getTableItem(source); Text text2 = (Text) tableItem.getData(FilterConstants.VALUE2TEXTBOX); Text text1 = (Text) tableItem.getData(FilterConstants.VALUE1TEXTBOX); String selectedValue = source.getItem(source.getSelectionIndex()); showToolTip(text1, selectedValue); enableAndDisableValue2TextBox(selectedValue, text2); processConditionalOperator(source, conditionsList, fieldsAndTypes, fieldNames, saveButton, displayButton); } @Override public void widgetDefaultSelected(SelectionEvent e) {} }; return listener; } private void showToolTip(Text text1, String selectedValue) { if (StringUtils.equalsIgnoreCase(selectedValue, FilterConstants.IN) || StringUtils.equalsIgnoreCase(selectedValue, FilterConstants.NOT_IN)) { text1.setToolTipText(Messages.COMMA_SEPERATED_VALUE); } else { text1.setToolTipText(""); } } private TableItem getTableItem(CCombo source) { TableEditor tableEditor = (TableEditor) source.getData(FilterConstants.CONDITIONAL_EDITOR); TableItem tableItem = tableEditor.getItem(); return tableItem; } /** * Gets the conditional operator modify listener. * * @param conditionsList * the conditions list * @param fieldsAndTypes * the fields and types * @param fieldNames * the field names * @param saveButton * the save button * @param displayButton * the display button * @return the conditional operator modify listener */ public ModifyListener getConditionalOperatorModifyListener(final List<Condition> conditionsList, final Map<String, String> fieldsAndTypes, final String[] fieldNames, final Button saveButton, final Button displayButton) { ModifyListener listener = new ModifyListener() { @Override public void modifyText(ModifyEvent e) { CCombo source = (CCombo) e.getSource(); TableItem tableItem = getTableItem(source); Condition condition = (Condition) tableItem.getData(); if (tableItem.getData(FilterConstants.VALUE2TEXTBOX) != null) { Text text = (Text) tableItem.getData(FilterConstants.VALUE2TEXTBOX); enableAndDisableValue2TextBox(condition.getConditionalOperator(), text); } processConditionalOperator(source, conditionsList, fieldsAndTypes, fieldNames, saveButton, displayButton); } }; return listener; } private void enableAndDisableValue2TextBox(String condition, Text text) { if(StringUtils.equalsIgnoreCase(condition,FilterConstants.BETWEEN) || StringUtils.equalsIgnoreCase(condition,FilterConstants.BETWEEN_FIELD)){ text.setVisible(true); } else { text.setVisible(false); } } /** * Returns focus-listener object * @return */ public FocusListener getConditionalOperatorFocusListener() { FocusListener focusListener = new FocusListener() { @Override public void focusLost(FocusEvent e) { if (e.getSource() instanceof CCombo) { CCombo source = (CCombo) e.getSource(); for (String option : source.getItems()) { if (StringUtils.equalsIgnoreCase(source.getText(), option)) { source.setText(option); break; } } } } @Override public void focusGained(FocusEvent e) { /* do nothing. */ } }; return focusListener; } private void processConditionalOperator(CCombo source, List<Condition> conditionsList, Map<String, String> fieldsAndTypes, String[] fieldNames, Button saveButton, Button displayButton){ int index = (int) source.getData(FilterConstants.ROW_INDEX); Condition filterConditions = conditionsList.get(index); filterConditions.setConditionalOperator(source.getText()); validateCombo(source); toggleSaveDisplayButton(conditionsList, fieldsAndTypes, fieldNames, saveButton, displayButton); } /** * Gets the relational op selection listener. * * @param conditionsList * the conditions list * @param fieldsAndTypes * the fields and types * @param fieldNames * the field names * @param saveButton * the save button * @param displayButton * the display button * @return the relational op selection listener */ public SelectionListener getRelationalOpSelectionListener(final List<Condition> conditionsList, final Map<String, String> fieldsAndTypes, final String[] fieldNames, final Button saveButton, final Button displayButton) { SelectionListener listener = new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { CCombo source = (CCombo) e.getSource(); processRelationalOperator(source, conditionsList, fieldsAndTypes, fieldNames, saveButton, displayButton); } @Override public void widgetDefaultSelected(SelectionEvent e) {} }; return listener; } /** * Gets the relational op modify listener. * * @param conditionsList * the conditions list * @param fieldsAndTypes * the fields and types * @param fieldNames * the field names * @param saveButton * the save button * @param displayButton * the display button * @return the relational op modify listener */ public ModifyListener getRelationalOpModifyListener(final List<Condition> conditionsList, final Map<String, String> fieldsAndTypes, final String[] fieldNames, final Button saveButton, final Button displayButton) { ModifyListener listener = new ModifyListener() { @Override public void modifyText(ModifyEvent e) { CCombo source = (CCombo) e.getSource(); processRelationalOperator(source, conditionsList, fieldsAndTypes, fieldNames, saveButton, displayButton); } }; return listener; } private void processRelationalOperator(CCombo source, List<Condition> conditionsList, Map<String, String> fieldsAndTypes, String[] fieldNames, Button saveButton, Button displayButton){ int index = (int) source.getData(FilterConstants.ROW_INDEX); Condition filterConditions = conditionsList.get(index); filterConditions.setRelationalOperator(source.getText()); if(index != 0){ validateCombo(source); } toggleSaveDisplayButton(conditionsList, fieldsAndTypes, fieldNames, saveButton, displayButton); } /** * Adds the button listener. * * @param tableViewer * the table viewer * @param conditionsList * the conditions list * @param dummyList * the dummy list * @param groupSelectionMap * the group selection map * @return the selection listener */ public SelectionListener addButtonListener(final TableViewer tableViewer, final List<Condition> conditionsList, final List<Condition> dummyList, final TreeMap<Integer, List<List<Integer>>> groupSelectionMap) { SelectionListener listener = new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { Button button = (Button) e.getSource(); int index = (int) button.getData(FilterConstants.ROW_INDEX); conditionsList.add(index, new Condition()); dummyList.clear(); dummyList.addAll(cloneList(conditionsList)); FilterHelper.INSTANCE.refreshGroupSelections(tableViewer, index, "ADD", groupSelectionMap); tableViewer.refresh(); } @Override public void widgetDefaultSelected(SelectionEvent e) {} }; return listener; } /** * Gets the save button listener. * * @param conditionsList * the conditions list * @param fieldsAndTypes * the fields and types * @param groupSelectionMap * the group selection map * @param dataset * the dataset * @param originalFilterConditions * the original filter conditions * @param retainRemoteFilter * the retain remote filter * @param retainLocalFilter * the retain local filter * @return the save button listener */ public SelectionListener getSaveButtonListener(final List<Condition> conditionsList, final Map<String, String> fieldsAndTypes, final Map<Integer,List<List<Integer>>> groupSelectionMap, final String dataset,final FilterConditions originalFilterConditions, final RetainFilter retainRemoteFilter,final RetainFilter retainLocalFilter) { SelectionListener listener = new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { StringBuffer buffer = getCondition(conditionsList, fieldsAndTypes, groupSelectionMap,false); logger.debug("Query String : " + buffer); if(dataset.equalsIgnoreCase(Messages.DOWNLOADED)){ localCondition=buffer.toString(); showLocalFilteredData(StringUtils.trim(buffer.toString())); debugDataViewer.setLocalCondition(localCondition); } else{ if(!retainLocalFilter.getRetainFilter()){ if(!debugDataViewer.getLocalCondition().equals("")){ MessageBox messageBox = new MessageBox(new Shell(), SWT.ICON_WARNING | SWT.OK | SWT.CANCEL); messageBox.setText("Warning"); messageBox.setMessage(Messages.NOT_RETAINED); int response = messageBox.open(); if (response != SWT.OK) { return; } } } else{ if(!debugDataViewer.getLocalCondition().equals("")){ MessageBox messageBox = new MessageBox(new Shell(), SWT.ICON_WARNING | SWT.OK | SWT.CANCEL); messageBox.setText("Warning"); messageBox.setMessage(Messages.RETAINED); int response = messageBox.open(); if (response != SWT.OK) { return; } }else{ retainLocalFilter.setRetainFilter(false); } } if (!retainLocalFilter.getRetainFilter()) { originalFilterConditions.setLocalCondition(""); originalFilterConditions.getLocalConditions().clear(); filterConditionsDialog.getLocalConditionsList().clear(); debugDataViewer.setLocalCondition(""); localCondition = ""; } remoteCondition=buffer.toString(); showRemoteFilteredData(StringUtils.trim(buffer.toString())); debugDataViewer.setRemoteCondition(remoteCondition); } filterConditionsDialog.close(); } @Override public void widgetDefaultSelected(SelectionEvent e) {} }; return listener; } private void showRemoteFilteredData(String buffer) { debugDataViewer.downloadDebugFiles(true,true); debugDataViewer.setOverWritten(true); } private void showLocalFilteredData(String buffer) { try { dataViewerAdapter.setFilterCondition(buffer); dataViewerAdapter.resetOffset(); dataViewerAdapter.initializeTableData(); debugDataViewer.clearJumpToText(); debugDataViewer.submitRecordCountJob(); debugDataViewer.getDataViewLoader().updateDataViewLists(); debugDataViewer.getDataViewLoader().reloadloadViews(); enableAndDisableNextButtonOfDataViewer(); } catch (SQLException|IOException exception) { logger.error("Error occuring while showing local filtered data",exception); } } private void enableAndDisableNextButtonOfDataViewer() { int pageSize = debugDataViewer.getViewDataPreferences().getPageSize(); if (dataViewerAdapter.getRowCount() < pageSize) { debugDataViewer.getStatusManager().enableNextPageButton(false); } else { debugDataViewer.getStatusManager().enableNextPageButton(true); } } /** * Creates the json object for remote filter. * * @param buffer * the buffer * @return the string */ public String createJsonObjectForRemoteFilter(String buffer) { Gson gson=new Gson(); RemoteFilterJson remoteFilterJson = new RemoteFilterJson(buffer, DataViewerUtility.INSTANCE.getSchema(debugDataViewer.getDebugFileLocation() + debugDataViewer.getDebugFileName()+SCHEMA_FILE_EXTENTION), debugDataViewer.getViewDataPreferences().getFileSize(), debugDataViewer.getJobDetails()); String filterJson=gson.toJson(remoteFilterJson); return filterJson; } /** * Sets the data viewer adapter. * * @param dataViewerAdapter * the data viewer adapter * @param filterConditionsDialog * the filter conditions dialog */ public void setDataViewerAdapter(DataViewerAdapter dataViewerAdapter, FilterConditionsDialog filterConditionsDialog) { this.dataViewerAdapter=dataViewerAdapter; this.filterConditionsDialog=filterConditionsDialog; } /** * Sets the debug data viewer. * * @param debugDataViewer * the new debug data viewer */ public void setDebugDataViewer(DebugDataViewer debugDataViewer) { this.debugDataViewer=debugDataViewer; } /** * Gets the condition value. * * @param fieldName * the field name * @param value * the value * @param conditional * the conditional * @param fieldsAndTypes * the fields and types * @param isDisplayPressed * the is display pressed * @return the condition value */ protected String getConditionValue(String fieldName, String value, String conditional, Map<String, String> fieldsAndTypes, boolean isDisplayPressed) { String trimmedCondition = StringUtils.trim(conditional); String dataType = fieldsAndTypes.get(fieldName); if((FilterConstants.TYPE_STRING.equalsIgnoreCase(dataType) || FilterConstants.TYPE_DATE.equalsIgnoreCase(dataType) || FilterConstants.TYPE_BOOLEAN.equalsIgnoreCase(dataType)) && !conditional.endsWith("(Field)")){ if(FilterConstants.IN.equalsIgnoreCase(trimmedCondition) || FilterConstants.NOT_IN.equalsIgnoreCase(trimmedCondition)){ if(StringUtils.isNotBlank(value) && value.contains(FilterConstants.DELIM_COMMA)){ StringTokenizer tokenizer = new StringTokenizer(value, FilterConstants.DELIM_COMMA); StringBuffer temp = new StringBuffer(); int numberOfTokens = tokenizer.countTokens(); temp.append(FilterConstants.OPEN_BRACKET); for (int index = 0; index < numberOfTokens; index++) { if (FilterConstants.TYPE_DATE.equalsIgnoreCase(dataType) && !isDisplayPressed) { try { Fields dataViewerFileSchema = getSchema(); SimpleDateFormat formatter = getDateFormatter(fieldName, dataViewerFileSchema); Date parsedDate = getParsedDate(tokenizer.nextToken(), formatter); temp.append(FilterConstants.SINGLE_QOUTE).append(formatter.format(parsedDate)) .append(FilterConstants.SINGLE_QOUTE); } catch (ParseException parseException) { logger.error("Error while parsing date value", parseException); } } else { temp.append(FilterConstants.SINGLE_QOUTE).append(tokenizer.nextToken()) .append(FilterConstants.SINGLE_QOUTE); } if(index < numberOfTokens - 1){ temp.append(FilterConstants.DELIM_COMMA); } } temp.append(FilterConstants.CLOSE_BRACKET); return temp.toString(); } else{ return FilterConstants.OPEN_BRACKET + FilterConstants.SINGLE_QOUTE + value + FilterConstants.SINGLE_QOUTE + FilterConstants.CLOSE_BRACKET; } } else{ if (!isDisplayPressed) { if (FilterConstants.TYPE_DATE.equalsIgnoreCase(dataType)) { try { Fields dataViewerFileSchema = getSchema(); SimpleDateFormat formatter = getDateFormatter(fieldName, dataViewerFileSchema); Date parsedDate = getParsedDate(value, formatter); return FilterConstants.SINGLE_QOUTE + formatter.format(parsedDate) + FilterConstants.SINGLE_QOUTE; } catch (ParseException parseException) { logger.error("Error while parsing date value",parseException); } } else { return FilterConstants.SINGLE_QOUTE + value + FilterConstants.SINGLE_QOUTE; } return null; } else { return FilterConstants.SINGLE_QOUTE + value + FilterConstants.SINGLE_QOUTE; } } } else{ if(FilterConstants.IN.equalsIgnoreCase(trimmedCondition) || FilterConstants.NOT_IN.equalsIgnoreCase(trimmedCondition)){ return FilterConstants.OPEN_BRACKET + value + FilterConstants.CLOSE_BRACKET; } else{ return value; } } } private Date getParsedDate(String nextToken, SimpleDateFormat formatter) throws ParseException { Date parsedDate = formatter.parse(nextToken); formatter.applyPattern(AdapterConstants.DATE_FORMAT); return parsedDate; } private SimpleDateFormat getDateFormatter(String fieldName, Fields dataViewerFileSchema) { SimpleDateFormat formatter = null; for (Field field : dataViewerFileSchema.getField()) { if (field.getName().equalsIgnoreCase(fieldName)) { formatter = new SimpleDateFormat(field.getFormat()); } } return formatter; } private Fields getSchema() { String debugFileName = debugDataViewer.getDebugFileName(); String debugFileLocation = debugDataViewer.getDebugFileLocation(); Fields dataViewerFileSchema = ViewDataSchemaHelper.INSTANCE .getFieldsFromSchema(debugFileLocation + debugFileName + AdapterConstants.SCHEMA_FILE_EXTENTION); return dataViewerFileSchema; } private boolean validateCombo(CCombo combo){ if((Arrays.asList(combo.getItems())).contains(combo.getText())){ combo.setBackground(CustomColorRegistry.INSTANCE.getColorFromRegistry( 255, 255, 255)); return true; }else { combo.setBackground(CustomColorRegistry.INSTANCE.getColorFromRegistry( 255, 244, 113)); return false; } } private boolean validateText(Text text, String fieldName, Map<String, String> fieldsAndTypes, String conditionalOperator) { String type = FilterValidator.INSTANCE.getType(fieldName, fieldsAndTypes); if((StringUtils.isNotBlank(text.getText()) && FilterValidator.INSTANCE.validateDataBasedOnTypes(type, text.getText(), conditionalOperator,debugDataViewer,fieldName)) || FilterValidator.INSTANCE.validateField(fieldsAndTypes,text.getText(),fieldName)){ text.setBackground(CustomColorRegistry.INSTANCE.getColorFromRegistry( 255, 255, 255)); return true; }else { text.setBackground(CustomColorRegistry.INSTANCE.getColorFromRegistry( 255, 244, 113)); return false; } } /** * Clone list. * * @param conditionsList * the conditions list * @return the list */ public List<Condition> cloneList(List<Condition> conditionsList) { List<Condition> tempList = new ArrayList<>(); for (Condition condition : conditionsList) { Condition newCondition = new Condition(); tempList.add(newCondition.copy(condition)); } return tempList; } /** * Gets the remote display button listener. * * @param conditionsList * the conditions list * @param fieldsAndTypes * the fields and types * @param groupSelectionMap * the group selection map * @param styledTextRemote * the styled text remote * @return the remote display button listener */ public SelectionListener getRemoteDisplayButtonListener(final List<Condition> conditionsList, final Map<String, String> fieldsAndTypes, final Map<Integer,List<List<Integer>>> groupSelectionMap,final StyledText styledTextRemote) { SelectionListener listner = new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { styledTextRemote.setText(getCondition(conditionsList,fieldsAndTypes, groupSelectionMap,true).toString()); } @Override public void widgetDefaultSelected(SelectionEvent e) { } }; return listner; } /** * Gets the local display button listener. * * @param conditionsList * the conditions list * @param fieldsAndTypes * the fields and types * @param groupSelectionMap * the group selection map * @param styledTextLocal * the styled text local * @return the local display button listener */ public SelectionListener getLocalDisplayButtonListener(final List<Condition> conditionsList, final Map<String, String> fieldsAndTypes, final Map<Integer,List<List<Integer>>> groupSelectionMap,final StyledText styledTextLocal) { SelectionListener listner = new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { styledTextLocal.setText(getCondition(conditionsList,fieldsAndTypes, groupSelectionMap,true).toString()); } @Override public void widgetDefaultSelected(SelectionEvent e) { } }; return listner; } /** * Gets the condition. * * @param conditionsList * the conditions list * @param fieldsAndTypes * the fields and types * @param groupSelectionMap * the group selection map * @param isDisplayPressed * the is display pressed * @return the condition */ public StringBuffer getCondition(final List<Condition> conditionsList, final Map<String, String> fieldsAndTypes, final Map<Integer, List<List<Integer>>> groupSelectionMap,boolean isDisplayPressed) { //put number of elements in the list //1 2 3 4 5 List<String> actualStringList = new LinkedList<>(); for (int conditionIndex = 0; conditionIndex < conditionsList.size(); conditionIndex++) { actualStringList.add(conditionIndex, String.valueOf((conditionIndex))); } logger.trace(actualStringList.toString()); //start adding brackets for grouping Set<Integer> treeSet = (Set<Integer>) groupSelectionMap.keySet(); if(treeSet.size() > 0){ for (Integer position : treeSet) { List<List<Integer>> groupsInColumn = groupSelectionMap.get(position); for (int groupIndex = 0; groupIndex < groupsInColumn.size(); groupIndex++) { List<Integer> group = groupsInColumn.get(groupIndex); //add opening bracket before first element in the group if(!group.isEmpty()){ Integer firstItem = group.get(0); Integer firstItemIndex = actualStringList.indexOf(String.valueOf(firstItem)); actualStringList.add(firstItemIndex, FilterConstants.OPEN_BRACKET); //add closing bracket after last element in the group Integer lastItem = group.get(group.size()-1); Integer lastItemIndex = actualStringList.indexOf(String.valueOf(lastItem)); actualStringList.add(lastItemIndex + 1, FilterConstants.CLOSE_BRACKET); } } } } //start adding relational operators int indexOfRelational = 1; //start from 2nd index for (int item = 1; item < conditionsList.size(); item++) { int indexOfItem = actualStringList.indexOf(String.valueOf(item)); while(true){ if((actualStringList.get(indexOfItem-1)).matches(FilterConstants.REGEX_DIGIT) ||(actualStringList.get(indexOfItem-1)).equalsIgnoreCase(FilterConstants.CLOSE_BRACKET)){ actualStringList.add(indexOfItem, conditionsList.get(indexOfRelational).getRelationalOperator()); break; }else{ indexOfItem = indexOfItem - 1; } } indexOfRelational += 1; logger.trace(actualStringList.toString()); } StringBuffer buffer = new StringBuffer(); for(int item = 0; item < conditionsList.size(); item++){ StringBuffer conditionString = new StringBuffer(); Condition condition = conditionsList.get(item); if(StringUtils.equalsIgnoreCase(condition.getConditionalOperator(), FilterConstants.BETWEEN) || StringUtils.equalsIgnoreCase(condition.getConditionalOperator(),FilterConstants.BETWEEN_FIELD)){ conditionString .append(condition.getFieldName()) .append(FilterConstants.SINGLE_SPACE) .append(condition.getConditionalOperator()) .append(FilterConstants.SINGLE_SPACE) .append(getConditionValue(condition.getFieldName(), condition.getValue1(), condition.getConditionalOperator(), fieldsAndTypes,isDisplayPressed)) .append(FilterConstants.SINGLE_SPACE) .append(FilterConstants.AND) .append(FilterConstants.SINGLE_SPACE) .append(getConditionValue(condition.getFieldName(), condition.getValue2(), condition.getConditionalOperator(), fieldsAndTypes,isDisplayPressed)); } else { conditionString .append(condition.getFieldName()) .append(FilterConstants.SINGLE_SPACE) .append(condition.getConditionalOperator()) .append(FilterConstants.SINGLE_SPACE) .append(getConditionValue(condition.getFieldName(), condition.getValue1(), condition.getConditionalOperator(), fieldsAndTypes,isDisplayPressed)); } int index = actualStringList.indexOf(String.valueOf(item)); actualStringList.set(index, conditionString.toString()); } for (String item : actualStringList) { buffer.append(item + FilterConstants.SINGLE_SPACE); } Pattern p = Pattern.compile("\\(Field\\)"); Matcher m = p.matcher(buffer); StringBuffer temp = new StringBuffer(); while(m.find()){ m.appendReplacement(temp, ""); } m.appendTail(temp); buffer = new StringBuffer(temp); return buffer; } /** * Gets the retain button listener. * * @param retainFilter * the retain filter * @return the retain button listener */ public SelectionListener getRetainButtonListener(final RetainFilter retainFilter) { SelectionListener listner = new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { Button button = (Button)e.getSource(); retainFilter.setRetainFilter(button.getSelection()); } @Override public void widgetDefaultSelected(SelectionEvent e) { } }; return listner; } /** * Gets the adds-at-the-end listener. * * @param tableViewer * the table viewer * @param conditionList * the condition list * @param dummyList * the dummy list * @return the adds the at end listener */ public SelectionAdapter getAddAtEndListener(final TableViewer tableViewer, final List<Condition> conditionList, final List<Condition> dummyList) { return new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { conditionList.add(conditionList.size(), new Condition()); dummyList.clear(); dummyList.addAll(cloneList(conditionList)); tableViewer.refresh(); } }; } /** * Check button listener. * * @param tableViewer * the table viewer * @param conditionsList * the conditions list * @param btnAddGrp * the btn add grp * @return the selection listener */ public SelectionListener checkButtonListener(final TableViewer tableViewer, final List<Condition> conditionsList, final Button btnAddGrp) { SelectionListener listener = new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { int count=0; boolean isEnabled=false; List<Integer> selectionPattern= new ArrayList<>(); TableItem[] items = tableViewer.getTable().getItems(); for (TableItem tableItem : items) { Button button = (Button) tableItem.getData(FilterConditionsDialog.GROUP_CHECKBOX); if(button.getSelection()){ count++; selectionPattern.add(tableViewer.getTable().indexOf(tableItem)); } } if(count>=2){ if(validateCheckSequence(selectionPattern)){ isEnabled=true; } } btnAddGrp.setEnabled(isEnabled); } @Override public void widgetDefaultSelected(SelectionEvent e) { } }; return listener; } private boolean validateCheckSequence(List<Integer> selectionPattern){ boolean retval=true; for(int i=0;i<selectionPattern.size()-1;i++){ if((selectionPattern.get(i+1)-selectionPattern.get(i))>1){ retval=false; break; } } return retval; } /** * Validate user group selection. * * @param groupSelectionMap * the group selection map * @param selectionList * the selection list * @return true, if successful */ public boolean validateUserGroupSelection(Map<Integer,List<List<Integer>>> groupSelectionMap,List<Integer> selectionList){ boolean retValue=true; for (int key : groupSelectionMap.keySet()) { List<List<Integer>> groups = groupSelectionMap.get(key); for (List<Integer> grp : groups) { if (selectionList.size() == grp.size()) { if (!ListUtils.isEqualList(selectionList, grp) && ListUtils.intersection(selectionList, grp).size()==0) { retValue = true; }else if(ListUtils.isEqualList(selectionList, grp)){ if (createErrorDialog(Messages.GROUP_CLAUSE_ALREADY_EXISTS).open() == SWT.OK) { retValue=false; break; } }else if(ListUtils.intersection(selectionList, grp).size() > 0){ if (createErrorDialog(Messages.CANNOT_CREATE_GROUP_CLAUSE).open() == SWT.OK) { retValue=false; break; } } }else { if (ListUtils.isEqualList(ListUtils.intersection(selectionList, grp), grp)) { retValue = true; } else if(ListUtils.isEqualList(ListUtils.intersection(grp,selectionList),selectionList)){ retValue=true; }else if (ListUtils.intersection(selectionList, grp).size() == 0) { retValue = true; }else{ if (createErrorDialog(Messages.CANNOT_CREATE_GROUP_CLAUSE).open() == SWT.OK) { retValue=false; break; } } } } if(!retValue){ break; } } return retValue; } /** * Checks if column is modifiable. * * @param groupSelectionMap * the group selection map * @param selectionList * the selection list * @return true, if is column modifiable */ public boolean isColumnModifiable(TreeMap<Integer,List<List<Integer>>> groupSelectionMap,List<Integer> selectionList){ boolean retValue = false; for(int i=groupSelectionMap.lastKey();i>=0;i--){ retValue=true; List<List<Integer>> groups = new ArrayList<>(groupSelectionMap.get(i)); for (List<Integer> grp : groups) { if (ListUtils.intersection(selectionList, grp).size()>0) { retValue=false; } } if(retValue){ groupSelectionMap.get(i).add(selectionList); break; } } return retValue; } /** * Creates the error dialog. * * @param errorMessage * the error message * @return the message box */ public MessageBox createErrorDialog(String errorMessage) { MessageBox messageBox = new MessageBox(new Shell(), SWT.ERROR | SWT.OK); messageBox.setMessage(errorMessage); messageBox.setText("Error"); return messageBox; } /** * Gets the color. * * @param colorIndex * the color index * @return the color */ public Color getColor(int colorIndex){ Map<Integer,Color> colorMap = new HashMap<>(); colorMap.put(0, CustomColorRegistry.INSTANCE.getColorFromRegistry(255,196,196)); // Light yellow colorMap.put(1, CustomColorRegistry.INSTANCE.getColorFromRegistry(176,255,176)); //Light green colorMap.put(2, CustomColorRegistry.INSTANCE.getColorFromRegistry(149,255,255)); //Light blue colorMap.put(3, CustomColorRegistry.INSTANCE.getColorFromRegistry(254,194,224)); //Light Pink colorMap.put(4, CustomColorRegistry.INSTANCE.getColorFromRegistry(147,194,147)); colorMap.put(5, CustomColorRegistry.INSTANCE.getColorFromRegistry(255,81,168)); return colorMap.get(colorIndex); } /** * Refresh group selections. * * @param tableViewer * the table viewer * @param indexOfRow * the index of row * @param addOrDeleteRow * the add or delete row * @param groupSelectionMap * the group selection map * @return true, if successful */ public boolean refreshGroupSelections(TableViewer tableViewer, int indexOfRow,String addOrDeleteRow, TreeMap<Integer,List<List<Integer>>> groupSelectionMap){ boolean isRemoveColumn = false; for(int key:groupSelectionMap.keySet()){ List<List<Integer>> groups = groupSelectionMap.get(key); boolean isNewIndexAddedorRemoved=false; for (List<Integer> grp : groups) { List<Integer> tempGrp= new ArrayList<>(grp); if("ADD".equalsIgnoreCase(addOrDeleteRow)){ for (int i = 0; i < grp.size(); i++) { if(grp.get(i)>=indexOfRow){ grp.set(i, grp.get(i) + 1); } } if(tempGrp.contains(indexOfRow)){ if(!isNewIndexAddedorRemoved && tempGrp.get(0)!=indexOfRow){//other than starting index then add row. grp.add(tempGrp.indexOf(indexOfRow),indexOfRow); isNewIndexAddedorRemoved=true; } } }else if("DEL".equalsIgnoreCase(addOrDeleteRow)){ if(tempGrp.contains(indexOfRow)){ if(!isNewIndexAddedorRemoved){//other than starting index then add row. grp.remove(grp.indexOf(indexOfRow)); if(grp.size()==1){ grp.clear(); } if(rearrangeGroupsAfterDeleteRow(groupSelectionMap, grp)&& groupSelectionMap.lastKey()!=key){ grp.clear(); } List tempList=new ArrayList<>(); for (List lst : groupSelectionMap.get(key)) { tempList.addAll(lst); } if(tempList.isEmpty()){ isRemoveColumn=true; } } isNewIndexAddedorRemoved=true; } for (int i = 0; i < grp.size(); i++) { if(grp.get(i)>=indexOfRow){ grp.set(i, grp.get(i) -1); } } } tempGrp.clear(); } } return isRemoveColumn; } /** * Rearrange groups. * * @param groupSelectionMap * the group selection map * @param selectionList * the selection list */ public void rearrangeGroups(TreeMap<Integer, List<List<Integer>>> groupSelectionMap,List<Integer> selectionList) { List<Integer> tempList = new ArrayList<>(); int lastKey=groupSelectionMap.lastKey(); for (int i = lastKey; i >= 0; i--) { List<List<Integer>> groups =groupSelectionMap.get(i); for (int j=0; j<=groups.size()-1;j++) { if (selectionList.size()< groups.get(j).size()&& ListUtils.intersection(selectionList, groups.get(j)).size() > 0) { tempList.addAll(groups.get(j)); groups.get(j).clear(); groups.set(j,new ArrayList<Integer>(selectionList)); selectionList.clear(); selectionList.addAll(tempList); } tempList.clear(); } } } /** * Rearrange groups after delete row. * * @param groupSelectionMap * the group selection map * @param selectionList * the selection list * @return true, if successful */ public boolean rearrangeGroupsAfterDeleteRow(TreeMap<Integer, List<List<Integer>>> groupSelectionMap, List<Integer> selectionList) { boolean retValue = false; int lastKey = groupSelectionMap.lastKey(); int count = 0; for (int i = lastKey; i >= 0; i--) { List<List<Integer>> groups = groupSelectionMap.get(i); for (int j = 0; j <= groups.size() - 1; j++) { if (selectionList.size() == groups.get(j).size() && ListUtils.isEqualList(selectionList, groups.get(j))) { count++; if (count >= 2) { retValue = true; } } } } return retValue; } /** * Dispose all columns. * * @param tableViewer * the table viewer */ public void disposeAllColumns(TableViewer tableViewer){ TableColumn[] columns = tableViewer.getTable().getColumns(); TableItem[] items = tableViewer.getTable().getItems(); for (int i = 0; i < items.length; i++) { items[i].dispose(); } for (TableColumn tc : columns) { tc.dispose(); } } /** * Rearrange group columns. * * @param groupSelectionMap * the group selection map */ public void rearrangeGroupColumns(TreeMap<Integer, List<List<Integer>>> groupSelectionMap){ Map<Integer, List<List<Integer>>> tempMap = new TreeMap<Integer, List<List<Integer>>>(groupSelectionMap); for(int key:tempMap.keySet()){ List<List<Integer>> groups = tempMap.get(key); List<Integer> tempList=new ArrayList<>(); for (List<Integer> grp : groups) { tempList.addAll(grp); } if(tempList.isEmpty()){ for(int i=key ;i<tempMap.size()-1;i++){ groupSelectionMap.put(i, tempMap.get(i+1)); } groupSelectionMap.remove(groupSelectionMap.lastKey()); } } } }