/*
* Licensed 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 com.addthis.hydra.data.filter.value;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import com.addthis.bundle.value.ValueArray;
import com.addthis.bundle.value.ValueFactory;
import com.addthis.bundle.value.ValueObject;
/**
* This {@link AbstractValueFilter ValueFilter} <span class="hydra-summary">sorts an array</span>.
* <p/>
* <p>Items in the array are sorted according to the natural ordering of their underlying type.
* Only arrays with elements of TYPE STRING, INT, or FLOAT are supported. All elements of the array must be from the same type.
* </p>
*/
public class ValueFilterSort extends AbstractValueFilter {
private static final Comparator<ValueObject> valueObjectComparator = (o1, o2) -> {
if (o1.getObjectType() != o2.getObjectType()) {
throw new RuntimeException("Sort error: different object types: " + o1.getObjectType() + "," + o2.getObjectType());
}
switch (o1.getObjectType()) {
case STRING:
return o1.asString().asNative().compareTo(o2.asString().asNative());
case INT:
return Long.compare(o1.asLong().getLong(), o2.asLong().getLong()); // DefaultLong.TYPE = INT, go figure
case FLOAT:
return Double.compare(o1.asDouble().getDouble(), o2.asDouble().getDouble()); // ... and DefaultDouble.TYPE = FLOAT
default:
throw new RuntimeException("Sort error: unsupported object type " + o1.getObjectType());
}
};
@Override
public ValueObject filterValue(ValueObject value) {
if (value == null) {
return null;
}
ValueObject.TYPE type = value.getObjectType();
switch (type) {
case ARRAY:
return sortArray(value.asArray());
case INT:
return value;
case FLOAT:
return value;
case STRING:
return value;
default:
throw new RuntimeException("Unsupported object type " + type);
}
}
public static ValueArray sortArray(ValueArray array) {
List<ValueObject> tmpObjs = new ArrayList<>();
for (ValueObject obj : array) {
tmpObjs.add(obj);
}
Collections.sort(tmpObjs, valueObjectComparator);
ValueArray rv = ValueFactory.createArray(array.size());
for (ValueObject obj : tmpObjs) {
rv.add(obj);
}
return rv;
}
}