/*
* 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.nifi.attribute.expression.language;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.apache.nifi.components.PropertyValue;
import org.apache.nifi.controller.ControllerService;
import org.apache.nifi.controller.ControllerServiceLookup;
import org.apache.nifi.expression.AttributeValueDecorator;
import org.apache.nifi.flowfile.FlowFile;
import org.apache.nifi.processor.DataUnit;
import org.apache.nifi.processor.exception.ProcessException;
import org.apache.nifi.registry.VariableRegistry;
import org.apache.nifi.util.FormatUtils;
public class StandardPropertyValue implements PropertyValue {
private final String rawValue;
private final ControllerServiceLookup serviceLookup;
private final PreparedQuery preparedQuery;
private final VariableRegistry variableRegistry;
public StandardPropertyValue(final String rawValue, final ControllerServiceLookup serviceLookup) {
this(rawValue, serviceLookup, Query.prepare(rawValue), VariableRegistry.EMPTY_REGISTRY);
}
public StandardPropertyValue(final String rawValue, final ControllerServiceLookup serviceLookup, final VariableRegistry variableRegistry) {
this(rawValue, serviceLookup, Query.prepare(rawValue), variableRegistry);
}
/**
* Constructs a new StandardPropertyValue with the given value & service
* lookup and indicates whether or not the rawValue contains any NiFi
* Expressions. If it is unknown whether or not the value contains any NiFi
* Expressions, the
* {@link #StandardPropertyValue(String, ControllerServiceLookup, VariableRegistry)}
* constructor should be used or <code>true</code> should be passed.
* However, if it is known that the value contains no NiFi Expression, that
* information should be provided so that calls to
* {@link #evaluateAttributeExpressions()} are much more efficient
*
* @param rawValue value
* @param serviceLookup lookup
* @param preparedQuery query
* @param variableRegistry variableRegistry
*/
public StandardPropertyValue(final String rawValue, final ControllerServiceLookup serviceLookup, final PreparedQuery preparedQuery,
final VariableRegistry variableRegistry) {
this.rawValue = rawValue;
this.serviceLookup = serviceLookup;
this.preparedQuery = preparedQuery;
this.variableRegistry = variableRegistry;
}
@Override
public String getValue() {
return rawValue;
}
@Override
public Integer asInteger() {
return (rawValue == null) ? null : Integer.parseInt(rawValue.trim());
}
@Override
public Long asLong() {
return (rawValue == null) ? null : Long.parseLong(rawValue.trim());
}
@Override
public Boolean asBoolean() {
return (rawValue == null) ? null : Boolean.parseBoolean(rawValue.trim());
}
@Override
public Float asFloat() {
return (rawValue == null) ? null : Float.parseFloat(rawValue.trim());
}
@Override
public Double asDouble() {
return (rawValue == null) ? null : Double.parseDouble(rawValue.trim());
}
@Override
public Long asTimePeriod(final TimeUnit timeUnit) {
return (rawValue == null) ? null : FormatUtils.getTimeDuration(rawValue.trim(), timeUnit);
}
@Override
public Double asDataSize(final DataUnit dataUnit) {
return rawValue == null ? null : DataUnit.parseDataSize(rawValue.trim(), dataUnit);
}
@Override
public PropertyValue evaluateAttributeExpressions() throws ProcessException {
return evaluateAttributeExpressions(null, null, null);
}
@Override
public PropertyValue evaluateAttributeExpressions(final Map<String, String> attributes) throws ProcessException {
return evaluateAttributeExpressions(null, attributes, null);
}
@Override
public PropertyValue evaluateAttributeExpressions(final Map<String, String> attributes, final AttributeValueDecorator decorator) throws ProcessException {
return evaluateAttributeExpressions(null, attributes, decorator);
}
@Override
public PropertyValue evaluateAttributeExpressions(final AttributeValueDecorator decorator) throws ProcessException {
return evaluateAttributeExpressions(null, null, decorator);
}
@Override
public PropertyValue evaluateAttributeExpressions(final FlowFile flowFile) throws ProcessException {
return evaluateAttributeExpressions(flowFile, null, null);
}
@Override
public PropertyValue evaluateAttributeExpressions(final FlowFile flowFile, final Map<String, String> additionalAttributes) throws ProcessException {
return evaluateAttributeExpressions(flowFile, additionalAttributes, null);
}
@Override
public PropertyValue evaluateAttributeExpressions(final FlowFile flowFile, final AttributeValueDecorator decorator) throws ProcessException {
return evaluateAttributeExpressions(flowFile, null, decorator);
}
@Override
public PropertyValue evaluateAttributeExpressions(final FlowFile flowFile, final Map<String, String> additionalAttributes, final AttributeValueDecorator decorator) throws ProcessException {
return evaluateAttributeExpressions(flowFile, additionalAttributes, decorator, null);
}
@Override
@SuppressWarnings("unchecked")
public PropertyValue evaluateAttributeExpressions(FlowFile flowFile, Map<String, String> additionalAttributes, AttributeValueDecorator decorator, Map<String, String> stateValues)
throws ProcessException {
if (rawValue == null || preparedQuery == null) {
return this;
}
final ValueLookup lookup = new ValueLookup(variableRegistry, flowFile, additionalAttributes);
final String evaluated = preparedQuery.evaluateExpressions(lookup, decorator, stateValues);
return new StandardPropertyValue(evaluated, serviceLookup, new EmptyPreparedQuery(evaluated), null);
}
@Override
public String toString() {
return rawValue;
}
@Override
public ControllerService asControllerService() {
if (rawValue == null || rawValue.equals("") || serviceLookup == null) {
return null;
}
return serviceLookup.getControllerService(rawValue);
}
@Override
public <T extends ControllerService> T asControllerService(final Class<T> serviceType) throws IllegalArgumentException {
if (!serviceType.isInterface()) {
throw new IllegalArgumentException("ControllerServices may be referenced only via their interfaces; " + serviceType + " is not an interface");
}
if (rawValue == null || rawValue.equals("") || serviceLookup == null) {
return null;
}
final ControllerService service = serviceLookup.getControllerService(rawValue);
if (service == null) {
return null;
}
if (serviceType.isAssignableFrom(service.getClass())) {
return serviceType.cast(service);
}
throw new IllegalArgumentException("Controller Service with identifier " + rawValue + " is of type " + service.getClass() + " and cannot be cast to " + serviceType);
}
@Override
public boolean isSet() {
return rawValue != null;
}
@Override
public boolean isExpressionLanguagePresent() {
return preparedQuery.isExpressionLanguagePresent();
}
}