/*
* 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 com.addthis.bundle.core.Bundle;
import com.addthis.bundle.util.AutoField;
import com.addthis.bundle.util.AutoParam;
import com.addthis.bundle.util.ValueUtil;
import com.addthis.bundle.value.ValueArray;
import com.addthis.bundle.value.ValueObject;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* This {@link AbstractValueFilter ValueFilter} <span class="hydra-summary">returns the <i>i</i><sup>th</sup> element of an array</span>.
* <p/>
* <p>The {@link #index index} specifies the 0-based offset of the element to retrieve.
* A negative value for the index will retrieve the (-i) value from the opposite end of the array.
* If {@link #toNull toNull} is true, then a null value is returned when the index is out of bounds.
* If toNull is false, then the entire array is returned when the index is out of bounds.
* <p/>
* <p>Example:</p>
* <pre>
* {from:"FOO_2_BAR", to:"FOO", filter:[{split:"="}, {index:0}]}
* </pre>
*
* @user-reference
* @exclude-fields once
*/
public class ValueFilterIndex extends AbstractValueFilterContextual {
/** The array offset of the element to return. */
@AutoParam private AutoField index;
/** If true, then return null when the index is out of bounds. Default is true. */
@JsonProperty private boolean toNull = true;
@Override public ValueObject filter(ValueObject value, Bundle context) {
ValueObject nullReturn = toNull ? null : value;
if (ValueUtil.isEmpty(value)) {
return nullReturn;
}
if (value.getObjectType() == ValueObject.TYPE.ARRAY) {
ValueArray arr = value.asArray();
if (arr.isEmpty()) {
return nullReturn;
}
int i = index.getInt(context).getAsInt();
while (i < 0) {
i = arr.size() + i;
}
return (arr.size() > i) ? arr.get(i) : nullReturn;
}
return nullReturn;
}
/** required to override by contract -- not used */
@Override public ValueObject filterValue(ValueObject value, Bundle context) {
throw new UnsupportedOperationException("only filter should be called");
}
}