/* * Copyright 2015 The 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 * * 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.intellij.lang.ognl; import com.intellij.lang.injection.MultiHostRegistrar; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiLanguageInjectionHost; /** * Injects OGNL language. * * @author Yann Cébron */ public class OgnlLanguageInjector { private final MultiHostRegistrar registrar; private final PsiLanguageInjectionHost element; private boolean addPrefixSuffix; private OgnlLanguageInjector(final MultiHostRegistrar registrar, final PsiLanguageInjectionHost element) { this.registrar = registrar; this.element = element; } private OgnlLanguageInjector addPrefixSuffix() { this.addPrefixSuffix = true; return this; } public static void injectElementWithPrefixSuffix(final MultiHostRegistrar registrar, final PsiLanguageInjectionHost element) { new OgnlLanguageInjector(registrar, element) .addPrefixSuffix() .injectWholeXmlAttributeValue(); } public static void injectOccurrences(final MultiHostRegistrar registrar, final PsiLanguageInjectionHost element) { new OgnlLanguageInjector(registrar, element).injectOccurrences(); } private void injectWholeXmlAttributeValue() { final int textLength = element.getTextLength(); if (textLength < 2) { return; } final TextRange range = new TextRange(1, textLength - 1); registrar.startInjecting(OgnlLanguage.INSTANCE) .addPlace(addPrefixSuffix ? OgnlLanguage.EXPRESSION_PREFIX : null, addPrefixSuffix ? OgnlLanguage.EXPRESSION_SUFFIX : null, element, range) .doneInjecting(); } private void injectOccurrences() { registrar.startInjecting(OgnlLanguage.INSTANCE); final String text = element.getText(); final int textLength = text.length() - 1; final int lastStartPosition = Math.max(textLength, text.lastIndexOf(OgnlLanguage.EXPRESSION_SUFFIX)); int startOffset = 0; while (startOffset < lastStartPosition) { startOffset = text.indexOf(OgnlLanguage.EXPRESSION_PREFIX, startOffset); if (startOffset == -1) { break; } // search closing '}' from text end/next expr start backwards to support sequence expressions final int nextStartOffset = text.indexOf(OgnlLanguage.EXPRESSION_PREFIX, startOffset + OgnlLanguage.EXPRESSION_PREFIX.length()); final int searchClosingBraceIdx = nextStartOffset != -1 ? nextStartOffset : textLength; final int closingBraceIdx = text.lastIndexOf(OgnlLanguage.EXPRESSION_SUFFIX, searchClosingBraceIdx); final int length = (closingBraceIdx != -1 && closingBraceIdx > nextStartOffset ? closingBraceIdx + 1 : textLength) - startOffset; final TextRange range = TextRange.from(startOffset, length); registrar.addPlace(null, null, element, range); startOffset += length; } registrar.doneInjecting(); } }