/* * JBoss, Home of Professional Open Source. * * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. * * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. */ package org.teiid.designer.runtime.ui.views; import static org.teiid.designer.runtime.ui.DqpUiConstants.UTIL; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Properties; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.viewers.ICellEditorValidator; import org.eclipse.ui.views.properties.IPropertyDescriptor; import org.eclipse.ui.views.properties.IPropertySheetEntry; import org.eclipse.ui.views.properties.IPropertySource; import org.eclipse.ui.views.properties.PropertyDescriptor; import org.eclipse.ui.views.properties.TextPropertyDescriptor; import org.teiid.core.designer.util.CoreArgCheck; import org.teiid.designer.runtime.JDBCConnectionPropertyNames; import org.teiid.designer.runtime.spi.ITeiidTranslator; import org.teiid.designer.runtime.spi.TeiidPropertyDefinition; import org.teiid.designer.runtime.spi.ITeiidTranslator.TranslatorPropertyType; import org.teiid.designer.ui.common.util.WidgetFactory; /** * @since 8.0 */ public class ConnectionPropertySource implements IPropertySource { private ITeiidTranslator translator; private final Properties initialValues; private boolean isEditable = false; private RuntimePropertySourceProvider provider; /** * @param connector the connector whose properties are being edited (never <code>null</code>) */ public ConnectionPropertySource( ITeiidTranslator translator ) { this(translator.getProperties()); this.translator = translator; } /** * @param type the connector type of the connector (never <code>null</code>) * @param properties the properties of the connector (never <code>null</code>) */ private ConnectionPropertySource( Properties properties ) { CoreArgCheck.isNotNull(properties, "properties"); //$NON-NLS-1$ this.initialValues = new Properties(properties); } /** * @see org.eclipse.ui.views.properties.IPropertySource#getEditableValue() * @since 4.2 */ @Override public Object getEditableValue() { return this.translator; } /** * @see org.eclipse.ui.views.properties.IPropertySource#getPropertyDescriptors() * @since 4.2 */ @Override public IPropertyDescriptor[] getPropertyDescriptors() { IPropertyDescriptor[] result = new IPropertyDescriptor[0]; Collection<TeiidPropertyDefinition> typeDefs = this.translator.getPropertyDefinitions(); boolean showExpertProps = this.provider.isShowingExpertProperties(); Collection<PropertyDescriptor> temp = new ArrayList<PropertyDescriptor>(typeDefs.size()); for (final TeiidPropertyDefinition propDefn : typeDefs) { final String id = propDefn.getName(); String displayName = propDefn.getDisplayName(); // // // don't add if an expert or readonly property and expert properties are not being shown // if ((propDefn.isAdvanced() || !propDefn.isModifiable()) && !showExpertProps) { // continue; // } PropertyDescriptor descriptor = null; // make sure readonly definitions are not modifiable if (this.isEditable && propDefn.isModifiable()) { if (propDefn.isMasked()) { descriptor = new MaskedTextPropertyDescriptor(id, displayName); } else { descriptor = new TextPropertyDescriptor(id, displayName); } // set validator final ITeiidTranslator validator = this.translator; descriptor.setValidator(new ICellEditorValidator() { @Override public String isValid( Object value ) { String newValue = (String)value; // OK not to have a value if not required if (((newValue == null) || (newValue.length() == 0)) && !propDefn.isRequired()) { return null; } return (validator.isValidPropertyValue(id, newValue, TranslatorPropertyType.OVERRIDE)); } }); } else { // read only if (propDefn.isMasked()) { descriptor = new MaskedTextPropertyDescriptor(id, displayName); ((MaskedTextPropertyDescriptor)descriptor).setEditable(false); } else { descriptor = new PropertyDescriptor(id, displayName); } } // identify as expert property if (!showExpertProps && propDefn.isAdvanced()) { descriptor.setFilterFlags(new String[] {IPropertySheetEntry.FILTER_ID_EXPERT}); } temp.add(descriptor); } if (!temp.isEmpty()) { temp.toArray(result = new IPropertyDescriptor[temp.size()]); } result = sortPropertyDescriptors(result); return result; } /** * @see org.eclipse.ui.views.properties.IPropertySource#getPropertyValue(java.lang.Object) * @since 4.2 */ @Override public Object getPropertyValue( Object id ) { String propName = (String)id; String result = this.translator.getPropertyValue(propName, TranslatorPropertyType.OVERRIDE); // property not found or value is null if (result == null) return null; // return empty string if (result.length() == 0) return result; TeiidPropertyDefinition propDefn = this.translator.getPropertyDefinition(propName, TranslatorPropertyType.OVERRIDE); // if masked property don't return actual result if (propDefn.isMasked()) { StringBuilder sb = new StringBuilder(10); for (int i = 0; i < 10; ++i) { sb.append(WidgetFactory.PASSWORD_ECHO_CHAR); } return sb.toString(); } return result; } /** * @see org.eclipse.ui.views.properties.IPropertySource#isPropertySet(java.lang.Object) * @since 4.2 */ @Override public boolean isPropertySet( Object id ) { return false; } /** * @see org.eclipse.ui.views.properties.IPropertySource#resetPropertyValue(java.lang.Object) * @since 4.2 */ @Override public void resetPropertyValue( Object id ) { TeiidPropertyDefinition propDefn = ((TeiidPropertyDefinition)id); setPropertyValue(id, this.initialValues.getProperty(propDefn.getName())); } public void setEditable( boolean isEditable ) { this.isEditable = isEditable; } /** * @see org.eclipse.ui.views.properties.IPropertySource#setPropertyValue(java.lang.Object, java.lang.Object) * @since 4.2 */ @Override public void setPropertyValue( Object id, Object value ) { String propName = (String)id; try { String oldValue = this.translator.getPropertyValue(propName, TranslatorPropertyType.OVERRIDE); String newValue = value.toString(); this.translator.setPropertyValue(propName, newValue, TranslatorPropertyType.OVERRIDE); this.provider.propertyChanged(new PropertyChangeEvent(translator, propName, oldValue, newValue)); } catch (Exception e) { UTIL.log(e); } } public void setProvider( RuntimePropertySourceProvider provider ) { this.provider = provider; } /** * Sorts the properties using a custom sorter that puts the URL, user, and password always before other properties. * * @param theDescriptors the descriptors being sorted * @return the sorted descriptors * @since 5.5 */ private IPropertyDescriptor[] sortPropertyDescriptors( IPropertyDescriptor[] theDescriptors ) { List descriptors = Arrays.asList(theDescriptors); Collections.sort(descriptors, new DescriptorSorter()); return (IPropertyDescriptor[])descriptors.toArray(new IPropertyDescriptor[descriptors.size()]); } /** * Sorts property descriptors using there display names but making sure the URL, user, and password (in that order) are always * the first 3 properties. * * @since 5.5 */ class DescriptorSorter implements Comparator { @Override public int compare( Object theDescriptor, Object theOtherDescriptor ) { int result = 0; Object tempId = ((IPropertyDescriptor)theDescriptor).getId(); Object otherTempId = ((IPropertyDescriptor)theOtherDescriptor).getId(); if ((tempId instanceof String) && (otherTempId instanceof String)) { String id = (String)tempId; String otherId = (String)otherTempId; // ensure URL comes first, user next, password next, and then sort by display name. if (id.equals(JDBCConnectionPropertyNames.CONNECTOR_JDBC_URL)) { result = -100; } else if (id.equals(JDBCConnectionPropertyNames.CONNECTOR_JDBC_USER)) { result = (otherId.equals(JDBCConnectionPropertyNames.CONNECTOR_JDBC_URL) ? 1 : -50); } else if (id.equals(JDBCConnectionPropertyNames.CONNECTOR_JDBC_PASSWORD)) { result = (otherId.equals(JDBCConnectionPropertyNames.CONNECTOR_JDBC_URL) || otherId.equals(JDBCConnectionPropertyNames.CONNECTOR_JDBC_USER) ? 1 : -25); } else if (otherId.equals(JDBCConnectionPropertyNames.CONNECTOR_JDBC_URL) || otherId.equals(JDBCConnectionPropertyNames.CONNECTOR_JDBC_USER) || otherId.equals(JDBCConnectionPropertyNames.CONNECTOR_JDBC_PASSWORD)) { result = 1; } else { result = ((IPropertyDescriptor)theDescriptor).getDisplayName().compareTo(((IPropertyDescriptor)theOtherDescriptor).getDisplayName()); } } else if (tempId instanceof Comparable) { result = ((Comparable)tempId).compareTo(otherTempId); } else { result = ((IPropertyDescriptor)theDescriptor).getDisplayName().compareTo(((IPropertyDescriptor)theOtherDescriptor).getDisplayName()); } return result; } } }