/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 org.apache.ambari.server.controller.predicate; import java.text.NumberFormat; import java.text.ParsePosition; import org.apache.ambari.server.controller.spi.Resource; /** * Predicate that compares a given value to a {@link Resource} property. */ public abstract class ComparisonPredicate<T> extends PropertyPredicate implements BasePredicate { private final Comparable<T> value; private final String stringValue; private final Double doubleValue; protected ComparisonPredicate(String propertyId, Comparable<T> value) { super(propertyId); this.value = value; if (value instanceof Number) { stringValue = null; doubleValue = ((Number) value).doubleValue(); } else if (value instanceof String) { stringValue = (String) value; doubleValue = stringToDouble(stringValue); } else { stringValue = null; doubleValue = null; } } public Comparable<T> getValue() { return value; } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof ComparisonPredicate)) return false; if (!super.equals(o)) return false; ComparisonPredicate that = (ComparisonPredicate) o; return !(value != null ? !value.equals(that.value) : that.value != null); } @Override public int hashCode() { int result = super.hashCode(); result = 31 * result + (value != null ? value.hashCode() : 0); return result; } @Override public void accept(PredicateVisitor visitor) { visitor.acceptComparisonPredicate(this); } protected int compareValueToIgnoreCase(Object propertyValue) throws ClassCastException{ return compareValueTo(propertyValue, true); // case insensitive } protected int compareValueTo(Object propertyValue) throws ClassCastException{ return compareValueTo(propertyValue, false); // case sensitive } private int compareValueTo(Object propertyValue, boolean ignoreCase) throws ClassCastException { if (doubleValue != null) { if (propertyValue instanceof Number) { return doubleValue.compareTo(((Number) propertyValue).doubleValue()); } else if (propertyValue instanceof String) { Double doubleFromString = stringToDouble((String) propertyValue); if (doubleFromString != null) { return doubleValue.compareTo(doubleFromString); } } } if (stringValue != null) { if (ignoreCase) { return stringValue.compareToIgnoreCase(propertyValue.toString()); } else { return stringValue.compareTo(propertyValue.toString()); } } return getValue().compareTo((T) propertyValue); } private Double stringToDouble(String stringValue) { if (stringValue == null || stringValue.isEmpty()) { return null; } ParsePosition parsePosition = new ParsePosition(0); NumberFormat numberFormat = NumberFormat.getInstance(); Number parsedNumber = numberFormat.parse(stringValue, parsePosition); return parsePosition.getIndex() == stringValue.length() ? parsedNumber.doubleValue() : null; } public abstract String getOperator(); public abstract ComparisonPredicate<T> copy(String propertyId); // ----- Object overrides -------------------------------------------------- @Override public String toString() { return getPropertyId() + getOperator() + getValue(); } }