/* * JBoss, Home of Professional Open Source * Copyright 2005, JBoss Inc., and individual contributors as indicated * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.hibernate.eclipse.console.views; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Observer; import java.util.Set; import java.util.StringTokenizer; import org.eclipse.jface.action.Action; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.CheckboxCellEditor; import org.eclipse.jface.viewers.ComboBoxCellEditor; import org.eclipse.jface.viewers.ICellModifier; import org.eclipse.jface.viewers.ILabelProviderListener; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TextCellEditor; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; import org.eclipse.ui.part.IPageSite; import org.eclipse.ui.part.Page; import org.hibernate.console.ConsoleQueryParameter; import org.hibernate.console.ImageConstants; import org.hibernate.console.QueryInputModel; import org.hibernate.eclipse.console.HibernateConsoleMessages; import org.hibernate.eclipse.console.QueryEditor; import org.hibernate.eclipse.console.utils.EclipseImages; import org.hibernate.util.xpl.StringHelper; import org.jboss.tools.hibernate.runtime.spi.IType; public class QueryParametersPage extends Page implements IQueryParametersPage { private static final String NAME_PROPERTY = "name"; //$NON-NLS-1$ private static final String TYPE_PROPERTY = "type"; //$NON-NLS-1$ private static final String VALUE_PROPERTY = "value"; //$NON-NLS-1$ private static final String NULL_PROPERTY = "null_prop"; //$NON-NLS-1$ private static final String HQL_SEPARATORS = " \n\r\f\t,()=<>&|+-=/*'^![]#~\\"; //$NON-NLS-1$ private static final String HQL_VARIABLE_PREFIX = ":"; //$NON-NLS-1$ private Composite top = null; private Table queryParametersTable = null; private TableViewer tableViewer; private Label statusLabel; final QueryInputModel model; private ToggleActive toggleActive; private Observer observer = new Observer() { public void update(java.util.Observable o, Object arg) { if(!tableViewer.getTable().isDisposed()) { tableViewer.refresh(); tableViewer.getTable().setEnabled(!model.ignoreParameters()); } } }; private final QueryEditor editor; public QueryParametersPage(QueryEditor editor) { this.editor = editor; model = editor.getQueryInputModel(); } public Control getControl() { return top; } public void createControl(Composite parent) { top = new Composite( parent, SWT.NONE ); top.setLayout( new GridLayout() ); createQueryParametersTable(); createStatusLabel(); model.addObserver(observer); toggleActive.setChecked(model.ignoreParameters()); tableViewer.getTable().setEnabled(!model.ignoreParameters()); tableViewer.setInput(model); } private void createStatusLabel() { GridData gridData = new org.eclipse.swt.layout.GridData(); gridData.horizontalAlignment = org.eclipse.swt.layout.GridData.FILL; gridData.verticalAlignment = org.eclipse.swt.layout.GridData.FILL; statusLabel = new Label( top, SWT.NULL ); //statusLabel.setText("max"); statusLabel.setLayoutData(gridData); } public void setFocus() { queryParametersTable.setFocus(); } /** * This method initializes queryParametersTable * */ private void createQueryParametersTable() { GridData gridData = new org.eclipse.swt.layout.GridData(); gridData.horizontalAlignment = org.eclipse.swt.layout.GridData.FILL; gridData.grabExcessVerticalSpace = true; gridData.grabExcessHorizontalSpace = true; gridData.verticalAlignment = org.eclipse.swt.layout.GridData.FILL; queryParametersTable = new Table( top, SWT.FULL_SELECTION ); queryParametersTable.setHeaderVisible( true ); queryParametersTable.setLayoutData( gridData ); queryParametersTable.setLinesVisible( true ); TableColumn nameColumn = new TableColumn( queryParametersTable, SWT.NONE ); nameColumn.setWidth(100); nameColumn.setText( HibernateConsoleMessages.QueryParametersPage_name ); TableColumn typeColumn = new TableColumn( queryParametersTable, SWT.NONE ); typeColumn.setWidth(75); typeColumn.setText( HibernateConsoleMessages.QueryParametersPage_type ); TableColumn valueColumn = new TableColumn( queryParametersTable, SWT.NONE ); valueColumn.setWidth( 100 ); valueColumn.setText( HibernateConsoleMessages.QueryParametersPage_value ); TableColumn nullColumn = new TableColumn( queryParametersTable, SWT.NONE ); nullColumn.setWidth( 32 ); nullColumn.setText( HibernateConsoleMessages.QueryParametersPage_null ); tableViewer = new TableViewer( queryParametersTable ); tableViewer.addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { if(statusLabel!=null) { Object firstElement = ((IStructuredSelection)tableViewer.getSelection()).getFirstElement(); if(firstElement instanceof ConsoleQueryParameter) { statusLabel.setText(HibernateConsoleMessages.QueryParametersPage_format + ((ConsoleQueryParameter)firstElement).getDefaultFormat()); } else { statusLabel.setText(""); //$NON-NLS-1$ } } } }); final List<IType> possibleTypes = new ArrayList<IType>(model.getService().newTypeFactory().getTypeFormats().keySet()); Collections.sort(possibleTypes, new Comparator<IType>() { public int compare(IType t1, IType t2) { return t1.getName().compareTo(t2.getName()); } }); tableViewer.setCellModifier( new ICellModifier() { public void modify(Object element, String property, Object value) { TableItem item = (TableItem) element; ConsoleQueryParameter cqp = (ConsoleQueryParameter) item .getData(); if ( NAME_PROPERTY.equals( property ) ) { cqp.setName( (String) value ); } if ( TYPE_PROPERTY.equals( property ) ) { Iterator<IType> iterator = possibleTypes.iterator(); int i = 0; while(iterator.hasNext()) { IType type = iterator.next(); if(i==((Integer)value).intValue()) { if(!cqp.getTypeName().equals(type.getName())) { cqp.setType(type); cqp.setNull(); // have to reset to ensure it's working } break; } i++; } } if ( VALUE_PROPERTY.equals( property ) ) { String[] inputStrings; if (value instanceof String[]){ inputStrings = (String[])value; } else { inputStrings = new String[]{(String) value}; } Object[] values = new Object[inputStrings.length]; for (int i = 0; i < inputStrings.length; i++) { values[i] = cqp.convertStringToValue(inputStrings[i]); } if (values.length > 1){ cqp.setValue(values); } else if (values.length == 1){ cqp.setValue(values[0]); } else { cqp.setValue(null); } } if ( NULL_PROPERTY.equals( property ) ) { if(cqp.isNull()) { cqp.setValue(cqp.convertStringToValue( "" )); // best attempt to "unnull" //$NON-NLS-1$ } else { cqp.setNull(); } } tableViewer.refresh(cqp); } public Object getValue(Object element, String property) { ConsoleQueryParameter cqp = (ConsoleQueryParameter) element; if ( NAME_PROPERTY.equals( property ) ) { return cqp.getName(); } if ( TYPE_PROPERTY.equals( property ) ) { Iterator<IType> iterator = possibleTypes.iterator(); String type = cqp.getTypeName(); int i = 0; while(iterator.hasNext()) { if (type.equals(iterator.next().getName())) { return Integer.valueOf(i); } i++; } } if ( VALUE_PROPERTY.equals( property ) ) { return cqp.getStringValues(); } if ( NULL_PROPERTY.equals( property )) { return Boolean.valueOf(cqp.isNull()); } return null; } public boolean canModify(Object element, String property) { return true; } } ); tableViewer.setContentProvider( new IStructuredContentProvider() { public Object[] getElements(Object inputElement) { return ((QueryInputModel) inputElement).getQueryParameters(); } public void dispose() { } public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { } } ); String[] columnProperties = new String[] { NAME_PROPERTY, TYPE_PROPERTY, VALUE_PROPERTY, NULL_PROPERTY }; tableViewer.setColumnProperties( columnProperties ); String[] valueTypes = new String[possibleTypes.size()]; Iterator<IType> iterator = possibleTypes.iterator(); int i=0; while ( iterator.hasNext() ) { IType element = iterator.next(); valueTypes[i++] = element.getName(); } CellEditor[] editors = new CellEditor[columnProperties.length]; editors[0] = new TextCellEditor( queryParametersTable ); editors[1] = new ComboBoxCellEditor( queryParametersTable, valueTypes, SWT.READ_ONLY ); editors[2] = new StringArrayDialogCellEditor(queryParametersTable) { private Button b; public void activate() { Object param = ((IStructuredSelection) tableViewer.getSelection()).getFirstElement(); if (param instanceof ConsoleQueryParameter) { try { Integer.parseInt(((ConsoleQueryParameter) param).getName()); // "ordered" parameter doesn't allow list value // see also HQLQueryPage#setupParameters() b.setVisible(false); } catch (NumberFormatException nfe) { // "named" parameter allows parameter list value b.setVisible(true); } } }; protected org.eclipse.swt.widgets.Button createButton(Composite parent) { return b = super.createButton(parent); }; }; editors[3] = new CheckboxCellEditor( queryParametersTable ); tableViewer.setCellEditors( editors ); tableViewer.setLabelProvider( new ITableLabelProvider() { public void removeListener(ILabelProviderListener listener) { } public boolean isLabelProperty(Object element, String property) { return true; } public void dispose() { } public void addListener(ILabelProviderListener listener) { } public String getColumnText(Object element, int columnIndex) { ConsoleQueryParameter cqp = (ConsoleQueryParameter) element; switch (columnIndex) { case 0: return cqp.getName(); case 1: return cqp.getTypeName(); case 2: { String label = cqp.getStringValues()[0]; for (int j = 1; j < cqp.getStringValues().length; j++) { label += "|" + cqp.getStringValues()[j]; //$NON-NLS-1$ } return label; } case 3: return null; //cqp.isNull()?"X":""; default: return null; } } public Image getColumnImage(Object element, int columnIndex) { if(columnIndex==3) { ConsoleQueryParameter cqp = (ConsoleQueryParameter) element; return cqp.isNull()?EclipseImages.getImage( ImageConstants.CHECKBOX_FULL ):EclipseImages.getImage( ImageConstants.CHECKBOX_EMPTY ); } else { return null; } } } ); } public void init(IPageSite site) { super.init( site ); NewRowAction newRowAction = new NewRowAction(); site.getActionBars().getToolBarManager().add(newRowAction); site.getActionBars().getToolBarManager().add(new RemoveRowAction()); toggleActive = new ToggleActive(); site.getActionBars().getToolBarManager().add(toggleActive); } private class NewRowAction extends Action { public NewRowAction() { super( "" ); //$NON-NLS-1$ setToolTipText(HibernateConsoleMessages.QueryParametersPage_add_query_parameter_tooltip); setImageDescriptor(EclipseImages.getImageDescriptor(ImageConstants.NEW_PARAMETER)); } public void run() { ConsoleQueryParameter[] queryParameters = model.getQueryParameters(); Map<String, ConsoleQueryParameter> qp = new HashMap<String, ConsoleQueryParameter>(); for (int i = 0; i < queryParameters.length; i++) { ConsoleQueryParameter parameter = queryParameters[i]; qp.put(parameter.getName(), parameter); } model.clear(); String queryString = editor.getQueryString(); ConsoleQueryParameter cqp = null; int[] positions = StringHelper.locateUnquoted( queryString, '?' ); for (int i = 0; i < positions.length; i++) { cqp = qp.get(""+i); //$NON-NLS-1$ if(cqp==null) { cqp = model.createUniqueParameter(""+i); //$NON-NLS-1$ } model.addParameter( cqp ); } StringTokenizer st = new StringTokenizer(queryString, HQL_SEPARATORS); Set<String> result = new HashSet<String>(); while ( st.hasMoreTokens() ) { String string = st.nextToken(); if( string.startsWith(HQL_VARIABLE_PREFIX) ) { result.add( string.substring(1) ); } } Iterator<String> iterator = result.iterator(); while ( iterator.hasNext() ) { String paramName = iterator.next(); cqp = qp.get(paramName); if(cqp==null) { cqp = model.createUniqueParameter(paramName); } model.addParameter(cqp); } /* if(cqp==null) { cqp = model.createUniqueParameter("param"); model.addParameter( cqp ); }*/ } } private class RemoveRowAction extends Action { public RemoveRowAction() { super( "" ); //$NON-NLS-1$ setToolTipText(HibernateConsoleMessages.QueryParametersPage_remove_query_parameter_tooltip); setImageDescriptor(getSite().getWorkbenchWindow().getWorkbench().getSharedImages().getImageDescriptor(org.eclipse.ui.ISharedImages.IMG_TOOL_DELETE)); } public void run() { Object firstElement = ((IStructuredSelection)tableViewer.getSelection()).getFirstElement(); if(firstElement!=null) { tableViewer.cancelEditing(); model.removeParameter((ConsoleQueryParameter) firstElement); if(model.getParameterCount()>0) { tableViewer.setSelection(new StructuredSelection(model.getQueryParameters()[0])); } } } } private class ToggleActive extends Action { public ToggleActive() { super(""); //$NON-NLS-1$ setToolTipText(HibernateConsoleMessages.QueryParametersPage_enable_disable_parameters_tooltip); setChecked(false); setImageDescriptor(EclipseImages.getImageDescriptor(ImageConstants.IGNORE_PARAMETER)); } public void run() { model.setIgnoreParameters(isChecked()); setChecked(model.ignoreParameters()); } } public void dispose() { super.dispose(); } }