/******************************************************************************* * 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.sling.scripting.sightly.impl.compiler.optimization.reduce; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.sling.scripting.sightly.compiler.SightlyCompilerException; import org.apache.sling.scripting.sightly.compiler.expression.ExpressionNode; import org.apache.sling.scripting.sightly.compiler.expression.nodes.ArrayLiteral; import org.apache.sling.scripting.sightly.compiler.expression.nodes.BooleanConstant; import org.apache.sling.scripting.sightly.compiler.expression.nodes.MapLiteral; import org.apache.sling.scripting.sightly.compiler.expression.nodes.NullLiteral; import org.apache.sling.scripting.sightly.compiler.expression.nodes.NumericConstant; import org.apache.sling.scripting.sightly.compiler.expression.nodes.StringConstant; /** * Data structure used in expression reducing */ public final class EvalResult { private final ExpressionNode node; private final Object value; public static EvalResult constant(Object obj) { return new EvalResult(null, obj); } public static EvalResult nonConstant(ExpressionNode node) { return new EvalResult(node, null); } private EvalResult(ExpressionNode node, Object value) { this.node = node; this.value = value; } public boolean isConstant() { return node == null; } public Object getValue() { if (!isConstant()) { throw new SightlyCompilerException("Cannot get constant value from non-constant result."); } return value; } public ExpressionNode getNode() { return (isConstant()) ? asLiteral(getValue()) : node; } private static ExpressionNode asLiteral(Object value) { if (value instanceof Boolean) { return new BooleanConstant((Boolean) value); } if (value instanceof String) { return new StringConstant((String) value); } if (value instanceof Number) { return new NumericConstant((Number) value); } if (value instanceof Map) { //noinspection unchecked return asMapLiteral((Map<String, Object>) value); } if (value instanceof List) { //noinspection unchecked return asArrayLiteral((List<Object>) value); } if (value == null) { return NullLiteral.INSTANCE; } throw new SightlyCompilerException("Cannot transform to literal: " + value); } private static MapLiteral asMapLiteral(Map<String, Object> map) { HashMap<String, ExpressionNode> literal = new HashMap<>(); for (Map.Entry<String, Object> entry : map.entrySet()) { literal.put(entry.getKey(), asLiteral(entry.getValue())); } return new MapLiteral(literal); } private static ArrayLiteral asArrayLiteral(List<Object> list) { ArrayList<ExpressionNode> literal = new ArrayList<>(); for (Object obj : list) { literal.add(asLiteral(obj)); } return new ArrayLiteral(literal); } }