TextSqlNode.java
- /*
- * Copyright 2009-2024 the original author or authors.
- *
- * 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
- *
- * https://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.ibatis.scripting.xmltags;
- import java.util.regex.Pattern;
- import org.apache.ibatis.parsing.GenericTokenParser;
- import org.apache.ibatis.parsing.TokenHandler;
- import org.apache.ibatis.scripting.ScriptingException;
- import org.apache.ibatis.type.SimpleTypeRegistry;
- /**
- * @author Clinton Begin
- */
- public class TextSqlNode implements SqlNode {
- private final String text;
- private final Pattern injectionFilter;
- public TextSqlNode(String text) {
- this(text, null);
- }
- public TextSqlNode(String text, Pattern injectionFilter) {
- this.text = text;
- this.injectionFilter = injectionFilter;
- }
- public boolean isDynamic() {
- DynamicCheckerTokenParser checker = new DynamicCheckerTokenParser();
- GenericTokenParser parser = createParser(checker);
- parser.parse(text);
- return checker.isDynamic();
- }
- @Override
- public boolean apply(DynamicContext context) {
- GenericTokenParser parser = createParser(new BindingTokenParser(context, injectionFilter));
- context.appendSql(parser.parse(text));
- return true;
- }
- private GenericTokenParser createParser(TokenHandler handler) {
- return new GenericTokenParser("${", "}", handler);
- }
- private static class BindingTokenParser implements TokenHandler {
- private final DynamicContext context;
- private final Pattern injectionFilter;
- public BindingTokenParser(DynamicContext context, Pattern injectionFilter) {
- this.context = context;
- this.injectionFilter = injectionFilter;
- }
- @Override
- public String handleToken(String content) {
- Object parameter = context.getBindings().get("_parameter");
- if (parameter == null) {
- context.getBindings().put("value", null);
- } else if (SimpleTypeRegistry.isSimpleType(parameter.getClass())) {
- context.getBindings().put("value", parameter);
- }
- Object value = OgnlCache.getValue(content, context.getBindings());
- String srtValue = value == null ? "" : String.valueOf(value); // issue #274 return "" instead of "null"
- checkInjection(srtValue);
- return srtValue;
- }
- private void checkInjection(String value) {
- if (injectionFilter != null && !injectionFilter.matcher(value).matches()) {
- throw new ScriptingException("Invalid input. Please conform to regex" + injectionFilter.pattern());
- }
- }
- }
- private static class DynamicCheckerTokenParser implements TokenHandler {
- private boolean isDynamic;
- public DynamicCheckerTokenParser() {
- // Prevent Synthetic Access
- }
- public boolean isDynamic() {
- return isDynamic;
- }
- @Override
- public String handleToken(String content) {
- this.isDynamic = true;
- return null;
- }
- }
- }