/* Generated By:JJTree: Do not edit this line. Constant.java Version 4.3 */ /* JavaCCOptions:MULTI=true,NODE_USES_PARSER=true,VISITOR=true,TRACK_TOKENS=false,NODE_PREFIX=,NODE_EXTENDS=,NODE_FACTORY=,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */ package org.teiid.query.sql.symbol; import java.math.BigDecimal; import java.text.Collator; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import org.teiid.core.types.ClobType; import org.teiid.core.types.DataTypeManagerService; import org.teiid.core.types.DataTypeManagerService.DefaultDataTypes; import org.teiid.core.util.PropertiesUtils; import org.teiid.designer.query.sql.symbol.IConstant; import org.teiid.designer.runtime.version.spi.ITeiidServerVersion; import org.teiid.query.function.FunctionMethods; import org.teiid.query.parser.LanguageVisitor; import org.teiid.query.parser.TeiidNodeFactory; import org.teiid.query.parser.TeiidNodeFactory.ASTNodes; import org.teiid.query.sql.lang.SimpleNode; import org.teiid.runtime.client.Messages; /** * */ public class Constant extends SimpleNode implements Expression, IConstant<LanguageVisitor> { private Class<?> type = DataTypeManagerService.DefaultDataTypes.NULL.getTypeClass(); private boolean multiValued; private static Map<ITeiidServerVersion, Constant> nullCache = new HashMap<ITeiidServerVersion, Constant>(); /** * @param teiidParser * @return a null constant for the given teiid parser if one has not already been created */ public static Constant getNullConstant(ITeiidServerVersion teiidVersion) { Constant constant = nullCache.get(teiidVersion); if (constant == null) { constant = TeiidNodeFactory.createASTNode(teiidVersion, ASTNodes.CONSTANT); nullCache.put(teiidVersion, constant); } return constant; } /** * locale for comparison of constant values */ public static final String COLLATION_LOCALE = System.getProperties().getProperty("org.teiid.collationLocale"); //$NON-NLS-1$ /** * System property indicating whether to compare padded constant values */ public static final boolean PAD_SPACE = PropertiesUtils.getBooleanProperty(System.getProperties(), "org.teiid.padSpace", false); //$NON-NLS-1$ /** * Comparator for comparing constants */ public static final Comparator<Object> COMPARATOR = getComparator(COLLATION_LOCALE, PAD_SPACE); static Comparator<Object> getComparator(String localeString, final boolean padSpace) { if (localeString == null) { return getComparator(padSpace); } String[] parts = localeString.split("_"); //$NON-NLS-1$ Locale locale = null; if (parts.length == 1) { locale = new Locale(parts[0]); } else if (parts.length == 2) { locale = new Locale(parts[0], parts[1]); } else if (parts.length == 3) { locale = new Locale(parts[0], parts[1], parts[2]); } else { return getComparator(padSpace); } final Collator c = Collator.getInstance(locale); return new Comparator<Object>() { @Override public int compare(Object o1, Object o2) { Class<?> clazz = o1.getClass(); if (clazz == String.class) { String s1 = (String)o1; String s2 = (String)o2; if (padSpace) { s1 = FunctionMethods.rightTrim(s1, ' ', false); s2 = FunctionMethods.rightTrim(s2, ' ', false); } return c.compare(s1, s2); } return ((Comparable<Object>)o1).compareTo(o2); } }; } static Comparator<Object> getComparator(boolean padSpace) { if (!padSpace) { return new Comparator<Object>() { @Override public int compare(Object o1, Object o2) { return ((Comparable<Object>)o1).compareTo(o2); } }; } return new Comparator<Object>() { @Override public int compare(Object o1, Object o2) { Class<?> clazz = o1.getClass(); if (clazz == String.class) { CharSequence s1 = (CharSequence)o1; CharSequence s2 = (CharSequence)o2; return comparePadded(s1, s2); } else if (clazz == ClobType.class) { CharSequence s1 = ((ClobType)o1).getCharSequence(); CharSequence s2 = ((ClobType)o2).getCharSequence(); return comparePadded(s1, s2); } return ((Comparable<Object>)o1).compareTo(o2); } }; } /** * @param p * @param id */ public Constant(ITeiidServerVersion p, int id) { super(p, id); } /** * Get type of constant, if known * @return Java class name of type */ @Override public Class<?> getType() { return this.type; } /** * @param type */ public void setType(Class<?> type) { // Check that type is valid, then set it if(type == null) { throw new IllegalArgumentException(Messages.getString(Messages.ERR.ERR_015_010_0014)); } this.type = type; } /** * Get value of constant * @return Constant value */ @Override public Object getValue() { return this.value; } /** * @param value */ public void setValue(Object value) { jjtSetValue(value); if (this.value == null) { this.type = DataTypeManagerService.DefaultDataTypes.NULL.getClass(); } else { this.type = this.value.getClass(); Class<?> originalType = type; while (type.isArray() && !type.getComponentType().isPrimitive()) { type = type.getComponentType(); } DefaultDataTypes dataType = getDataTypeService().getDataType(type); if (dataType != null) { //array of a runtime-type this.type = originalType; } else if (originalType.isArray() && !originalType.getComponentType().isPrimitive()) { this.type = DataTypeManagerService.DefaultDataTypes.OBJECT.getTypeArrayClass(); } else { this.type = DataTypeManagerService.DefaultDataTypes.OBJECT.getClass(); } } } @Override public boolean isMultiValued() { return multiValued; } final static int comparePadded(CharSequence s1, CharSequence s2) { int len1 = s1.length(); int len2 = s2.length(); int n = Math.min(len1, len2); int i = 0; int result = 0; for (; i < n; i++) { char c1 = s1.charAt(i); char c2 = s2.charAt(i); if (c1 != c2) { return c1 - c2; } } result = len1 - len2; for (int j = i; j < len1; j++) { if (s1.charAt(j) != ' ') { return result; } } for (int j = i; j < len2; j++) { if (s2.charAt(j) != ' ') { return result; } } return 0; } /** * @param value */ public void setMultiValued(List<?> value) { this.multiValued = true; this.value = value; } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); if(this.value != null && !isMultiValued()) { if (this.value instanceof BigDecimal) { BigDecimal bd = (BigDecimal)this.value; int xsign = bd.signum(); if (xsign == 0) return 0; bd = bd.stripTrailingZeros(); return prime * result + bd.hashCode(); } result = prime * result + this.value.hashCode(); } return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (!super.equals(obj)) return false; if (getClass() != obj.getClass()) return false; Constant other = (Constant)obj; if (this.value == null && other.value == null) { // Only consider type information if values are not null return true; } if (this.value instanceof BigDecimal) { if (this.value == other.value) { return true; } if (!(other.value instanceof BigDecimal)) { return false; } return ((BigDecimal)this.value).compareTo((BigDecimal)other.value) == 0; } if (this.type == null) { if (other.type != null) return false; } else if (!this.type.equals(other.type)) return false; return multiValued == other.multiValued && other.getValue().equals(this.getValue()); } /** Accept the visitor. **/ @Override public void acceptVisitor(LanguageVisitor visitor) { visitor.visit(this); } @Override public Constant clone() { Constant clone = new Constant(getTeiidVersion(), this.id); if(getType() != null) clone.setType(getType()); clone.multiValued = multiValued; if(getValue() != null) clone.setValue(getValue()); return clone; } } /* JavaCC - OriginalChecksum=6271d54b51de261eb4775571a208cc1b (do not edit this line) */