/* * 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.query.ui.builder.model; import java.lang.reflect.Constructor; import java.sql.Date; import java.sql.Time; import java.sql.Timestamp; import java.util.Calendar; import org.eclipse.core.runtime.IStatus; import org.teiid.core.designer.util.CoreArgCheck; import org.teiid.core.designer.util.I18nUtil; import org.teiid.designer.core.ModelerCore; import org.teiid.designer.query.IQueryFactory; import org.teiid.designer.query.IQueryService; import org.teiid.designer.query.sql.lang.ILanguageObject; import org.teiid.designer.query.sql.symbol.IConstant; import org.teiid.designer.type.IDataTypeManagerService; import org.teiid.designer.type.IDataTypeManagerService.DataTypeName; import org.teiid.query.ui.builder.util.BuilderUtils; /** * The <code>ConstantEditorModel</code> class is used as a model for the * org.teiid.designer.transformation.ui.builder.expression.ConstantEditor. * * @since 8.0 */ public class ConstantEditorModel extends AbstractLanguageObjectEditorModel implements BuilderUtils.LoggingConstants { /** Properties key prefix. */ private static final String PREFIX = I18nUtil.getPropertyPrefix(ConstantEditorModel.class); /** The default type for constants. */ private final String DEFAULT_TYPE; // event types public static final String TYPE = "TYPE"; //$NON-NLS-1$ public static final String BOOLEAN = "BOOLEAN"; //$NON-NLS-1$ public static final String DATE = "DATE"; //$NON-NLS-1$ public static final String NULL = "NULL"; //$NON-NLS-1$ public static final String TEXT = "TEXT"; //$NON-NLS-1$ public static final String TIME = "TIME"; //$NON-NLS-1$ public static final String TIMESTAMP = "TIMESTAMP"; //$NON-NLS-1$ private Boolean booleanValue = null; private Date dateValue = null; private String textValue = null; private Time timeValue = null; private Timestamp timestampValue = null; private boolean conversionType = false; private String type; public ConstantEditorModel() { super(IConstant.class); IDataTypeManagerService service = ModelerCore.getTeiidDataTypeManagerService(); DEFAULT_TYPE = service.getDefaultDataType(DataTypeName.STRING); setDefaults(); } /* (non-Javadoc) * @see org.teiid.query.ui.builder.model.AbstractLanguageObjectEditorModel#clear() */ @Override public void clear() { setDefaults(); type = DEFAULT_TYPE; conversionType = false; super.clear(); } /** * Gets the <code>boolean</code> value. * * @return the value if type is not boolean #see BuilderUtils#BOOLEAN_TYPES */ public boolean getBoolean() { if (!isBoolean()) { CoreArgCheck.isTrue(isBoolean(), Util.getString(PREFIX + "invalidRequest", //$NON-NLS-1$ new Object[] {"getBoolean()", type})); //$NON-NLS-1$ } return booleanValue.booleanValue(); } /** * Gets the current value. * * @return the current <code>Constant</code> * @throws IllegalStateException if the current value is not complete */ public IConstant getConstant() { return (IConstant)getLanguageObject(); } /* (non-Javadoc) * @see org.teiid.query.ui.builder.model.AbstractLanguageObjectEditorModel#getLanguageObject() */ @Override public ILanguageObject getLanguageObject() { // return null if not complete or valid if (!isComplete() || !isValid()) { return null; } Object value = null; if (conversionType) { value = type; } else { if (isText()) { Class typeClass = BuilderUtils.getTypeClass(type); if (Number.class.isAssignableFrom(typeClass)) { try { Constructor constructor = typeClass.getConstructor(new Class[] {String.class}); value = constructor.newInstance(new Object[] {textValue}); } catch (Exception theException) { Util.log(IStatus.ERROR, theException, Util.getString(PREFIX + "invalidTextValue", //$NON-NLS-1$); new Object[] {textValue, typeClass})); } } else if (typeClass == Character.class) { value = new Character(textValue.charAt(0)); } else { value = textValue; } } else if (isDate()) { value = getDate(); } else if (isTimestamp()) { value = getTimestamp(); } else if (isTime()) { value = getTime(); } else if (isBoolean()) { value = booleanValue; } } IQueryService queryService = ModelerCore.getTeiidQueryService(); IQueryFactory factory = queryService.createQueryFactory(); return factory.createConstant(value); } /** * Gets the <code>Date</code> value. * * @return the value */ public Date getDate() { if (!isDate()) { CoreArgCheck.isTrue(isDate(), Util.getString(PREFIX + "invalidRequest", //$NON-NLS-1$ new Object[] {"getDate()", type})); //$NON-NLS-1$ } return dateValue; } /** * Gets the <code>String</code> value. * * @return the value */ public String getText() { if (!isText()) { CoreArgCheck.isTrue(isText(), Util.getString(PREFIX + "invalidRequest", //$NON-NLS-1$ new Object[] {"getText()", type})); //$NON-NLS-1$ } return textValue; } public static int getTextLimit( String theTextType ) { return BuilderUtils.getTextLimit(theTextType); } /** * Gets the <code>Time</code> value. * * @return the value */ public Time getTime() { CoreArgCheck.isTrue(isTime(), Util.getString(PREFIX + "invalidRequest", //$NON-NLS-1$ new Object[] {"getTime()", type})); //$NON-NLS-1$ // zero out the seconds and milliseconds if (timeValue != null) { Calendar date = Calendar.getInstance(); date.setTime(timeValue); date.set(Calendar.SECOND, 0); date.set(Calendar.MILLISECOND, 0); timeValue = new Time(date.getTime().getTime()); } return timeValue; } /** * Gets the <code>Time</code> value. * * @return the value */ public Timestamp getTimestamp() { if (!isTimestamp()) { CoreArgCheck.isTrue(isTimestamp(), Util.getString(PREFIX + "invalidRequest", //$NON-NLS-1$ new Object[] {"getTimestamp()", type})); //$NON-NLS-1$ } // zero out the seconds and milliseconds if (timestampValue != null) { Calendar date = Calendar.getInstance(); date.setTime(timestampValue); date.set(Calendar.SECOND, 0); date.set(Calendar.MILLISECOND, 0); timestampValue = new Timestamp(date.getTime().getTime()); } return timestampValue; } public String getType() { return type; } public boolean isBoolean() { return !isConversionType() && BuilderUtils.isBooleanType(type); } /* (non-Javadoc) * @see org.teiid.query.ui.builder.model.AbstractLanguageObjectEditorModel#isComplete() */ @Override public boolean isComplete() { boolean result = false; if (conversionType) { result = true; } else { if (isText()) { result = (textValue != null) && isValid(); } else if (isDate()) { result = (dateValue != null); } else if (isTimestamp()) { result = (timestampValue != null); } else if (isTime()) { result = (timeValue != null); } else if (isBoolean()) { result = (booleanValue != null); } else if (isNull()) { result = true; } } return result; } public boolean isConversionType() { return conversionType; } public boolean isDate() { return !isConversionType() && BuilderUtils.isDateType(type); } public boolean isNull() { return !isConversionType() && BuilderUtils.isNullType(type); } public boolean isText() { return !isConversionType() && BuilderUtils.isStringType(type); } public boolean isTime() { return !isConversionType() && BuilderUtils.isTimeType(type); } public boolean isTimestamp() { return !isConversionType() && BuilderUtils.isTimestampType(type); } public boolean isValid() { return (isText()) ? isValidValue(textValue) && isValidNumber(textValue) : true; } public boolean isValidValue( String theString ) { if (!isText()) { return true; } if ((textValue.length() > getTextLimit(type))) { return false; } // check to see if all valid chars String validChars = BuilderUtils.getValidChars(type); if (validChars != null) { for (int length = textValue.length(), i = 0; i < length; i++) { if (validChars.indexOf(textValue.charAt(i)) == -1) { return false; } } } return true; } private boolean isValidNumber( String theString ) { // could only not be valid if text type or number type Class typeClass = BuilderUtils.getTypeClass(type); if (Number.class.isAssignableFrom(typeClass)) { try { Constructor constructor = typeClass.getConstructor(new Class[] {String.class}); constructor.newInstance(new Object[] {theString}); } catch (Exception theException) { // this will catch values too big or too small return false; } } return true; } public String paramString() { return new StringBuffer().append("type=").append(type) //$NON-NLS-1$ .append(", conversionType=").append(conversionType) //$NON-NLS-1$ .append(", booleanValue=").append(booleanValue) //$NON-NLS-1$ .append(", dateValue=").append(dateValue) //$NON-NLS-1$ .append(", textValue=").append(textValue) //$NON-NLS-1$ .append(", timeValue=").append(timeValue) //$NON-NLS-1$ .append(", timestampValue=").append(timestampValue) //$NON-NLS-1$ .toString(); } public void setBoolean( boolean theFlag ) { if (!isBoolean()) { CoreArgCheck.isTrue(isBoolean(), Util.getString(PREFIX + "invalidRequest", //$NON-NLS-1$ new Object[] {"setBoolean()", type})); //$NON-NLS-1$ } if ((booleanValue == null) || (getBoolean() != theFlag)) { booleanValue = new Boolean(theFlag); fireModelChanged(BOOLEAN); } } private void setConstant( IConstant theConstant ) { // return if current value is the same if (((theConstant == null) && (getConstant() == null)) || ((theConstant != null) && (getConstant() != null) && theConstant.equals(getConstant()))) { return; } notifyListeners = false; if (theConstant == null || theConstant.getValue() == null) { clear(); } else { conversionType = BuilderUtils.isConversionType(theConstant); // for conversion types the type is actually the value type = (conversionType) ? (String)theConstant.getValue() : BuilderUtils.getType(theConstant); setDefaults(); if (!conversionType) { if (isText()) { setText(theConstant.getValue().toString()); } else if (isBoolean()) { Boolean value = (Boolean)theConstant.getValue(); setBoolean(value.booleanValue()); } else if (isNull()) { setNull(); } else if (isDate()) { Date value = (Date)theConstant.getValue(); setDate(value); } else if (isTimestamp()) { Timestamp value = (Timestamp)theConstant.getValue(); setTimestamp(value); } else if (isTime()) { Time value = (Time)theConstant.getValue(); setTime(value); } else { type = DEFAULT_TYPE; setText(theConstant.getValue().toString()); } } } notifyListeners = true; fireModelChanged(LanguageObjectEditorModelEvent.SAVED); } public void setDate( Date theDate ) { if (!isDate()) { CoreArgCheck.isTrue(isDate(), Util.getString(PREFIX + "invalidRequest", //$NON-NLS-1$ new Object[] {"setDate()", type})); //$NON-NLS-1$ } if ((dateValue == null) || !dateValue.equals(theDate)) { dateValue = theDate; fireModelChanged(DATE); } } private void setDefaults() { type = DEFAULT_TYPE; booleanValue = new Boolean(true); dateValue = new Date(Calendar.getInstance().getTime().getTime()); textValue = ""; //$NON-NLS-1$ timeValue = new Time(Calendar.getInstance().getTime().getTime()); timestampValue = new Timestamp(Calendar.getInstance().getTime().getTime()); } /* (non-Javadoc) * @see org.teiid.query.ui.builder.model.AbstractLanguageObjectEditorModel#setLanguageObject(org.teiid.query.sql.LanguageObject) */ @Override public void setLanguageObject( ILanguageObject theLangObj ) { super.setLanguageObject(theLangObj); setConstant((IConstant)theLangObj); } public void setNull() { if (!isNull()) { CoreArgCheck.isTrue(isNull(), Util.getString(PREFIX + "invalidRequest", //$NON-NLS-1$ new Object[] {"setNull()", type})); //$NON-NLS-1$ } // does nothing since only the type we care about } public void setText( String theText ) { if (!isText()) { CoreArgCheck.isTrue(isText(), Util.getString(PREFIX + "invalidRequest", //$NON-NLS-1$ new Object[] {"setText()", type})); //$NON-NLS-1$ } if ((textValue == null) || !getText().equals(theText)) { textValue = theText; fireModelChanged(TEXT); } } public void setTime( Time theTime ) { if (!isTime()) { CoreArgCheck.isTrue(isTime(), Util.getString(PREFIX + "invalidRequest", //$NON-NLS-1$ new Object[] {"setTime()", type})); //$NON-NLS-1$ } if ((timeValue == null) || !timeValue.equals(theTime)) { timeValue = theTime; fireModelChanged(TIME); } } public void setTimestamp( Timestamp theTimestamp ) { if (!isTimestamp()) { CoreArgCheck.isTrue(isTimestamp(), Util.getString(PREFIX + "invalidRequest", //$NON-NLS-1$ new Object[] {"setTimestamp()", type})); //$NON-NLS-1$ } if ((timestampValue == null) || !timestampValue.equals(theTimestamp)) { timestampValue = theTimestamp; fireModelChanged(TIMESTAMP); } } public void setType( String theType ) { boolean changed = false; if (BuilderUtils.isValidType(theType)) { if (!type.equals(theType)) { type = theType; changed = true; } } else { type = DEFAULT_TYPE; changed = true; } if (changed) { fireModelChanged(TYPE); } } }