You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by lu...@apache.org on 2024/02/06 13:17:24 UTC
(struts-intellij-plugin) 01/01: Struts 2 moved to obsolete plugins
This is an automated email from the ASF dual-hosted git repository.
lukaszlenart pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/struts-intellij-plugin.git
commit 8bb4fd35e2c46a7bb03c17fd264b31a883d98734
Author: Yuriy Artamonov <yu...@jetbrains.com>
AuthorDate: Sun May 7 19:22:23 2023 +0200
Struts 2 moved to obsolete plugins
---
.gitignore | 42 +
LICENSE.TXT | 176 +++
build.gradle.kts | 58 +
gradle.properties | 3 +
gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 60756 bytes
gradle/wrapper/gradle-wrapper.properties | 5 +
gradlew | 234 ++++
gradlew.bat | 89 ++
settings.gradle.kts | 8 +
src/main/gen/OgnlIcons.java | 18 +
src/main/gen/OgnlTypes.java | 183 +++
src/main/gen/lexer/_OgnlLexer.java | 1287 ++++++++++++++++++++
src/main/gen/parser/OgnlParser.java | 1006 +++++++++++++++
src/main/gen/psi/OgnlBinaryExpression.java | 35 +
src/main/gen/psi/OgnlConditionalExpression.java | 35 +
src/main/gen/psi/OgnlExpression.java | 30 +
src/main/gen/psi/OgnlFqnTypeExpression.java | 26 +
src/main/gen/psi/OgnlIndexedExpression.java | 32 +
src/main/gen/psi/OgnlLambdaExpression.java | 29 +
src/main/gen/psi/OgnlLiteralExpression.java | 29 +
src/main/gen/psi/OgnlMapEntryElement.java | 32 +
src/main/gen/psi/OgnlMapExpression.java | 32 +
src/main/gen/psi/OgnlMethodCallExpression.java | 32 +
src/main/gen/psi/OgnlNewArrayExpression.java | 32 +
src/main/gen/psi/OgnlNewExpression.java | 32 +
src/main/gen/psi/OgnlParameterList.java | 31 +
src/main/gen/psi/OgnlParenthesizedExpression.java | 29 +
src/main/gen/psi/OgnlProjectionExpression.java | 29 +
src/main/gen/psi/OgnlReferenceExpression.java | 29 +
src/main/gen/psi/OgnlSelectionExpression.java | 29 +
src/main/gen/psi/OgnlSequenceExpression.java | 29 +
src/main/gen/psi/OgnlUnaryExpression.java | 32 +
.../gen/psi/OgnlVariableAssignmentExpression.java | 32 +
src/main/gen/psi/OgnlVariableExpression.java | 26 +
src/main/gen/psi/OgnlVisitor.java | 113 ++
.../gen/psi/impl/OgnlBinaryExpressionImpl.java | 63 +
.../psi/impl/OgnlConditionalExpressionImpl.java | 65 +
src/main/gen/psi/impl/OgnlExpressionImpl.java | 50 +
.../gen/psi/impl/OgnlFqnTypeExpressionImpl.java | 44 +
.../gen/psi/impl/OgnlIndexedExpressionImpl.java | 58 +
.../gen/psi/impl/OgnlLambdaExpressionImpl.java | 50 +
.../gen/psi/impl/OgnlLiteralExpressionImpl.java | 49 +
src/main/gen/psi/impl/OgnlMapEntryElementImpl.java | 58 +
src/main/gen/psi/impl/OgnlMapExpressionImpl.java | 56 +
.../gen/psi/impl/OgnlMethodCallExpressionImpl.java | 56 +
.../gen/psi/impl/OgnlNewArrayExpressionImpl.java | 58 +
src/main/gen/psi/impl/OgnlNewExpressionImpl.java | 56 +
src/main/gen/psi/impl/OgnlParameterListImpl.java | 54 +
.../psi/impl/OgnlParenthesizedExpressionImpl.java | 50 +
.../gen/psi/impl/OgnlProjectionExpressionImpl.java | 50 +
.../gen/psi/impl/OgnlReferenceExpressionImpl.java | 50 +
.../gen/psi/impl/OgnlSelectionExpressionImpl.java | 50 +
.../gen/psi/impl/OgnlSequenceExpressionImpl.java | 50 +
src/main/gen/psi/impl/OgnlUnaryExpressionImpl.java | 55 +
.../impl/OgnlVariableAssignmentExpressionImpl.java | 55 +
.../gen/psi/impl/OgnlVariableExpressionImpl.java | 44 +
src/main/grammar/apache2.txt | 17 +
src/main/grammar/ognl.bnf | 317 +++++
.../com/intellij/struts2/Struts2IconProvider.java | 89 ++
.../java/com/intellij/struts2/Struts2Icons.java | 20 +
.../struts2/Struts2PresentationProvider.java | 150 +++
.../struts2/Struts2ProblemFileHighlightFilter.java | 82 ++
.../intellij/struts2/Struts2ResourceProvider.java | 99 ++
.../Struts2ValidationPresentationProvider.java | 70 ++
.../java/com/intellij/struts2/StrutsBundle.java | 46 +
.../java/com/intellij/struts2/StrutsConstants.java | 277 +++++
.../StrutsFileTemplateGroupDescriptorFactory.java | 83 ++
.../struts2/StrutsFileTemplateProvider.java | 67 +
.../java/com/intellij/struts2/StrutsIcons.java | 112 ++
.../actions/create/CreateStrutsXmlAction.java | 72 ++
.../struts2/annotators/ActionAnnotatorBase.java | 230 ++++
.../struts2/annotators/ActionJavaAnnotator.java | 64 +
.../annotators/DomElementListCellRenderer.java | 97 ++
.../struts2/annotators/JspActionAnnotator.java | 149 +++
.../StrutsConventionImplicitUsageProvider.java | 104 ++
.../annotators/StrutsFileSetCheckingAnnotator.java | 216 ++++
.../intellij/struts2/annotators/package-info.java | 19 +
.../struts2/dom/BeanPropertyPathConverterBase.java | 90 ++
.../com/intellij/struts2/dom/ConverterUtil.java | 95 ++
.../struts2/dom/ExtendableClassConverter.java | 91 ++
.../intellij/struts2/dom/StrutsDomConstants.java | 47 +
.../dom/inspection/Struts2ModelInspection.java | 198 +++
.../inspection/Struts2ModelInspectionVisitor.java | 150 +++
.../dom/inspection/Struts2ModelValidator.java | 86 ++
.../struts2/dom/inspection/ValidatorBase.java | 52 +
.../inspection/ValidatorConfigModelInspection.java | 44 +
.../dom/inspection/ValidatorModelInspection.java | 46 +
.../dom/inspection/ValidatorModelValidator.java | 104 ++
.../struts2/dom/inspection/package-info.java | 19 +
.../com/intellij/struts2/dom/params/Param.java | 38 +
.../struts2/dom/params/ParamNameConverter.java | 49 +
.../struts2/dom/params/ParamNameConverterImpl.java | 62 +
.../struts2/dom/params/ParamValueConverter.java | 56 +
.../dom/params/ParamValueConvertersRegistry.java | 39 +
.../intellij/struts2/dom/params/ParamsElement.java | 45 +
...erceptorRefInStackParamNameCustomConverter.java | 148 +++
.../custom/ResultParamNameCustomConverter.java | 130 ++
.../java/com/intellij/struts2/dom/struts/Bean.java | 54 +
.../com/intellij/struts2/dom/struts/BeanScope.java | 46 +
.../intellij/struts2/dom/struts/HasResultType.java | 47 +
.../com/intellij/struts2/dom/struts/Include.java | 40 +
.../dom/struts/IncludeFileResolvingConverter.java | 68 ++
.../dom/struts/Struts2DomFileDescription.java | 48 +
.../intellij/struts2/dom/struts/StrutsRoot.java | 65 +
.../struts2/dom/struts/UnknownHandlerRef.java | 34 +
.../dom/struts/UnknownHandlerRefConverter.java | 45 +
.../struts2/dom/struts/UnknownHandlerStack.java | 32 +
.../intellij/struts2/dom/struts/action/Action.java | 151 +++
.../dom/struts/action/ActionMethodConverter.java | 88 ++
.../action/ActionNameCustomReferenceConverter.java | 106 ++
.../dom/struts/action/AllowedMethodsConverter.java | 83 ++
.../struts/action/CreateActionMethodQuickFix.java | 94 ++
.../dom/struts/action/ExceptionMapping.java | 42 +
.../ExceptionMappingResultResolveConverter.java | 83 ++
.../intellij/struts2/dom/struts/action/Result.java | 61 +
.../action/ResultTypeResolvingConverter.java | 41 +
.../action/StrutsPathReferenceConverter.java | 24 +
.../struts2/dom/struts/constant/Constant.java | 40 +
.../dom/struts/constant/ConstantNameConverter.java | 27 +
.../struts/constant/ConstantNameConverterImpl.java | 48 +
.../struts/constant/ConstantValueConverter.java | 26 +
.../constant/ConstantValueConverterImpl.java | 49 +
.../struts2/dom/struts/constant/package-info.java | 4 +
.../struts2/dom/struts/impl/ActionImpl.java | 135 ++
.../struts2/dom/struts/impl/ActionImplUtil.java | 148 +++
.../DefaultInterceptorRefResolveConverterImpl.java | 87 ++
.../struts/impl/ExtendableClassConverterImpl.java | 127 ++
.../struts2/dom/struts/impl/GlobalResultImpl.java | 48 +
.../impl/IncludeFileResolvingConverterImpl.java | 132 ++
.../struts2/dom/struts/impl/InterceptorImpl.java | 33 +
.../dom/struts/impl/InterceptorRefImpl.java | 38 +
.../impl/InterceptorRefResolveConverterImpl.java | 87 ++
.../dom/struts/impl/InterceptorStackImpl.java | 25 +
.../struts2/dom/struts/impl/ResultImpl.java | 55 +
.../struts2/dom/struts/impl/ResultTypeImpl.java | 31 +
.../impl/ResultTypeResolvingConverterImpl.java | 83 ++
.../StrutsPackageExtendsResolveConverterImpl.java | 93 ++
.../struts2/dom/struts/impl/StrutsPackageImpl.java | 108 ++
.../impl/UnknownHandlerRefConverterImpl.java | 82 ++
.../struts2/dom/struts/impl/package-info.java | 19 +
.../ActionChainOrRedirectResultContributor.java | 155 +++
.../impl/path/ActionPathResultContributor.java | 190 +++
.../impl/path/DispatchPathResultContributor.java | 71 ++
.../struts/impl/path/FileReferenceSetHelper.java | 117 ++
.../dom/struts/impl/path/ResultTypeResolver.java | 82 ++
.../path/StrutsPathReferenceConverterImpl.java | 67 +
.../struts/impl/path/StrutsResultContributor.java | 140 +++
.../struts2/dom/struts/impl/path/package-info.java | 19 +
.../struts2/dom/struts/model/StrutsManager.java | 96 ++
.../dom/struts/model/StrutsManagerImpl.java | 87 ++
.../struts2/dom/struts/model/StrutsModel.java | 100 ++
.../dom/struts/model/StrutsModelFactory.java | 94 ++
.../struts2/dom/struts/model/StrutsModelImpl.java | 142 +++
.../struts2/dom/struts/model/package-info.java | 19 +
.../intellij/struts2/dom/struts/package-info.java | 19 +
.../dom/struts/strutspackage/DefaultActionRef.java | 39 +
.../dom/struts/strutspackage/DefaultClassRef.java | 38 +
.../strutspackage/DefaultInterceptorRef.java | 35 +
.../DefaultInterceptorRefResolveConverter.java | 42 +
.../strutspackage/GlobalExceptionMapping.java | 44 +
...obalExceptionMappingResultResolveConverter.java | 73 ++
.../strutspackage/GlobalExceptionMappings.java | 33 +
.../dom/struts/strutspackage/GlobalResult.java | 45 +
.../dom/struts/strutspackage/GlobalResults.java | 35 +
.../dom/struts/strutspackage/Interceptor.java | 37 +
.../strutspackage/InterceptorOrStackBase.java | 33 +
.../dom/struts/strutspackage/InterceptorRef.java | 35 +
.../InterceptorRefResolveConverter.java | 43 +
.../dom/struts/strutspackage/InterceptorStack.java | 36 +
.../dom/struts/strutspackage/Interceptors.java | 37 +
.../dom/struts/strutspackage/ResultType.java | 50 +
.../dom/struts/strutspackage/ResultTypes.java | 38 +
.../dom/struts/strutspackage/StrutsPackage.java | 131 ++
.../StrutsPackageExtendsResolveConverter.java | 44 +
.../StrutsPackageHierarchyWalker.java | 59 +
.../StrutsPackageWithinPackageScopeProvider.java | 36 +
.../com/intellij/struts2/dom/validator/Field.java | 48 +
.../struts2/dom/validator/FieldNameConverter.java | 27 +
.../struts2/dom/validator/FieldValidator.java | 49 +
.../intellij/struts2/dom/validator/Message.java | 42 +
.../intellij/struts2/dom/validator/Validator.java | 42 +
.../ValidatorConfigDomFileDescription.java | 49 +
.../dom/validator/ValidatorDomFileDescription.java | 47 +
.../struts2/dom/validator/ValidatorManager.java | 88 ++
.../dom/validator/ValidatorManagerImpl.java | 195 +++
.../intellij/struts2/dom/validator/Validators.java | 49 +
.../dom/validator/config/ValidatorConfig.java | 41 +
.../config/ValidatorConfigResolveConverter.java | 39 +
.../dom/validator/config/ValidatorsConfig.java | 40 +
.../dom/validator/impl/FieldNameConverterImpl.java | 71 ++
.../dom/validator/impl/FieldValidatorImpl.java | 34 +
.../impl/ValidatorConfigResolveConverterImpl.java | 59 +
.../struts2/dom/validator/impl/ValidatorImpl.java | 32 +
.../struts2/dom/validator/package-info.java | 19 +
.../intellij/struts2/facet/Struts2LibraryType.java | 49 +
.../com/intellij/struts2/facet/StrutsFacet.java | 81 ++
.../struts2/facet/StrutsFacetConfiguration.java | 159 +++
.../StrutsFacetLibrariesValidatorDescription.java | 54 +
.../intellij/struts2/facet/StrutsFacetType.java | 71 ++
.../struts2/facet/StrutsFrameworkDetector.java | 68 ++
.../facet/StrutsFrameworkSupportProvider.java | 223 ++++
.../com/intellij/struts2/facet/package-info.java | 4 +
.../java/com/intellij/struts2/facet/struts2.xml | 31 +
.../struts2/facet/ui/FeaturesConfigurationTab.form | 44 +
.../struts2/facet/ui/FeaturesConfigurationTab.java | 72 ++
.../struts2/facet/ui/FileSetConfigurationTab.form | 21 +
.../struts2/facet/ui/FileSetConfigurationTab.java | 446 +++++++
.../intellij/struts2/facet/ui/FileSetEditor.form | 43 +
.../intellij/struts2/facet/ui/FileSetEditor.java | 178 +++
.../struts2/facet/ui/StrutsConfigsSearcher.java | 51 +
.../intellij/struts2/facet/ui/StrutsFileSet.java | 170 +++
.../intellij/struts2/facet/ui/StrutsFilesTree.java | 83 ++
.../struts2/facet/ui/StrutsVersionDetector.java | 79 ++
.../intellij/struts2/facet/ui/package-info.java | 4 +
.../FreeMarkerCssInlineStyleInjector.java | 73 ++
.../freemarker/FreeMarkerJavaScriptInjector.java | 73 ++
.../struts2/freemarker/FreeMarkerOgnlInjector.java | 82 ++
.../FreeMarkerStrutsResultContributor.java | 72 ++
.../freemarker/FreemarkerInjectionConstants.java | 45 +
.../freemarker/Struts2GlobalVariableProvider.java | 175 +++
.../intellij/struts2/freemarker/package-info.java | 4 +
.../gotosymbol/GoToActionSymbolProvider.java | 81 ++
.../gotosymbol/GoToPackageSymbolProvider.java | 90 ++
.../gotosymbol/GotoRelatedActionProvider.java | 107 ++
.../intellij/struts2/gotosymbol/package-info.java | 19 +
.../intellij/struts2/graph/StrutsDataModel.java | 207 ++++
.../intellij/struts2/graph/StrutsNodeRenderer.java | 45 +
.../struts2/graph/StrutsPresentationModel.java | 168 +++
.../intellij/struts2/graph/beans/ActionNode.java | 41 +
.../struts2/graph/beans/BasicStrutsEdge.java | 82 ++
.../struts2/graph/beans/BasicStrutsNode.java | 82 ++
.../intellij/struts2/graph/beans/ResultNode.java | 59 +
.../graph/fileEditor/Struts2GraphComponent.java | 161 +++
.../graph/fileEditor/Struts2GraphFileEditor.java | 123 ++
.../fileEditor/Struts2GraphFileEditorProvider.java | 91 ++
.../com/intellij/struts2/graph/package-info.java | 19 +
.../struts2/groovy/ActionGroovyAnnotator.java | 55 +
.../code/CreateValidationXmlIntention.java | 236 ++++
.../struts2/jsp/TaglibCssInlineStyleInjector.java | 77 ++
.../struts2/jsp/TaglibJavaScriptInjector.java | 117 ++
.../intellij/struts2/jsp/TaglibOgnlInjector.java | 110 ++
.../inspection/HardcodedActionUrlInspection.java | 299 +++++
...gnlStruts2JspVariableReferencesContributor.java | 58 +
.../ConstantValueConverterClassContributor.java | 34 +
.../struts2/model/constant/StrutsConstant.java | 53 +
.../model/constant/StrutsConstantContributor.java | 47 +
.../model/constant/StrutsConstantHelper.java | 86 ++
.../struts2/model/constant/StrutsConstantKey.java | 51 +
.../model/constant/StrutsConstantManager.java | 78 ++
.../model/constant/StrutsConstantManagerImpl.java | 276 +++++
.../contributor/ConstantValueClassConverter.java | 120 ++
.../DelimitedStringValuesConverter.java | 64 +
.../constant/contributor/ResultTypeConverter.java | 95 ++
.../contributor/StringValuesConverter.java | 49 +
.../contributor/StrutsConstantContributorBase.java | 98 ++
.../StrutsConventionPluginConstantContributor.java | 72 ++
.../contributor/StrutsCoreConstantContributor.java | 150 +++
.../StrutsOSGiPluginConstantContributor.java | 51 +
.../contributor/StrutsPackageConverter.java | 74 ++
.../StrutsRESTPluginConstantContributor.java | 59 +
.../StrutsSpringPluginConstantContributor.java | 57 +
.../intellij/struts2/model/jam/StrutsJamUtils.java | 51 +
.../struts2/model/jam/StrutsSemContributor.java | 64 +
.../InterceptorJamReferenceConverter.java | 77 ++
.../jam/convention/JamDefaultInterceptorRef.java | 66 +
.../model/jam/convention/JamInterceptorRef.java | 93 ++
.../model/jam/convention/JamParentPackage.java | 116 ++
.../model/jam/convention/JamResultPath.java | 170 +++
.../jam/convention/StrutsConventionConstants.java | 35 +
.../struts2/model/jam/convention/package-info.java | 4 +
.../intellij/struts2/model/jam/package-info.java | 4 +
.../java/com/intellij/struts2/ognl/OgnlFile.java | 43 +
.../com/intellij/struts2/ognl/OgnlFileType.java | 66 +
.../com/intellij/struts2/ognl/OgnlLanguage.java | 52 +
.../struts2/ognl/OgnlLanguageInjector.java | 100 ++
.../struts2/ognl/OgnlParserDefinition.java | 94 ++
.../intellij/struts2/ognl/OgnlTypedHandler.java | 106 ++
.../OgnlKeywordCompletionContributor.java | 143 +++
.../struts2/ognl/formatting/OgnlBlock.java | 115 ++
.../formatting/OgnlFormattingModelBuilder.java | 72 ++
.../struts2/ognl/highlight/OgnlBraceMatcher.java | 53 +
.../ognl/highlight/OgnlColorSettingsPage.java | 98 ++
.../struts2/ognl/highlight/OgnlHighlighter.java | 141 +++
.../ognl/highlight/OgnlHighlightingAnnotator.java | 33 +
.../ognl/highlight/OgnlHighlightingLexer.java | 48 +
.../struts2/ognl/highlight/OgnlQuoteHandler.java | 29 +
.../com/intellij/struts2/ognl/lexer/OgnlLexer.java | 34 +
.../intellij/struts2/ognl/lexer/_OgnlLexer.flex | 192 +++
.../com/intellij/struts2/ognl/package-info.java | 21 +
.../com/intellij/struts2/ognl/psi/OgnlKeyword.java | 52 +
.../struts2/ognl/psi/OgnlPsiCompositeElement.java | 24 +
.../intellij/struts2/ognl/psi/OgnlTokenGroups.java | 69 ++
.../intellij/struts2/ognl/psi/OgnlTokenType.java | 29 +
.../ognl/psi/impl/OgnlFqnTypeExpressionBase.java | 58 +
.../ognl/psi/impl/OgnlPsiCompositeElementBase.java | 36 +
.../struts2/ognl/psi/impl/OgnlPsiUtil.java | 183 +++
.../ognl/psi/impl/OgnlReferenceExpressionBase.java | 79 ++
.../ognl/psi/impl/OgnlVariableExpressionBase.java | 83 ++
.../OgnlFqnTypeExpressionManipulator.java | 48 +
.../struts2/ognl/psi/resolve/OgnlResolveUtil.java | 41 +
.../OgnlDefaultVariableReferencesContributor.java | 53 +
.../resolve/variable/OgnlVariableReference.java | 17 +
.../OgnlVariableReferencesContributor.java | 32 +
.../spellchecker/OgnlSpellcheckingStrategy.java | 42 +
.../ognl/template/OgnlTemplateContextType.java | 52 +
.../java/com/intellij/struts2/package-info.java | 19 +
.../struts2/preview/Struts2UrlConverter.java | 57 +
.../ResultActionPropertyReferenceProvider.java | 110 ++
.../StaticStringValuesReferenceProvider.java | 81 ++
.../StrutsBootstrapTaglibReferenceContributor.java | 47 +
...trutsJQueryChartTaglibReferenceContributor.java | 65 +
...StrutsJQueryGridTaglibReferenceContributor.java | 87 ++
...rutsJQueryMobileTaglibReferenceContributor.java | 88 ++
...tsJQueryRichtextTaglibReferenceContributor.java | 88 ++
.../StrutsJQueryTaglibReferenceContributor.java | 200 +++
...StrutsJQueryTaglibReferenceContributorBase.java | 128 ++
...StrutsJQueryTreeTaglibReferenceContributor.java | 53 +
.../reference/StrutsReferenceContributor.java | 106 ++
.../StrutsTaglibReferenceContributorBase.java | 186 +++
.../StrutsUITaglibReferenceContributor.java | 252 ++++
.../com/intellij/struts2/reference/TaglibUtil.java | 66 +
.../WrappedPropertiesReferenceProvider.java | 49 +
.../common/BeanPropertyPathReference.java | 164 +++
.../common/BeanPropertyPathReferenceSet.java | 80 ++
.../reference/jsp/ActionLinkReferenceProvider.java | 264 ++++
.../jsp/ActionMethodReferenceProvider.java | 133 ++
.../jsp/ActionPropertyReferenceProvider.java | 113 ++
.../reference/jsp/ActionReferenceInjector.java | 58 +
.../reference/jsp/ActionReferenceProvider.java | 182 +++
.../reference/jsp/NamespaceReferenceProvider.java | 104 ++
.../reference/jsp/ThemeReferenceProvider.java | 60 +
.../intellij/struts2/reference/package-info.java | 4 +
.../web/StrutsConstantValueReference.java | 180 +++
.../WebXmlStrutsConstantNameReferenceProvider.java | 72 ++
...WebXmlStrutsConstantValueReferenceProvider.java | 37 +
.../struts2/reference/web/package-info.java | 4 +
.../Struts2BundledDictionaryProvider.java | 32 +
.../com/intellij/struts2/spellchecker/struts2.dic | 48 +
...nstantValueConverterSpringClassContributor.java | 58 +
.../ExtendableClassConverterSpringContributor.java | 165 +++
.../BaseStructureViewBuilderProvider.java | 83 ++
.../structure/StructureViewTreeElement.java | 113 ++
.../struts2/structure/StructureViewTreeModel.java | 125 ++
.../StrutsStructureViewBuilderProvider.java | 53 +
.../structure/StrutsTreeDescriptionProvider.java | 70 ++
.../ValidationStructureViewBuilderProvider.java | 52 +
.../intellij/struts2/structure/package-info.java | 19 +
.../velocity/Struts2GlobalMacroProvider.java | 60 +
.../velocity/Struts2GlobalVariableProvider.java | 82 ++
.../velocity/VelocityStrutsResultContributor.java | 74 ++
src/main/resources/META-INF/ognl.xml | 41 +
src/main/resources/META-INF/plugin.xml | 258 ++++
src/main/resources/META-INF/struts2-freemarker.xml | 24 +
src/main/resources/META-INF/struts2-groovy.xml | 20 +
src/main/resources/META-INF/struts2-spring.xml | 10 +
src/main/resources/META-INF/struts2-velocity.xml | 22 +
.../resources/fileTemplates/j2ee/struts.xml.ft | 8 +
.../resources/fileTemplates/j2ee/struts.xml.html | 7 +
.../resources/fileTemplates/j2ee/struts_2_1.xml.ft | 8 +
.../fileTemplates/j2ee/struts_2_1.xml.html | 7 +
.../fileTemplates/j2ee/struts_2_1_7.xml.ft | 8 +
.../fileTemplates/j2ee/struts_2_1_7.xml.html | 7 +
.../resources/fileTemplates/j2ee/struts_2_3.xml.ft | 8 +
.../fileTemplates/j2ee/struts_2_3.xml.html | 7 +
.../resources/fileTemplates/j2ee/struts_2_5.xml.ft | 8 +
.../fileTemplates/j2ee/struts_2_5.xml.html | 7 +
.../resources/fileTemplates/j2ee/validator.xml.ft | 8 +
.../fileTemplates/j2ee/validator.xml.html | 7 +
src/main/resources/icons/action.svg | 14 +
src/main/resources/icons/action_small.svg | 14 +
src/main/resources/icons/edit_small.svg | 6 +
.../inspectionDescriptions/HardcodedActionUrl.html | 17 +
.../Struts2ModelInspection.html | 5 +
.../ValidatorConfigModelInspection.html | 5 +
.../ValidatorModelInspection.html | 5 +
.../after.java.template | 7 +
.../before.java.template | 7 +
.../CreateValidationXmlIntention/description.html | 6 +
src/main/resources/liveTemplates/ognl-struts2.xml | 8 +
src/main/resources/liveTemplates/ognl.xml | 19 +
.../resources/messages/Struts2Bundle.properties | 80 ++
src/main/resources/resources/dtds/struts-2.0.dtd | 140 +++
src/main/resources/resources/dtds/struts-2.1.7.dtd | 141 +++
src/main/resources/resources/dtds/struts-2.1.dtd | 145 +++
src/main/resources/resources/dtds/struts-2.3.dtd | 152 +++
src/main/resources/resources/dtds/struts-2.5.dtd | 153 +++
.../resources/dtds/xwork-validator-1.0.2.dtd | 42 +
.../resources/dtds/xwork-validator-1.0.3.dtd | 44 +
.../resources/dtds/xwork-validator-1.0.dtd | 42 +
.../resources/dtds/xwork-validator-config-1.0.dtd | 19 +
.../dtds/xwork-validator-config-struts-1.0.dtd | 19 +
.../dtds/xwork-validator-definition-1.0.dtd | 21 +
.../dtds/xwork-validator-struts-1.0.2.dtd | 44 +
.../resources/dtds/xwork-validator-struts-1.0.dtd | 42 +
.../lang/ognl/OgnlCodeInsightSanityTest.java | 105 ++
.../java/com/intellij/lang/ognl/OgnlTestUtils.java | 40 +
.../intellij/lang/ognl/OgnlTypedHandlerTest.java | 46 +
.../ognl/completion/OgnlCompletionTestCase.java | 40 +
.../OgnlFqnTypeExpressionCompletionTest.java | 80 ++
.../ognl/completion/OgnlKeywordCompletionTest.java | 77 ++
.../OgnlVariableExpressionCompletionTest.java | 28 +
.../lang/ognl/formatting/OgnlFormattingTest.java | 109 ++
.../ognl/highlight/OgnlHighlightingLexerTest.java | 47 +
.../intellij/lang/ognl/lexer/OgnlLexerTest.java | 57 +
.../parsing/ConditionalExpressionParsingTest.java | 38 +
.../ognl/parsing/ExpressionHolderParsingTest.java | 35 +
.../ognl/parsing/IndexedExpressionParsingTest.java | 46 +
.../ognl/parsing/LambdaExpressionParsingTest.java | 39 +
.../ognl/parsing/MapExpressionParsingTest.java | 46 +
.../parsing/MethodCallExpressionParsingTest.java | 43 +
.../parsing/NewArrayExpressionParsingTest.java | 41 +
.../ognl/parsing/NewExpressionParsingTest.java | 44 +
.../lang/ognl/parsing/OgnlParsingTestCase.java | 42 +
.../ParenthesizedExpressionParsingTest.java | 35 +
.../ProjectionSelectionExpressionParsingTest.java | 34 +
.../parsing/SequenceExpressionParsingTest.java | 39 +
.../ognl/parsing/UnaryExpressionParsingTest.java | 39 +
.../VariableAssignmentExpressionParsingTest.java | 31 +
.../parsing/VariableExpressionParsingTest.java | 31 +
.../ognl/psi/ConditionalExpressionPsiTest.java | 83 ++
.../lang/ognl/psi/IndexedExpressionPsiTest.java | 92 ++
.../lang/ognl/psi/LambdaExpressionPsiTest.java | 49 +
.../lang/ognl/psi/LiteralExpressionPsiTest.java | 132 ++
.../lang/ognl/psi/MapExpressionPsiTest.java | 86 ++
.../lang/ognl/psi/MethodCallExpressionPsiTest.java | 94 ++
.../lang/ognl/psi/NewArrayExpressionPsiTest.java | 65 +
.../lang/ognl/psi/NewExpressionPsiTest.java | 71 ++
.../ognl/psi/ParenthesizedExpressionPsiTest.java | 92 ++
.../lang/ognl/psi/ProjectionExpressionPsiTest.java | 44 +
.../com/intellij/lang/ognl/psi/PsiTestCase.java | 78 ++
.../lang/ognl/psi/ReferenceExpressionPsiTest.java | 70 ++
.../lang/ognl/psi/SelectionExpressionPsiTest.java | 64 +
.../lang/ognl/psi/SequenceExpressionPsiTest.java | 63 +
.../lang/ognl/psi/UnaryExpressionPsiTest.java | 81 ++
.../psi/VariableAssignmentExpressionPsiTest.java | 44 +
.../lang/ognl/psi/VariableExpressionPsiTest.java | 94 ++
.../ArithmeticBinaryExpressionPsiTest.java | 46 +
.../BinaryExpressionPsiTestCase.java | 77 ++
.../BitwiseBooleanBinaryExpressionPsiTest.java | 48 +
.../BitwiseShiftBinaryExpressionPsiTest.java | 48 +
.../BooleanBinaryExpressionPsiTest.java | 49 +
.../ComparisonBinaryExpressionPsiTest.java | 57 +
.../EqualityBinaryExpressionPsiTest.java | 40 +
.../InNotInBinaryExpressionPsiTest.java | 38 +
.../InstanceOfBinaryExpressionPsiTest.java | 31 +
.../lang/ognl/template/OgnlLiveTemplatesTest.java | 52 +
.../struts2/BasicLightHighlightingTestCase.java | 175 +++
.../struts2/Struts2ProjectDescriptorBuilder.java | 175 +++
.../annotators/ActionJavaAnnotatorTest.java | 75 ++
.../struts2/annotators/AnnotatorTestUtils.java | 66 +
.../struts2/annotators/JspActionAnnotatorTest.java | 65 +
.../StrutsConventionImplicitUsageProviderTest.java | 116 ++
.../StrutsFileSetCheckingAnnotatorTest.java | 51 +
.../java/com/intellij/struts2/dom/DomStubTest.java | 93 ++
.../intellij/struts2/dom/StrutsDomStubTest.java | 52 +
.../struts2/dom/struts/StrutsCompletionTest.java | 93 ++
.../dom/struts/StrutsHighlightingSpringTest.java | 144 +++
.../struts2/dom/struts/StrutsHighlightingTest.java | 84 ++
.../struts2/dom/struts/StrutsIncludeTest.java | 43 +
.../struts2/dom/struts/StrutsIntentionTest.java | 52 +
.../struts/StrutsLightHighlightingTestCase.java | 56 +
.../dom/struts/StrutsResultResolvingTest.java | 137 +++
.../dom/struts/impl/ActionImplUtilTest.java | 70 ++
.../validator/ValidationFieldCompletionTest.java | 36 +
...ValidationFieldValidatorTypeCompletionTest.java | 37 +
.../dom/validator/ValidationHighlightingTest.java | 37 +
.../ValidationLightHighlightingTestCase.java | 55 +
.../validator/ValidatorConfigHighlightingTest.java | 40 +
.../facet/ui/StrutsConfigsSearcherTest.java | 53 +
.../facet/ui/StrutsVersionDetectorTest.java | 38 +
.../freemarker/FreemarkerIntegrationTest.java | 51 +
.../struts2/gotosymbol/GoToSymbolProviderTest.java | 88 ++
.../HardcodedActionUrlInspectionTest.java | 95 ++
.../struts2/jsp/ognl/Struts2OgnlJspTest.java | 57 +
.../StrutsConstantManagerNoCustomTest.java | 66 +
.../constant/StrutsConstantManagerTestCase.java | 47 +
...rutsConstantManagerWithStrutsPluginXmlTest.java | 72 ++
...utsConstantManagerWithStrutsPropertiesTest.java | 48 +
.../StrutsConstantManagerWithWebXmlTest.java | 52 +
.../jam/convention/JamConventionLightTestCase.java | 99 ++
.../convention/JamDefaultInterceptorRefTest.java | 57 +
.../jam/convention/JamInterceptorRefTest.java | 54 +
.../model/jam/convention/JamParentPackageTest.java | 65 +
.../model/jam/convention/JamResultPathTest.java | 81 ++
.../intellij/struts2/reference/TaglibUtilTest.java | 45 +
.../jsp/ActionLinkReferenceProviderTest.java | 99 ++
.../jsp/ActionPropertyReferenceProviderTest.java | 59 +
.../reference/jsp/ActionReferenceProviderTest.java | 79 ++
.../jsp/NamespaceReferenceProviderTest.java | 51 +
.../jsp/UITagsAttributesReferenceProviderTest.java | 63 +
.../reference/struts/ResultActionPropertyTest.java | 36 +
.../struts2/reference/web/WebXmlConstantTest.java | 85 ++
.../struts2/structure/StrutsStructureViewTest.java | 70 ++
.../structure/ValidationStructureViewTest.java | 67 +
src/test/testData/configsSearcher/struts.xml | 9 +
.../MacroParametersResolveOnlyToParameters.ftl | 1 +
src/test/testData/freemarker/MyTestAction.java | 4 +
.../freemarker/StrutsActionToplevel-struts.xml | 37 +
.../testData/freemarker/StrutsActionToplevel.ftl | 2 +
.../testData/freemarker/StrutsCommonVariables.ftl | 9 +
.../testData/gutterJava/actionClass/MyAction.java | 7 +
.../com/MyValidationAction-validation.xml | 13 +
.../actionClass/com/MyValidationAction.java | 19 +
.../struts-actionClass-multiple_mappings.xml | 23 +
.../gutterJava/actionClass/struts-actionClass.xml | 15 +
.../gutterJava/actionClass/struts-validation.xml | 16 +
.../testData/gutterJsp/actionClass/MyAction.java | 7 +
.../jsp/test_gutter_action_attribute.jsp | 3 +
.../actionClass/jsp/test_gutter_name_attribute.jsp | 3 +
.../gutterJsp/actionClass/struts-actionClass.xml | 15 +
.../hardcodedUrl/customActionExtension.jsp | 1 +
.../hardcodedUrl/customActionExtension_after.jsp | 2 +
.../jsp/inspection/hardcodedUrl/customTag.jsp | 2 +
.../inspection/hardcodedUrl/customTag_after.jsp | 4 +
.../jsp/inspection/hardcodedUrl/dynamic.jsp | 1 +
.../testData/jsp/inspection/hardcodedUrl/host.jsp | 1 +
.../jsp/inspection/hardcodedUrl/method.jsp | 1 +
.../jsp/inspection/hardcodedUrl/method_after.jsp | 2 +
.../jsp/inspection/hardcodedUrl/multiParams.jsp | 1 +
.../inspection/hardcodedUrl/multiParamsEscaped.jsp | 1 +
.../hardcodedUrl/multiParamsEscaped_after.jsp | 5 +
.../inspection/hardcodedUrl/multiParams_after.jsp | 5 +
.../jsp/inspection/hardcodedUrl/namespace.jsp | 1 +
.../inspection/hardcodedUrl/namespace_after.jsp | 2 +
.../jsp/inspection/hardcodedUrl/oneParam.jsp | 1 +
.../jsp/inspection/hardcodedUrl/oneParam_after.jsp | 4 +
.../jsp/inspection/hardcodedUrl/protocol.jsp | 1 +
.../jsp/inspection/hardcodedUrl/simple.jsp | 1 +
.../hardcodedUrl/simpleTaglibPrefixDefined.jsp | 2 +
.../simpleTaglibPrefixDefined_after.jsp | 2 +
.../jsp/inspection/hardcodedUrl/simple_after.jsp | 2 +
.../jsp/inspection/hardcodedUrl/struts.properties | 2 +
.../jsp/inspection/hardcodedUrl/struts.xml | 9 +
src/test/testData/jsp/ognl/WEB-INF/web.xml | 14 +
.../jsp/ognl/struts2-jsp-variables-completion.jsp | 3 +
.../testData/jsp/ognl/taglib-ognl-injection.jsp | 14 +
src/test/testData/lexer/nestedBraces.txt | 11 +
.../lexer/nestedBracesWithoutExpression.txt | 7 +
src/test/testData/lexer/nestedModuloAndCurly.txt | 7 +
src/test/testData/lexer/twoRightCurly.txt | 6 +
.../testData/model/constant/noCustom/dummy.xml | 0
.../testData/model/constant/noCustom/struts.xml | 9 +
.../model/constant/withPluginXml/struts.xml | 9 +
.../withStrutsProperties/struts.properties | 3 +
.../model/constant/withStrutsProperties/struts.xml | 13 +
.../model/constant/withWebXml/WEB-INF/web.xml | 23 +
.../testData/model/constant/withWebXml/struts.xml | 13 +
.../defaultInterceptorRef/jam/package-info.java | 2 +
.../convention/defaultInterceptorRef/struts.xml | 23 +
.../testcompletion/package-info.java | 2 +
.../interceptorRef/completion/ActionSingle.java | 8 +
.../interceptorRef/jam/ActionSingle.java | 8 +
.../model/jam/convention/interceptorRef/struts.xml | 23 +
.../jam/convention/parentPackage/jam/Action.java | 8 +
.../convention/parentPackage/jam/package-info.java | 2 +
.../model/jam/convention/parentPackage/struts.xml | 23 +
.../parentPackage/testcompletion/Action.java | 8 +
.../parentPackage/testcompletion/package-info.java | 2 +
.../resultPath/WEB-INF/customContent/test.jsp | 1 +
.../convention/resultPath/jam/ActionProperty.java | 8 +
.../jam/convention/resultPath/jam/ActionValue.java | 8 +
.../jam/convention/resultPath/struts.properties | 2 +
.../resultPath/testcompletion/ActionProperty.java | 8 +
.../psi/conditionalExpression/ColonMissing.ognl | 1 +
.../psi/conditionalExpression/ColonMissing.txt | 13 +
.../psi/conditionalExpression/ElseMissing.ognl | 1 +
.../psi/conditionalExpression/ElseMissing.txt | 15 +
.../psi/conditionalExpression/ThenMissing.ognl | 1 +
.../psi/conditionalExpression/ThenMissing.txt | 10 +
.../psi/expressionHolder/MissingClosingBrace.ognl | 1 +
.../psi/expressionHolder/MissingClosingBrace.txt | 7 +
.../psi/expressionHolder/NoExpression.ognl | 1 +
.../testData/psi/expressionHolder/NoExpression.txt | 5 +
.../psi/indexedExpression/AfterIdentifier.ognl | 1 +
.../psi/indexedExpression/AfterIdentifier.txt | 10 +
.../testData/psi/indexedExpression/AfterVar.ognl | 1 +
.../testData/psi/indexedExpression/AfterVar.txt | 11 +
.../AfterVarFollowedByProperty.ognl | 1 +
.../AfterVarFollowedByProperty.txt | 13 +
.../AfterVarFollowedBySelection.ognl | 1 +
.../AfterVarFollowedBySelection.txt | 18 +
.../MissingClosingRightBracket.ognl | 1 +
.../MissingClosingRightBracket.txt | 11 +
.../AfterBracketExpressionExpected.ognl | 1 +
.../AfterBracketExpressionExpected.txt | 8 +
.../AfterColonBracketExpected.ognl | 1 +
.../lambdaExpression/AfterColonBracketExpected.txt | 7 +
.../AfterExpressionClosingBracketExpected.ognl | 1 +
.../AfterExpressionClosingBracketExpected.txt | 12 +
.../psi/mapExpression/MissingColonAfterKey.ognl | 1 +
.../psi/mapExpression/MissingColonAfterKey.txt | 16 +
.../mapExpression/MissingKeyAfterFirstElement.ognl | 1 +
.../mapExpression/MissingKeyAfterFirstElement.txt | 22 +
.../mapExpression/MissingMapEntryAfterComma.ognl | 1 +
.../mapExpression/MissingMapEntryAfterComma.txt | 22 +
.../psi/mapExpression/MissingValueAfterColon.ognl | 1 +
.../psi/mapExpression/MissingValueAfterColon.txt | 18 +
.../testData/psi/mapExpression/NoMapEntries.ognl | 1 +
.../testData/psi/mapExpression/NoMapEntries.txt | 12 +
.../MissingClosingParenthesesNoParameter.ognl | 1 +
.../MissingClosingParenthesesNoParameter.txt | 11 +
.../MissingClosingParenthesesOneParameter.ognl | 1 +
.../MissingClosingParenthesesOneParameter.txt | 12 +
.../MissingClosingParenthesesTwoParameters.ognl | 1 +
.../MissingClosingParenthesesTwoParameters.txt | 15 +
.../MissingExpressionInParameters.ognl | 1 +
.../MissingExpressionInParameters.txt | 14 +
.../newArrayExpression/MissingArrayExpression.ognl | 1 +
.../newArrayExpression/MissingArrayExpression.txt | 11 +
.../MissingClosingRightBrace.ognl | 1 +
.../MissingClosingRightBrace.txt | 13 +
.../MissingSequenceClosingRightBrace.ognl | 1 +
.../MissingSequenceClosingRightBrace.txt | 21 +
.../psi/newExpression/ConstructorOrArray.ognl | 1 +
.../psi/newExpression/ConstructorOrArray.txt | 10 +
.../MissingClosingRightParenthesis.ognl | 1 +
.../MissingClosingRightParenthesis.txt | 14 +
.../psi/newExpression/MissingParameter.ognl | 1 +
.../psi/newExpression/MissingParameter.txt | 13 +
.../testData/psi/newExpression/TypeExpected.ognl | 1 +
.../testData/psi/newExpression/TypeExpected.txt | 7 +
.../MissingClosingRightParenthesis.ognl | 1 +
.../MissingClosingRightParenthesis.txt | 13 +
.../MissingClosingRightParenthesisNested.ognl | 1 +
.../MissingClosingRightParenthesisNested.txt | 23 +
.../ExpressionExpectedAfterSelectorType.ognl | 1 +
.../ExpressionExpectedAfterSelectorType.txt | 13 +
...rTypeOrExpressionExpectedAfterOpeningBrace.ognl | 1 +
...orTypeOrExpressionExpectedAfterOpeningBrace.txt | 10 +
.../ExpressionAfterCommaExpected.ognl | 1 +
.../ExpressionAfterCommaExpected.txt | 11 +
.../MissingClosingRightBrace.ognl | 1 +
.../MissingClosingRightBrace.txt | 11 +
.../SingleExpressionIsNotSequence.ognl | 1 +
.../SingleExpressionIsNotSequence.txt | 10 +
.../unaryExpression/MissingAfterBitwiseNegate.ognl | 1 +
.../unaryExpression/MissingAfterBitwiseNegate.txt | 7 +
.../unaryExpression/MissingAfterNotKeyword.ognl | 1 +
.../psi/unaryExpression/MissingAfterNotKeyword.txt | 7 +
.../UnaryNotOperatorBeforeVariable.ognl | 1 +
.../UnaryNotOperatorBeforeVariable.txt | 19 +
.../MissingExpression.ognl | 1 +
.../MissingExpression.txt | 11 +
.../MissingVariableIdentifier.ognl | 1 +
.../MissingVariableIdentifier.txt | 6 +
.../reference/jsp/action/ActionMethods.java | 11 +
.../action/jsp/action-completionvariants-bang.jsp | 3 +
.../jsp/action/jsp/action-completionvariants.jsp | 3 +
.../jsp/action-completionvariants_method.jsp | 4 +
.../jsp/action-completionvariants_namespace.jsp | 19 +
.../jsp/action/jsp/action-highlighting.jsp | 37 +
.../reference/jsp/action/struts-action.xml | 26 +
.../reference/jsp/actionLink/WEB-INF/web.xml | 14 +
...tionLink-completionvariants-namespace_given.jsp | 1 +
.../actionLink-completionvariants-no-namespace.jsp | 2 +
.../jsp/actionLink/jsp/actionLink-highlighting.jsp | 20 +
.../jsp/actionLink/jsp/actionLink-reference_1.jsp | 1 +
.../jsp/actionLink/jsp/actionLink-reference_2.jsp | 1 +
.../reference/jsp/actionLink/jsp/index.jsp | 0
.../reference/jsp/actionLink/struts-actionLink.xml | 19 +
.../reference/jsp/actionproperty/MyAction.java | 68 ++
...actionproperty-forminput-completionvariants.jsp | 6 +
.../jsp/actionproperty-forminput-highlighting.jsp | 74 ++
...perty-forminput-readonly-completionvariants.jsp | 6 +
.../jsp/actionproperty-param-highlighting.jsp | 33 +
.../jsp/actionproperty/struts-actionproperty.xml | 14 +
.../namespace/jsp/namespace-completionvariants.jsp | 3 +
.../jsp/namespace/jsp/namespace-highlighting.jsp | 12 +
.../reference/jsp/namespace/struts-namespace.xml | 18 +
.../reference/jsp/uitags/MyBundle.properties | 1 +
.../testData/reference/jsp/uitags/jsp/common.jsp | 48 +
.../testData/reference/jsp/uitags/jsp/paths.jsp | 13 +
.../testData/reference/jsp/uitags/jsp/specific.jsp | 88 ++
.../reference/web/constant/WEB-INF/web.xml | 68 ++
.../web/constant/WEB-INF/web_name_completion.xml | 19 +
.../web/constant/WEB-INF/web_value_completion.xml | 19 +
.../constant/WEB-INF/web_value_completion_2.xml | 19 +
src/test/testData/structure/struts-structure.xml | 23 +
.../testData/structure/validation-structure.xml | 22 +
.../testData/strutsXml/completion/ActionClass.java | 45 +
.../struts-completionvariants-action_method.xml | 14 +
.../struts-completionvariants-constant_name.xml | 12 +
...-completionvariants-interceptor-ref-extends.xml | 50 +
.../struts-completionvariants-interceptor-ref.xml | 24 +
.../struts-completionvariants-package_extends.xml | 20 +
.../struts-completionvariants-result_name.xml | 18 +
...ts-completionvariants-result_type-extending.xml | 40 +
.../struts-completionvariants-result_type.xml | 24 +
.../strutsXml/highlighting/MyAbstractClass.java | 1 +
.../testData/strutsXml/highlighting/MyClass.java | 54 +
.../strutsXml/highlighting/MyException.java | 2 +
.../strutsXml/highlighting/MyInterface.java | 2 +
.../strutsXml/highlighting/MyInterfaceImpl.java | 2 +
.../strutsXml/highlighting/MyNestedClass.java | 22 +
.../highlighting/struts-action-allowedMethods.xml | 26 +
.../strutsXml/highlighting/struts-constants.xml | 40 +
.../highlighting/struts-default-2_1_8.xml | 324 +++++
.../highlighting/struts-default-2_3_1.xml | 306 +++++
.../strutsXml/highlighting/struts-default.xml | 315 +++++
.../strutsXml/highlighting/struts-errors.xml | 14 +
.../highlighting/struts-exceptionmapping.xml | 108 ++
.../highlighting/struts-interceptor-ref.xml | 33 +
.../strutsXml/highlighting/struts-param.xml | 192 +++
.../strutsXml/highlighting/struts-simple.xml | 216 ++++
.../highlighting/struts-unknownhandlerstack.xml | 20 +
.../strutsXml/include/com/test/struts-sub.xml | 8 +
.../testData/strutsXml/include/struts-include.xml | 8 +
.../strutsXml/include/struts-notinfileset.xml | 16 +
src/test/testData/strutsXml/include/struts.xml | 20 +
.../testData/strutsXml/intentions/MyClass.java | 2 +
.../strutsXml/intentions/struts-action-method.xml | 15 +
src/test/testData/strutsXml/result/WEB-INF/web.xml | 8 +
src/test/testData/strutsXml/result/jsp/index.jsp | 1 +
.../testData/strutsXml/result/jsp2/jsp2-index.jsp | 1 +
.../strutsXml/result/struts-actionRedirect.xml | 61 +
.../strutsXml/result/struts-actionchain.xml | 81 ++
.../strutsXml/result/struts-actionpath-fq.xml | 54 +
.../strutsXml/result/struts-actionpath.xml | 86 ++
.../result/struts-completionvariants-chain.xml | 28 +
.../strutsXml/result/struts-completionvariants.xml | 44 +
.../strutsXml/result/struts-path-dispatcher.xml | 90 ++
.../strutsXml/result/struts-unknownResultType.xml | 38 +
.../resultActionProperty/ActionClass.java | 19 +
.../struts-resultActionProperty.xml | 42 +
.../testData/strutsXml/spring/MyAbstractClass.java | 1 +
src/test/testData/strutsXml/spring/MyClass.java | 7 +
.../testData/strutsXml/spring/MyInterface.java | 1 +
src/test/testData/strutsXml/spring/spring.xml | 19 +
.../spring/struts-completionvariants-spring.xml | 15 +
.../struts-completionvariants-subclass-spring.xml | 18 +
.../testData/strutsXml/spring/struts-spring.xml | 72 ++
src/test/testData/stubs/struts-stubs.xml | 21 +
.../completion/field/com/MyAction-validation.xml | 32 +
.../completion/field/com/MyAction.java | 39 +
.../src/com/MyAction-validation.xml | 32 +
.../fieldValidatorType/src/com/MyAction.java | 39 +
.../config/validator-config-default.xml | 21 +
.../config/validator-config-simple.xml | 18 +
.../highlighting/com/MyAction-validation.xml | 64 +
.../validationXml/highlighting/com/MyAction.java | 24 +
740 files changed, 41380 insertions(+)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b63da45
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,42 @@
+.gradle
+build/
+!gradle/wrapper/gradle-wrapper.jar
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### IntelliJ IDEA ###
+.idea/modules.xml
+.idea/jarRepositories.xml
+.idea/compiler.xml
+.idea/libraries/
+*.iws
+*.iml
+*.ipr
+out/
+!**/src/main/**/out/
+!**/src/test/**/out/
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+bin/
+!**/src/main/**/bin/
+!**/src/test/**/bin/
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store
\ No newline at end of file
diff --git a/LICENSE.TXT b/LICENSE.TXT
new file mode 100644
index 0000000..2bb9ad2
--- /dev/null
+++ b/LICENSE.TXT
@@ -0,0 +1,176 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
\ No newline at end of file
diff --git a/build.gradle.kts b/build.gradle.kts
new file mode 100644
index 0000000..0345203
--- /dev/null
+++ b/build.gradle.kts
@@ -0,0 +1,58 @@
+plugins {
+ id("java")
+ id("org.jetbrains.kotlin.jvm") version "1.8.21"
+ id("org.jetbrains.intellij") version "1.13.3"
+}
+
+group = "com.intellij"
+version = "2023.2"
+
+repositories {
+ mavenCentral()
+}
+
+java.sourceSets["main"].java {
+ srcDir("src/main/gen")
+}
+
+intellij {
+ version.set("2023.1.1")
+ type.set("IU") // Target IDE Platform
+
+ plugins.set(listOf(
+ "com.intellij.javaee",
+ "com.intellij.javaee.web",
+ "com.intellij.spring",
+ "com.intellij.freemarker",
+ "com.intellij.velocity",
+ "org.intellij.groovy",
+ "JavaScript",
+ "com.intellij.java-i18n"
+ ))
+}
+
+tasks {
+ // Set the JVM compatibility versions
+ withType<JavaCompile> {
+ sourceCompatibility = "17"
+ targetCompatibility = "17"
+ }
+ withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
+ kotlinOptions.jvmTarget = "17"
+ }
+
+ patchPluginXml {
+ sinceBuild.set("231")
+ untilBuild.set("232.*")
+ }
+
+ signPlugin {
+ certificateChain.set(System.getenv("CERTIFICATE_CHAIN"))
+ privateKey.set(System.getenv("PRIVATE_KEY"))
+ password.set(System.getenv("PRIVATE_KEY_PASSWORD"))
+ }
+
+ publishPlugin {
+ token.set(System.getenv("PUBLISH_TOKEN"))
+ }
+}
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..2bca45c
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,3 @@
+kotlin.stdlib.default.dependency=false
+# TODO temporary workaround for Kotlin 1.8.20+ (https://jb.gg/intellij-platform-kotlin-oom)
+kotlin.incremental.useClasspathSnapshot=false
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..249e583
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..fae0804
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
new file mode 100755
index 0000000..1b6c787
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,234 @@
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original 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.
+#
+
+##############################################################################
+#
+# Gradle start up script for POSIX generated by Gradle.
+#
+# Important for running:
+#
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+# noncompliant, but you have some other compliant shell such as ksh or
+# bash, then to run this script, type that shell name before the whole
+# command line, like:
+#
+# ksh Gradle
+#
+# Busybox and similar reduced shells will NOT work, because this script
+# requires all of these POSIX shell features:
+# * functions;
+# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+# * compound commands having a testable exit status, especially «case»;
+# * various built-in commands including «command», «set», and «ulimit».
+#
+# Important for patching:
+#
+# (2) This script targets any POSIX shell, so it avoids extensions provided
+# by Bash, Ksh, etc; in particular arrays are avoided.
+#
+# The "traditional" practice of packing multiple parameters into a
+# space-separated string is a well documented source of bugs and security
+# problems, so this is (mostly) avoided, by progressively accumulating
+# options in "$@", and eventually passing that to Java.
+#
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+# see the in-line comments for details.
+#
+# There are tweaks for specific operating systems such as AIX, CygWin,
+# Darwin, MinGW, and NonStop.
+#
+# (3) This script is generated from the Groovy template
+# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# within the Gradle project.
+#
+# You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
+done
+
+APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
+
+APP_NAME="Gradle"
+APP_BASE_NAME=${0##*/}
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+ echo "$*"
+} >&2
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in #(
+ CYGWIN* ) cygwin=true ;; #(
+ Darwin* ) darwin=true ;; #(
+ MSYS* | MINGW* ) msys=true ;; #(
+ NONSTOP* ) nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD=$JAVA_HOME/jre/sh/java
+ else
+ JAVACMD=$JAVA_HOME/bin/java
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD=java
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ max*)
+ MAX_FD=$( ulimit -H -n ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | soft) :;; #(
+ *)
+ ulimit -n "$MAX_FD" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
+ esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; # don't mess with options #(
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
+ [ -e "$t" ] ;; #(
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
+ fi
+ # Roll the args list around exactly as many times as the number of
+ # args, so each arg winds up back in the position where it started, but
+ # possibly modified.
+ #
+ # NB: a `for` loop captures its iteration list before it begins, so
+ # changing the positional parameters here affects neither the number of
+ # iterations, nor the values presented in `arg`.
+ shift # remove old arg
+ set -- "$@" "$arg" # push replacement arg
+ done
+fi
+
+# Collect all arguments for the java command;
+# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
+# shell script including quotes and variable substitutions, so put them in
+# double quotes to make sure that they get re-expanded; and
+# * put everything else in single quotes, so that it's not re-expanded.
+
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ org.gradle.wrapper.GradleWrapperMain \
+ "$@"
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+# set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+ xargs -n1 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+ tr '\n' ' '
+ )" '"$@"'
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..ac1b06f
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/settings.gradle.kts b/settings.gradle.kts
new file mode 100644
index 0000000..1c62927
--- /dev/null
+++ b/settings.gradle.kts
@@ -0,0 +1,8 @@
+pluginManagement {
+ repositories {
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+
+rootProject.name = "struts2"
\ No newline at end of file
diff --git a/src/main/gen/OgnlIcons.java b/src/main/gen/OgnlIcons.java
new file mode 100644
index 0000000..449531f
--- /dev/null
+++ b/src/main/gen/OgnlIcons.java
@@ -0,0 +1,18 @@
+// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+package com.intellij.lang.ognl;
+
+import com.intellij.ui.IconManager;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+
+/**
+ * NOTE THIS FILE IS AUTO-GENERATED
+ * DO NOT EDIT IT BY HAND, run "Generate icon classes" configuration instead
+ */
+public final class OgnlIcons {
+ private static @NotNull Icon load(@NotNull String path, int cacheKey, int flags) {
+ return IconManager.getInstance().loadRasterizedIcon(path, OgnlIcons.class.getClassLoader(), cacheKey, flags);
+ }
+ /** 10x10 */ public static final @NotNull Icon Action_small = load("icons/action_small.svg", -592871696, 0);
+}
diff --git a/src/main/gen/OgnlTypes.java b/src/main/gen/OgnlTypes.java
new file mode 100644
index 0000000..b9e4c6c
--- /dev/null
+++ b/src/main/gen/OgnlTypes.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl;
+
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.PsiElement;
+import com.intellij.lang.ASTNode;
+import com.intellij.lang.ognl.psi.OgnlTokenType;
+import com.intellij.lang.ognl.psi.impl.*;
+
+public interface OgnlTypes {
+
+ IElementType BINARY_EXPRESSION = new OgnlTokenType("BINARY_EXPRESSION");
+ IElementType CONDITIONAL_EXPRESSION = new OgnlTokenType("CONDITIONAL_EXPRESSION");
+ IElementType EXPRESSION = new OgnlTokenType("EXPRESSION");
+ IElementType FQN_TYPE_EXPRESSION = new OgnlTokenType("FQN_TYPE_EXPRESSION");
+ IElementType INDEXED_EXPRESSION = new OgnlTokenType("INDEXED_EXPRESSION");
+ IElementType LAMBDA_EXPRESSION = new OgnlTokenType("LAMBDA_EXPRESSION");
+ IElementType LITERAL_EXPRESSION = new OgnlTokenType("LITERAL_EXPRESSION");
+ IElementType MAP_ENTRY_ELEMENT = new OgnlTokenType("MAP_ENTRY_ELEMENT");
+ IElementType MAP_EXPRESSION = new OgnlTokenType("MAP_EXPRESSION");
+ IElementType METHOD_CALL_EXPRESSION = new OgnlTokenType("METHOD_CALL_EXPRESSION");
+ IElementType NEW_ARRAY_EXPRESSION = new OgnlTokenType("NEW_ARRAY_EXPRESSION");
+ IElementType NEW_EXPRESSION = new OgnlTokenType("NEW_EXPRESSION");
+ IElementType PARAMETER_LIST = new OgnlTokenType("PARAMETER_LIST");
+ IElementType PARENTHESIZED_EXPRESSION = new OgnlTokenType("PARENTHESIZED_EXPRESSION");
+ IElementType PROJECTION_EXPRESSION = new OgnlTokenType("PROJECTION_EXPRESSION");
+ IElementType REFERENCE_EXPRESSION = new OgnlTokenType("REFERENCE_EXPRESSION");
+ IElementType SELECTION_EXPRESSION = new OgnlTokenType("SELECTION_EXPRESSION");
+ IElementType SEQUENCE_EXPRESSION = new OgnlTokenType("SEQUENCE_EXPRESSION");
+ IElementType UNARY_EXPRESSION = new OgnlTokenType("UNARY_EXPRESSION");
+ IElementType VARIABLE_ASSIGNMENT_EXPRESSION = new OgnlTokenType("VARIABLE_ASSIGNMENT_EXPRESSION");
+ IElementType VARIABLE_EXPRESSION = new OgnlTokenType("VARIABLE_EXPRESSION");
+
+ IElementType AND = new OgnlTokenType("&");
+ IElementType AND_AND = new OgnlTokenType("&&");
+ IElementType AND_KEYWORD = new OgnlTokenType("and");
+ IElementType AT = new OgnlTokenType("@");
+ IElementType BAND_KEYWORD = new OgnlTokenType("band");
+ IElementType BIG_DECIMAL_LITERAL = new OgnlTokenType("BIG_DECIMAL_LITERAL");
+ IElementType BIG_INTEGER_LITERAL = new OgnlTokenType("BIG_INTEGER_LITERAL");
+ IElementType BOR_KEYWORD = new OgnlTokenType("bor");
+ IElementType CHARACTER_LITERAL = new OgnlTokenType("CHARACTER_LITERAL");
+ IElementType COLON = new OgnlTokenType(":");
+ IElementType COMMA = new OgnlTokenType(",");
+ IElementType DIVISION = new OgnlTokenType("/");
+ IElementType DOLLAR = new OgnlTokenType("$");
+ IElementType DOT = new OgnlTokenType(".");
+ IElementType DOUBLE_LITERAL = new OgnlTokenType("DOUBLE_LITERAL");
+ IElementType EQ = new OgnlTokenType("=");
+ IElementType EQUAL = new OgnlTokenType("==");
+ IElementType EQ_KEYWORD = new OgnlTokenType("eq");
+ IElementType EXPRESSION_END = new OgnlTokenType("EXPRESSION_END");
+ IElementType EXPRESSION_START = new OgnlTokenType("%{");
+ IElementType FALSE_KEYWORD = new OgnlTokenType("false");
+ IElementType GREATER = new OgnlTokenType(">");
+ IElementType GREATER_EQUAL = new OgnlTokenType(">=");
+ IElementType GT_EQ_KEYWORD = new OgnlTokenType("gte");
+ IElementType GT_KEYWORD = new OgnlTokenType("gt");
+ IElementType HASH = new OgnlTokenType("#");
+ IElementType IDENTIFIER = new OgnlTokenType("IDENTIFIER");
+ IElementType INSTANCEOF_KEYWORD = new OgnlTokenType("instanceof");
+ IElementType INTEGER_LITERAL = new OgnlTokenType("INTEGER_LITERAL");
+ IElementType IN_KEYWORD = new OgnlTokenType("in");
+ IElementType LBRACE = new OgnlTokenType("{");
+ IElementType LBRACKET = new OgnlTokenType("[");
+ IElementType LESS = new OgnlTokenType("<");
+ IElementType LESS_EQUAL = new OgnlTokenType("<=");
+ IElementType LPARENTH = new OgnlTokenType("(");
+ IElementType LT_EQ_KEYWORD = new OgnlTokenType("lte");
+ IElementType LT_KEYWORD = new OgnlTokenType("lt");
+ IElementType MINUS = new OgnlTokenType("-");
+ IElementType MODULO = new OgnlTokenType("%");
+ IElementType MULTIPLY = new OgnlTokenType("*");
+ IElementType NEGATE = new OgnlTokenType("!");
+ IElementType NEQ_KEYWORD = new OgnlTokenType("neq");
+ IElementType NEW_KEYWORD = new OgnlTokenType("new");
+ IElementType NOT = new OgnlTokenType("~");
+ IElementType NOT_EQUAL = new OgnlTokenType("!=");
+ IElementType NOT_IN_KEYWORD = new OgnlTokenType("not in");
+ IElementType NOT_KEYWORD = new OgnlTokenType("not");
+ IElementType NULL_KEYWORD = new OgnlTokenType("null");
+ IElementType OR = new OgnlTokenType("|");
+ IElementType OR_KEYWORD = new OgnlTokenType("or");
+ IElementType OR_OR = new OgnlTokenType("||");
+ IElementType PLUS = new OgnlTokenType("+");
+ IElementType QUESTION = new OgnlTokenType("?");
+ IElementType RBRACE = new OgnlTokenType("}");
+ IElementType RBRACKET = new OgnlTokenType("]");
+ IElementType RPARENTH = new OgnlTokenType(")");
+ IElementType SHIFT_LEFT = new OgnlTokenType("<<");
+ IElementType SHIFT_LEFT_KEYWORD = new OgnlTokenType("shl");
+ IElementType SHIFT_RIGHT = new OgnlTokenType(">>");
+ IElementType SHIFT_RIGHT_KEYWORD = new OgnlTokenType("shr");
+ IElementType SHIFT_RIGHT_LOGICAL = new OgnlTokenType(">>>");
+ IElementType SHIFT_RIGHT_LOGICAL_KEYWORD = new OgnlTokenType("ushr");
+ IElementType STRING_LITERAL = new OgnlTokenType("STRING_LITERAL");
+ IElementType TRUE_KEYWORD = new OgnlTokenType("true");
+ IElementType XOR = new OgnlTokenType("^");
+ IElementType XOR_KEYWORD = new OgnlTokenType("xor");
+
+ class Factory {
+ public static PsiElement createElement(ASTNode node) {
+ IElementType type = node.getElementType();
+ if (type == BINARY_EXPRESSION) {
+ return new OgnlBinaryExpressionImpl(node);
+ }
+ else if (type == CONDITIONAL_EXPRESSION) {
+ return new OgnlConditionalExpressionImpl(node);
+ }
+ else if (type == FQN_TYPE_EXPRESSION) {
+ return new OgnlFqnTypeExpressionImpl(node);
+ }
+ else if (type == INDEXED_EXPRESSION) {
+ return new OgnlIndexedExpressionImpl(node);
+ }
+ else if (type == LAMBDA_EXPRESSION) {
+ return new OgnlLambdaExpressionImpl(node);
+ }
+ else if (type == LITERAL_EXPRESSION) {
+ return new OgnlLiteralExpressionImpl(node);
+ }
+ else if (type == MAP_ENTRY_ELEMENT) {
+ return new OgnlMapEntryElementImpl(node);
+ }
+ else if (type == MAP_EXPRESSION) {
+ return new OgnlMapExpressionImpl(node);
+ }
+ else if (type == METHOD_CALL_EXPRESSION) {
+ return new OgnlMethodCallExpressionImpl(node);
+ }
+ else if (type == NEW_ARRAY_EXPRESSION) {
+ return new OgnlNewArrayExpressionImpl(node);
+ }
+ else if (type == NEW_EXPRESSION) {
+ return new OgnlNewExpressionImpl(node);
+ }
+ else if (type == PARAMETER_LIST) {
+ return new OgnlParameterListImpl(node);
+ }
+ else if (type == PARENTHESIZED_EXPRESSION) {
+ return new OgnlParenthesizedExpressionImpl(node);
+ }
+ else if (type == PROJECTION_EXPRESSION) {
+ return new OgnlProjectionExpressionImpl(node);
+ }
+ else if (type == REFERENCE_EXPRESSION) {
+ return new OgnlReferenceExpressionImpl(node);
+ }
+ else if (type == SELECTION_EXPRESSION) {
+ return new OgnlSelectionExpressionImpl(node);
+ }
+ else if (type == SEQUENCE_EXPRESSION) {
+ return new OgnlSequenceExpressionImpl(node);
+ }
+ else if (type == UNARY_EXPRESSION) {
+ return new OgnlUnaryExpressionImpl(node);
+ }
+ else if (type == VARIABLE_ASSIGNMENT_EXPRESSION) {
+ return new OgnlVariableAssignmentExpressionImpl(node);
+ }
+ else if (type == VARIABLE_EXPRESSION) {
+ return new OgnlVariableExpressionImpl(node);
+ }
+ throw new AssertionError("Unknown element type: " + type);
+ }
+ }
+}
diff --git a/src/main/gen/lexer/_OgnlLexer.java b/src/main/gen/lexer/_OgnlLexer.java
new file mode 100644
index 0000000..e9dec60
--- /dev/null
+++ b/src/main/gen/lexer/_OgnlLexer.java
@@ -0,0 +1,1287 @@
+// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+
+// Generated by JFlex 1.9.1 http://jflex.de/ (tweaked for IntelliJ platform)
+// source: _OgnlLexer.flex
+
+/* Generated code. Do not modify it. */
+package com.intellij.lang.ognl.lexer;
+
+import com.intellij.lexer.FlexLexer;
+import com.intellij.psi.tree.IElementType;
+import java.util.*;
+import java.lang.reflect.Field;
+import org.jetbrains.annotations.NotNull;
+
+import com.intellij.psi.TokenType;
+import com.intellij.lang.ognl.OgnlTypes;
+
+
+public class _OgnlLexer implements FlexLexer {
+
+ /** This character denotes the end of file */
+ public static final int YYEOF = -1;
+
+ /** initial size of the lookahead buffer */
+ private static final int ZZ_BUFFERSIZE = 16384;
+
+ /** lexical states */
+ public static final int YYINITIAL = 0;
+ public static final int NESTED_BRACE = 2;
+ public static final int EXPR = 4;
+
+ /**
+ * ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l
+ * ZZ_LEXSTATE[l+1] is the state in the DFA for the lexical state l
+ * at the beginning of a line
+ * l is of the form l = 2*k, k a non negative integer
+ */
+ private static final int ZZ_LEXSTATE[] = {
+ 0, 0, 1, 1, 1, 1
+ };
+
+ /**
+ * Top-level table for translating characters to character classes
+ */
+ private static final int [] ZZ_CMAP_TOP = zzUnpackcmap_top();
+
+ private static final String ZZ_CMAP_TOP_PACKED_0 =
+ "\1\0\1\u0100\1\u0200\1\u0300\1\u0400\1\u0500\1\u0600\1\u0700"+
+ "\1\u0800\1\u0900\1\u0a00\1\u0b00\1\u0c00\1\u0d00\1\u0e00\1\u0f00"+
+ "\1\u1000\1\u0100\1\u1100\1\u1200\1\u1300\1\u0100\1\u1400\1\u1500"+
+ "\1\u1600\1\u1700\1\u1800\1\u1900\1\u1a00\1\u1b00\1\u0100\1\u1c00"+
+ "\1\u1d00\1\u1e00\12\u1f00\1\u2000\1\u2100\1\u2200\1\u1f00\1\u2300"+
+ "\1\u2400\2\u1f00\31\u0100\1\u2500\121\u0100\1\u2600\4\u0100\1\u2700"+
+ "\1\u0100\1\u2800\1\u2900\1\u2a00\1\u2b00\1\u2c00\1\u2d00\53\u0100"+
+ "\1\u2e00\41\u1f00\1\u0100\1\u2f00\1\u3000\1\u0100\1\u3100\1\u3200"+
+ "\1\u3300\1\u3400\1\u3500\1\u3600\1\u3700\1\u3800\1\u3900\1\u0100"+
+ "\1\u3a00\1\u3b00\1\u3c00\1\u3d00\1\u3e00\1\u3f00\1\u4000\1\u4100"+
+ "\1\u4200\1\u4300\1\u4400\1\u4500\1\u4600\1\u4700\1\u4800\1\u4900"+
+ "\1\u4a00\1\u4b00\1\u4c00\1\u4d00\1\u1f00\1\u4e00\1\u4f00\1\u5000"+
+ "\1\u5100\3\u0100\1\u5200\1\u5300\1\u5400\12\u1f00\4\u0100\1\u5500"+
+ "\17\u1f00\2\u0100\1\u5600\41\u1f00\2\u0100\1\u5700\1\u5800\2\u1f00"+
+ "\1\u5900\1\u5a00\27\u0100\1\u5b00\2\u0100\1\u5c00\1\u5d00\1\u5e00"+
+ "\1\u5f00\42\u1f00\1\u0100\1\u6000\1\u6100\11\u1f00\1\u6200\24\u1f00"+
+ "\1\u6300\1\u6400\1\u1f00\1\u6500\1\u6600\1\u6700\1\u6800\2\u1f00"+
+ "\1\u6900\5\u1f00\1\u6a00\1\u6b00\1\u6c00\5\u1f00\1\u6d00\1\u6e00"+
+ "\2\u1f00\1\u6f00\1\u1f00\1\u7000\14\u1f00\1\u7100\4\u1f00\246\u0100"+
+ "\1\u7200\20\u0100\1\u7300\1\u7400\25\u0100\1\u7500\34\u0100\1\u7600"+
+ "\14\u1f00\2\u0100\1\u7700\5\u1f00\23\u5d00\1\u7800\u0aec\u1f00\1\u7900"+
+ "\1\u7a00\u02fe\u1f00";
+
+ private static int [] zzUnpackcmap_top() {
+ int [] result = new int[4352];
+ int offset = 0;
+ offset = zzUnpackcmap_top(ZZ_CMAP_TOP_PACKED_0, offset, result);
+ return result;
+ }
+
+ private static int zzUnpackcmap_top(String packed, int offset, int [] result) {
+ int i = 0; /* index in packed string */
+ int j = offset; /* index in unpacked array */
+ int l = packed.length();
+ while (i < l) {
+ int count = packed.charAt(i++);
+ int value = packed.charAt(i++);
+ do result[j++] = value; while (--count > 0);
+ }
+ return j;
+ }
+
+
+ /**
+ * Second-level tables for translating characters to character classes
+ */
+ private static final int [] ZZ_CMAP_BLOCKS = zzUnpackcmap_blocks();
+
+ private static final String ZZ_CMAP_BLOCKS_PACKED_0 =
+ "\11\0\1\1\1\2\1\3\1\1\1\2\16\0\4\3"+
+ "\1\4\1\5\1\6\1\7\1\10\1\11\1\12\1\13"+
+ "\1\14\1\15\1\16\1\17\1\20\1\21\1\22\1\23"+
+ "\1\24\11\25\1\26\1\3\1\27\1\30\1\31\1\32"+
+ "\1\33\1\34\1\35\2\34\1\36\2\34\1\37\22\34"+
+ "\1\40\1\41\1\42\1\43\1\0\1\3\1\44\1\45"+
+ "\1\46\1\47\1\50\1\51\1\52\1\53\1\54\2\34"+
+ "\1\55\1\34\1\56\1\57\1\34\1\60\1\61\1\62"+
+ "\1\63\1\64\1\34\1\65\1\66\2\34\1\67\1\70"+
+ "\1\71\1\72\41\0\2\3\4\0\4\3\1\34\2\3"+
+ "\1\0\7\3\1\34\4\3\1\34\5\3\27\34\1\3"+
+ "\37\34\1\3\u01ca\34\4\3\14\34\16\3\5\34\7\3"+
+ "\1\34\1\3\1\34\21\3\160\0\5\34\1\3\2\34"+
+ "\2\3\4\34\1\3\1\34\6\3\1\34\1\3\3\34"+
+ "\1\3\1\34\1\3\24\34\1\3\123\34\1\3\213\34"+
+ "\1\3\5\0\2\3\246\34\1\3\46\34\2\3\1\34"+
+ "\6\3\51\34\6\3\1\0\1\3\55\0\1\3\1\0"+
+ "\1\3\2\0\1\3\2\0\1\3\1\0\10\3\33\34"+
+ "\4\3\4\34\15\3\6\0\5\3\1\0\4\3\13\0"+
+ "\1\3\1\0\3\3\53\34\37\0\4\3\2\34\1\0"+
+ "\143\34\1\3\1\34\10\0\1\3\6\0\2\34\2\0"+
+ "\1\3\4\0\2\34\12\0\3\34\2\3\1\34\17\3"+
+ "\1\0\1\34\1\0\36\34\33\0\2\3\131\34\13\0"+
+ "\1\34\16\3\12\0\41\34\11\0\2\34\4\3\1\34"+
+ "\2\3\3\0\26\34\4\0\1\34\11\0\1\34\3\0"+
+ "\1\34\5\0\22\3\31\34\3\0\4\3\13\34\65\3"+
+ "\25\34\1\3\10\34\12\0\13\3\61\0\66\34\3\0"+
+ "\1\34\22\0\1\34\7\0\12\34\2\0\2\3\12\0"+
+ "\1\3\20\34\3\0\1\3\10\34\2\3\2\34\2\3"+
+ "\26\34\1\3\7\34\1\3\1\34\3\3\4\34\2\3"+
+ "\1\0\1\34\7\0\2\3\2\0\2\3\3\0\1\34"+
+ "\10\3\1\0\4\3\2\34\1\3\3\34\2\0\2\3"+
+ "\12\0\2\34\2\0\7\3\1\0\1\34\1\3\1\0"+
+ "\2\3\3\0\1\3\6\34\4\3\2\34\2\3\26\34"+
+ "\1\3\7\34\1\3\2\34\1\3\2\34\1\3\2\34"+
+ "\2\3\1\0\1\3\5\0\4\3\2\0\2\3\3\0"+
+ "\3\3\1\0\7\3\4\34\1\3\1\34\7\3\14\0"+
+ "\3\34\1\0\13\3\3\0\1\3\11\34\1\3\3\34"+
+ "\1\3\26\34\1\3\7\34\1\3\2\34\1\3\5\34"+
+ "\2\3\1\0\1\34\10\0\1\3\3\0\1\3\3\0"+
+ "\2\3\1\34\17\3\2\34\2\0\2\3\12\0\1\3"+
+ "\1\0\7\3\1\34\6\0\1\3\3\0\1\3\10\34"+
+ "\2\3\2\34\2\3\26\34\1\3\7\34\1\3\2\34"+
+ "\1\3\5\34\2\3\1\0\1\34\7\0\2\3\2\0"+
+ "\2\3\3\0\7\3\3\0\4\3\2\34\1\3\3\34"+
+ "\2\0\2\3\12\0\1\3\1\34\20\3\1\0\1\34"+
+ "\1\3\6\34\3\3\3\34\1\3\4\34\3\3\2\34"+
+ "\1\3\1\34\1\3\2\34\3\3\2\34\3\3\3\34"+
+ "\3\3\14\34\4\3\5\0\3\3\3\0\1\3\4\0"+
+ "\2\3\1\34\6\3\1\0\16\3\12\0\11\3\1\0"+
+ "\6\3\5\0\10\34\1\3\3\34\1\3\27\34\1\3"+
+ "\20\34\3\3\1\34\7\0\1\3\3\0\1\3\4\0"+
+ "\7\3\2\0\1\3\3\34\5\3\2\34\2\0\2\3"+
+ "\12\0\20\3\1\34\3\0\1\3\10\34\1\3\3\34"+
+ "\1\3\27\34\1\3\12\34\1\3\5\34\2\3\1\0"+
+ "\1\34\7\0\1\3\3\0\1\3\4\0\7\3\2\0"+
+ "\7\3\1\34\1\3\2\34\2\0\2\3\12\0\1\3"+
+ "\2\34\15\3\5\0\10\34\1\3\3\34\1\3\51\34"+
+ "\2\0\1\34\7\0\1\3\3\0\1\3\4\0\1\34"+
+ "\5\3\3\34\1\0\7\3\3\34\2\0\2\3\12\0"+
+ "\12\3\6\34\1\3\3\0\1\3\22\34\3\3\30\34"+
+ "\1\3\11\34\1\3\1\34\2\3\7\34\3\3\1\0"+
+ "\4\3\6\0\1\3\1\0\1\3\10\0\6\3\12\0"+
+ "\2\3\2\0\15\3\60\34\1\0\2\34\7\0\4\3"+
+ "\1\0\7\34\10\0\1\3\12\0\47\3\2\34\1\3"+
+ "\1\34\1\3\5\34\1\3\30\34\1\3\1\34\1\3"+
+ "\12\34\1\0\2\34\11\0\1\34\2\3\5\34\1\3"+
+ "\1\34\1\3\6\0\2\3\12\0\2\3\4\34\40\3"+
+ "\1\34\27\3\2\0\6\3\12\0\13\3\1\0\1\3"+
+ "\1\0\1\3\1\0\4\3\2\0\10\34\1\3\44\34"+
+ "\4\3\24\0\1\3\2\0\5\34\13\0\1\3\44\0"+
+ "\11\3\1\0\71\3\53\34\24\0\1\34\12\0\6\3"+
+ "\6\34\4\0\4\34\3\0\1\34\3\0\2\34\7\0"+
+ "\3\34\4\0\15\34\14\0\1\34\17\0\2\3\46\34"+
+ "\1\3\1\34\5\3\1\34\2\3\53\34\1\3\115\34"+
+ "\1\3\4\34\2\3\7\34\1\3\1\34\1\3\4\34"+
+ "\2\3\51\34\1\3\4\34\2\3\41\34\1\3\4\34"+
+ "\2\3\7\34\1\3\1\34\1\3\4\34\2\3\17\34"+
+ "\1\3\71\34\1\3\4\34\2\3\103\34\2\3\3\0"+
+ "\40\3\20\34\20\3\126\34\2\3\6\34\3\3\u016c\34"+
+ "\2\3\21\34\1\3\32\34\5\3\113\34\3\3\3\0"+
+ "\10\34\7\3\15\34\1\3\4\34\3\0\13\3\22\34"+
+ "\3\0\13\3\22\34\2\0\14\3\15\34\1\3\3\34"+
+ "\1\3\2\0\14\3\64\34\40\0\3\3\1\34\3\3"+
+ "\1\0\1\34\1\0\2\3\12\0\41\3\4\0\1\3"+
+ "\12\0\6\3\131\34\7\3\5\34\2\0\42\34\1\0"+
+ "\1\34\5\3\106\34\12\3\37\34\1\3\14\0\4\3"+
+ "\14\0\12\3\12\0\36\34\2\3\5\34\13\3\54\34"+
+ "\4\3\32\34\6\3\12\0\46\3\27\34\5\0\4\3"+
+ "\65\34\12\0\1\3\35\0\2\3\13\0\6\3\12\0"+
+ "\15\3\1\34\10\3\16\0\1\3\2\0\77\3\5\0"+
+ "\57\34\21\0\7\34\4\3\12\0\21\3\11\0\14\3"+
+ "\3\0\36\34\15\0\2\34\12\0\54\34\16\0\14\3"+
+ "\44\34\24\0\10\3\12\0\3\3\3\34\12\0\44\34"+
+ "\2\3\11\34\7\3\53\34\2\3\3\34\20\3\3\0"+
+ "\1\3\25\0\4\34\1\0\6\34\1\0\2\34\3\0"+
+ "\1\34\5\3\300\34\72\0\1\3\5\0\26\34\2\3"+
+ "\6\34\2\3\46\34\2\3\6\34\2\3\10\34\1\3"+
+ "\1\34\1\3\1\34\1\3\1\34\1\3\37\34\2\3"+
+ "\65\34\1\3\7\34\1\3\1\34\3\3\3\34\1\3"+
+ "\7\34\3\3\4\34\2\3\6\34\4\3\15\34\5\3"+
+ "\3\34\1\3\7\34\16\3\5\0\32\3\5\0\20\3"+
+ "\2\0\23\3\1\0\13\3\5\0\1\3\12\0\1\3"+
+ "\1\34\15\3\1\34\20\3\15\34\3\3\40\0\20\3"+
+ "\15\0\4\3\1\0\3\3\14\0\21\3\1\34\4\3"+
+ "\1\34\2\3\12\34\1\3\1\34\3\3\5\34\6\3"+
+ "\1\34\1\3\1\34\1\3\1\34\1\3\4\34\1\3"+
+ "\13\34\2\3\4\34\5\3\5\34\4\3\1\34\21\3"+
+ "\43\0\2\34\4\0\u0177\3\57\34\1\3\57\34\1\3"+
+ "\205\34\6\3\4\34\3\0\2\34\14\3\46\34\1\3"+
+ "\1\34\5\3\1\34\2\3\70\34\7\3\1\34\17\3"+
+ "\1\0\27\34\11\3\7\34\1\3\7\34\1\3\7\34"+
+ "\1\3\7\34\1\3\7\34\1\3\7\34\1\3\7\34"+
+ "\1\3\7\34\1\3\40\0\57\3\1\34\325\3\2\34"+
+ "\1\0\31\3\17\0\1\3\5\34\2\3\3\0\2\34"+
+ "\4\3\126\34\2\3\2\0\2\3\3\34\1\3\132\34"+
+ "\1\3\4\34\5\3\53\34\1\3\136\34\21\3\33\34"+
+ "\5\0\60\3\306\34\12\0\100\3\360\34\15\0\3\3"+
+ "\215\34\103\3\56\34\2\3\15\34\3\3\20\34\12\0"+
+ "\2\34\24\3\57\34\1\0\4\3\12\0\1\3\37\34"+
+ "\2\0\106\34\14\0\45\3\11\34\2\3\147\34\2\3"+
+ "\65\34\2\3\5\34\4\0\52\3\2\0\13\34\1\0"+
+ "\3\34\1\0\4\34\1\0\27\34\5\0\4\3\1\0"+
+ "\13\3\1\0\7\3\64\34\14\3\2\0\62\34\22\0"+
+ "\12\3\12\0\6\3\22\0\6\34\3\3\1\34\1\3"+
+ "\2\34\13\0\34\34\10\0\2\3\27\34\15\0\14\3"+
+ "\35\34\3\3\4\0\57\34\16\0\16\3\1\34\12\0"+
+ "\6\3\5\34\1\0\12\34\12\0\5\34\1\3\51\34"+
+ "\16\0\11\3\3\34\1\0\10\34\2\0\2\3\12\0"+
+ "\6\3\27\34\3\3\1\34\3\0\62\34\1\0\1\34"+
+ "\3\0\2\34\2\0\5\34\2\0\1\34\1\0\1\34"+
+ "\30\3\3\34\2\3\13\34\5\0\2\3\3\34\2\0"+
+ "\12\3\6\34\2\3\6\34\2\3\6\34\11\3\7\34"+
+ "\1\3\7\34\1\3\53\34\1\3\14\34\2\0\6\3"+
+ "\163\34\10\0\1\3\2\0\2\3\12\0\6\3\244\34"+
+ "\14\3\27\34\4\3\61\34\4\3\156\34\2\3\152\34"+
+ "\46\3\7\34\14\3\5\34\5\3\1\34\1\0\12\34"+
+ "\1\3\15\34\1\3\5\34\1\3\1\34\1\3\2\34"+
+ "\1\3\2\34\1\3\154\34\41\3\153\34\22\3\100\34"+
+ "\2\3\66\34\50\3\14\34\1\0\3\3\20\0\20\3"+
+ "\20\0\3\3\2\0\30\3\3\0\31\3\1\0\6\3"+
+ "\5\34\1\3\207\34\2\3\1\0\4\3\1\0\13\3"+
+ "\12\0\7\3\32\34\4\3\1\0\1\3\32\34\13\3"+
+ "\131\34\3\3\6\34\2\3\6\34\2\3\6\34\2\3"+
+ "\3\34\3\3\2\0\3\3\2\0\22\3\3\0\4\3"+
+ "\14\34\1\3\32\34\1\3\23\34\1\3\2\34\1\3"+
+ "\17\34\2\3\16\34\42\3\173\34\105\3\65\0\210\3"+
+ "\1\0\202\3\35\34\3\3\61\34\17\3\1\0\37\3"+
+ "\40\34\15\3\24\34\1\0\10\34\1\0\5\3\46\34"+
+ "\5\0\5\3\36\34\2\3\44\34\4\3\10\34\1\3"+
+ "\5\0\52\3\236\34\2\3\12\0\6\3\44\34\4\3"+
+ "\44\34\4\3\50\34\10\3\64\34\234\3\67\34\11\3"+
+ "\26\34\12\3\10\34\230\3\6\34\2\3\1\34\1\3"+
+ "\54\34\1\3\2\34\3\3\1\34\2\3\27\34\12\3"+
+ "\27\34\11\3\37\34\101\3\23\34\1\3\2\34\12\3"+
+ "\26\34\12\3\32\34\106\3\70\34\6\3\2\34\100\3"+
+ "\1\34\3\0\1\3\2\0\5\3\4\0\4\34\1\3"+
+ "\3\34\1\3\35\34\2\3\3\0\4\3\1\0\40\3"+
+ "\35\34\3\3\35\34\43\3\10\34\1\3\34\34\2\0"+
+ "\31\3\66\34\12\3\26\34\12\3\23\34\15\3\22\34"+
+ "\156\3\111\34\67\3\63\34\15\3\63\34\15\3\44\34"+
+ "\4\0\10\3\12\0\u0146\3\52\0\1\3\2\0\3\3"+
+ "\2\0\116\3\35\34\12\3\1\34\10\3\26\34\13\0"+
+ "\137\3\25\0\33\3\27\34\11\3\3\0\65\34\17\0"+
+ "\37\3\12\0\17\3\4\0\55\34\13\0\2\3\1\0"+
+ "\17\3\1\0\2\3\31\34\7\3\12\0\6\3\3\0"+
+ "\44\34\16\0\1\3\12\0\4\3\1\34\3\0\10\3"+
+ "\43\34\1\0\2\3\1\34\11\3\3\0\60\34\16\0"+
+ "\4\34\4\3\4\0\1\3\14\0\1\34\1\3\1\34"+
+ "\43\3\22\34\1\3\31\34\14\0\6\3\1\0\101\3"+
+ "\7\34\1\3\1\34\1\3\4\34\1\3\17\34\1\3"+
+ "\12\34\7\3\57\34\14\0\5\3\12\0\6\3\4\0"+
+ "\1\3\10\34\2\3\2\34\2\3\26\34\1\3\7\34"+
+ "\1\3\2\34\1\3\5\34\1\3\2\0\1\34\7\0"+
+ "\2\3\2\0\2\3\3\0\2\3\1\34\6\3\1\0"+
+ "\5\3\5\34\2\0\2\3\7\0\3\3\5\0\213\3"+
+ "\65\34\22\0\4\34\5\3\12\0\4\3\1\0\1\34"+
+ "\2\0\36\3\60\34\24\0\2\34\1\3\1\34\10\3"+
+ "\12\0\246\3\57\34\7\0\2\3\11\0\27\3\4\34"+
+ "\2\0\42\3\60\34\21\0\3\3\1\34\13\3\12\0"+
+ "\46\3\53\34\15\0\1\34\7\3\12\0\66\3\33\34"+
+ "\2\3\17\0\4\3\12\0\306\3\54\34\17\0\145\3"+
+ "\100\34\12\0\25\3\1\34\7\0\2\3\1\0\2\3"+
+ "\10\0\1\3\2\0\1\3\36\0\1\3\2\0\2\3"+
+ "\11\0\14\3\12\0\106\3\10\34\2\3\47\34\7\0"+
+ "\2\3\7\0\1\34\1\3\1\34\1\0\33\3\1\34"+
+ "\12\0\50\34\7\0\1\34\4\0\10\3\1\0\10\3"+
+ "\1\34\13\0\56\34\20\0\3\3\1\34\42\3\71\34"+
+ "\7\3\11\34\1\3\45\34\10\0\1\3\10\0\1\34"+
+ "\17\3\12\0\30\3\36\34\2\3\26\0\1\3\16\0"+
+ "\111\3\7\34\1\3\2\34\1\3\46\34\6\0\3\3"+
+ "\1\0\1\3\2\0\1\3\7\0\1\34\1\0\10\3"+
+ "\12\0\6\3\6\34\1\3\2\34\1\3\40\34\5\0"+
+ "\1\3\2\0\1\3\5\0\1\34\7\3\12\0\u0136\3"+
+ "\23\34\4\0\271\3\1\0\54\3\4\0\37\3\232\34"+
+ "\146\3\157\0\21\3\304\34\274\3\57\34\1\3\11\0"+
+ "\307\3\107\34\271\3\71\34\7\3\37\34\1\3\12\0"+
+ "\146\3\36\34\2\3\5\0\13\3\60\34\7\0\11\3"+
+ "\4\34\14\3\12\0\11\3\25\34\5\3\23\34\260\3"+
+ "\100\34\200\3\113\34\4\3\1\0\1\34\67\0\7\3"+
+ "\4\0\15\34\100\3\2\34\1\3\1\34\1\0\13\3"+
+ "\2\0\16\3\370\34\10\3\363\34\u01e3\0\52\3\11\0"+
+ "\367\3\37\34\61\3\3\34\21\3\4\34\10\3\u018c\34"+
+ "\4\3\153\34\5\3\15\34\3\3\11\34\7\3\12\34"+
+ "\3\3\2\0\1\3\4\0\301\3\5\0\3\3\26\0"+
+ "\2\3\7\0\36\3\4\0\224\3\3\0\273\3\125\34"+
+ "\1\3\107\34\1\3\2\34\2\3\1\34\2\3\2\34"+
+ "\2\3\4\34\1\3\14\34\1\3\1\34\1\3\7\34"+
+ "\1\3\101\34\1\3\4\34\2\3\10\34\1\3\7\34"+
+ "\1\3\34\34\1\3\4\34\1\3\5\34\1\3\1\34"+
+ "\3\3\7\34\1\3\u0154\34\2\3\31\34\1\3\31\34"+
+ "\1\3\37\34\1\3\31\34\1\3\37\34\1\3\31\34"+
+ "\1\3\37\34\1\3\31\34\1\3\37\34\1\3\31\34"+
+ "\1\3\10\34\2\3\151\0\4\3\62\0\10\3\1\0"+
+ "\16\3\1\0\26\3\5\0\1\3\17\0\120\3\7\0"+
+ "\1\3\21\0\2\3\7\0\1\3\2\0\1\3\5\0"+
+ "\325\3\55\34\3\3\7\0\7\34\2\3\12\0\4\3"+
+ "\1\34\u0171\3\54\34\16\0\5\3\1\0\305\34\13\3"+
+ "\7\0\51\3\104\34\7\0\1\34\4\3\12\0\u0156\3"+
+ "\1\0\117\3\4\34\1\3\33\34\1\3\2\34\1\3"+
+ "\1\34\2\3\1\34\1\3\12\34\1\3\4\34\1\3"+
+ "\1\34\1\3\1\34\6\3\1\34\4\3\1\34\1\3"+
+ "\1\34\1\3\1\34\1\3\3\34\1\3\2\34\1\3"+
+ "\1\34\2\3\1\34\1\3\1\34\1\3\1\34\1\3"+
+ "\1\34\1\3\1\34\1\3\2\34\1\3\1\34\2\3"+
+ "\4\34\1\3\7\34\1\3\4\34\1\3\4\34\1\3"+
+ "\1\34\1\3\12\34\1\3\21\34\5\3\3\34\1\3"+
+ "\5\34\1\3\21\34\u0134\3\12\0\6\3\327\34\7\0"+
+ "\42\3\65\34\13\3\336\34\2\3\u0182\34\16\3\u0131\34"+
+ "\37\3\36\34\342\3\113\0\266\3\1\0\36\3\140\0"+
+ "\200\3\360\0\20\3";
+
+ private static int [] zzUnpackcmap_blocks() {
+ int [] result = new int[31488];
+ int offset = 0;
+ offset = zzUnpackcmap_blocks(ZZ_CMAP_BLOCKS_PACKED_0, offset, result);
+ return result;
+ }
+
+ private static int zzUnpackcmap_blocks(String packed, int offset, int [] result) {
+ int i = 0; /* index in packed string */
+ int j = offset; /* index in unpacked array */
+ int l = packed.length();
+ while (i < l) {
+ int count = packed.charAt(i++);
+ int value = packed.charAt(i++);
+ do result[j++] = value; while (--count > 0);
+ }
+ return j;
+ }
+
+ /**
+ * Translates DFA states to action switch labels.
+ */
+ private static final int [] ZZ_ACTION = zzUnpackAction();
+
+ private static final String ZZ_ACTION_PACKED_0 =
+ "\2\0\1\1\1\2\1\3\1\4\1\5\1\6\1\7"+
+ "\1\10\1\11\1\12\1\13\1\14\1\15\1\16\1\17"+
+ "\1\20\1\21\2\22\1\23\1\24\1\25\1\26\1\27"+
+ "\1\30\1\31\1\32\1\33\1\34\15\31\1\35\1\36"+
+ "\1\37\1\7\1\40\1\41\2\4\1\42\1\43\2\11"+
+ "\1\44\1\0\1\44\1\45\1\46\1\47\1\50\1\51"+
+ "\1\52\3\31\1\53\1\31\1\54\1\55\1\56\3\31"+
+ "\1\57\4\31\1\60\1\61\1\44\1\62\1\63\1\31"+
+ "\1\64\1\31\1\65\1\31\1\66\1\67\1\70\1\71"+
+ "\1\31\1\72\1\73\2\31\1\74\1\75\2\31\1\0"+
+ "\1\76\1\77\1\100\1\101\1\31\1\0\1\31\1\102"+
+ "\3\31\1\103";
+
+ private static int [] zzUnpackAction() {
+ int [] result = new int[117];
+ int offset = 0;
+ offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result);
+ return result;
+ }
+
+ private static int zzUnpackAction(String packed, int offset, int [] result) {
+ int i = 0; /* index in packed string */
+ int j = offset; /* index in unpacked array */
+ int l = packed.length();
+ while (i < l) {
+ int count = packed.charAt(i++);
+ int value = packed.charAt(i++);
+ do result[j++] = value; while (--count > 0);
+ }
+ return j;
+ }
+
+
+ /**
+ * Translates a state to a row index in the transition table
+ */
+ private static final int [] ZZ_ROWMAP = zzUnpackRowMap();
+
+ private static final String ZZ_ROWMAP_PACKED_0 =
+ "\0\0\0\73\0\166\0\261\0\354\0\u0127\0\166\0\166"+
+ "\0\u0162\0\u019d\0\u01d8\0\166\0\166\0\166\0\166\0\166"+
+ "\0\166\0\u0213\0\166\0\u024e\0\u0289\0\166\0\u02c4\0\u02ff"+
+ "\0\u033a\0\166\0\166\0\u0375\0\166\0\166\0\166\0\u03b0"+
+ "\0\u03eb\0\u0426\0\u0461\0\u049c\0\u04d7\0\u0512\0\u054d\0\u0588"+
+ "\0\u05c3\0\u05fe\0\u0639\0\u0674\0\166\0\u06af\0\166\0\166"+
+ "\0\166\0\166\0\166\0\u06ea\0\166\0\166\0\166\0\u0725"+
+ "\0\u0760\0\u079b\0\u07d6\0\166\0\166\0\166\0\166\0\166"+
+ "\0\u0811\0\u084c\0\u0887\0\u08c2\0\u0375\0\u08fd\0\u0938\0\u0973"+
+ "\0\u09ae\0\u09e9\0\u0a24\0\u0a5f\0\u0375\0\u0a9a\0\u0ad5\0\u0b10"+
+ "\0\u0b4b\0\166\0\166\0\u0b86\0\166\0\u0375\0\u0bc1\0\u0375"+
+ "\0\u0bfc\0\u0375\0\u0c37\0\u0375\0\u0375\0\u0375\0\u0c72\0\u0cad"+
+ "\0\u0375\0\u0375\0\u0ce8\0\u0d23\0\u0375\0\u0375\0\u0d5e\0\u0d99"+
+ "\0\u0dd4\0\u0375\0\u0375\0\u0375\0\u0375\0\u0e0f\0\u0e4a\0\u0e85"+
+ "\0\166\0\u0ec0\0\u0efb\0\u0f36\0\u0375";
+
+ private static int [] zzUnpackRowMap() {
+ int [] result = new int[117];
+ int offset = 0;
+ offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result);
+ return result;
+ }
+
+ private static int zzUnpackRowMap(String packed, int offset, int [] result) {
+ int i = 0; /* index in packed string */
+ int j = offset; /* index in unpacked array */
+ int l = packed.length() - 1;
+ while (i < l) {
+ int high = packed.charAt(i++) << 16;
+ result[j++] = high | packed.charAt(i++);
+ }
+ return j;
+ }
+
+ /**
+ * The transition table of the DFA
+ */
+ private static final int [] ZZ_TRANS = zzUnpacktrans();
+
+ private static final String ZZ_TRANS_PACKED_0 =
+ "\1\3\2\4\1\3\1\4\1\5\1\6\1\7\1\10"+
+ "\1\11\1\12\1\13\1\14\1\15\1\16\1\17\1\20"+
+ "\1\21\1\22\1\23\1\24\1\25\1\26\1\27\1\30"+
+ "\1\31\1\32\1\33\4\34\1\35\1\3\1\36\1\37"+
+ "\1\40\1\41\2\34\1\42\1\43\1\44\1\34\1\45"+
+ "\1\46\1\47\1\50\2\34\1\51\1\52\1\53\1\34"+
+ "\1\54\1\55\1\56\1\3\1\57\1\3\2\4\1\3"+
+ "\1\4\1\5\1\6\1\7\1\10\1\60\1\12\1\13"+
+ "\1\14\1\15\1\16\1\17\1\20\1\21\1\22\1\23"+
+ "\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33"+
+ "\4\34\1\35\1\3\1\36\1\37\1\40\1\41\2\34"+
+ "\1\42\1\43\1\44\1\34\1\45\1\46\1\47\1\50"+
+ "\2\34\1\51\1\52\1\53\1\34\1\54\1\55\1\56"+
+ "\1\61\1\57\74\0\2\4\1\0\1\4\116\0\1\62"+
+ "\42\0\2\6\1\0\3\6\1\63\32\6\1\64\31\6"+
+ "\67\0\1\65\15\0\1\66\60\0\2\13\1\0\10\13"+
+ "\1\67\25\13\1\70\31\13\24\0\2\71\67\0\1\71"+
+ "\1\0\2\72\10\0\1\73\1\74\10\0\1\73\2\0"+
+ "\1\74\41\0\1\71\1\0\2\25\10\0\1\73\1\74"+
+ "\10\0\1\73\2\0\1\74\46\0\1\75\1\76\72\0"+
+ "\1\77\72\0\1\100\1\101\41\0\1\34\7\0\1\34"+
+ "\13\0\2\34\6\0\4\34\4\0\23\34\4\0\1\34"+
+ "\7\0\1\34\13\0\2\34\6\0\4\34\4\0\12\34"+
+ "\1\102\10\34\4\0\1\34\7\0\1\34\13\0\2\34"+
+ "\6\0\4\34\4\0\1\103\12\34\1\104\7\34\4\0"+
+ "\1\34\7\0\1\34\13\0\2\34\6\0\4\34\4\0"+
+ "\14\34\1\105\6\34\4\0\1\34\7\0\1\34\13\0"+
+ "\2\34\6\0\4\34\4\0\1\106\22\34\4\0\1\34"+
+ "\7\0\1\34\13\0\2\34\6\0\4\34\4\0\17\34"+
+ "\1\107\3\34\4\0\1\34\7\0\1\34\13\0\2\34"+
+ "\6\0\4\34\4\0\12\34\1\110\10\34\4\0\1\34"+
+ "\7\0\1\34\13\0\2\34\6\0\4\34\4\0\17\34"+
+ "\1\111\3\34\4\0\1\34\7\0\1\34\13\0\2\34"+
+ "\6\0\4\34\4\0\4\34\1\112\6\34\1\113\4\34"+
+ "\1\114\2\34\4\0\1\34\7\0\1\34\13\0\2\34"+
+ "\6\0\4\34\4\0\15\34\1\115\5\34\4\0\1\34"+
+ "\7\0\1\34\13\0\2\34\6\0\4\34\4\0\7\34"+
+ "\1\116\13\34\4\0\1\34\7\0\1\34\13\0\2\34"+
+ "\6\0\4\34\4\0\15\34\1\117\5\34\4\0\1\34"+
+ "\7\0\1\34\13\0\2\34\6\0\4\34\4\0\16\34"+
+ "\1\120\4\34\4\0\1\34\7\0\1\34\13\0\2\34"+
+ "\6\0\4\34\4\0\13\34\1\121\7\34\74\0\1\122"+
+ "\2\0\2\6\1\0\70\6\2\13\1\0\70\13\24\0"+
+ "\2\71\7\0\1\123\1\73\6\0\1\123\2\0\1\73"+
+ "\44\0\1\71\1\0\2\72\10\0\1\73\11\0\1\73"+
+ "\41\0\1\124\1\0\1\124\2\0\2\124\7\0\1\123"+
+ "\7\0\1\123\56\0\1\125\41\0\1\34\7\0\1\34"+
+ "\13\0\2\34\6\0\4\34\4\0\3\34\1\126\17\34"+
+ "\4\0\1\34\7\0\1\34\13\0\2\34\6\0\4\34"+
+ "\4\0\12\34\1\127\10\34\4\0\1\34\7\0\1\34"+
+ "\13\0\2\34\6\0\4\34\4\0\15\34\1\130\5\34"+
+ "\4\0\1\34\7\0\1\34\13\0\2\34\6\0\4\34"+
+ "\4\0\11\34\1\131\11\34\4\0\1\34\7\0\1\34"+
+ "\13\0\2\34\6\0\4\34\4\0\4\34\1\132\16\34"+
+ "\4\0\1\34\7\0\1\34\13\0\2\34\6\0\4\34"+
+ "\4\0\16\34\1\133\4\34\4\0\1\34\7\0\1\34"+
+ "\13\0\2\34\6\0\4\34\4\0\4\34\1\134\16\34"+
+ "\4\0\1\34\7\0\1\34\13\0\2\34\6\0\4\34"+
+ "\4\0\14\34\1\135\4\34\1\136\1\34\4\0\1\34"+
+ "\7\0\1\34\13\0\2\34\6\0\4\34\4\0\17\34"+
+ "\1\137\3\34\4\0\1\34\7\0\1\34\13\0\2\34"+
+ "\6\0\4\34\4\0\11\34\1\140\11\34\4\0\1\34"+
+ "\7\0\1\34\13\0\2\34\6\0\4\34\4\0\11\34"+
+ "\1\141\3\34\1\142\5\34\4\0\1\34\7\0\1\34"+
+ "\13\0\2\34\6\0\4\34\4\0\20\34\1\143\2\34"+
+ "\4\0\1\34\7\0\1\34\13\0\2\34\6\0\4\34"+
+ "\4\0\7\34\1\144\13\34\4\0\1\34\7\0\1\34"+
+ "\13\0\2\34\6\0\4\34\4\0\15\34\1\145\5\34"+
+ "\30\0\2\124\7\0\1\123\7\0\1\123\25\0\1\34"+
+ "\7\0\1\34\13\0\2\34\6\0\4\34\4\0\3\34"+
+ "\1\146\17\34\4\0\1\34\7\0\1\34\13\0\2\34"+
+ "\6\0\4\34\4\0\16\34\1\147\4\34\4\0\1\34"+
+ "\7\0\1\34\13\0\2\34\6\0\4\34\4\0\17\34"+
+ "\1\150\3\34\4\0\1\34\3\0\1\151\3\0\1\34"+
+ "\13\0\2\34\6\0\4\34\4\0\23\34\4\0\1\34"+
+ "\7\0\1\34\13\0\2\34\6\0\4\34\4\0\11\34"+
+ "\1\152\11\34\4\0\1\34\7\0\1\34\13\0\2\34"+
+ "\6\0\4\34\4\0\4\34\1\153\16\34\4\0\1\34"+
+ "\7\0\1\34\13\0\2\34\6\0\4\34\4\0\15\34"+
+ "\1\154\5\34\4\0\1\34\7\0\1\34\13\0\2\34"+
+ "\6\0\4\34\4\0\4\34\1\155\16\34\4\0\1\34"+
+ "\7\0\1\34\13\0\2\34\6\0\4\34\4\0\1\156"+
+ "\22\34\60\0\1\157\16\0\1\34\7\0\1\34\13\0"+
+ "\2\34\6\0\4\34\4\0\12\34\1\160\10\34\62\0"+
+ "\1\161\14\0\1\34\7\0\1\34\13\0\2\34\6\0"+
+ "\4\34\4\0\2\34\1\162\20\34\4\0\1\34\7\0"+
+ "\1\34\13\0\2\34\6\0\4\34\4\0\4\34\1\163"+
+ "\16\34\4\0\1\34\7\0\1\34\13\0\2\34\6\0"+
+ "\4\34\4\0\13\34\1\164\7\34\4\0\1\34\7\0"+
+ "\1\34\13\0\2\34\6\0\4\34\4\0\5\34\1\165"+
+ "\15\34\4\0";
+
+ private static int [] zzUnpacktrans() {
+ int [] result = new int[3953];
+ int offset = 0;
+ offset = zzUnpacktrans(ZZ_TRANS_PACKED_0, offset, result);
+ return result;
+ }
+
+ private static int zzUnpacktrans(String packed, int offset, int [] result) {
+ int i = 0; /* index in packed string */
+ int j = offset; /* index in unpacked array */
+ int l = packed.length();
+ while (i < l) {
+ int count = packed.charAt(i++);
+ int value = packed.charAt(i++);
+ value--;
+ do result[j++] = value; while (--count > 0);
+ }
+ return j;
+ }
+
+
+ /* error codes */
+ private static final int ZZ_UNKNOWN_ERROR = 0;
+ private static final int ZZ_NO_MATCH = 1;
+ private static final int ZZ_PUSHBACK_2BIG = 2;
+
+ /* error messages for the codes above */
+ private static final String[] ZZ_ERROR_MSG = {
+ "Unknown internal scanner error",
+ "Error: could not match input",
+ "Error: pushback value was too large"
+ };
+
+ /**
+ * ZZ_ATTRIBUTE[aState] contains the attributes of state {@code aState}
+ */
+ private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute();
+
+ private static final String ZZ_ATTRIBUTE_PACKED_0 =
+ "\2\0\1\11\3\1\2\11\3\1\6\11\1\1\1\11"+
+ "\2\1\1\11\3\1\2\11\1\1\3\11\15\1\1\11"+
+ "\1\1\5\11\1\1\3\11\2\1\1\0\1\1\5\11"+
+ "\21\1\2\11\1\1\1\11\23\1\1\0\5\1\1\0"+
+ "\1\1\1\11\4\1";
+
+ private static int [] zzUnpackAttribute() {
+ int [] result = new int[117];
+ int offset = 0;
+ offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result);
+ return result;
+ }
+
+ private static int zzUnpackAttribute(String packed, int offset, int [] result) {
+ int i = 0; /* index in packed string */
+ int j = offset; /* index in unpacked array */
+ int l = packed.length();
+ while (i < l) {
+ int count = packed.charAt(i++);
+ int value = packed.charAt(i++);
+ do result[j++] = value; while (--count > 0);
+ }
+ return j;
+ }
+
+ /** the input device */
+ private java.io.Reader zzReader;
+
+ /** the current state of the DFA */
+ private int zzState;
+
+ /** the current lexical state */
+ private int zzLexicalState = YYINITIAL;
+
+ /** this buffer contains the current text to be matched and is
+ the source of the yytext() string */
+ private CharSequence zzBuffer = "";
+
+ /** the textposition at the last accepting state */
+ private int zzMarkedPos;
+
+ /** the current text position in the buffer */
+ private int zzCurrentPos;
+
+ /** startRead marks the beginning of the yytext() string in the buffer */
+ private int zzStartRead;
+
+ /** endRead marks the last character in the buffer, that has been read
+ from input */
+ private int zzEndRead;
+
+ /** zzAtEOF == true <=> the scanner is at the EOF */
+ private boolean zzAtEOF;
+
+ /** Number of newlines encountered up to the start of the matched text. */
+ @SuppressWarnings("unused")
+ private int yyline;
+
+ /** Number of characters from the last newline up to the start of the matched text. */
+ @SuppressWarnings("unused")
+ protected int yycolumn;
+
+ /** Number of characters up to the start of the matched text. */
+ @SuppressWarnings("unused")
+ private long yychar;
+
+ /** Whether the scanner is currently at the beginning of a line. */
+ @SuppressWarnings("unused")
+ private boolean zzAtBOL = true;
+
+ /** Whether the user-EOF-code has already been executed. */
+ private boolean zzEOFDone;
+
+ /* user code: */
+ public _OgnlLexer(){
+ this((java.io.Reader)null);
+ }
+
+ private static final class State {
+ final int lBraceCount;
+ final int state;
+
+ private State(int state, int lBraceCount) {
+ this.state = state;
+ this.lBraceCount = lBraceCount;
+ }
+
+ @Override
+ public String toString() {
+ return "yystate = " + state + (lBraceCount == 0 ? "" : "lBraceCount = " + lBraceCount);
+ }
+ }
+
+ private final Stack<State> myStateStack = new Stack<>();
+ private int myLeftBraceCount;
+
+ protected void resetInternal() {
+ myLeftBraceCount = 0;
+ myStateStack.clear();
+ }
+
+ private void pushState(int newState) {
+ myStateStack.push(new State(yystate(), myLeftBraceCount));
+ myLeftBraceCount = 0;
+ yybegin(newState);
+ }
+
+ private void popState() {
+ if (myStateStack.empty()) return;
+
+ State state = myStateStack.pop();
+ myLeftBraceCount = state.lBraceCount;
+ yybegin(state.state);
+ }
+
+
+ /**
+ * Creates a new scanner
+ *
+ * @param in the java.io.Reader to read input from.
+ */
+ public _OgnlLexer(java.io.Reader in) {
+ this.zzReader = in;
+ }
+
+
+ /** Returns the maximum size of the scanner buffer, which limits the size of tokens. */
+ private int zzMaxBufferLen() {
+ return Integer.MAX_VALUE;
+ }
+
+ /** Whether the scanner buffer can grow to accommodate a larger token. */
+ private boolean zzCanGrow() {
+ return true;
+ }
+
+ /**
+ * Translates raw input code points to DFA table row
+ */
+ private static int zzCMap(int input) {
+ int offset = input & 255;
+ return offset == input ? ZZ_CMAP_BLOCKS[offset] : ZZ_CMAP_BLOCKS[ZZ_CMAP_TOP[input >> 8] | offset];
+ }
+
+ public final int getTokenStart() {
+ return zzStartRead;
+ }
+
+ public final int getTokenEnd() {
+ return getTokenStart() + yylength();
+ }
+
+ public void reset(CharSequence buffer, int start, int end, int initialState) {
+ zzBuffer = buffer;
+ zzCurrentPos = zzMarkedPos = zzStartRead = start;
+ zzAtEOF = false;
+ zzAtBOL = true;
+ zzEndRead = end;
+ yybegin(initialState);
+ }
+
+ /**
+ * Refills the input buffer.
+ *
+ * @return {@code false}, iff there was new input.
+ *
+ * @exception java.io.IOException if any I/O-Error occurs
+ */
+ private boolean zzRefill() throws java.io.IOException {
+ return true;
+ }
+
+
+ /**
+ * Returns the current lexical state.
+ */
+ public final int yystate() {
+ return zzLexicalState;
+ }
+
+
+ /**
+ * Enters a new lexical state
+ *
+ * @param newState the new lexical state
+ */
+ public final void yybegin(int newState) {
+ zzLexicalState = newState;
+ }
+
+
+ /**
+ * Returns the text matched by the current regular expression.
+ */
+ public final CharSequence yytext() {
+ return zzBuffer.subSequence(zzStartRead, zzMarkedPos);
+ }
+
+
+ /**
+ * Returns the character at position {@code pos} from the
+ * matched text.
+ *
+ * It is equivalent to yytext().charAt(pos), but faster
+ *
+ * @param pos the position of the character to fetch.
+ * A value from 0 to yylength()-1.
+ *
+ * @return the character at position pos
+ */
+ public final char yycharat(int pos) {
+ return zzBuffer.charAt(zzStartRead+pos);
+ }
+
+
+ /**
+ * Returns the length of the matched text region.
+ */
+ public final int yylength() {
+ return zzMarkedPos-zzStartRead;
+ }
+
+
+ /**
+ * Reports an error that occurred while scanning.
+ *
+ * In a wellformed scanner (no or only correct usage of
+ * yypushback(int) and a match-all fallback rule) this method
+ * will only be called with things that "Can't Possibly Happen".
+ * If this method is called, something is seriously wrong
+ * (e.g. a JFlex bug producing a faulty scanner etc.).
+ *
+ * Usual syntax/scanner level error handling should be done
+ * in error fallback rules.
+ *
+ * @param errorCode the code of the errormessage to display
+ */
+ private void zzScanError(int errorCode) {
+ String message;
+ try {
+ message = ZZ_ERROR_MSG[errorCode];
+ }
+ catch (ArrayIndexOutOfBoundsException e) {
+ message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR];
+ }
+
+ throw new Error(message);
+ }
+
+
+ /**
+ * Pushes the specified amount of characters back into the input stream.
+ *
+ * They will be read again by then next call of the scanning method
+ *
+ * @param number the number of characters to be read again.
+ * This number must not be greater than yylength()!
+ */
+ public void yypushback(int number) {
+ if ( number > yylength() )
+ zzScanError(ZZ_PUSHBACK_2BIG);
+
+ zzMarkedPos -= number;
+ }
+
+
+ /**
+ * Contains user EOF-code, which will be executed exactly once,
+ * when the end of file is reached
+ */
+ private void zzDoEOF() {
+ if (!zzEOFDone) {
+ zzEOFDone = true;
+
+ resetInternal();
+ }
+ }
+
+
+ /**
+ * Resumes scanning until the next regular expression is matched,
+ * the end of input is encountered or an I/O-Error occurs.
+ *
+ * @return the next token
+ * @exception java.io.IOException if any I/O-Error occurs
+ */
+ public IElementType advance() throws java.io.IOException
+ {
+ int zzInput;
+ int zzAction;
+
+ // cached fields:
+ int zzCurrentPosL;
+ int zzMarkedPosL;
+ int zzEndReadL = zzEndRead;
+ CharSequence zzBufferL = zzBuffer;
+
+ int [] zzTransL = ZZ_TRANS;
+ int [] zzRowMapL = ZZ_ROWMAP;
+ int [] zzAttrL = ZZ_ATTRIBUTE;
+
+ while (true) {
+ zzMarkedPosL = zzMarkedPos;
+
+ zzAction = -1;
+
+ zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL;
+
+ zzState = ZZ_LEXSTATE[zzLexicalState];
+
+ // set up zzAction for empty match case:
+ int zzAttributes = zzAttrL[zzState];
+ if ( (zzAttributes & 1) == 1 ) {
+ zzAction = zzState;
+ }
+
+
+ zzForAction: {
+ while (true) {
+
+ if (zzCurrentPosL < zzEndReadL) {
+ zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL);
+ zzCurrentPosL += Character.charCount(zzInput);
+ }
+ else if (zzAtEOF) {
+ zzInput = YYEOF;
+ break zzForAction;
+ }
+ else {
+ // store back cached positions
+ zzCurrentPos = zzCurrentPosL;
+ zzMarkedPos = zzMarkedPosL;
+ boolean eof = zzRefill();
+ // get translated positions and possibly new buffer
+ zzCurrentPosL = zzCurrentPos;
+ zzMarkedPosL = zzMarkedPos;
+ zzBufferL = zzBuffer;
+ zzEndReadL = zzEndRead;
+ if (eof) {
+ zzInput = YYEOF;
+ break zzForAction;
+ }
+ else {
+ zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL);
+ zzCurrentPosL += Character.charCount(zzInput);
+ }
+ }
+ int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMap(zzInput) ];
+ if (zzNext == -1) break zzForAction;
+ zzState = zzNext;
+
+ zzAttributes = zzAttrL[zzState];
+ if ( (zzAttributes & 1) == 1 ) {
+ zzAction = zzState;
+ zzMarkedPosL = zzCurrentPosL;
+ if ( (zzAttributes & 8) == 8 ) break zzForAction;
+ }
+
+ }
+ }
+
+ // store back cached position
+ zzMarkedPos = zzMarkedPosL;
+
+ if (zzInput == YYEOF && zzStartRead == zzCurrentPos) {
+ zzAtEOF = true;
+ zzDoEOF();
+ return null;
+ }
+ else {
+ switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) {
+ case 1:
+ { return TokenType.BAD_CHARACTER;
+ }
+ // fall through
+ case 68: break;
+ case 2:
+ { return TokenType.WHITE_SPACE;
+ }
+ // fall through
+ case 69: break;
+ case 3:
+ { return OgnlTypes.NEGATE;
+ }
+ // fall through
+ case 70: break;
+ case 4:
+ { return OgnlTypes.STRING_LITERAL;
+ }
+ // fall through
+ case 71: break;
+ case 5:
+ { return OgnlTypes.HASH;
+ }
+ // fall through
+ case 72: break;
+ case 6:
+ { return OgnlTypes.DOLLAR;
+ }
+ // fall through
+ case 73: break;
+ case 7:
+ { return OgnlTypes.MODULO;
+ }
+ // fall through
+ case 74: break;
+ case 8:
+ { return OgnlTypes.AND;
+ }
+ // fall through
+ case 75: break;
+ case 9:
+ { return OgnlTypes.CHARACTER_LITERAL;
+ }
+ // fall through
+ case 76: break;
+ case 10:
+ { return OgnlTypes.LPARENTH;
+ }
+ // fall through
+ case 77: break;
+ case 11:
+ { return OgnlTypes.RPARENTH;
+ }
+ // fall through
+ case 78: break;
+ case 12:
+ { return OgnlTypes.MULTIPLY;
+ }
+ // fall through
+ case 79: break;
+ case 13:
+ { return OgnlTypes.PLUS;
+ }
+ // fall through
+ case 80: break;
+ case 14:
+ { return OgnlTypes.COMMA;
+ }
+ // fall through
+ case 81: break;
+ case 15:
+ { return OgnlTypes.MINUS;
+ }
+ // fall through
+ case 82: break;
+ case 16:
+ { return OgnlTypes.DOT;
+ }
+ // fall through
+ case 83: break;
+ case 17:
+ { return OgnlTypes.DIVISION;
+ }
+ // fall through
+ case 84: break;
+ case 18:
+ { return OgnlTypes.INTEGER_LITERAL;
+ }
+ // fall through
+ case 85: break;
+ case 19:
+ { return OgnlTypes.COLON;
+ }
+ // fall through
+ case 86: break;
+ case 20:
+ { return OgnlTypes.LESS;
+ }
+ // fall through
+ case 87: break;
+ case 21:
+ { return OgnlTypes.EQ;
+ }
+ // fall through
+ case 88: break;
+ case 22:
+ { return OgnlTypes.GREATER;
+ }
+ // fall through
+ case 89: break;
+ case 23:
+ { return OgnlTypes.QUESTION;
+ }
+ // fall through
+ case 90: break;
+ case 24:
+ { return OgnlTypes.AT;
+ }
+ // fall through
+ case 91: break;
+ case 25:
+ { return OgnlTypes.IDENTIFIER;
+ }
+ // fall through
+ case 92: break;
+ case 26:
+ { return OgnlTypes.LBRACKET;
+ }
+ // fall through
+ case 93: break;
+ case 27:
+ { return OgnlTypes.RBRACKET;
+ }
+ // fall through
+ case 94: break;
+ case 28:
+ { return OgnlTypes.XOR;
+ }
+ // fall through
+ case 95: break;
+ case 29:
+ { myLeftBraceCount++;
+ pushState(NESTED_BRACE);
+ return OgnlTypes.LBRACE;
+ }
+ // fall through
+ case 96: break;
+ case 30:
+ { return OgnlTypes.OR;
+ }
+ // fall through
+ case 97: break;
+ case 31:
+ { return OgnlTypes.NOT;
+ }
+ // fall through
+ case 98: break;
+ case 32:
+ { popState();
+ if (myLeftBraceCount == 0) {
+ return OgnlTypes.EXPRESSION_END;
+ }
+
+ myLeftBraceCount--;
+ return OgnlTypes.RBRACE;
+ }
+ // fall through
+ case 99: break;
+ case 33:
+ { return OgnlTypes.NOT_EQUAL;
+ }
+ // fall through
+ case 100: break;
+ case 34:
+ { pushState(EXPR);
+ return OgnlTypes.EXPRESSION_START;
+ }
+ // fall through
+ case 101: break;
+ case 35:
+ { return OgnlTypes.AND_AND;
+ }
+ // fall through
+ case 102: break;
+ case 36:
+ { return OgnlTypes.DOUBLE_LITERAL;
+ }
+ // fall through
+ case 103: break;
+ case 37:
+ { return OgnlTypes.BIG_INTEGER_LITERAL;
+ }
+ // fall through
+ case 104: break;
+ case 38:
+ { return OgnlTypes.SHIFT_LEFT;
+ }
+ // fall through
+ case 105: break;
+ case 39:
+ { return OgnlTypes.LESS_EQUAL;
+ }
+ // fall through
+ case 106: break;
+ case 40:
+ { return OgnlTypes.EQUAL;
+ }
+ // fall through
+ case 107: break;
+ case 41:
+ { return OgnlTypes.GREATER_EQUAL;
+ }
+ // fall through
+ case 108: break;
+ case 42:
+ { return OgnlTypes.SHIFT_RIGHT;
+ }
+ // fall through
+ case 109: break;
+ case 43:
+ { return OgnlTypes.EQ_KEYWORD;
+ }
+ // fall through
+ case 110: break;
+ case 44:
+ { return OgnlTypes.GT_KEYWORD;
+ }
+ // fall through
+ case 111: break;
+ case 45:
+ { return OgnlTypes.IN_KEYWORD;
+ }
+ // fall through
+ case 112: break;
+ case 46:
+ { return OgnlTypes.LT_KEYWORD;
+ }
+ // fall through
+ case 113: break;
+ case 47:
+ { return OgnlTypes.OR_KEYWORD;
+ }
+ // fall through
+ case 114: break;
+ case 48:
+ { return OgnlTypes.OR_OR;
+ }
+ // fall through
+ case 115: break;
+ case 49:
+ { return OgnlTypes.BIG_DECIMAL_LITERAL;
+ }
+ // fall through
+ case 116: break;
+ case 50:
+ { return OgnlTypes.SHIFT_RIGHT_LOGICAL;
+ }
+ // fall through
+ case 117: break;
+ case 51:
+ { return OgnlTypes.AND_KEYWORD;
+ }
+ // fall through
+ case 118: break;
+ case 52:
+ { return OgnlTypes.BOR_KEYWORD;
+ }
+ // fall through
+ case 119: break;
+ case 53:
+ { return OgnlTypes.GT_EQ_KEYWORD;
+ }
+ // fall through
+ case 120: break;
+ case 54:
+ { return OgnlTypes.LT_EQ_KEYWORD;
+ }
+ // fall through
+ case 121: break;
+ case 55:
+ { return OgnlTypes.NEQ_KEYWORD;
+ }
+ // fall through
+ case 122: break;
+ case 56:
+ { return OgnlTypes.NEW_KEYWORD;
+ }
+ // fall through
+ case 123: break;
+ case 57:
+ { return OgnlTypes.NOT_KEYWORD;
+ }
+ // fall through
+ case 124: break;
+ case 58:
+ { return OgnlTypes.SHIFT_LEFT_KEYWORD;
+ }
+ // fall through
+ case 125: break;
+ case 59:
+ { return OgnlTypes.SHIFT_RIGHT_KEYWORD;
+ }
+ // fall through
+ case 126: break;
+ case 60:
+ { return OgnlTypes.XOR_KEYWORD;
+ }
+ // fall through
+ case 127: break;
+ case 61:
+ { return OgnlTypes.BAND_KEYWORD;
+ }
+ // fall through
+ case 128: break;
+ case 62:
+ { return OgnlTypes.NULL_KEYWORD;
+ }
+ // fall through
+ case 129: break;
+ case 63:
+ { return OgnlTypes.TRUE_KEYWORD;
+ }
+ // fall through
+ case 130: break;
+ case 64:
+ { return OgnlTypes.SHIFT_RIGHT_LOGICAL_KEYWORD;
+ }
+ // fall through
+ case 131: break;
+ case 65:
+ { return OgnlTypes.FALSE_KEYWORD;
+ }
+ // fall through
+ case 132: break;
+ case 66:
+ { return OgnlTypes.NOT_IN_KEYWORD;
+ }
+ // fall through
+ case 133: break;
+ case 67:
+ { return OgnlTypes.INSTANCEOF_KEYWORD;
+ }
+ // fall through
+ case 134: break;
+ default:
+ zzScanError(ZZ_NO_MATCH);
+ }
+ }
+ }
+ }
+
+
+}
diff --git a/src/main/gen/parser/OgnlParser.java b/src/main/gen/parser/OgnlParser.java
new file mode 100644
index 0000000..741c85a
--- /dev/null
+++ b/src/main/gen/parser/OgnlParser.java
@@ -0,0 +1,1006 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.parser;
+
+import com.intellij.lang.PsiBuilder;
+import com.intellij.lang.PsiBuilder.Marker;
+import static com.intellij.lang.ognl.OgnlTypes.*;
+import static com.intellij.lang.parser.GeneratedParserUtilBase.*;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.tree.TokenSet;
+import com.intellij.lang.PsiParser;
+import com.intellij.lang.LightPsiParser;
+
+@SuppressWarnings({"SimplifiableIfStatement", "UnusedAssignment"})
+public class OgnlParser implements PsiParser, LightPsiParser {
+
+ public ASTNode parse(IElementType t, PsiBuilder b) {
+ parseLight(t, b);
+ return b.getTreeBuilt();
+ }
+
+ public void parseLight(IElementType t, PsiBuilder b) {
+ boolean r;
+ b = adapt_builder_(t, b, this, EXTENDS_SETS_);
+ Marker m = enter_section_(b, 0, _COLLAPSE_, null);
+ r = parse_root_(t, b);
+ exit_section_(b, 0, m, t, r, true, TRUE_CONDITION);
+ }
+
+ protected boolean parse_root_(IElementType t, PsiBuilder b) {
+ return parse_root_(t, b, 0);
+ }
+
+ static boolean parse_root_(IElementType t, PsiBuilder b, int l) {
+ return root(b, l + 1);
+ }
+
+ public static final TokenSet[] EXTENDS_SETS_ = new TokenSet[] {
+ create_token_set_(BINARY_EXPRESSION, CONDITIONAL_EXPRESSION, EXPRESSION, FQN_TYPE_EXPRESSION,
+ INDEXED_EXPRESSION, LAMBDA_EXPRESSION, LITERAL_EXPRESSION, MAP_EXPRESSION,
+ METHOD_CALL_EXPRESSION, NEW_ARRAY_EXPRESSION, NEW_EXPRESSION, PARENTHESIZED_EXPRESSION,
+ PROJECTION_EXPRESSION, REFERENCE_EXPRESSION, SELECTION_EXPRESSION, SEQUENCE_EXPRESSION,
+ UNARY_EXPRESSION, VARIABLE_ASSIGNMENT_EXPRESSION, VARIABLE_EXPRESSION),
+ };
+
+ /* ********************************************************** */
+ // '[' expression? ']' sequenceExpression?
+ static boolean arrayConstructorExpression(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "arrayConstructorExpression")) return false;
+ if (!nextTokenIs(b, LBRACKET)) return false;
+ boolean r, p;
+ Marker m = enter_section_(b, l, _NONE_);
+ r = consumeToken(b, LBRACKET);
+ p = r; // pin = 1
+ r = r && report_error_(b, arrayConstructorExpression_1(b, l + 1));
+ r = p && report_error_(b, consumeToken(b, RBRACKET)) && r;
+ r = p && arrayConstructorExpression_3(b, l + 1) && r;
+ exit_section_(b, l, m, r, p, null);
+ return r || p;
+ }
+
+ // expression?
+ private static boolean arrayConstructorExpression_1(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "arrayConstructorExpression_1")) return false;
+ expression(b, l + 1, -1);
+ return true;
+ }
+
+ // sequenceExpression?
+ private static boolean arrayConstructorExpression_3(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "arrayConstructorExpression_3")) return false;
+ sequenceExpression(b, l + 1);
+ return true;
+ }
+
+ /* ********************************************************** */
+ // plusMinusOperations |
+ // divideMultiplyOperations |
+ // bitwiseBooleanOperations |
+ // instanceOfOperation |
+ // shiftOperations |
+ // booleanOperations |
+ // equalityOperations |
+ // relationalOperations |
+ // setOperations
+ static boolean binaryOperations(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "binaryOperations")) return false;
+ boolean r;
+ Marker m = enter_section_(b, l, _NONE_, null, "<operator>");
+ r = plusMinusOperations(b, l + 1);
+ if (!r) r = divideMultiplyOperations(b, l + 1);
+ if (!r) r = bitwiseBooleanOperations(b, l + 1);
+ if (!r) r = instanceOfOperation(b, l + 1);
+ if (!r) r = shiftOperations(b, l + 1);
+ if (!r) r = booleanOperations(b, l + 1);
+ if (!r) r = equalityOperations(b, l + 1);
+ if (!r) r = relationalOperations(b, l + 1);
+ if (!r) r = setOperations(b, l + 1);
+ exit_section_(b, l, m, r, false, null);
+ return r;
+ }
+
+ /* ********************************************************** */
+ // "|" | "^" | "&" | "band" | "bor" | "xor"
+ static boolean bitwiseBooleanOperations(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "bitwiseBooleanOperations")) return false;
+ boolean r;
+ r = consumeToken(b, OR);
+ if (!r) r = consumeToken(b, XOR);
+ if (!r) r = consumeToken(b, AND);
+ if (!r) r = consumeToken(b, BAND_KEYWORD);
+ if (!r) r = consumeToken(b, BOR_KEYWORD);
+ if (!r) r = consumeToken(b, XOR_KEYWORD);
+ return r;
+ }
+
+ /* ********************************************************** */
+ // '!' | "~"
+ static boolean bitwiseOperations(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "bitwiseOperations")) return false;
+ if (!nextTokenIs(b, "", NEGATE, NOT)) return false;
+ boolean r;
+ r = consumeToken(b, NEGATE);
+ if (!r) r = consumeToken(b, NOT);
+ return r;
+ }
+
+ /* ********************************************************** */
+ // "true" | "false"
+ static boolean booleanLiteralExpression(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "booleanLiteralExpression")) return false;
+ if (!nextTokenIs(b, "", FALSE_KEYWORD, TRUE_KEYWORD)) return false;
+ boolean r;
+ r = consumeToken(b, TRUE_KEYWORD);
+ if (!r) r = consumeToken(b, FALSE_KEYWORD);
+ return r;
+ }
+
+ /* ********************************************************** */
+ // "&&" | "||" |
+ // "and" | "or" |
+ // "not"
+ static boolean booleanOperations(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "booleanOperations")) return false;
+ boolean r;
+ r = consumeToken(b, AND_AND);
+ if (!r) r = consumeToken(b, OR_OR);
+ if (!r) r = consumeToken(b, AND_KEYWORD);
+ if (!r) r = consumeToken(b, OR_KEYWORD);
+ if (!r) r = consumeToken(b, NOT_KEYWORD);
+ return r;
+ }
+
+ /* ********************************************************** */
+ // ':' expression
+ static boolean conditionalExpressionTail(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "conditionalExpressionTail")) return false;
+ if (!nextTokenIs(b, COLON)) return false;
+ boolean r, p;
+ Marker m = enter_section_(b, l, _NONE_);
+ r = consumeToken(b, COLON);
+ p = r; // pin = 1
+ r = r && expression(b, l + 1, -1);
+ exit_section_(b, l, m, r, p, null);
+ return r || p;
+ }
+
+ /* ********************************************************** */
+ // '(' parameterList ')'
+ static boolean constructorExpression(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "constructorExpression")) return false;
+ if (!nextTokenIs(b, LPARENTH)) return false;
+ boolean r, p;
+ Marker m = enter_section_(b, l, _NONE_);
+ r = consumeToken(b, LPARENTH);
+ p = r; // pin = 1
+ r = r && report_error_(b, parameterList(b, l + 1));
+ r = p && consumeToken(b, RPARENTH) && r;
+ exit_section_(b, l, m, r, p, null);
+ return r || p;
+ }
+
+ /* ********************************************************** */
+ // '*' | '/' | '%'
+ static boolean divideMultiplyOperations(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "divideMultiplyOperations")) return false;
+ boolean r;
+ r = consumeToken(b, MULTIPLY);
+ if (!r) r = consumeToken(b, DIVISION);
+ if (!r) r = consumeToken(b, MODULO);
+ return r;
+ }
+
+ /* ********************************************************** */
+ // "==" | "!=" |
+ // "eq" | "neq"
+ static boolean equalityOperations(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "equalityOperations")) return false;
+ boolean r;
+ r = consumeToken(b, EQUAL);
+ if (!r) r = consumeToken(b, NOT_EQUAL);
+ if (!r) r = consumeToken(b, EQ_KEYWORD);
+ if (!r) r = consumeToken(b, NEQ_KEYWORD);
+ return r;
+ }
+
+ /* ********************************************************** */
+ // expression (',' expression)+
+ static boolean expressionSequenceRequired(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "expressionSequenceRequired")) return false;
+ boolean r, p;
+ Marker m = enter_section_(b, l, _NONE_);
+ r = expression(b, l + 1, -1);
+ p = r; // pin = 1
+ r = r && expressionSequenceRequired_1(b, l + 1);
+ exit_section_(b, l, m, r, p, null);
+ return r || p;
+ }
+
+ // (',' expression)+
+ private static boolean expressionSequenceRequired_1(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "expressionSequenceRequired_1")) return false;
+ boolean r;
+ Marker m = enter_section_(b);
+ r = expressionSequenceRequired_1_0(b, l + 1);
+ while (r) {
+ int c = current_position_(b);
+ if (!expressionSequenceRequired_1_0(b, l + 1)) break;
+ if (!empty_element_parsed_guard_(b, "expressionSequenceRequired_1", c)) break;
+ }
+ exit_section_(b, m, null, r);
+ return r;
+ }
+
+ // ',' expression
+ private static boolean expressionSequenceRequired_1_0(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "expressionSequenceRequired_1_0")) return false;
+ boolean r, p;
+ Marker m = enter_section_(b, l, _NONE_);
+ r = consumeToken(b, COMMA);
+ p = r; // pin = 1
+ r = r && expression(b, l + 1, -1);
+ exit_section_(b, l, m, r, p, null);
+ return r || p;
+ }
+
+ /* ********************************************************** */
+ // IDENTIFIER ('.' IDENTIFIER)*
+ public static boolean fqnTypeExpression(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "fqnTypeExpression")) return false;
+ if (!nextTokenIs(b, IDENTIFIER)) return false;
+ boolean r, p;
+ Marker m = enter_section_(b, l, _NONE_, FQN_TYPE_EXPRESSION, null);
+ r = consumeToken(b, IDENTIFIER);
+ p = r; // pin = 1
+ r = r && fqnTypeExpression_1(b, l + 1);
+ exit_section_(b, l, m, r, p, null);
+ return r || p;
+ }
+
+ // ('.' IDENTIFIER)*
+ private static boolean fqnTypeExpression_1(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "fqnTypeExpression_1")) return false;
+ while (true) {
+ int c = current_position_(b);
+ if (!fqnTypeExpression_1_0(b, l + 1)) break;
+ if (!empty_element_parsed_guard_(b, "fqnTypeExpression_1", c)) break;
+ }
+ return true;
+ }
+
+ // '.' IDENTIFIER
+ private static boolean fqnTypeExpression_1_0(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "fqnTypeExpression_1_0")) return false;
+ boolean r, p;
+ Marker m = enter_section_(b, l, _NONE_);
+ r = consumeTokens(b, 1, DOT, IDENTIFIER);
+ p = r; // pin = 1
+ exit_section_(b, l, m, r, p, null);
+ return r || p;
+ }
+
+ /* ********************************************************** */
+ // "instanceof"
+ static boolean instanceOfOperation(PsiBuilder b, int l) {
+ return consumeToken(b, INSTANCEOF_KEYWORD);
+ }
+
+ /* ********************************************************** */
+ // expression ':' expression
+ public static boolean mapEntryElement(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "mapEntryElement")) return false;
+ boolean r, p;
+ Marker m = enter_section_(b, l, _NONE_, MAP_ENTRY_ELEMENT, "<map entry>");
+ r = expression(b, l + 1, -1);
+ p = r; // pin = 1
+ r = r && report_error_(b, consumeToken(b, COLON));
+ r = p && expression(b, l + 1, -1) && r;
+ exit_section_(b, l, m, r, p, null);
+ return r || p;
+ }
+
+ /* ********************************************************** */
+ // [] mapEntryElement (',' mapEntryElement)*
+ static boolean mapExpressionSequence(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "mapExpressionSequence")) return false;
+ boolean r, p;
+ Marker m = enter_section_(b, l, _NONE_);
+ r = mapExpressionSequence_0(b, l + 1);
+ p = r; // pin = 1
+ r = r && report_error_(b, mapEntryElement(b, l + 1));
+ r = p && mapExpressionSequence_2(b, l + 1) && r;
+ exit_section_(b, l, m, r, p, null);
+ return r || p;
+ }
+
+ // []
+ private static boolean mapExpressionSequence_0(PsiBuilder b, int l) {
+ return true;
+ }
+
+ // (',' mapEntryElement)*
+ private static boolean mapExpressionSequence_2(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "mapExpressionSequence_2")) return false;
+ while (true) {
+ int c = current_position_(b);
+ if (!mapExpressionSequence_2_0(b, l + 1)) break;
+ if (!empty_element_parsed_guard_(b, "mapExpressionSequence_2", c)) break;
+ }
+ return true;
+ }
+
+ // ',' mapEntryElement
+ private static boolean mapExpressionSequence_2_0(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "mapExpressionSequence_2_0")) return false;
+ boolean r, p;
+ Marker m = enter_section_(b, l, _NONE_);
+ r = consumeToken(b, COMMA);
+ p = r; // pin = 1
+ r = r && mapEntryElement(b, l + 1);
+ exit_section_(b, l, m, r, p, null);
+ return r || p;
+ }
+
+ /* ********************************************************** */
+ // '#@' fqnTypeExpression '@{'
+ static boolean mapTypeExpression(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "mapTypeExpression")) return false;
+ boolean r, p;
+ Marker m = enter_section_(b, l, _NONE_);
+ r = consumeToken(b, "#@");
+ p = r; // pin = 1
+ r = r && report_error_(b, fqnTypeExpression(b, l + 1));
+ r = p && consumeToken(b, "@{") && r;
+ exit_section_(b, l, m, r, p, null);
+ return r || p;
+ }
+
+ /* ********************************************************** */
+ // INTEGER_LITERAL | BIG_INTEGER_LITERAL | DOUBLE_LITERAL | BIG_DECIMAL_LITERAL
+ static boolean numberLiteralExpression(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "numberLiteralExpression")) return false;
+ boolean r;
+ r = consumeToken(b, INTEGER_LITERAL);
+ if (!r) r = consumeToken(b, BIG_INTEGER_LITERAL);
+ if (!r) r = consumeToken(b, DOUBLE_LITERAL);
+ if (!r) r = consumeToken(b, BIG_DECIMAL_LITERAL);
+ return r;
+ }
+
+ /* ********************************************************** */
+ // expression? (',' expression)*
+ public static boolean parameterList(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "parameterList")) return false;
+ boolean r;
+ Marker m = enter_section_(b, l, _NONE_, PARAMETER_LIST, "<parameter list>");
+ r = parameterList_0(b, l + 1);
+ r = r && parameterList_1(b, l + 1);
+ exit_section_(b, l, m, r, false, null);
+ return r;
+ }
+
+ // expression?
+ private static boolean parameterList_0(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "parameterList_0")) return false;
+ expression(b, l + 1, -1);
+ return true;
+ }
+
+ // (',' expression)*
+ private static boolean parameterList_1(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "parameterList_1")) return false;
+ while (true) {
+ int c = current_position_(b);
+ if (!parameterList_1_0(b, l + 1)) break;
+ if (!empty_element_parsed_guard_(b, "parameterList_1", c)) break;
+ }
+ return true;
+ }
+
+ // ',' expression
+ private static boolean parameterList_1_0(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "parameterList_1_0")) return false;
+ boolean r;
+ Marker m = enter_section_(b);
+ r = consumeToken(b, COMMA);
+ r = r && expression(b, l + 1, -1);
+ exit_section_(b, m, null, r);
+ return r;
+ }
+
+ /* ********************************************************** */
+ // '+' | '-'
+ static boolean plusMinusOperations(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "plusMinusOperations")) return false;
+ if (!nextTokenIs(b, "", MINUS, PLUS)) return false;
+ boolean r;
+ r = consumeToken(b, PLUS);
+ if (!r) r = consumeToken(b, MINUS);
+ return r;
+ }
+
+ /* ********************************************************** */
+ // '{' expression '}'
+ public static boolean projectionExpression(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "projectionExpression")) return false;
+ if (!nextTokenIs(b, LBRACE)) return false;
+ boolean r;
+ Marker m = enter_section_(b);
+ r = consumeToken(b, LBRACE);
+ r = r && expression(b, l + 1, -1);
+ r = r && consumeToken(b, RBRACE);
+ exit_section_(b, m, PROJECTION_EXPRESSION, r);
+ return r;
+ }
+
+ /* ********************************************************** */
+ // '<' | "<=" | '>' | ">=" |
+ // "lt" | "lte" | "gt" | "gte"
+ static boolean relationalOperations(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "relationalOperations")) return false;
+ boolean r;
+ r = consumeToken(b, LESS);
+ if (!r) r = consumeToken(b, LESS_EQUAL);
+ if (!r) r = consumeToken(b, GREATER);
+ if (!r) r = consumeToken(b, GREATER_EQUAL);
+ if (!r) r = consumeToken(b, LT_KEYWORD);
+ if (!r) r = consumeToken(b, LT_EQ_KEYWORD);
+ if (!r) r = consumeToken(b, GT_KEYWORD);
+ if (!r) r = consumeToken(b, GT_EQ_KEYWORD);
+ return r;
+ }
+
+ /* ********************************************************** */
+ // EXPRESSION_START rootElement EXPRESSION_END
+ static boolean root(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "root")) return false;
+ if (!nextTokenIs(b, EXPRESSION_START)) return false;
+ boolean r, p;
+ Marker m = enter_section_(b, l, _NONE_);
+ r = consumeToken(b, EXPRESSION_START);
+ p = r; // pin = 1
+ r = r && report_error_(b, rootElement(b, l + 1));
+ r = p && consumeToken(b, EXPRESSION_END) && r;
+ exit_section_(b, l, m, r, p, null);
+ return r || p;
+ }
+
+ /* ********************************************************** */
+ // expression
+ static boolean rootElement(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "rootElement")) return false;
+ boolean r;
+ Marker m = enter_section_(b, l, _NONE_);
+ r = expression(b, l + 1, -1);
+ exit_section_(b, l, m, r, false, rootRecover_parser_);
+ return r;
+ }
+
+ /* ********************************************************** */
+ // !(EXPRESSION_END)
+ static boolean rootRecover(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "rootRecover")) return false;
+ boolean r;
+ Marker m = enter_section_(b, l, _NOT_);
+ r = !consumeToken(b, EXPRESSION_END);
+ exit_section_(b, l, m, r, false, null);
+ return r;
+ }
+
+ /* ********************************************************** */
+ // '{' ('?' | '^' | '$') expression '}'
+ public static boolean selectionExpression(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "selectionExpression")) return false;
+ if (!nextTokenIs(b, LBRACE)) return false;
+ boolean r;
+ Marker m = enter_section_(b);
+ r = consumeToken(b, LBRACE);
+ r = r && selectionExpression_1(b, l + 1);
+ r = r && expression(b, l + 1, -1);
+ r = r && consumeToken(b, RBRACE);
+ exit_section_(b, m, SELECTION_EXPRESSION, r);
+ return r;
+ }
+
+ // '?' | '^' | '$'
+ private static boolean selectionExpression_1(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "selectionExpression_1")) return false;
+ boolean r;
+ r = consumeToken(b, QUESTION);
+ if (!r) r = consumeToken(b, XOR);
+ if (!r) r = consumeToken(b, DOLLAR);
+ return r;
+ }
+
+ /* ********************************************************** */
+ // "not in" | "in"
+ static boolean setOperations(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "setOperations")) return false;
+ if (!nextTokenIs(b, "", IN_KEYWORD, NOT_IN_KEYWORD)) return false;
+ boolean r;
+ r = consumeToken(b, NOT_IN_KEYWORD);
+ if (!r) r = consumeToken(b, IN_KEYWORD);
+ return r;
+ }
+
+ /* ********************************************************** */
+ // "<<" | ">>" | ">>>" |
+ // "shl" | "shr" | "ushr"
+ static boolean shiftOperations(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "shiftOperations")) return false;
+ boolean r;
+ r = consumeToken(b, SHIFT_LEFT);
+ if (!r) r = consumeToken(b, SHIFT_RIGHT);
+ if (!r) r = consumeToken(b, SHIFT_RIGHT_LOGICAL);
+ if (!r) r = consumeToken(b, SHIFT_LEFT_KEYWORD);
+ if (!r) r = consumeToken(b, SHIFT_RIGHT_KEYWORD);
+ if (!r) r = consumeToken(b, SHIFT_RIGHT_LOGICAL_KEYWORD);
+ return r;
+ }
+
+ /* ********************************************************** */
+ // STRING_LITERAL | CHARACTER_LITERAL
+ static boolean textLiteralExpression(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "textLiteralExpression")) return false;
+ if (!nextTokenIs(b, "", CHARACTER_LITERAL, STRING_LITERAL)) return false;
+ boolean r;
+ r = consumeToken(b, STRING_LITERAL);
+ if (!r) r = consumeToken(b, CHARACTER_LITERAL);
+ return r;
+ }
+
+ /* ********************************************************** */
+ // bitwiseOperations |
+ // '+' | '-' | "not"
+ static boolean unaryOperator(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "unaryOperator")) return false;
+ boolean r;
+ r = bitwiseOperations(b, l + 1);
+ if (!r) r = consumeToken(b, PLUS);
+ if (!r) r = consumeToken(b, MINUS);
+ if (!r) r = consumeToken(b, NOT_KEYWORD);
+ return r;
+ }
+
+ /* ********************************************************** */
+ // Expression root: expression
+ // Operator priority table:
+ // 0: PREFIX(unaryExpression)
+ // 1: ATOM(lambdaExpression)
+ // 2: ATOM(mapExpression)
+ // 3: ATOM(sequenceExpression)
+ // 4: ATOM(parenthesizedExpression)
+ // 5: ATOM(variableAssignmentExpression)
+ // 6: BINARY(conditionalExpression)
+ // 7: BINARY(binaryExpression)
+ // 8: ATOM(newArrayExpression)
+ // 9: ATOM(newExpression)
+ // 10: POSTFIX(methodCallExpression)
+ // 11: ATOM(indexedExpression)
+ // 12: ATOM(referenceExpression)
+ // 13: ATOM(variableExpression)
+ // 14: ATOM(literalExpression)
+ public static boolean expression(PsiBuilder b, int l, int g) {
+ if (!recursion_guard_(b, l, "expression")) return false;
+ addVariant(b, "<expression>");
+ boolean r, p;
+ Marker m = enter_section_(b, l, _NONE_, "<expression>");
+ r = unaryExpression(b, l + 1);
+ if (!r) r = lambdaExpression(b, l + 1);
+ if (!r) r = mapExpression(b, l + 1);
+ if (!r) r = sequenceExpression(b, l + 1);
+ if (!r) r = parenthesizedExpression(b, l + 1);
+ if (!r) r = variableAssignmentExpression(b, l + 1);
+ if (!r) r = newArrayExpression(b, l + 1);
+ if (!r) r = newExpression(b, l + 1);
+ if (!r) r = indexedExpression(b, l + 1);
+ if (!r) r = referenceExpression(b, l + 1);
+ if (!r) r = variableExpression(b, l + 1);
+ if (!r) r = literalExpression(b, l + 1);
+ p = r;
+ r = r && expression_0(b, l + 1, g);
+ exit_section_(b, l, m, null, r, p, null);
+ return r || p;
+ }
+
+ public static boolean expression_0(PsiBuilder b, int l, int g) {
+ if (!recursion_guard_(b, l, "expression_0")) return false;
+ boolean r = true;
+ while (true) {
+ Marker m = enter_section_(b, l, _LEFT_, null);
+ if (g < 6 && consumeTokenSmart(b, QUESTION)) {
+ r = report_error_(b, expression(b, l, 6));
+ r = conditionalExpressionTail(b, l + 1) && r;
+ exit_section_(b, l, m, CONDITIONAL_EXPRESSION, r, true, null);
+ }
+ else if (g < 7 && binaryOperations(b, l + 1)) {
+ r = expression(b, l, 7);
+ exit_section_(b, l, m, BINARY_EXPRESSION, r, true, null);
+ }
+ else if (g < 10 && leftMarkerIs(b, REFERENCE_EXPRESSION) && methodCallExpression_0(b, l + 1)) {
+ r = true;
+ exit_section_(b, l, m, METHOD_CALL_EXPRESSION, r, true, null);
+ }
+ else {
+ exit_section_(b, l, m, null, false, false, null);
+ break;
+ }
+ }
+ return r;
+ }
+
+ public static boolean unaryExpression(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "unaryExpression")) return false;
+ boolean r, p;
+ Marker m = enter_section_(b, l, _NONE_, null);
+ r = unaryOperator(b, l + 1);
+ p = r;
+ r = p && expression(b, l, 0);
+ exit_section_(b, l, m, UNARY_EXPRESSION, r, p, null);
+ return r || p;
+ }
+
+ // ':' '[' expression "]"
+ public static boolean lambdaExpression(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "lambdaExpression")) return false;
+ if (!nextTokenIsSmart(b, COLON)) return false;
+ boolean r, p;
+ Marker m = enter_section_(b, l, _NONE_, LAMBDA_EXPRESSION, null);
+ r = consumeTokensSmart(b, 1, COLON, LBRACKET);
+ p = r; // pin = 1
+ r = r && report_error_(b, expression(b, l + 1, -1));
+ r = p && consumeToken(b, RBRACKET) && r;
+ exit_section_(b, l, m, r, p, null);
+ return r || p;
+ }
+
+ // ('#{' | mapTypeExpression) mapExpressionSequence '}'
+ public static boolean mapExpression(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "mapExpression")) return false;
+ boolean r, p;
+ Marker m = enter_section_(b, l, _COLLAPSE_, MAP_EXPRESSION, "<map expression>");
+ r = mapExpression_0(b, l + 1);
+ p = r; // pin = 1
+ r = r && report_error_(b, mapExpressionSequence(b, l + 1));
+ r = p && consumeToken(b, RBRACE) && r;
+ exit_section_(b, l, m, r, p, null);
+ return r || p;
+ }
+
+ // '#{' | mapTypeExpression
+ private static boolean mapExpression_0(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "mapExpression_0")) return false;
+ boolean r;
+ r = consumeTokenSmart(b, "#{");
+ if (!r) r = mapTypeExpression(b, l + 1);
+ return r;
+ }
+
+ // '{' expressionSequenceRequired '}'
+ public static boolean sequenceExpression(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "sequenceExpression")) return false;
+ if (!nextTokenIsSmart(b, LBRACE)) return false;
+ boolean r, p;
+ Marker m = enter_section_(b, l, _NONE_, SEQUENCE_EXPRESSION, null);
+ r = consumeTokenSmart(b, LBRACE);
+ p = r; // pin = 1
+ r = r && report_error_(b, expressionSequenceRequired(b, l + 1));
+ r = p && consumeToken(b, RBRACE) && r;
+ exit_section_(b, l, m, r, p, null);
+ return r || p;
+ }
+
+ // '(' expression ')'
+ public static boolean parenthesizedExpression(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "parenthesizedExpression")) return false;
+ if (!nextTokenIsSmart(b, LPARENTH)) return false;
+ boolean r, p;
+ Marker m = enter_section_(b, l, _NONE_, PARENTHESIZED_EXPRESSION, null);
+ r = consumeTokenSmart(b, LPARENTH);
+ p = r; // pin = 1
+ r = r && report_error_(b, expression(b, l + 1, -1));
+ r = p && consumeToken(b, RPARENTH) && r;
+ exit_section_(b, l, m, r, p, null);
+ return r || p;
+ }
+
+ // '#' IDENTIFIER '=' expression
+ public static boolean variableAssignmentExpression(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "variableAssignmentExpression")) return false;
+ if (!nextTokenIsSmart(b, HASH)) return false;
+ boolean r, p;
+ Marker m = enter_section_(b, l, _NONE_, VARIABLE_ASSIGNMENT_EXPRESSION, null);
+ r = consumeTokensSmart(b, 3, HASH, IDENTIFIER, EQ);
+ p = r; // pin = 3
+ r = r && expression(b, l + 1, -1);
+ exit_section_(b, l, m, r, p, null);
+ return r || p;
+ }
+
+ // "new" fqnTypeExpression arrayConstructorExpression
+ public static boolean newArrayExpression(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "newArrayExpression")) return false;
+ if (!nextTokenIsSmart(b, NEW_KEYWORD)) return false;
+ boolean r;
+ Marker m = enter_section_(b);
+ r = consumeTokenSmart(b, NEW_KEYWORD);
+ r = r && fqnTypeExpression(b, l + 1);
+ r = r && arrayConstructorExpression(b, l + 1);
+ exit_section_(b, m, NEW_ARRAY_EXPRESSION, r);
+ return r;
+ }
+
+ // "new" fqnTypeExpression constructorExpression
+ public static boolean newExpression(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "newExpression")) return false;
+ if (!nextTokenIsSmart(b, NEW_KEYWORD)) return false;
+ boolean r, p;
+ Marker m = enter_section_(b, l, _NONE_, NEW_EXPRESSION, null);
+ r = consumeTokenSmart(b, NEW_KEYWORD);
+ p = r; // pin = 1
+ r = r && report_error_(b, fqnTypeExpression(b, l + 1));
+ r = p && constructorExpression(b, l + 1) && r;
+ exit_section_(b, l, m, r, p, null);
+ return r || p;
+ }
+
+ // '(' parameterList ')'
+ private static boolean methodCallExpression_0(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "methodCallExpression_0")) return false;
+ boolean r, p;
+ Marker m = enter_section_(b, l, _NONE_);
+ r = consumeTokenSmart(b, LPARENTH);
+ p = r; // pin = '\('
+ r = r && report_error_(b, parameterList(b, l + 1));
+ r = p && consumeToken(b, RPARENTH) && r;
+ exit_section_(b, l, m, r, p, null);
+ return r || p;
+ }
+
+ // (referenceExpression | variableExpression) '[' expression ']'
+ // ('.' IDENTIFIER)*
+ // ('.' selectionExpression | projectionExpression)?
+ public static boolean indexedExpression(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "indexedExpression")) return false;
+ boolean r, p;
+ Marker m = enter_section_(b, l, _NONE_, INDEXED_EXPRESSION, "<indexed expression>");
+ r = indexedExpression_0(b, l + 1);
+ r = r && consumeToken(b, LBRACKET);
+ p = r; // pin = 2
+ r = r && report_error_(b, expression(b, l + 1, -1));
+ r = p && report_error_(b, consumeToken(b, RBRACKET)) && r;
+ r = p && report_error_(b, indexedExpression_4(b, l + 1)) && r;
+ r = p && indexedExpression_5(b, l + 1) && r;
+ exit_section_(b, l, m, r, p, null);
+ return r || p;
+ }
+
+ // referenceExpression | variableExpression
+ private static boolean indexedExpression_0(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "indexedExpression_0")) return false;
+ boolean r;
+ r = referenceExpression(b, l + 1);
+ if (!r) r = variableExpression(b, l + 1);
+ return r;
+ }
+
+ // ('.' IDENTIFIER)*
+ private static boolean indexedExpression_4(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "indexedExpression_4")) return false;
+ while (true) {
+ int c = current_position_(b);
+ if (!indexedExpression_4_0(b, l + 1)) break;
+ if (!empty_element_parsed_guard_(b, "indexedExpression_4", c)) break;
+ }
+ return true;
+ }
+
+ // '.' IDENTIFIER
+ private static boolean indexedExpression_4_0(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "indexedExpression_4_0")) return false;
+ boolean r;
+ Marker m = enter_section_(b);
+ r = consumeTokensSmart(b, 0, DOT, IDENTIFIER);
+ exit_section_(b, m, null, r);
+ return r;
+ }
+
+ // ('.' selectionExpression | projectionExpression)?
+ private static boolean indexedExpression_5(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "indexedExpression_5")) return false;
+ indexedExpression_5_0(b, l + 1);
+ return true;
+ }
+
+ // '.' selectionExpression | projectionExpression
+ private static boolean indexedExpression_5_0(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "indexedExpression_5_0")) return false;
+ boolean r;
+ Marker m = enter_section_(b);
+ r = indexedExpression_5_0_0(b, l + 1);
+ if (!r) r = projectionExpression(b, l + 1);
+ exit_section_(b, m, null, r);
+ return r;
+ }
+
+ // '.' selectionExpression
+ private static boolean indexedExpression_5_0_0(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "indexedExpression_5_0_0")) return false;
+ boolean r;
+ Marker m = enter_section_(b);
+ r = consumeTokenSmart(b, DOT);
+ r = r && selectionExpression(b, l + 1);
+ exit_section_(b, m, null, r);
+ return r;
+ }
+
+ // (variableExpression | ('@')? IDENTIFIER)
+ // ('.' IDENTIFIER)* ('@' IDENTIFIER)?
+ // ('.' selectionExpression)?
+ // ('.' projectionExpression )?
+ public static boolean referenceExpression(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "referenceExpression")) return false;
+ boolean r;
+ Marker m = enter_section_(b, l, _COLLAPSE_, REFERENCE_EXPRESSION, "<reference expression>");
+ r = referenceExpression_0(b, l + 1);
+ r = r && referenceExpression_1(b, l + 1);
+ r = r && referenceExpression_2(b, l + 1);
+ r = r && referenceExpression_3(b, l + 1);
+ r = r && referenceExpression_4(b, l + 1);
+ exit_section_(b, l, m, r, false, null);
+ return r;
+ }
+
+ // variableExpression | ('@')? IDENTIFIER
+ private static boolean referenceExpression_0(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "referenceExpression_0")) return false;
+ boolean r;
+ Marker m = enter_section_(b);
+ r = variableExpression(b, l + 1);
+ if (!r) r = referenceExpression_0_1(b, l + 1);
+ exit_section_(b, m, null, r);
+ return r;
+ }
+
+ // ('@')? IDENTIFIER
+ private static boolean referenceExpression_0_1(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "referenceExpression_0_1")) return false;
+ boolean r;
+ Marker m = enter_section_(b);
+ r = referenceExpression_0_1_0(b, l + 1);
+ r = r && consumeToken(b, IDENTIFIER);
+ exit_section_(b, m, null, r);
+ return r;
+ }
+
+ // ('@')?
+ private static boolean referenceExpression_0_1_0(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "referenceExpression_0_1_0")) return false;
+ consumeTokenSmart(b, AT);
+ return true;
+ }
+
+ // ('.' IDENTIFIER)*
+ private static boolean referenceExpression_1(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "referenceExpression_1")) return false;
+ while (true) {
+ int c = current_position_(b);
+ if (!referenceExpression_1_0(b, l + 1)) break;
+ if (!empty_element_parsed_guard_(b, "referenceExpression_1", c)) break;
+ }
+ return true;
+ }
+
+ // '.' IDENTIFIER
+ private static boolean referenceExpression_1_0(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "referenceExpression_1_0")) return false;
+ boolean r;
+ Marker m = enter_section_(b);
+ r = consumeTokensSmart(b, 0, DOT, IDENTIFIER);
+ exit_section_(b, m, null, r);
+ return r;
+ }
+
+ // ('@' IDENTIFIER)?
+ private static boolean referenceExpression_2(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "referenceExpression_2")) return false;
+ referenceExpression_2_0(b, l + 1);
+ return true;
+ }
+
+ // '@' IDENTIFIER
+ private static boolean referenceExpression_2_0(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "referenceExpression_2_0")) return false;
+ boolean r;
+ Marker m = enter_section_(b);
+ r = consumeTokensSmart(b, 0, AT, IDENTIFIER);
+ exit_section_(b, m, null, r);
+ return r;
+ }
+
+ // ('.' selectionExpression)?
+ private static boolean referenceExpression_3(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "referenceExpression_3")) return false;
+ referenceExpression_3_0(b, l + 1);
+ return true;
+ }
+
+ // '.' selectionExpression
+ private static boolean referenceExpression_3_0(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "referenceExpression_3_0")) return false;
+ boolean r;
+ Marker m = enter_section_(b);
+ r = consumeTokenSmart(b, DOT);
+ r = r && selectionExpression(b, l + 1);
+ exit_section_(b, m, null, r);
+ return r;
+ }
+
+ // ('.' projectionExpression )?
+ private static boolean referenceExpression_4(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "referenceExpression_4")) return false;
+ referenceExpression_4_0(b, l + 1);
+ return true;
+ }
+
+ // '.' projectionExpression
+ private static boolean referenceExpression_4_0(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "referenceExpression_4_0")) return false;
+ boolean r;
+ Marker m = enter_section_(b);
+ r = consumeTokenSmart(b, DOT);
+ r = r && projectionExpression(b, l + 1);
+ exit_section_(b, m, null, r);
+ return r;
+ }
+
+ // '#' IDENTIFIER
+ public static boolean variableExpression(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "variableExpression")) return false;
+ if (!nextTokenIsSmart(b, HASH)) return false;
+ boolean r;
+ Marker m = enter_section_(b);
+ r = consumeTokensSmart(b, 0, HASH, IDENTIFIER);
+ exit_section_(b, m, VARIABLE_EXPRESSION, r);
+ return r;
+ }
+
+ // numberLiteralExpression |
+ // textLiteralExpression |
+ // booleanLiteralExpression |
+ // "null"
+ public static boolean literalExpression(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "literalExpression")) return false;
+ boolean r;
+ Marker m = enter_section_(b, l, _NONE_, LITERAL_EXPRESSION, "<literal expression>");
+ r = numberLiteralExpression(b, l + 1);
+ if (!r) r = textLiteralExpression(b, l + 1);
+ if (!r) r = booleanLiteralExpression(b, l + 1);
+ if (!r) r = consumeTokenSmart(b, NULL_KEYWORD);
+ exit_section_(b, l, m, r, false, null);
+ return r;
+ }
+
+ static final Parser rootRecover_parser_ = new Parser() {
+ public boolean parse(PsiBuilder b, int l) {
+ return rootRecover(b, l + 1);
+ }
+ };
+}
diff --git a/src/main/gen/psi/OgnlBinaryExpression.java b/src/main/gen/psi/OgnlBinaryExpression.java
new file mode 100644
index 0000000..8dddbd7
--- /dev/null
+++ b/src/main/gen/psi/OgnlBinaryExpression.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.psi.PsiElement;
+
+public interface OgnlBinaryExpression extends OgnlExpression {
+
+ @NotNull
+ OgnlExpression getLeft();
+
+ @Nullable
+ OgnlExpression getRight();
+
+ @NotNull
+ OgnlTokenType getOperator();
+
+}
diff --git a/src/main/gen/psi/OgnlConditionalExpression.java b/src/main/gen/psi/OgnlConditionalExpression.java
new file mode 100644
index 0000000..52be3cd
--- /dev/null
+++ b/src/main/gen/psi/OgnlConditionalExpression.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.psi.PsiElement;
+
+public interface OgnlConditionalExpression extends OgnlExpression {
+
+ @NotNull
+ OgnlExpression getCondition();
+
+ @Nullable
+ OgnlExpression getThen();
+
+ @Nullable
+ OgnlExpression getElse();
+
+}
diff --git a/src/main/gen/psi/OgnlExpression.java b/src/main/gen/psi/OgnlExpression.java
new file mode 100644
index 0000000..8efe65c
--- /dev/null
+++ b/src/main/gen/psi/OgnlExpression.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiType;
+
+public interface OgnlExpression extends OgnlPsiCompositeElement {
+
+ @Nullable
+ PsiType getType();
+
+}
diff --git a/src/main/gen/psi/OgnlFqnTypeExpression.java b/src/main/gen/psi/OgnlFqnTypeExpression.java
new file mode 100644
index 0000000..88a0d22
--- /dev/null
+++ b/src/main/gen/psi/OgnlFqnTypeExpression.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.psi.PsiElement;
+
+public interface OgnlFqnTypeExpression extends OgnlExpression {
+
+}
diff --git a/src/main/gen/psi/OgnlIndexedExpression.java b/src/main/gen/psi/OgnlIndexedExpression.java
new file mode 100644
index 0000000..e38130a
--- /dev/null
+++ b/src/main/gen/psi/OgnlIndexedExpression.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.psi.PsiElement;
+
+public interface OgnlIndexedExpression extends OgnlExpression {
+
+ @NotNull
+ OgnlExpression getReferenceQualifier();
+
+ @Nullable
+ OgnlExpression getIndexExpression();
+
+}
diff --git a/src/main/gen/psi/OgnlLambdaExpression.java b/src/main/gen/psi/OgnlLambdaExpression.java
new file mode 100644
index 0000000..ef32614
--- /dev/null
+++ b/src/main/gen/psi/OgnlLambdaExpression.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.psi.PsiElement;
+
+public interface OgnlLambdaExpression extends OgnlExpression {
+
+ @Nullable
+ OgnlExpression getExpression();
+
+}
diff --git a/src/main/gen/psi/OgnlLiteralExpression.java b/src/main/gen/psi/OgnlLiteralExpression.java
new file mode 100644
index 0000000..aad2156
--- /dev/null
+++ b/src/main/gen/psi/OgnlLiteralExpression.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.psi.PsiElement;
+
+public interface OgnlLiteralExpression extends OgnlExpression {
+
+ @Nullable
+ Object getConstantValue();
+
+}
diff --git a/src/main/gen/psi/OgnlMapEntryElement.java b/src/main/gen/psi/OgnlMapEntryElement.java
new file mode 100644
index 0000000..c96f13a
--- /dev/null
+++ b/src/main/gen/psi/OgnlMapEntryElement.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.psi.PsiElement;
+
+public interface OgnlMapEntryElement extends OgnlPsiCompositeElement {
+
+ @NotNull
+ OgnlExpression getKeyExpression();
+
+ @Nullable
+ OgnlExpression getValueExpression();
+
+}
diff --git a/src/main/gen/psi/OgnlMapExpression.java b/src/main/gen/psi/OgnlMapExpression.java
new file mode 100644
index 0000000..ffaaaa2
--- /dev/null
+++ b/src/main/gen/psi/OgnlMapExpression.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.psi.PsiElement;
+
+public interface OgnlMapExpression extends OgnlExpression {
+
+ @NotNull
+ List<OgnlMapEntryElement> getMapEntryElementList();
+
+ @Nullable
+ OgnlFqnTypeExpression getMapType();
+
+}
diff --git a/src/main/gen/psi/OgnlMethodCallExpression.java b/src/main/gen/psi/OgnlMethodCallExpression.java
new file mode 100644
index 0000000..256909f
--- /dev/null
+++ b/src/main/gen/psi/OgnlMethodCallExpression.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.psi.PsiElement;
+
+public interface OgnlMethodCallExpression extends OgnlExpression {
+
+ @Nullable
+ OgnlParameterList getParameterList();
+
+ @Nullable
+ OgnlExpression getMethod();
+
+}
diff --git a/src/main/gen/psi/OgnlNewArrayExpression.java b/src/main/gen/psi/OgnlNewArrayExpression.java
new file mode 100644
index 0000000..de1470a
--- /dev/null
+++ b/src/main/gen/psi/OgnlNewArrayExpression.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.psi.PsiElement;
+
+public interface OgnlNewArrayExpression extends OgnlExpression {
+
+ @NotNull
+ OgnlExpression getObjectType();
+
+ @Nullable
+ OgnlExpression getConstructorExpression();
+
+}
diff --git a/src/main/gen/psi/OgnlNewExpression.java b/src/main/gen/psi/OgnlNewExpression.java
new file mode 100644
index 0000000..9a1c4f2
--- /dev/null
+++ b/src/main/gen/psi/OgnlNewExpression.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.psi.PsiElement;
+
+public interface OgnlNewExpression extends OgnlExpression {
+
+ @Nullable
+ OgnlParameterList getParameterList();
+
+ @Nullable
+ OgnlFqnTypeExpression getObjectType();
+
+}
diff --git a/src/main/gen/psi/OgnlParameterList.java b/src/main/gen/psi/OgnlParameterList.java
new file mode 100644
index 0000000..2dabd1d
--- /dev/null
+++ b/src/main/gen/psi/OgnlParameterList.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.psi.PsiElement;
+
+public interface OgnlParameterList extends OgnlPsiCompositeElement {
+
+ @NotNull
+ List<OgnlExpression> getParametersList();
+
+ int getParameterCount();
+
+}
diff --git a/src/main/gen/psi/OgnlParenthesizedExpression.java b/src/main/gen/psi/OgnlParenthesizedExpression.java
new file mode 100644
index 0000000..27ebcec
--- /dev/null
+++ b/src/main/gen/psi/OgnlParenthesizedExpression.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.psi.PsiElement;
+
+public interface OgnlParenthesizedExpression extends OgnlExpression {
+
+ @Nullable
+ OgnlExpression getExpression();
+
+}
diff --git a/src/main/gen/psi/OgnlProjectionExpression.java b/src/main/gen/psi/OgnlProjectionExpression.java
new file mode 100644
index 0000000..2e85a93
--- /dev/null
+++ b/src/main/gen/psi/OgnlProjectionExpression.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.psi.PsiElement;
+
+public interface OgnlProjectionExpression extends OgnlExpression {
+
+ @NotNull
+ OgnlExpression getProjectionExpression();
+
+}
diff --git a/src/main/gen/psi/OgnlReferenceExpression.java b/src/main/gen/psi/OgnlReferenceExpression.java
new file mode 100644
index 0000000..9275dff
--- /dev/null
+++ b/src/main/gen/psi/OgnlReferenceExpression.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.psi.PsiElement;
+
+public interface OgnlReferenceExpression extends OgnlExpression {
+
+ @NotNull
+ List<OgnlExpression> getExpressionList();
+
+}
diff --git a/src/main/gen/psi/OgnlSelectionExpression.java b/src/main/gen/psi/OgnlSelectionExpression.java
new file mode 100644
index 0000000..fb7e309
--- /dev/null
+++ b/src/main/gen/psi/OgnlSelectionExpression.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.psi.PsiElement;
+
+public interface OgnlSelectionExpression extends OgnlExpression {
+
+ @NotNull
+ OgnlExpression getSelectorExpression();
+
+}
diff --git a/src/main/gen/psi/OgnlSequenceExpression.java b/src/main/gen/psi/OgnlSequenceExpression.java
new file mode 100644
index 0000000..4ee460d
--- /dev/null
+++ b/src/main/gen/psi/OgnlSequenceExpression.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.psi.PsiElement;
+
+public interface OgnlSequenceExpression extends OgnlExpression {
+
+ @NotNull
+ List<OgnlExpression> getElementsList();
+
+}
diff --git a/src/main/gen/psi/OgnlUnaryExpression.java b/src/main/gen/psi/OgnlUnaryExpression.java
new file mode 100644
index 0000000..237b00d
--- /dev/null
+++ b/src/main/gen/psi/OgnlUnaryExpression.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.psi.PsiElement;
+
+public interface OgnlUnaryExpression extends OgnlExpression {
+
+ @Nullable
+ OgnlExpression getExpression();
+
+ @NotNull
+ OgnlTokenType getUnaryOperator();
+
+}
diff --git a/src/main/gen/psi/OgnlVariableAssignmentExpression.java b/src/main/gen/psi/OgnlVariableAssignmentExpression.java
new file mode 100644
index 0000000..c264457
--- /dev/null
+++ b/src/main/gen/psi/OgnlVariableAssignmentExpression.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.psi.PsiElement;
+
+public interface OgnlVariableAssignmentExpression extends OgnlExpression {
+
+ @NotNull
+ String getVariableName();
+
+ @Nullable
+ OgnlExpression getAssignment();
+
+}
diff --git a/src/main/gen/psi/OgnlVariableExpression.java b/src/main/gen/psi/OgnlVariableExpression.java
new file mode 100644
index 0000000..f852bd8
--- /dev/null
+++ b/src/main/gen/psi/OgnlVariableExpression.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.psi.PsiElement;
+
+public interface OgnlVariableExpression extends OgnlExpression {
+
+}
diff --git a/src/main/gen/psi/OgnlVisitor.java b/src/main/gen/psi/OgnlVisitor.java
new file mode 100644
index 0000000..0465189
--- /dev/null
+++ b/src/main/gen/psi/OgnlVisitor.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi;
+
+import org.jetbrains.annotations.*;
+import com.intellij.psi.PsiElementVisitor;
+
+public class OgnlVisitor extends PsiElementVisitor {
+
+ public void visitBinaryExpression(@NotNull OgnlBinaryExpression o) {
+ visitExpression(o);
+ }
+
+ public void visitConditionalExpression(@NotNull OgnlConditionalExpression o) {
+ visitExpression(o);
+ }
+
+ public void visitExpression(@NotNull OgnlExpression o) {
+ visitPsiCompositeElement(o);
+ }
+
+ public void visitFqnTypeExpression(@NotNull OgnlFqnTypeExpression o) {
+ visitExpression(o);
+ }
+
+ public void visitIndexedExpression(@NotNull OgnlIndexedExpression o) {
+ visitExpression(o);
+ }
+
+ public void visitLambdaExpression(@NotNull OgnlLambdaExpression o) {
+ visitExpression(o);
+ }
+
+ public void visitLiteralExpression(@NotNull OgnlLiteralExpression o) {
+ visitExpression(o);
+ }
+
+ public void visitMapEntryElement(@NotNull OgnlMapEntryElement o) {
+ visitPsiCompositeElement(o);
+ }
+
+ public void visitMapExpression(@NotNull OgnlMapExpression o) {
+ visitExpression(o);
+ }
+
+ public void visitMethodCallExpression(@NotNull OgnlMethodCallExpression o) {
+ visitExpression(o);
+ }
+
+ public void visitNewArrayExpression(@NotNull OgnlNewArrayExpression o) {
+ visitExpression(o);
+ }
+
+ public void visitNewExpression(@NotNull OgnlNewExpression o) {
+ visitExpression(o);
+ }
+
+ public void visitParameterList(@NotNull OgnlParameterList o) {
+ visitPsiCompositeElement(o);
+ }
+
+ public void visitParenthesizedExpression(@NotNull OgnlParenthesizedExpression o) {
+ visitExpression(o);
+ }
+
+ public void visitProjectionExpression(@NotNull OgnlProjectionExpression o) {
+ visitExpression(o);
+ }
+
+ public void visitReferenceExpression(@NotNull OgnlReferenceExpression o) {
+ visitExpression(o);
+ }
+
+ public void visitSelectionExpression(@NotNull OgnlSelectionExpression o) {
+ visitExpression(o);
+ }
+
+ public void visitSequenceExpression(@NotNull OgnlSequenceExpression o) {
+ visitExpression(o);
+ }
+
+ public void visitUnaryExpression(@NotNull OgnlUnaryExpression o) {
+ visitExpression(o);
+ }
+
+ public void visitVariableAssignmentExpression(@NotNull OgnlVariableAssignmentExpression o) {
+ visitExpression(o);
+ }
+
+ public void visitVariableExpression(@NotNull OgnlVariableExpression o) {
+ visitExpression(o);
+ }
+
+ public void visitPsiCompositeElement(@NotNull OgnlPsiCompositeElement o) {
+ visitElement(o);
+ }
+
+}
diff --git a/src/main/gen/psi/impl/OgnlBinaryExpressionImpl.java b/src/main/gen/psi/impl/OgnlBinaryExpressionImpl.java
new file mode 100644
index 0000000..b92c4fe
--- /dev/null
+++ b/src/main/gen/psi/impl/OgnlBinaryExpressionImpl.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi.impl;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.util.PsiTreeUtil;
+import static com.intellij.lang.ognl.OgnlTypes.*;
+import com.intellij.lang.ognl.psi.*;
+
+public class OgnlBinaryExpressionImpl extends OgnlExpressionImpl implements OgnlBinaryExpression {
+
+ public OgnlBinaryExpressionImpl(ASTNode node) {
+ super(node);
+ }
+
+ public void accept(@NotNull OgnlVisitor visitor) {
+ visitor.visitBinaryExpression(this);
+ }
+
+ public void accept(@NotNull PsiElementVisitor visitor) {
+ if (visitor instanceof OgnlVisitor) accept((OgnlVisitor)visitor);
+ else super.accept(visitor);
+ }
+
+ @Override
+ @NotNull
+ public OgnlExpression getLeft() {
+ List<OgnlExpression> p1 = PsiTreeUtil.getChildrenOfTypeAsList(this, OgnlExpression.class);
+ return p1.get(0);
+ }
+
+ @Override
+ @Nullable
+ public OgnlExpression getRight() {
+ List<OgnlExpression> p1 = PsiTreeUtil.getChildrenOfTypeAsList(this, OgnlExpression.class);
+ return p1.size() < 2 ? null : p1.get(1);
+ }
+
+ @NotNull
+ public OgnlTokenType getOperator() {
+ return OgnlPsiUtil.getOperator(this);
+ }
+
+}
diff --git a/src/main/gen/psi/impl/OgnlConditionalExpressionImpl.java b/src/main/gen/psi/impl/OgnlConditionalExpressionImpl.java
new file mode 100644
index 0000000..2105da2
--- /dev/null
+++ b/src/main/gen/psi/impl/OgnlConditionalExpressionImpl.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi.impl;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.util.PsiTreeUtil;
+import static com.intellij.lang.ognl.OgnlTypes.*;
+import com.intellij.lang.ognl.psi.*;
+
+public class OgnlConditionalExpressionImpl extends OgnlExpressionImpl implements OgnlConditionalExpression {
+
+ public OgnlConditionalExpressionImpl(ASTNode node) {
+ super(node);
+ }
+
+ public void accept(@NotNull OgnlVisitor visitor) {
+ visitor.visitConditionalExpression(this);
+ }
+
+ public void accept(@NotNull PsiElementVisitor visitor) {
+ if (visitor instanceof OgnlVisitor) accept((OgnlVisitor)visitor);
+ else super.accept(visitor);
+ }
+
+ @Override
+ @NotNull
+ public OgnlExpression getCondition() {
+ List<OgnlExpression> p1 = PsiTreeUtil.getChildrenOfTypeAsList(this, OgnlExpression.class);
+ return p1.get(0);
+ }
+
+ @Override
+ @Nullable
+ public OgnlExpression getThen() {
+ List<OgnlExpression> p1 = PsiTreeUtil.getChildrenOfTypeAsList(this, OgnlExpression.class);
+ return p1.size() < 2 ? null : p1.get(1);
+ }
+
+ @Override
+ @Nullable
+ public OgnlExpression getElse() {
+ List<OgnlExpression> p1 = PsiTreeUtil.getChildrenOfTypeAsList(this, OgnlExpression.class);
+ return p1.size() < 3 ? null : p1.get(2);
+ }
+
+}
diff --git a/src/main/gen/psi/impl/OgnlExpressionImpl.java b/src/main/gen/psi/impl/OgnlExpressionImpl.java
new file mode 100644
index 0000000..9a82d06
--- /dev/null
+++ b/src/main/gen/psi/impl/OgnlExpressionImpl.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi.impl;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.util.PsiTreeUtil;
+import static com.intellij.lang.ognl.OgnlTypes.*;
+import com.intellij.lang.ognl.psi.*;
+import com.intellij.psi.PsiType;
+
+public abstract class OgnlExpressionImpl extends OgnlPsiCompositeElementBase implements OgnlExpression {
+
+ public OgnlExpressionImpl(ASTNode node) {
+ super(node);
+ }
+
+ public void accept(@NotNull OgnlVisitor visitor) {
+ visitor.visitExpression(this);
+ }
+
+ public void accept(@NotNull PsiElementVisitor visitor) {
+ if (visitor instanceof OgnlVisitor) accept((OgnlVisitor)visitor);
+ else super.accept(visitor);
+ }
+
+ @Nullable
+ public PsiType getType() {
+ return OgnlPsiUtil.getType(this);
+ }
+
+}
diff --git a/src/main/gen/psi/impl/OgnlFqnTypeExpressionImpl.java b/src/main/gen/psi/impl/OgnlFqnTypeExpressionImpl.java
new file mode 100644
index 0000000..0ed4ede
--- /dev/null
+++ b/src/main/gen/psi/impl/OgnlFqnTypeExpressionImpl.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi.impl;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.util.PsiTreeUtil;
+import static com.intellij.lang.ognl.OgnlTypes.*;
+import com.intellij.lang.ognl.psi.*;
+
+public class OgnlFqnTypeExpressionImpl extends OgnlFqnTypeExpressionBase implements OgnlFqnTypeExpression {
+
+ public OgnlFqnTypeExpressionImpl(ASTNode node) {
+ super(node);
+ }
+
+ public void accept(@NotNull OgnlVisitor visitor) {
+ visitor.visitFqnTypeExpression(this);
+ }
+
+ public void accept(@NotNull PsiElementVisitor visitor) {
+ if (visitor instanceof OgnlVisitor) accept((OgnlVisitor)visitor);
+ else super.accept(visitor);
+ }
+
+}
diff --git a/src/main/gen/psi/impl/OgnlIndexedExpressionImpl.java b/src/main/gen/psi/impl/OgnlIndexedExpressionImpl.java
new file mode 100644
index 0000000..ed36109
--- /dev/null
+++ b/src/main/gen/psi/impl/OgnlIndexedExpressionImpl.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi.impl;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.util.PsiTreeUtil;
+import static com.intellij.lang.ognl.OgnlTypes.*;
+import com.intellij.lang.ognl.psi.*;
+
+public class OgnlIndexedExpressionImpl extends OgnlExpressionImpl implements OgnlIndexedExpression {
+
+ public OgnlIndexedExpressionImpl(ASTNode node) {
+ super(node);
+ }
+
+ public void accept(@NotNull OgnlVisitor visitor) {
+ visitor.visitIndexedExpression(this);
+ }
+
+ public void accept(@NotNull PsiElementVisitor visitor) {
+ if (visitor instanceof OgnlVisitor) accept((OgnlVisitor)visitor);
+ else super.accept(visitor);
+ }
+
+ @Override
+ @NotNull
+ public OgnlExpression getReferenceQualifier() {
+ List<OgnlExpression> p1 = PsiTreeUtil.getChildrenOfTypeAsList(this, OgnlExpression.class);
+ return p1.get(0);
+ }
+
+ @Override
+ @Nullable
+ public OgnlExpression getIndexExpression() {
+ List<OgnlExpression> p1 = PsiTreeUtil.getChildrenOfTypeAsList(this, OgnlExpression.class);
+ return p1.size() < 2 ? null : p1.get(1);
+ }
+
+}
diff --git a/src/main/gen/psi/impl/OgnlLambdaExpressionImpl.java b/src/main/gen/psi/impl/OgnlLambdaExpressionImpl.java
new file mode 100644
index 0000000..ea3939b
--- /dev/null
+++ b/src/main/gen/psi/impl/OgnlLambdaExpressionImpl.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi.impl;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.util.PsiTreeUtil;
+import static com.intellij.lang.ognl.OgnlTypes.*;
+import com.intellij.lang.ognl.psi.*;
+
+public class OgnlLambdaExpressionImpl extends OgnlExpressionImpl implements OgnlLambdaExpression {
+
+ public OgnlLambdaExpressionImpl(ASTNode node) {
+ super(node);
+ }
+
+ public void accept(@NotNull OgnlVisitor visitor) {
+ visitor.visitLambdaExpression(this);
+ }
+
+ public void accept(@NotNull PsiElementVisitor visitor) {
+ if (visitor instanceof OgnlVisitor) accept((OgnlVisitor)visitor);
+ else super.accept(visitor);
+ }
+
+ @Override
+ @Nullable
+ public OgnlExpression getExpression() {
+ return findChildByClass(OgnlExpression.class);
+ }
+
+}
diff --git a/src/main/gen/psi/impl/OgnlLiteralExpressionImpl.java b/src/main/gen/psi/impl/OgnlLiteralExpressionImpl.java
new file mode 100644
index 0000000..177e2d7
--- /dev/null
+++ b/src/main/gen/psi/impl/OgnlLiteralExpressionImpl.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi.impl;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.util.PsiTreeUtil;
+import static com.intellij.lang.ognl.OgnlTypes.*;
+import com.intellij.lang.ognl.psi.*;
+
+public class OgnlLiteralExpressionImpl extends OgnlExpressionImpl implements OgnlLiteralExpression {
+
+ public OgnlLiteralExpressionImpl(ASTNode node) {
+ super(node);
+ }
+
+ public void accept(@NotNull OgnlVisitor visitor) {
+ visitor.visitLiteralExpression(this);
+ }
+
+ public void accept(@NotNull PsiElementVisitor visitor) {
+ if (visitor instanceof OgnlVisitor) accept((OgnlVisitor)visitor);
+ else super.accept(visitor);
+ }
+
+ @Nullable
+ public Object getConstantValue() {
+ return OgnlPsiUtil.getConstantValue(this);
+ }
+
+}
diff --git a/src/main/gen/psi/impl/OgnlMapEntryElementImpl.java b/src/main/gen/psi/impl/OgnlMapEntryElementImpl.java
new file mode 100644
index 0000000..e1c6e86
--- /dev/null
+++ b/src/main/gen/psi/impl/OgnlMapEntryElementImpl.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi.impl;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.util.PsiTreeUtil;
+import static com.intellij.lang.ognl.OgnlTypes.*;
+import com.intellij.lang.ognl.psi.*;
+
+public class OgnlMapEntryElementImpl extends OgnlPsiCompositeElementBase implements OgnlMapEntryElement {
+
+ public OgnlMapEntryElementImpl(ASTNode node) {
+ super(node);
+ }
+
+ public void accept(@NotNull OgnlVisitor visitor) {
+ visitor.visitMapEntryElement(this);
+ }
+
+ public void accept(@NotNull PsiElementVisitor visitor) {
+ if (visitor instanceof OgnlVisitor) accept((OgnlVisitor)visitor);
+ else super.accept(visitor);
+ }
+
+ @Override
+ @NotNull
+ public OgnlExpression getKeyExpression() {
+ List<OgnlExpression> p1 = PsiTreeUtil.getChildrenOfTypeAsList(this, OgnlExpression.class);
+ return p1.get(0);
+ }
+
+ @Override
+ @Nullable
+ public OgnlExpression getValueExpression() {
+ List<OgnlExpression> p1 = PsiTreeUtil.getChildrenOfTypeAsList(this, OgnlExpression.class);
+ return p1.size() < 2 ? null : p1.get(1);
+ }
+
+}
diff --git a/src/main/gen/psi/impl/OgnlMapExpressionImpl.java b/src/main/gen/psi/impl/OgnlMapExpressionImpl.java
new file mode 100644
index 0000000..034ee59
--- /dev/null
+++ b/src/main/gen/psi/impl/OgnlMapExpressionImpl.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi.impl;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.util.PsiTreeUtil;
+import static com.intellij.lang.ognl.OgnlTypes.*;
+import com.intellij.lang.ognl.psi.*;
+
+public class OgnlMapExpressionImpl extends OgnlExpressionImpl implements OgnlMapExpression {
+
+ public OgnlMapExpressionImpl(ASTNode node) {
+ super(node);
+ }
+
+ public void accept(@NotNull OgnlVisitor visitor) {
+ visitor.visitMapExpression(this);
+ }
+
+ public void accept(@NotNull PsiElementVisitor visitor) {
+ if (visitor instanceof OgnlVisitor) accept((OgnlVisitor)visitor);
+ else super.accept(visitor);
+ }
+
+ @Override
+ @NotNull
+ public List<OgnlMapEntryElement> getMapEntryElementList() {
+ return PsiTreeUtil.getChildrenOfTypeAsList(this, OgnlMapEntryElement.class);
+ }
+
+ @Override
+ @Nullable
+ public OgnlFqnTypeExpression getMapType() {
+ return findChildByClass(OgnlFqnTypeExpression.class);
+ }
+
+}
diff --git a/src/main/gen/psi/impl/OgnlMethodCallExpressionImpl.java b/src/main/gen/psi/impl/OgnlMethodCallExpressionImpl.java
new file mode 100644
index 0000000..cc80c23
--- /dev/null
+++ b/src/main/gen/psi/impl/OgnlMethodCallExpressionImpl.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi.impl;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.util.PsiTreeUtil;
+import static com.intellij.lang.ognl.OgnlTypes.*;
+import com.intellij.lang.ognl.psi.*;
+
+public class OgnlMethodCallExpressionImpl extends OgnlExpressionImpl implements OgnlMethodCallExpression {
+
+ public OgnlMethodCallExpressionImpl(ASTNode node) {
+ super(node);
+ }
+
+ public void accept(@NotNull OgnlVisitor visitor) {
+ visitor.visitMethodCallExpression(this);
+ }
+
+ public void accept(@NotNull PsiElementVisitor visitor) {
+ if (visitor instanceof OgnlVisitor) accept((OgnlVisitor)visitor);
+ else super.accept(visitor);
+ }
+
+ @Override
+ @Nullable
+ public OgnlParameterList getParameterList() {
+ return findChildByClass(OgnlParameterList.class);
+ }
+
+ @Override
+ @Nullable
+ public OgnlExpression getMethod() {
+ return findChildByClass(OgnlExpression.class);
+ }
+
+}
diff --git a/src/main/gen/psi/impl/OgnlNewArrayExpressionImpl.java b/src/main/gen/psi/impl/OgnlNewArrayExpressionImpl.java
new file mode 100644
index 0000000..68dbdd4
--- /dev/null
+++ b/src/main/gen/psi/impl/OgnlNewArrayExpressionImpl.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi.impl;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.util.PsiTreeUtil;
+import static com.intellij.lang.ognl.OgnlTypes.*;
+import com.intellij.lang.ognl.psi.*;
+
+public class OgnlNewArrayExpressionImpl extends OgnlExpressionImpl implements OgnlNewArrayExpression {
+
+ public OgnlNewArrayExpressionImpl(ASTNode node) {
+ super(node);
+ }
+
+ public void accept(@NotNull OgnlVisitor visitor) {
+ visitor.visitNewArrayExpression(this);
+ }
+
+ public void accept(@NotNull PsiElementVisitor visitor) {
+ if (visitor instanceof OgnlVisitor) accept((OgnlVisitor)visitor);
+ else super.accept(visitor);
+ }
+
+ @Override
+ @NotNull
+ public OgnlExpression getObjectType() {
+ List<OgnlExpression> p1 = PsiTreeUtil.getChildrenOfTypeAsList(this, OgnlExpression.class);
+ return p1.get(0);
+ }
+
+ @Override
+ @Nullable
+ public OgnlExpression getConstructorExpression() {
+ List<OgnlExpression> p1 = PsiTreeUtil.getChildrenOfTypeAsList(this, OgnlExpression.class);
+ return p1.size() < 2 ? null : p1.get(1);
+ }
+
+}
diff --git a/src/main/gen/psi/impl/OgnlNewExpressionImpl.java b/src/main/gen/psi/impl/OgnlNewExpressionImpl.java
new file mode 100644
index 0000000..378176c
--- /dev/null
+++ b/src/main/gen/psi/impl/OgnlNewExpressionImpl.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi.impl;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.util.PsiTreeUtil;
+import static com.intellij.lang.ognl.OgnlTypes.*;
+import com.intellij.lang.ognl.psi.*;
+
+public class OgnlNewExpressionImpl extends OgnlExpressionImpl implements OgnlNewExpression {
+
+ public OgnlNewExpressionImpl(ASTNode node) {
+ super(node);
+ }
+
+ public void accept(@NotNull OgnlVisitor visitor) {
+ visitor.visitNewExpression(this);
+ }
+
+ public void accept(@NotNull PsiElementVisitor visitor) {
+ if (visitor instanceof OgnlVisitor) accept((OgnlVisitor)visitor);
+ else super.accept(visitor);
+ }
+
+ @Override
+ @Nullable
+ public OgnlParameterList getParameterList() {
+ return findChildByClass(OgnlParameterList.class);
+ }
+
+ @Override
+ @Nullable
+ public OgnlFqnTypeExpression getObjectType() {
+ return findChildByClass(OgnlFqnTypeExpression.class);
+ }
+
+}
diff --git a/src/main/gen/psi/impl/OgnlParameterListImpl.java b/src/main/gen/psi/impl/OgnlParameterListImpl.java
new file mode 100644
index 0000000..496e86b
--- /dev/null
+++ b/src/main/gen/psi/impl/OgnlParameterListImpl.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi.impl;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.util.PsiTreeUtil;
+import static com.intellij.lang.ognl.OgnlTypes.*;
+import com.intellij.lang.ognl.psi.*;
+
+public class OgnlParameterListImpl extends OgnlPsiCompositeElementBase implements OgnlParameterList {
+
+ public OgnlParameterListImpl(ASTNode node) {
+ super(node);
+ }
+
+ public void accept(@NotNull OgnlVisitor visitor) {
+ visitor.visitParameterList(this);
+ }
+
+ public void accept(@NotNull PsiElementVisitor visitor) {
+ if (visitor instanceof OgnlVisitor) accept((OgnlVisitor)visitor);
+ else super.accept(visitor);
+ }
+
+ @Override
+ @NotNull
+ public List<OgnlExpression> getParametersList() {
+ return PsiTreeUtil.getChildrenOfTypeAsList(this, OgnlExpression.class);
+ }
+
+ public int getParameterCount() {
+ return OgnlPsiUtil.getParameterCount(this);
+ }
+
+}
diff --git a/src/main/gen/psi/impl/OgnlParenthesizedExpressionImpl.java b/src/main/gen/psi/impl/OgnlParenthesizedExpressionImpl.java
new file mode 100644
index 0000000..e934ef4
--- /dev/null
+++ b/src/main/gen/psi/impl/OgnlParenthesizedExpressionImpl.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi.impl;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.util.PsiTreeUtil;
+import static com.intellij.lang.ognl.OgnlTypes.*;
+import com.intellij.lang.ognl.psi.*;
+
+public class OgnlParenthesizedExpressionImpl extends OgnlExpressionImpl implements OgnlParenthesizedExpression {
+
+ public OgnlParenthesizedExpressionImpl(ASTNode node) {
+ super(node);
+ }
+
+ public void accept(@NotNull OgnlVisitor visitor) {
+ visitor.visitParenthesizedExpression(this);
+ }
+
+ public void accept(@NotNull PsiElementVisitor visitor) {
+ if (visitor instanceof OgnlVisitor) accept((OgnlVisitor)visitor);
+ else super.accept(visitor);
+ }
+
+ @Override
+ @Nullable
+ public OgnlExpression getExpression() {
+ return findChildByClass(OgnlExpression.class);
+ }
+
+}
diff --git a/src/main/gen/psi/impl/OgnlProjectionExpressionImpl.java b/src/main/gen/psi/impl/OgnlProjectionExpressionImpl.java
new file mode 100644
index 0000000..dc31e57
--- /dev/null
+++ b/src/main/gen/psi/impl/OgnlProjectionExpressionImpl.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi.impl;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.util.PsiTreeUtil;
+import static com.intellij.lang.ognl.OgnlTypes.*;
+import com.intellij.lang.ognl.psi.*;
+
+public class OgnlProjectionExpressionImpl extends OgnlExpressionImpl implements OgnlProjectionExpression {
+
+ public OgnlProjectionExpressionImpl(ASTNode node) {
+ super(node);
+ }
+
+ public void accept(@NotNull OgnlVisitor visitor) {
+ visitor.visitProjectionExpression(this);
+ }
+
+ public void accept(@NotNull PsiElementVisitor visitor) {
+ if (visitor instanceof OgnlVisitor) accept((OgnlVisitor)visitor);
+ else super.accept(visitor);
+ }
+
+ @Override
+ @NotNull
+ public OgnlExpression getProjectionExpression() {
+ return findNotNullChildByClass(OgnlExpression.class);
+ }
+
+}
diff --git a/src/main/gen/psi/impl/OgnlReferenceExpressionImpl.java b/src/main/gen/psi/impl/OgnlReferenceExpressionImpl.java
new file mode 100644
index 0000000..9386fb3
--- /dev/null
+++ b/src/main/gen/psi/impl/OgnlReferenceExpressionImpl.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi.impl;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.util.PsiTreeUtil;
+import static com.intellij.lang.ognl.OgnlTypes.*;
+import com.intellij.lang.ognl.psi.*;
+
+public class OgnlReferenceExpressionImpl extends OgnlReferenceExpressionBase implements OgnlReferenceExpression {
+
+ public OgnlReferenceExpressionImpl(ASTNode node) {
+ super(node);
+ }
+
+ public void accept(@NotNull OgnlVisitor visitor) {
+ visitor.visitReferenceExpression(this);
+ }
+
+ public void accept(@NotNull PsiElementVisitor visitor) {
+ if (visitor instanceof OgnlVisitor) accept((OgnlVisitor)visitor);
+ else super.accept(visitor);
+ }
+
+ @Override
+ @NotNull
+ public List<OgnlExpression> getExpressionList() {
+ return PsiTreeUtil.getChildrenOfTypeAsList(this, OgnlExpression.class);
+ }
+
+}
diff --git a/src/main/gen/psi/impl/OgnlSelectionExpressionImpl.java b/src/main/gen/psi/impl/OgnlSelectionExpressionImpl.java
new file mode 100644
index 0000000..42f56c2
--- /dev/null
+++ b/src/main/gen/psi/impl/OgnlSelectionExpressionImpl.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi.impl;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.util.PsiTreeUtil;
+import static com.intellij.lang.ognl.OgnlTypes.*;
+import com.intellij.lang.ognl.psi.*;
+
+public class OgnlSelectionExpressionImpl extends OgnlExpressionImpl implements OgnlSelectionExpression {
+
+ public OgnlSelectionExpressionImpl(ASTNode node) {
+ super(node);
+ }
+
+ public void accept(@NotNull OgnlVisitor visitor) {
+ visitor.visitSelectionExpression(this);
+ }
+
+ public void accept(@NotNull PsiElementVisitor visitor) {
+ if (visitor instanceof OgnlVisitor) accept((OgnlVisitor)visitor);
+ else super.accept(visitor);
+ }
+
+ @Override
+ @NotNull
+ public OgnlExpression getSelectorExpression() {
+ return findNotNullChildByClass(OgnlExpression.class);
+ }
+
+}
diff --git a/src/main/gen/psi/impl/OgnlSequenceExpressionImpl.java b/src/main/gen/psi/impl/OgnlSequenceExpressionImpl.java
new file mode 100644
index 0000000..d07a5dd
--- /dev/null
+++ b/src/main/gen/psi/impl/OgnlSequenceExpressionImpl.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi.impl;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.util.PsiTreeUtil;
+import static com.intellij.lang.ognl.OgnlTypes.*;
+import com.intellij.lang.ognl.psi.*;
+
+public class OgnlSequenceExpressionImpl extends OgnlExpressionImpl implements OgnlSequenceExpression {
+
+ public OgnlSequenceExpressionImpl(ASTNode node) {
+ super(node);
+ }
+
+ public void accept(@NotNull OgnlVisitor visitor) {
+ visitor.visitSequenceExpression(this);
+ }
+
+ public void accept(@NotNull PsiElementVisitor visitor) {
+ if (visitor instanceof OgnlVisitor) accept((OgnlVisitor)visitor);
+ else super.accept(visitor);
+ }
+
+ @Override
+ @NotNull
+ public List<OgnlExpression> getElementsList() {
+ return PsiTreeUtil.getChildrenOfTypeAsList(this, OgnlExpression.class);
+ }
+
+}
diff --git a/src/main/gen/psi/impl/OgnlUnaryExpressionImpl.java b/src/main/gen/psi/impl/OgnlUnaryExpressionImpl.java
new file mode 100644
index 0000000..4be737b
--- /dev/null
+++ b/src/main/gen/psi/impl/OgnlUnaryExpressionImpl.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi.impl;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.util.PsiTreeUtil;
+import static com.intellij.lang.ognl.OgnlTypes.*;
+import com.intellij.lang.ognl.psi.*;
+
+public class OgnlUnaryExpressionImpl extends OgnlExpressionImpl implements OgnlUnaryExpression {
+
+ public OgnlUnaryExpressionImpl(ASTNode node) {
+ super(node);
+ }
+
+ public void accept(@NotNull OgnlVisitor visitor) {
+ visitor.visitUnaryExpression(this);
+ }
+
+ public void accept(@NotNull PsiElementVisitor visitor) {
+ if (visitor instanceof OgnlVisitor) accept((OgnlVisitor)visitor);
+ else super.accept(visitor);
+ }
+
+ @Override
+ @Nullable
+ public OgnlExpression getExpression() {
+ return findChildByClass(OgnlExpression.class);
+ }
+
+ @NotNull
+ public OgnlTokenType getUnaryOperator() {
+ return OgnlPsiUtil.getUnaryOperator(this);
+ }
+
+}
diff --git a/src/main/gen/psi/impl/OgnlVariableAssignmentExpressionImpl.java b/src/main/gen/psi/impl/OgnlVariableAssignmentExpressionImpl.java
new file mode 100644
index 0000000..59d8eac
--- /dev/null
+++ b/src/main/gen/psi/impl/OgnlVariableAssignmentExpressionImpl.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi.impl;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.util.PsiTreeUtil;
+import static com.intellij.lang.ognl.OgnlTypes.*;
+import com.intellij.lang.ognl.psi.*;
+
+public class OgnlVariableAssignmentExpressionImpl extends OgnlExpressionImpl implements OgnlVariableAssignmentExpression {
+
+ public OgnlVariableAssignmentExpressionImpl(ASTNode node) {
+ super(node);
+ }
+
+ public void accept(@NotNull OgnlVisitor visitor) {
+ visitor.visitVariableAssignmentExpression(this);
+ }
+
+ public void accept(@NotNull PsiElementVisitor visitor) {
+ if (visitor instanceof OgnlVisitor) accept((OgnlVisitor)visitor);
+ else super.accept(visitor);
+ }
+
+ @NotNull
+ public String getVariableName() {
+ return OgnlPsiUtil.getVariableName(this);
+ }
+
+ @Override
+ @Nullable
+ public OgnlExpression getAssignment() {
+ return findChildByClass(OgnlExpression.class);
+ }
+
+}
diff --git a/src/main/gen/psi/impl/OgnlVariableExpressionImpl.java b/src/main/gen/psi/impl/OgnlVariableExpressionImpl.java
new file mode 100644
index 0000000..bb88355
--- /dev/null
+++ b/src/main/gen/psi/impl/OgnlVariableExpressionImpl.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
+package com.intellij.lang.ognl.psi.impl;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.util.PsiTreeUtil;
+import static com.intellij.lang.ognl.OgnlTypes.*;
+import com.intellij.lang.ognl.psi.*;
+
+public class OgnlVariableExpressionImpl extends OgnlVariableExpressionBase implements OgnlVariableExpression {
+
+ public OgnlVariableExpressionImpl(ASTNode node) {
+ super(node);
+ }
+
+ public void accept(@NotNull OgnlVisitor visitor) {
+ visitor.visitVariableExpression(this);
+ }
+
+ public void accept(@NotNull PsiElementVisitor visitor) {
+ if (visitor instanceof OgnlVisitor) accept((OgnlVisitor)visitor);
+ else super.accept(visitor);
+ }
+
+}
diff --git a/src/main/grammar/apache2.txt b/src/main/grammar/apache2.txt
new file mode 100644
index 0000000..190fec4
--- /dev/null
+++ b/src/main/grammar/apache2.txt
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2018 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.
+ */
+
+
+// Generated from ognl.bnf, do not modify
\ No newline at end of file
diff --git a/src/main/grammar/ognl.bnf b/src/main/grammar/ognl.bnf
new file mode 100644
index 0000000..ef532d5
--- /dev/null
+++ b/src/main/grammar/ognl.bnf
@@ -0,0 +1,317 @@
+/*
+ * Copyright 2017 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.
+ */
+{
+ classHeader="apache2.txt"
+
+ psiImplUtilClass="com.intellij.lang.ognl.psi.impl.OgnlPsiUtil"
+
+ parserClass="com.intellij.lang.ognl.parser.OgnlParser"
+
+ implements="com.intellij.lang.ognl.psi.OgnlPsiCompositeElement"
+ extends="com.intellij.lang.ognl.psi.impl.OgnlPsiCompositeElementBase"
+
+ psiClassPrefix="Ognl"
+ psiImplClassSuffix="Impl"
+ psiPackage="com.intellij.lang.ognl.psi"
+ psiImplPackage="com.intellij.lang.ognl.psi.impl"
+
+ elementTypeHolderClass="com.intellij.lang.ognl.OgnlTypes"
+ elementTypePrefix=""
+ elementTypeClass="com.intellij.lang.ognl.psi.OgnlTokenType"
+ tokenTypeClass="com.intellij.lang.ognl.psi.OgnlTokenType"
+
+ extends(".*(Expression|Literal)")="expression"
+
+ tokens = [
+ EXPRESSION_START="%{"
+ EXPRESSION_END="}"
+
+ DOT="."
+ COMMA=","
+ COLON=":"
+
+ LPARENTH="("
+ RPARENTH=")"
+ LBRACKET="["
+ RBRACKET="]"
+ LBRACE="{"
+ RBRACE="}"
+
+ AT="@"
+ QUESTION="?"
+ DOLLAR="$"
+ HASH="#"
+
+ PLUS="+"
+ MINUS="-"
+ MULTIPLY="*"
+ DIVISION="/"
+ MODULO="%"
+
+ NEGATE="!"
+ NOT_EQUAL="!="
+ EQUAL="=="
+ EQ="="
+ LESS="<"
+ LESS_EQUAL="<="
+ GREATER=">"
+ GREATER_EQUAL=">="
+
+ EQ_KEYWORD="eq"
+ NEQ_KEYWORD="neq"
+ LT_KEYWORD="lt"
+ LT_EQ_KEYWORD="lte"
+ GT_KEYWORD="gt"
+ GT_EQ_KEYWORD="gte"
+
+ AND_AND="&&"
+ OR_OR="||"
+ AND_KEYWORD="and"
+ OR_KEYWORD="or"
+ NOT_KEYWORD="not"
+
+ OR="|"
+ XOR="^"
+ AND="&"
+ NOT="~"
+
+ BAND_KEYWORD="band"
+ BOR_KEYWORD="bor"
+ XOR_KEYWORD="xor"
+
+ NEW_KEYWORD="new"
+ TRUE_KEYWORD="true"
+ FALSE_KEYWORD="false"
+ NULL_KEYWORD="null"
+
+ INSTANCEOF_KEYWORD="instanceof"
+ NOT_IN_KEYWORD="not in"
+ IN_KEYWORD="in"
+
+ SHIFT_LEFT="<<"
+ SHIFT_RIGHT=">>"
+ SHIFT_RIGHT_LOGICAL=">>>"
+
+ SHIFT_LEFT_KEYWORD="shl"
+ SHIFT_RIGHT_KEYWORD="shr"
+ SHIFT_RIGHT_LOGICAL_KEYWORD="ushr"
+ ]
+}
+
+root ::= EXPRESSION_START rootElement EXPRESSION_END { pin=1 }
+private rootRecover ::= !(EXPRESSION_END)
+private rootElement ::= expression {recoverWhile="rootRecover"}
+
+expression ::= unaryExpression |
+ lambdaExpression |
+ mapExpression |
+ sequenceExpression |
+ parenthesizedExpression |
+ variableAssignmentExpression |
+ conditionalExpression |
+ binaryExpression |
+ newArrayExpression |
+ newExpression |
+ methodCallExpression |
+ indexedExpression |
+ referenceExpression |
+ variableExpression |
+ literalExpression
+{
+ methods=[
+ getType
+ ]
+}
+
+private numberLiteralExpression ::= INTEGER_LITERAL | BIG_INTEGER_LITERAL | DOUBLE_LITERAL | BIG_DECIMAL_LITERAL
+private booleanLiteralExpression ::= "true" | "false"
+private textLiteralExpression ::= STRING_LITERAL | CHARACTER_LITERAL // TODO detect missing closing quote/tick
+literalExpression ::= numberLiteralExpression |
+ textLiteralExpression |
+ booleanLiteralExpression |
+ "null" {
+ methods=[
+ getConstantValue
+ ]
+}
+
+projectionExpression ::= '{' expression '}'
+{
+ methods=[
+ projectionExpression="expression"
+ ]
+}
+selectionExpression ::= '{' ('?' | '^' | '$') expression '}'
+{
+ methods=[
+ selectorExpression="expression"
+ ]
+}
+
+referenceExpression ::= (variableExpression | ('@')? IDENTIFIER)
+ ('.' IDENTIFIER)* ('@' IDENTIFIER)?
+ ('.' selectionExpression)?
+ ('.' projectionExpression )?
+{
+ mixin="com.intellij.lang.ognl.psi.impl.OgnlReferenceExpressionBase"
+}
+
+variableExpression ::= '#' IDENTIFIER {
+ mixin="com.intellij.lang.ognl.psi.impl.OgnlVariableExpressionBase"
+}
+
+variableAssignmentExpression ::= '#' IDENTIFIER '=' expression {
+ methods=[
+ getVariableName
+ assignment="expression"
+ ]
+ pin=3
+}
+
+parameterList ::= expression? (',' expression)* {
+ methods=[
+ parametersList="expression"
+ getParameterCount
+ ]
+}
+methodCallExpression ::= referenceExpression '(' parameterList ')' {
+ methods=[
+ method="expression"
+ ]
+ pin(".*")="'\('"
+}
+
+private expressionSequenceRequired ::= expression (',' expression)+ { pin(".*")=1 }
+sequenceExpression ::= '{' expressionSequenceRequired '}' {
+ methods=[
+ elementsList="expression"
+ ]
+ pin=1
+}
+
+mapEntryElement ::= expression ':' expression {
+ methods=[
+ expression=""
+ keyExpression="expression[0]"
+ valueExpression="expression[1]"
+ ]
+ name="map entry"
+ pin=1
+}
+private mapExpressionSequence ::= [] mapEntryElement (',' mapEntryElement)* {pin(".*")=1}
+private mapTypeExpression ::= '#@' fqnTypeExpression '@{' {
+ pin=1
+}
+mapExpression ::= ('#{' | mapTypeExpression) mapExpressionSequence '}' {
+ methods=[
+ mapType="fqnTypeExpression"
+ ]
+ pin=1
+}
+
+lambdaExpression ::= ':' '[' expression "]" {
+ pin=1
+}
+
+indexedExpression ::= (referenceExpression | variableExpression) '[' expression ']'
+ ('.' IDENTIFIER)*
+ ('.' selectionExpression | projectionExpression)? {
+ methods=[
+ expression=""
+ referenceQualifier="expression[0]"
+ indexExpression="expression[1]"
+ ]
+ pin=2
+}
+
+parenthesizedExpression ::= '(' expression ')' { pin=1 }
+
+// binary ----------------------------------------------------------------
+private plusMinusOperations ::= '+' | '-'
+private divideMultiplyOperations ::= '*' | '/' | '%'
+private booleanOperations ::= "&&" | "||" |
+ "and" | "or" |
+ "not"
+private bitwiseBooleanOperations ::= "|" | "^" | "&" | "band" | "bor" | "xor"
+private equalityOperations ::= "==" | "!=" |
+ "eq" | "neq"
+private relationalOperations ::= '<' | "<=" | '>' | ">=" |
+ "lt" | "lte" | "gt" | "gte"
+private shiftOperations ::= "<<" | ">>" | ">>>" |
+ "shl" | "shr" | "ushr"
+private instanceOfOperation ::= "instanceof"
+private setOperations ::= "not in" | "in"
+private binaryOperations ::=
+ plusMinusOperations |
+ divideMultiplyOperations |
+ bitwiseBooleanOperations |
+ instanceOfOperation |
+ shiftOperations |
+ booleanOperations |
+ equalityOperations |
+ relationalOperations |
+ setOperations
+ { name="operator" }
+binaryExpression ::= expression binaryOperations expression {
+ methods=[
+ expression=""
+ left="expression[0]"
+ right="expression[1]"
+ getOperator
+ ]
+}
+
+private bitwiseOperations ::= '!' | "~"
+private unaryOperator ::= bitwiseOperations |
+ '+' | '-' | "not"
+unaryExpression ::= unaryOperator expression {
+ methods=[
+ getUnaryOperator
+ ]
+}
+
+private conditionalExpressionTail ::= ':' expression {pin=1}
+conditionalExpression ::= expression '?' expression conditionalExpressionTail {
+ methods=[
+ expression=""
+ condition="expression[0]"
+ then="expression[1]"
+ else="expression[2]"
+ ]
+}
+
+private constructorExpression ::= '(' parameterList ')' {pin=1}
+newExpression ::= "new" fqnTypeExpression constructorExpression {
+ methods=[
+ objectType="fqnTypeExpression"
+ ]
+ pin=1
+}
+
+private arrayConstructorExpression ::= '[' expression? ']' sequenceExpression? {pin=1}
+newArrayExpression ::= "new" fqnTypeExpression arrayConstructorExpression {
+ methods=[
+ expression=""
+ objectType="expression[0]"
+ constructorExpression="expression[1]"
+ ]
+}
+
+
+// common
+fqnTypeExpression ::= IDENTIFIER ('.' IDENTIFIER)* {
+ pin(".*")=1
+ mixin="com.intellij.lang.ognl.psi.impl.OgnlFqnTypeExpressionBase"
+}
diff --git a/src/main/java/com/intellij/struts2/Struts2IconProvider.java b/src/main/java/com/intellij/struts2/Struts2IconProvider.java
new file mode 100644
index 0000000..1cf4c4e
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/Struts2IconProvider.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2014 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.struts2;
+
+import com.intellij.ide.IconProvider;
+import com.intellij.jam.model.util.JamCommonUtil;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleUtilCore;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiModifier;
+import com.intellij.psi.impl.PsiClassImplUtil;
+import com.intellij.struts2.dom.struts.model.StrutsManager;
+import com.intellij.struts2.dom.struts.model.StrutsModel;
+import com.intellij.struts2.facet.StrutsFacet;
+import com.intellij.ui.LayeredIcon;
+import com.intellij.ui.scale.JBUIScale;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+
+/**
+ * Provides icons for Struts-related code. <br/>Original code posted by Sascha Weinreuter.
+ *
+ * @author Yann Cébron
+ */
+public class Struts2IconProvider extends IconProvider {
+
+ @Override
+ @Nullable
+ public Icon getIcon(@NotNull final PsiElement element, final int flags) {
+
+ if (!(element instanceof PsiClass psiClass)) {
+ return null;
+ }
+
+ // IconProvider queries non-physical PSI as well (e.g. completion items); check validity
+ if (!element.isPhysical() ||
+ !element.isValid()) {
+ return null;
+ }
+
+ // no icons when no facet present
+ final Module module = ModuleUtilCore.findModuleForPsiElement(element);
+ if (module == null) {
+ return null;
+ }
+
+ final StrutsFacet strutsFacet = StrutsFacet.getInstance(module);
+ if (strutsFacet == null) {
+ return null;
+ }
+
+ // handle suitable JAVA classes --> overlay icon
+ if (psiClass.isInterface() ||
+ psiClass.isEnum() ||
+ !psiClass.hasModifierProperty(PsiModifier.PUBLIC) ||
+ psiClass.hasModifierProperty(PsiModifier.ABSTRACT) ||
+ !JamCommonUtil.isPlainJavaFile(psiClass.getContainingFile())) {
+ return null;
+ }
+
+ final StrutsModel strutsModel = StrutsManager.getInstance(psiClass.getProject()).getCombinedModel(module);
+ if (strutsModel == null ||
+ !strutsModel.isActionClass(psiClass)) {
+ return null;
+ }
+
+ final LayeredIcon layeredIcon = new LayeredIcon(2);
+ final Icon original = PsiClassImplUtil.getClassIcon(flags, psiClass);
+ layeredIcon.setIcon(original, 0);
+ layeredIcon.setIcon(Struts2Icons.Action_small, 1, StrutsIcons.OVERLAY_X_OFFSET, StrutsIcons.OVERLAY_Y_OFFSET);
+ return JBUIScale.scaleIcon(layeredIcon);
+ }
+}
diff --git a/src/main/java/com/intellij/struts2/Struts2Icons.java b/src/main/java/com/intellij/struts2/Struts2Icons.java
new file mode 100644
index 0000000..5a7b8a1
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/Struts2Icons.java
@@ -0,0 +1,20 @@
+// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+package com.intellij.struts2;
+
+import com.intellij.ui.IconManager;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+
+/**
+ * NOTE THIS FILE IS AUTO-GENERATED
+ * DO NOT EDIT IT BY HAND, run "Generate icon classes" configuration instead
+ */
+public final class Struts2Icons {
+ private static @NotNull Icon load(@NotNull String path, int cacheKey, int flags) {
+ return IconManager.getInstance().loadRasterizedIcon(path, Struts2Icons.class.getClassLoader(), cacheKey, flags);
+ }
+ /** 16x16 */ public static final @NotNull Icon Action = load("icons/action.svg", 1640284181, 0);
+ /** 10x10 */ public static final @NotNull Icon Action_small = load("icons/action_small.svg", -592871696, 0);
+ /** 10x10 */ public static final @NotNull Icon Edit_small = load("icons/edit_small.svg", 1635832574, 0);
+}
diff --git a/src/main/java/com/intellij/struts2/Struts2PresentationProvider.java b/src/main/java/com/intellij/struts2/Struts2PresentationProvider.java
new file mode 100644
index 0000000..2c3a962
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/Struts2PresentationProvider.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2019 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.struts2;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.ide.presentation.PresentationProvider;
+import com.intellij.psi.PsiClass;
+import com.intellij.struts2.dom.struts.Include;
+import com.intellij.struts2.dom.struts.StrutsRoot;
+import com.intellij.struts2.dom.struts.action.ExceptionMapping;
+import com.intellij.struts2.dom.struts.action.Result;
+import com.intellij.struts2.dom.struts.strutspackage.*;
+import com.intellij.util.xml.DomUtil;
+import com.intellij.util.xml.GenericAttributeValue;
+
+import javax.swing.*;
+
+/**
+ * Provides icon/name for Struts DOM elements.
+ *
+ * @author Yann Cébron
+ */
+public class Struts2PresentationProvider extends PresentationProvider {
+
+ @Override
+ public Icon getIcon(final Object o) {
+
+ if (o instanceof DefaultInterceptorRef) {
+ return StrutsIcons.DEFAULT_INTERCEPTOR_REF;
+ }
+
+ if (o instanceof DefaultActionRef) {
+ return StrutsIcons.DEFAULT_ACTION_REF;
+ }
+
+ if (o instanceof DefaultClassRef) {
+ return StrutsIcons.DEFAULT_CLASS_REF;
+ }
+
+ if (o instanceof GlobalResult) {
+ return StrutsIcons.GLOBAL_RESULT;
+ }
+
+ if (o instanceof GlobalExceptionMapping) {
+ return StrutsIcons.GLOBAL_EXCEPTION_MAPPING;
+ }
+
+ if (o instanceof ExceptionMapping) {
+ return AllIcons.Nodes.ExceptionClass;
+ }
+
+ if (o instanceof StrutsRoot) {
+ return StrutsIcons.STRUTS_CONFIG_FILE;
+ }
+
+ if (o instanceof StrutsPackage) {
+ return StrutsIcons.STRUTS_PACKAGE;
+ }
+
+ if (o instanceof InterceptorRef) {
+ final InterceptorOrStackBase interceptorOrStackBase = ((InterceptorRef) o).getName().getValue();
+ if (interceptorOrStackBase instanceof Interceptor) {
+ return AllIcons.Nodes.Plugin;
+ }
+ if (interceptorOrStackBase instanceof InterceptorStack) {
+ return AllIcons.Nodes.Pluginobsolete;
+ }
+ }
+
+ if (o instanceof ResultType resultType) {
+ final GenericAttributeValue<Boolean> resultTypeDefault = resultType.getDefault();
+ if (DomUtil.hasXml(resultTypeDefault) &&
+ resultTypeDefault.getValue() == Boolean.TRUE) {
+ return StrutsIcons.RESULT_TYPE_DEFAULT;
+ }
+ return AllIcons.Debugger.Console;
+ }
+
+ return null;
+ }
+
+ @Override
+ public String getName(final Object o) {
+
+ if (o instanceof Result) {
+ return ((Result) o).getNameOrDefault();
+ }
+
+ if (o instanceof StrutsRoot) {
+ return DomUtil.getFile(((StrutsRoot) o)).getName();
+ }
+
+ if (o instanceof ExceptionMapping) {
+ final PsiClass exceptionClass = ((ExceptionMapping) o).getExceptionClass().getValue();
+ if (exceptionClass != null) {
+ return exceptionClass.getName();
+ }
+ return ((ExceptionMapping) o).getName().getStringValue();
+ }
+
+ if (o instanceof GlobalExceptionMapping) {
+ final PsiClass exceptionClass = ((GlobalExceptionMapping) o).getExceptionClass().getValue();
+ if (exceptionClass != null) {
+ return exceptionClass.getName();
+ }
+ return ((GlobalExceptionMapping) o).getName().getStringValue();
+ }
+
+ if (o instanceof InterceptorRef) {
+ return ((InterceptorRef) o).getName().getStringValue();
+ }
+
+ if (o instanceof DefaultInterceptorRef) {
+ return ((DefaultInterceptorRef) o).getName().getStringValue();
+ }
+
+ if (o instanceof Include) {
+ return ((Include) o).getFile().getStringValue();
+ }
+
+ if (o instanceof GlobalResult) {
+ final String globalResultName = ((GlobalResult) o).getName().getStringValue();
+ return globalResultName != null ? globalResultName : Result.DEFAULT_NAME;
+ }
+
+ if (o instanceof DefaultActionRef) {
+ return ((DefaultActionRef) o).getName().getStringValue();
+ }
+
+ if (o instanceof DefaultClassRef) {
+ return ((DefaultClassRef) o).getDefaultClass().getStringValue();
+ }
+
+ return null;
+ }
+
+}
diff --git a/src/main/java/com/intellij/struts2/Struts2ProblemFileHighlightFilter.java b/src/main/java/com/intellij/struts2/Struts2ProblemFileHighlightFilter.java
new file mode 100644
index 0000000..3ecbfb0
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/Struts2ProblemFileHighlightFilter.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2013 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.struts2;
+
+import com.intellij.ide.highlighter.XmlFileType;
+import com.intellij.openapi.application.ReadAction;
+import com.intellij.openapi.fileTypes.FileTypeRegistry;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleUtilCore;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiManager;
+import com.intellij.psi.xml.XmlFile;
+import com.intellij.struts2.dom.struts.model.StrutsManager;
+import com.intellij.struts2.dom.validator.ValidatorManager;
+import com.intellij.struts2.facet.StrutsFacet;
+
+/**
+ * Include {@code struts.xml}-files configured in filesets and all {@code *-validation.xml}-files
+ * for project view error highlighting.
+ * <p/>
+ * TODO include errors provided by DOM-inspections
+ *
+ * @author Yann Cébron
+ */
+public class Struts2ProblemFileHighlightFilter implements Condition<VirtualFile> {
+
+ private final Project project;
+
+ public Struts2ProblemFileHighlightFilter(final Project project) {
+ this.project = project;
+ }
+
+ @Override
+ public boolean value(final VirtualFile virtualFile) {
+ if (!FileTypeRegistry.getInstance().isFileOfType(virtualFile, XmlFileType.INSTANCE)) {
+ return false;
+ }
+
+ final Module module = ModuleUtilCore.findModuleForFile(virtualFile, project);
+ if (module == null) {
+ return false;
+ }
+
+ if (StrutsFacet.getInstance(module) == null) {
+ return false;
+ }
+
+ final boolean isStrutsXml = ReadAction.compute(() -> {
+ final StrutsManager strutsManager = StrutsManager.getInstance(project);
+
+ final PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile);
+ return psiFile instanceof XmlFile &&
+ strutsManager.isStruts2ConfigFile((XmlFile)psiFile) &&
+ strutsManager.getModelByFile((XmlFile)psiFile) != null;
+ });
+ if (isStrutsXml) {
+ return true;
+ }
+
+ return ReadAction.compute(() -> {
+ final PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile);
+ return psiFile instanceof XmlFile
+ && ValidatorManager.getInstance(project).isValidatorsFile((XmlFile)psiFile);
+ });
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/intellij/struts2/Struts2ResourceProvider.java b/src/main/java/com/intellij/struts2/Struts2ResourceProvider.java
new file mode 100644
index 0000000..0d45d63
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/Struts2ResourceProvider.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2019 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.struts2;
+
+import com.intellij.javaee.ResourceRegistrar;
+import com.intellij.javaee.StandardResourceProvider;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * Provides "External resources" (DTDs).
+ *
+ * @author Dmitry Avdeev
+ */
+final class Struts2ResourceProvider implements StandardResourceProvider {
+ @NonNls
+ private static final String DTD_PATH = "/resources/dtds/";
+
+ @Override
+ public void registerResources(final ResourceRegistrar registrar) {
+ addDTDResource(StrutsConstants.STRUTS_2_0_DTD_URI,
+ StrutsConstants.STRUTS_2_0_DTD_ID,
+ "struts-2.0.dtd", registrar);
+
+ addDTDResource(StrutsConstants.STRUTS_2_1_DTD_URI,
+ StrutsConstants.STRUTS_2_1_DTD_ID,
+ "struts-2.1.dtd", registrar);
+
+ addDTDResource(StrutsConstants.STRUTS_2_1_7_DTD_URI,
+ StrutsConstants.STRUTS_2_1_7_DTD_ID,
+ "struts-2.1.7.dtd", registrar);
+
+ addDTDResource(StrutsConstants.STRUTS_2_3_DTD_URI,
+ StrutsConstants.STRUTS_2_3_DTD_ID,
+ "struts-2.3.dtd", registrar);
+
+ addDTDResource(StrutsConstants.STRUTS_2_5_DTD_URI,
+ StrutsConstants.STRUTS_2_5_DTD_ID,
+ "struts-2.5.dtd", registrar);
+
+
+ addDTDResource(StrutsConstants.VALIDATOR_1_00_DTD_URI,
+ StrutsConstants.VALIDATOR_1_00_DTD_ID,
+ "xwork-validator-1.0.dtd", registrar);
+ addDTDResource(StrutsConstants.VALIDATOR_1_00_STRUTS_DTD_URI,
+ StrutsConstants.VALIDATOR_1_00_STRUTS_DTD_ID,
+ "xwork-validator-struts-1.0.dtd", registrar);
+
+ addDTDResource(StrutsConstants.VALIDATOR_1_02_DTD_URI,
+ StrutsConstants.VALIDATOR_1_02_DTD_ID,
+ "xwork-validator-1.0.2.dtd", registrar);
+ addDTDResource(StrutsConstants.VALIDATOR_1_02_STRUTS_DTD_URI,
+ StrutsConstants.VALIDATOR_1_02_STRUTS_DTD_ID,
+ "xwork-validator-struts-1.0.2.dtd", registrar);
+
+ addDTDResource(StrutsConstants.VALIDATOR_1_03_DTD_URI,
+ StrutsConstants.VALIDATOR_1_03_DTD_ID,
+ "xwork-validator-1.0.3.dtd", registrar);
+
+ addDTDResource(StrutsConstants.VALIDATOR_CONFIG_DTD_URI,
+ StrutsConstants.VALIDATOR_CONFIG_DTD_ID,
+ "xwork-validator-config-1.0.dtd", registrar);
+ addDTDResource(StrutsConstants.VALIDATOR_CONFIG_STRUTS_DTD_URI,
+ StrutsConstants.VALIDATOR_CONFIG_STRUTS_DTD_ID,
+ "xwork-validator-config-struts-1.0.dtd", registrar);
+ addDTDResource(StrutsConstants.VALIDATOR_DEFINITION_DTD_URI,
+ StrutsConstants.VALIDATOR_DEFINITION_DTD_ID,
+ "xwork-validator-definition-1.0.dtd", registrar);
+ }
+
+ /**
+ * Adds a DTD resource from local DTD resource path.
+ *
+ * @param uri Resource URI.
+ * @param id Resource ID.
+ * @param localFile DTD filename.
+ * @param registrar Resource registrar.
+ */
+ private static void addDTDResource(@NonNls final String uri,
+ @NonNls final String id,
+ @NonNls final String localFile,
+ final ResourceRegistrar registrar) {
+ registrar.addStdResource(uri, DTD_PATH + localFile, Struts2ResourceProvider.class);
+ registrar.addStdResource(id, DTD_PATH + localFile, Struts2ResourceProvider.class);
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/intellij/struts2/Struts2ValidationPresentationProvider.java b/src/main/java/com/intellij/struts2/Struts2ValidationPresentationProvider.java
new file mode 100644
index 0000000..415226e
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/Struts2ValidationPresentationProvider.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2011 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.struts2;
+
+import com.intellij.ide.presentation.PresentationProvider;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.struts2.dom.validator.Field;
+import com.intellij.struts2.dom.validator.FieldValidator;
+import com.intellij.struts2.dom.validator.Message;
+import com.intellij.struts2.dom.validator.Validators;
+import com.intellij.struts2.dom.validator.config.ValidatorConfig;
+import com.intellij.util.xml.DomUtil;
+
+import javax.swing.*;
+
+/**
+ * Presentation icon/name for Validation DOM elements.
+ *
+ * @author Yann Cébron
+ */
+public class Struts2ValidationPresentationProvider extends PresentationProvider {
+
+ @Override
+ public Icon getIcon(final Object o) {
+
+ if (o instanceof Validators) {
+ return StrutsIcons.VALIDATION_CONFIG_FILE;
+ }
+
+ return null;
+ }
+
+ @Override
+ public String getName(final Object o) {
+
+ if (o instanceof Validators) {
+ return DomUtil.getFile(((Validators) o)).getName();
+ }
+
+ if (o instanceof Field) {
+ return ((Field) o).getName().getStringValue();
+ }
+
+ if (o instanceof FieldValidator) {
+ final ValidatorConfig validatorConfig = ((FieldValidator) o).getType().getValue();
+ return validatorConfig != null ? validatorConfig.getName().getStringValue() : null;
+ }
+
+ if (o instanceof Message) {
+ final String key = ((Message) o).getKey().getStringValue();
+ return StringUtil.isNotEmpty(key) ? key : ((Message) o).getValue();
+ }
+
+ return null;
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/intellij/struts2/StrutsBundle.java b/src/main/java/com/intellij/struts2/StrutsBundle.java
new file mode 100644
index 0000000..db18f1d
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/StrutsBundle.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2013 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.struts2;
+
+import com.intellij.DynamicBundle;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.PropertyKey;
+
+import java.util.function.Supplier;
+
+/**
+ * MessageResource provider.
+ *
+ * @author Yann Cébron
+ */
+public final class StrutsBundle extends DynamicBundle {
+
+ public static @Nls String message(@NotNull @PropertyKey(resourceBundle = PATH_TO_BUNDLE) String key, Object @NotNull ... params) {
+ return ourInstance.getMessage(key, params);
+ }
+
+ @NotNull
+ public static Supplier<@Nls String> messagePointer(@NotNull @PropertyKey(resourceBundle = PATH_TO_BUNDLE) String key, Object @NotNull ... params) {
+ return ourInstance.getLazyMessage(key, params);
+ }
+
+ private static final String PATH_TO_BUNDLE = "messages.Struts2Bundle";
+ private static final StrutsBundle ourInstance = new StrutsBundle();
+
+ private StrutsBundle() {
+ super(PATH_TO_BUNDLE);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/intellij/struts2/StrutsConstants.java b/src/main/java/com/intellij/struts2/StrutsConstants.java
new file mode 100644
index 0000000..265e901
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/StrutsConstants.java
@@ -0,0 +1,277 @@
+/*
+ * Copyright 2013 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.struts2;
+
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * Plugin-wide constants.
+ *
+ * @author Yann Cébron
+ */
+@SuppressWarnings("SpellCheckingInspection")
+public final class StrutsConstants {
+
+ private StrutsConstants() {
+ }
+
+ @NonNls
+ public static final String STRUTS_2_0_FILTER_CLASS = "org.apache.struts2.dispatcher.FilterDispatcher";
+
+ @NonNls
+ public static final String STRUTS_2_1_FILTER_CLASS = "org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter";
+
+ @NonNls
+ public static final String XWORK_ACTION_CLASS = "com.opensymphony.xwork2.Action";
+
+ /**
+ * Spring object factory.
+ */
+ @NonNls
+ public static final String SPRING_OBJECT_FACTORY_CLASS = "org.apache.struts2.spring.StrutsSpringObjectFactory";
+
+ /**
+ * Default filename for Struts configuration file.
+ */
+ @NonNls
+ public static final String STRUTS_XML_DEFAULT_FILENAME = "struts.xml";
+
+ /**
+ * struts.xml 2.0 URI.
+ */
+ @NonNls
+ public static final String STRUTS_2_0_DTD_URI = "http://struts.apache.org/dtds/struts-2.0.dtd";
+
+ /**
+ * struts.xml 2.0 ID.
+ */
+ @NonNls
+ public static final String STRUTS_2_0_DTD_ID = "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN";
+
+ /**
+ * struts.xml 2.1 URI.
+ */
+ @NonNls
+ public static final String STRUTS_2_1_DTD_URI = "http://struts.apache.org/dtds/struts-2.1.dtd";
+
+ /**
+ * struts.xml 2.1 ID.
+ */
+ @NonNls
+ public static final String STRUTS_2_1_DTD_ID = "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN";
+
+ /**
+ * struts.xml 2.1.7 URI.
+ */
+ @NonNls
+ public static final String STRUTS_2_1_7_DTD_URI = "http://struts.apache.org/dtds/struts-2.1.7.dtd";
+
+ /**
+ * struts.xml 2.1.7 ID.
+ */
+ @NonNls
+ public static final String STRUTS_2_1_7_DTD_ID = "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN";
+
+ /**
+ * struts.xml 2.3 URI.
+ */
+ @NonNls
+ public static final String STRUTS_2_3_DTD_URI = "http://struts.apache.org/dtds/struts-2.3.dtd";
+
+ /**
+ * struts.xml 2.3 ID.
+ */
+ @NonNls
+ public static final String STRUTS_2_3_DTD_ID = "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN";
+
+
+ @NonNls
+ public static final String STRUTS_2_5_DTD_URI = "http://struts.apache.org/dtds/struts-2.5.dtd";
+ @NonNls
+ public static final String STRUTS_2_5_DTD_ID = "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN";
+
+ /**
+ * All struts.xml DTD-IDs/URIs.
+ */
+ @NonNls
+ public static final String[] STRUTS_DTDS = {
+ STRUTS_2_0_DTD_URI, STRUTS_2_0_DTD_ID,
+ STRUTS_2_1_DTD_URI, STRUTS_2_1_DTD_ID,
+ STRUTS_2_1_7_DTD_URI, STRUTS_2_1_7_DTD_ID,
+ STRUTS_2_3_DTD_URI, STRUTS_2_3_DTD_ID,
+ STRUTS_2_5_DTD_URI, STRUTS_2_5_DTD_ID
+ };
+
+ @NonNls
+ public static final String VALIDATOR_1_00_DTD_URI = "http://www.opensymphony.com/xwork/xwork-validator-1.0.dtd";
+ @NonNls
+ public static final String VALIDATOR_1_00_DTD_ID = "-//OpenSymphony Group//XWork Validator 1.0//EN";
+ @NonNls
+ public static final String VALIDATOR_1_00_STRUTS_DTD_URI = "http://struts.apache.org/dtds/xwork-validator-1.0.dtd";
+ @NonNls
+ public static final String VALIDATOR_1_00_STRUTS_DTD_ID = "-//Apache Struts//XWork Validator 1.0//EN";
+
+ @NonNls
+ public static final String VALIDATOR_1_02_DTD_URI = "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd";
+ @NonNls
+ public static final String VALIDATOR_1_02_DTD_ID = "-//OpenSymphony Group//XWork Validator 1.0.2//EN";
+ @NonNls
+ public static final String VALIDATOR_1_02_STRUTS_DTD_URI = "http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd";
+ @NonNls
+ public static final String VALIDATOR_1_02_STRUTS_DTD_ID = "-//Apache Struts//XWork Validator 1.0.2//EN";
+
+ @NonNls
+ public static final String VALIDATOR_1_03_DTD_URI = "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd";
+ @NonNls
+ public static final String VALIDATOR_1_03_DTD_ID = "-//Apache Struts//XWork Validator 1.0.3//EN";
+
+ /**
+ * All XXX-validation.xml DTD-IDs/URIs.
+ */
+ @NonNls
+ public static final String[] VALIDATOR_DTDS = {
+ VALIDATOR_1_00_DTD_URI, VALIDATOR_1_00_DTD_ID,
+ VALIDATOR_1_00_STRUTS_DTD_URI, VALIDATOR_1_00_STRUTS_DTD_ID,
+ VALIDATOR_1_02_DTD_URI, VALIDATOR_1_02_DTD_ID,
+ VALIDATOR_1_02_STRUTS_DTD_URI, VALIDATOR_1_02_STRUTS_DTD_ID,
+ VALIDATOR_1_03_DTD_URI, VALIDATOR_1_03_DTD_ID
+ };
+
+ @NonNls
+ public static final String VALIDATOR_CONFIG_DTD_URI = "http://www.opensymphony.com/xwork/xwork-validator-config-1.0.dtd";
+ @NonNls
+ public static final String VALIDATOR_CONFIG_DTD_ID = "-//OpenSymphony Group//XWork Validator Config 1.0//EN";
+ @NonNls
+ public static final String VALIDATOR_CONFIG_STRUTS_DTD_URI = "http://struts.apache.org/dtds/xwork-validator-config-1.0.dtd";
+ @NonNls
+ public static final String VALIDATOR_CONFIG_STRUTS_DTD_ID = "-//Apache Struts//XWork Validator Config 1.0//EN";
+
+
+ @NonNls
+ public static final String VALIDATOR_DEFINITION_DTD_URI = "http://struts.apache.org/dtds/xwork-validator-definition-1.0.dtd";
+ @NonNls
+ public static final String VALIDATOR_DEFINITION_DTD_ID = "-//Apache Struts//XWork Validator Definition 1.0//EN";
+
+ @NonNls
+ public static final String[] VALIDATOR_CONFIG_DTDS = {
+ VALIDATOR_CONFIG_DTD_URI, VALIDATOR_CONFIG_DTD_ID,
+ VALIDATOR_CONFIG_STRUTS_DTD_URI, VALIDATOR_CONFIG_STRUTS_DTD_ID,
+ VALIDATOR_DEFINITION_DTD_URI, VALIDATOR_DEFINITION_DTD_ID
+ };
+
+ /**
+ * Struts UI taglib URI.
+ */
+ @NonNls
+ public static final String TAGLIB_STRUTS_UI_URI = "/struts-tags";
+
+ /**
+ * Struts UI taglib default prefix.
+ */
+ @NonNls
+ public static final String TAGLIB_STRUTS_UI_PREFIX = "s";
+
+ /**
+ * Struts UI taglib CSS-attributes.
+ */
+ @NonNls
+ public static final String[] TAGLIB_STRUTS_UI_CSS_ATTRIBUTES =
+ new String[]{"buttonCssStyle", "cssErrorStyle", "cssStyle", "doubleCssStyle"};
+
+ /**
+ * Struts jQuery-plugin taglib URI.
+ */
+ @NonNls
+ public static final String TAGLIB_JQUERY_PLUGIN_URI = "/struts-jquery-tags";
+
+ /**
+ * Struts jQuery-plugin taglib default prefix.
+ */
+ @NonNls
+ public static final String TAGLIB_JQUERY_PLUGIN_PREFIX = "sj";
+
+ /**
+ * Struts jQuery-plugin richtext taglib URI.
+ */
+ @NonNls
+ public static final String TAGLIB_JQUERY_RICHTEXT_PLUGIN_URI = "/struts-jquery-richtext-tags";
+
+ /**
+ * Struts jQuery-plugin richtext taglib default prefix.
+ */
+ @NonNls
+ public static final String TAGLIB_JQUERY_RICHTEXT_PLUGIN_PREFIX = "sjr";
+
+ /**
+ * Struts jQuery-plugin chart taglib URI.
+ */
+ @NonNls
+ public static final String TAGLIB_JQUERY_CHART_PLUGIN_URI = "/struts-jquery-chart-tags";
+
+ /**
+ * Struts jQuery-plugin chart taglib default prefix.
+ */
+ @NonNls
+ public static final String TAGLIB_JQUERY_CHART_PLUGIN_PREFIX = "sjc";
+
+ /**
+ * Struts jQuery-plugin tree taglib URI.
+ */
+ @NonNls
+ public static final String TAGLIB_JQUERY_TREE_PLUGIN_URI = "/struts-jquery-tree-tags";
+
+ /**
+ * Struts jQuery-plugin tree taglib default prefix.
+ */
+ @NonNls
+ public static final String TAGLIB_JQUERY_TREE_PLUGIN_PREFIX = "sjt";
+
+ /**
+ * Struts jQuery-plugin grid taglib URI.
+ */
+ @NonNls
+ public static final String TAGLIB_JQUERY_GRID_PLUGIN_URI = "/struts-jquery-grid-tags";
+
+ /**
+ * Struts jQuery-plugin grid taglib default prefix.
+ */
+ @NonNls
+ public static final String TAGLIB_JQUERY_GRID_PLUGIN_PREFIX = "sjg";
+
+ /**
+ * Struts jQuery-plugin mobile taglib URI.
+ */
+ @NonNls
+ public static final String TAGLIB_JQUERY_MOBILE_PLUGIN_URI = "/struts-jquery-mobile-tags";
+
+ /**
+ * Struts jQuery-plugin mobile taglib default prefix.
+ */
+ @NonNls
+ public static final String TAGLIB_JQUERY_MOBILE_PLUGIN_PREFIX = "sjm";
+
+ /**
+ * Struts bootstrap-plugin taglib URI.
+ */
+ @NonNls
+ public static final String TAGLIB_BOOTSTRAP_PLUGIN_URI = "/struts-bootstrap-tags";
+
+ /**
+ * Struts bootstrap-plugin taglib default prefix.
+ */
+ @NonNls
+ public static final String TAGLIB_BOOTSTRAP_PLUGIN_PREFIX = "sb";
+}
\ No newline at end of file
diff --git a/src/main/java/com/intellij/struts2/StrutsFileTemplateGroupDescriptorFactory.java b/src/main/java/com/intellij/struts2/StrutsFileTemplateGroupDescriptorFactory.java
new file mode 100644
index 0000000..e8cbe92
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/StrutsFileTemplateGroupDescriptorFactory.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2016 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.struts2;
+
+import com.intellij.ide.fileTemplates.FileTemplateDescriptor;
+import com.intellij.ide.fileTemplates.FileTemplateGroupDescriptor;
+import com.intellij.ide.fileTemplates.FileTemplateGroupDescriptorFactory;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * Provides templates for struts.xml/validator.xml files.
+ *
+ * @author Yann Cébron
+ */
+public class StrutsFileTemplateGroupDescriptorFactory implements FileTemplateGroupDescriptorFactory {
+
+ /**
+ * Template for {@code 2.0.x}.
+ */
+ @NonNls
+ public static final String STRUTS_2_0_XML = "struts.xml";
+
+ /**
+ * Template for {@code 2.1.x}.
+ */
+ @NonNls
+ public static final String STRUTS_2_1_XML = "struts_2_1.xml";
+
+ /**
+ * Template for {@code >=2.1.7}.
+ */
+ @NonNls
+ public static final String STRUTS_2_1_7_XML = "struts_2_1_7.xml";
+
+ /**
+ * Template for {@code >=2.3}.
+ */
+ public static final String STRUTS_2_3_XML = "struts_2_3.xml";
+
+ /**
+ * Template for {@code >=2.5}.
+ */
+ public static final String STRUTS_2_5_XML = "struts_2_5.xml";
+
+ /**
+ * Template for {@code validation.xml}. TODO cannot name "validation.xml" due to SA using this template name.
+ */
+ public static final String VALIDATION_XML = "validator.xml";
+
+ @Override
+ public FileTemplateGroupDescriptor getFileTemplatesDescriptor() {
+ final FileTemplateGroupDescriptor group = new FileTemplateGroupDescriptor(StrutsBundle.message("struts2"),
+ Struts2Icons.Action);
+ group.addTemplate(new FileTemplateDescriptor(STRUTS_2_0_XML,
+ StrutsIcons.STRUTS_CONFIG_FILE));
+ group.addTemplate(new FileTemplateDescriptor(STRUTS_2_1_XML,
+ StrutsIcons.STRUTS_CONFIG_FILE));
+ group.addTemplate(new FileTemplateDescriptor(STRUTS_2_1_7_XML,
+ StrutsIcons.STRUTS_CONFIG_FILE));
+ group.addTemplate(new FileTemplateDescriptor(STRUTS_2_3_XML,
+ StrutsIcons.STRUTS_CONFIG_FILE));
+ group.addTemplate(new FileTemplateDescriptor(STRUTS_2_5_XML,
+ StrutsIcons.STRUTS_CONFIG_FILE));
+
+ group.addTemplate(new FileTemplateDescriptor(VALIDATION_XML,
+ StrutsIcons.VALIDATION_CONFIG_FILE));
+ return group;
+ }
+
+}
diff --git a/src/main/java/com/intellij/struts2/StrutsFileTemplateProvider.java b/src/main/java/com/intellij/struts2/StrutsFileTemplateProvider.java
new file mode 100644
index 0000000..b641863
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/StrutsFileTemplateProvider.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2016 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.struts2;
+
+import com.intellij.ide.fileTemplates.FileTemplate;
+import com.intellij.ide.fileTemplates.FileTemplateManager;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.struts2.facet.ui.StrutsVersionDetector;
+import com.intellij.util.text.VersionComparatorUtil;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Yann Cébron
+ */
+public class StrutsFileTemplateProvider {
+
+ private final String myVersionName;
+ private final boolean my21orNewer;
+
+ public StrutsFileTemplateProvider(Module module) {
+ myVersionName = StrutsVersionDetector.detectStrutsVersion(module);
+ my21orNewer = isNewerThan("2.1");
+ }
+
+ @NotNull
+ public FileTemplate determineFileTemplate(Project project) {
+ String template;
+ if (isNewerThan("2.5")) {
+ template = StrutsFileTemplateGroupDescriptorFactory.STRUTS_2_5_XML;
+ }
+ else if (isNewerThan("2.3")) {
+ template = StrutsFileTemplateGroupDescriptorFactory.STRUTS_2_3_XML;
+ }
+ else if (my21orNewer) {
+ template = isNewerThan("2.1.7") ?
+ StrutsFileTemplateGroupDescriptorFactory.STRUTS_2_1_7_XML :
+ StrutsFileTemplateGroupDescriptorFactory.STRUTS_2_1_XML;
+ }
+ else {
+ template = StrutsFileTemplateGroupDescriptorFactory.STRUTS_2_0_XML;
+ }
+
+ final FileTemplateManager fileTemplateManager = FileTemplateManager.getInstance(project);
+ return fileTemplateManager.getJ2eeTemplate(template);
+ }
+
+ public boolean is21orNewer() {
+ return my21orNewer;
+ }
+
+ private boolean isNewerThan(String versionName) {
+ return VersionComparatorUtil.compare(myVersionName, versionName) > 0;
+ }
+}
diff --git a/src/main/java/com/intellij/struts2/StrutsIcons.java b/src/main/java/com/intellij/struts2/StrutsIcons.java
new file mode 100644
index 0000000..3b669d2
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/StrutsIcons.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2014 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.struts2;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.fileTypes.StdFileTypes;
+import com.intellij.ui.LayeredIcon;
+import com.intellij.ui.scale.JBUIScale;
+
+import javax.swing.*;
+
+/**
+ * All icons.
+ *
+ * @author Yann Cébron
+ */
+public final class StrutsIcons {
+ /**
+ * Icon for struts.xml files.
+ */
+ public static final LayeredIcon STRUTS_CONFIG_FILE = new LayeredIcon(2);
+
+ /**
+ * Icon for validation.xml files.
+ */
+ public static final LayeredIcon VALIDATION_CONFIG_FILE = new LayeredIcon(2);
+
+
+ public static final LayeredIcon ACTION_CLASS = new LayeredIcon(2);
+
+ public static final LayeredIcon STRUTS_VARIABLE = new LayeredIcon(2);
+
+ public static final LayeredIcon STRUTS_PACKAGE = new LayeredIcon(2);
+
+ /**
+ * Vertical offset for small overlay icons.
+ */
+ static final int OVERLAY_Y_OFFSET = JBUIScale.scale(7);
+
+ /**
+ * Horizontal offset for small overlay icons.
+ */
+ static final int OVERLAY_X_OFFSET = JBUIScale.scale(8);
+
+ private StrutsIcons() {
+ }
+
+ /**
+ * Overlay icon for "default" elements.
+ */
+ private static final Icon OVERLAY_DEFAULT = AllIcons.Actions.Checked;
+
+ public static final LayeredIcon RESULT_TYPE_DEFAULT = new LayeredIcon(2);
+
+ public static final LayeredIcon GLOBAL_RESULT = new LayeredIcon(2);
+ public static final LayeredIcon GLOBAL_EXCEPTION_MAPPING = new LayeredIcon(2);
+
+ public static final LayeredIcon DEFAULT_ACTION_REF = new LayeredIcon(2);
+ public static final LayeredIcon DEFAULT_CLASS_REF = new LayeredIcon(2);
+ public static final LayeredIcon DEFAULT_INTERCEPTOR_REF = new LayeredIcon(2);
+
+ // generic reference providers
+ public static final Icon THEME = AllIcons.Gutter.Colors;
+
+ static {
+ STRUTS_CONFIG_FILE.setIcon(StdFileTypes.XML.getIcon(), 0);
+ STRUTS_CONFIG_FILE.setIcon(Struts2Icons.Action_small, 1, OVERLAY_X_OFFSET, OVERLAY_Y_OFFSET);
+
+ VALIDATION_CONFIG_FILE.setIcon(StdFileTypes.XML.getIcon(), 0);
+ VALIDATION_CONFIG_FILE.setIcon(Struts2Icons.Edit_small, 1, OVERLAY_X_OFFSET, OVERLAY_Y_OFFSET);
+
+ ACTION_CLASS.setIcon(AllIcons.Nodes.Class, 0);
+ ACTION_CLASS.setIcon(Struts2Icons.Action_small, 1, OVERLAY_X_OFFSET, OVERLAY_Y_OFFSET);
+
+ STRUTS_VARIABLE.setIcon(AllIcons.Nodes.Variable, 0);
+ STRUTS_VARIABLE.setIcon(Struts2Icons.Action_small, 1, OVERLAY_X_OFFSET, OVERLAY_Y_OFFSET);
+
+ STRUTS_PACKAGE.setIcon(AllIcons.Nodes.Folder, 0);
+ STRUTS_PACKAGE.setIcon(Struts2Icons.Action_small, 1, OVERLAY_X_OFFSET, OVERLAY_Y_OFFSET);
+
+ createGlobalIcon(GLOBAL_RESULT, AllIcons.Vcs.Arrow_right);
+ createGlobalIcon(GLOBAL_EXCEPTION_MAPPING, AllIcons.Nodes.ExceptionClass);
+
+ createDefaultIcon(DEFAULT_ACTION_REF, Struts2Icons.Action);
+ createDefaultIcon(DEFAULT_CLASS_REF, AllIcons.Nodes.Class);
+ createDefaultIcon(DEFAULT_INTERCEPTOR_REF, AllIcons.Nodes.Plugin);
+ createDefaultIcon(RESULT_TYPE_DEFAULT, AllIcons.Debugger.Console);
+ }
+
+ private static void createGlobalIcon(final LayeredIcon icon, final Icon baseIcon) {
+ icon.setIcon(baseIcon, 0);
+ icon.setIcon(AllIcons.General.Web, 1, OVERLAY_X_OFFSET, OVERLAY_Y_OFFSET);
+ }
+
+ private static void createDefaultIcon(final LayeredIcon icon, final Icon baseIcon) {
+ icon.setIcon(baseIcon, 0);
+ icon.setIcon(OVERLAY_DEFAULT, 1, OVERLAY_X_OFFSET, OVERLAY_Y_OFFSET);
+ }
+}
diff --git a/src/main/java/com/intellij/struts2/actions/create/CreateStrutsXmlAction.java b/src/main/java/com/intellij/struts2/actions/create/CreateStrutsXmlAction.java
new file mode 100644
index 0000000..5827a5c
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/actions/create/CreateStrutsXmlAction.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2013 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.struts2.actions.create;
+
+import com.intellij.ide.actions.CreateFileAction;
+import com.intellij.ide.fileTemplates.FileTemplate;
+import com.intellij.ide.fileTemplates.FileTemplateUtil;
+import com.intellij.ide.highlighter.XmlFileType;
+import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.actionSystem.PlatformCoreDataKeys;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleUtilCore;
+import com.intellij.psi.JavaPsiFacade;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiElement;
+import com.intellij.struts2.StrutsBundle;
+import com.intellij.struts2.StrutsFileTemplateProvider;
+import com.intellij.struts2.StrutsIcons;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Yann Cébron
+ */
+final class CreateStrutsXmlAction extends CreateFileAction {
+ public CreateStrutsXmlAction() {
+ super(StrutsBundle.messagePointer("create.config.new.file"),
+ StrutsBundle.messagePointer("create.config.new.file.description"),
+ StrutsIcons.STRUTS_CONFIG_FILE);
+ }
+
+ @Override
+ protected boolean isAvailable(final DataContext dataContext) {
+ if (!super.isAvailable(dataContext)) {
+ return false;
+ }
+
+ final Module module = PlatformCoreDataKeys.MODULE.getData(dataContext);
+ return module != null && JavaPsiFacade.getInstance(module.getProject()).findPackage("org.apache.struts2") != null;
+ }
+
+ @Override
+ protected PsiElement @NotNull [] create(@NotNull final String newName, final @NotNull PsiDirectory directory) throws Exception {
+ @NonNls final String fileName = getFileName(newName);
+
+ final Module module = ModuleUtilCore.findModuleForPsiElement(directory);
+ StrutsFileTemplateProvider templateProvider = new StrutsFileTemplateProvider(module);
+ final FileTemplate strutsXmlTemplate = templateProvider.determineFileTemplate(directory.getProject());
+ final PsiElement file = FileTemplateUtil.createFromTemplate(strutsXmlTemplate,
+ fileName,
+ null,
+ directory);
+ return new PsiElement[]{file};
+ }
+
+ @Override
+ protected String getDefaultExtension() {
+ return XmlFileType.DEFAULT_EXTENSION;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/intellij/struts2/annotators/ActionAnnotatorBase.java b/src/main/java/com/intellij/struts2/annotators/ActionAnnotatorBase.java
new file mode 100644
index 0000000..a911c67
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/annotators/ActionAnnotatorBase.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright 2013 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.struts2.annotators;
+
+import com.intellij.codeInsight.daemon.RelatedItemLineMarkerInfo;
+import com.intellij.codeInsight.daemon.RelatedItemLineMarkerProvider;
+import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder;
+import com.intellij.icons.AllIcons;
+import com.intellij.navigation.GotoRelatedItem;
+import com.intellij.openapi.editor.markup.GutterIconRenderer;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleUtilCore;
+import com.intellij.openapi.paths.PathReference;
+import com.intellij.psi.*;
+import com.intellij.psi.xml.XmlFile;
+import com.intellij.struts2.Struts2Icons;
+import com.intellij.struts2.StrutsBundle;
+import com.intellij.struts2.StrutsIcons;
+import com.intellij.struts2.dom.struts.action.Action;
+import com.intellij.struts2.dom.struts.action.Result;
+import com.intellij.struts2.dom.struts.model.StrutsManager;
+import com.intellij.struts2.dom.struts.model.StrutsModel;
+import com.intellij.struts2.dom.validator.ValidatorManager;
+import com.intellij.struts2.facet.StrutsFacet;
+import com.intellij.util.NotNullFunction;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.xml.DomElement;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.util.*;
+
+/**
+ * Base class for annotating Action-Classes.
+ * Provides gutter icon/Go To Related File-navigation to <action> declaration(s) in struts.xml,
+ * corresponding {@code validation.xml}-files and navigation to result(s) from action methods.
+ *
+ * @author Yann Cébron
+ */
+public abstract class ActionAnnotatorBase extends RelatedItemLineMarkerProvider {
+ private static DomElementListCellRenderer<Action> getActionRenderer() {
+ return new DomElementListCellRenderer<>(StrutsBundle.message("annotators.action.no.name")) {
+ @Override
+ @NotNull
+ @NonNls
+ public String getAdditionalLocation(final Action action) {
+ return action != null ? "[" + action.getNamespace() + "] " : "";
+ }
+ };
+ }
+
+ private static final NotNullFunction<PathReference, Collection<? extends PsiElement>> PATH_REFERENCE_CONVERTER =
+ pathReference -> {
+ final PsiElement resolve = pathReference.resolve();
+ return resolve != null ? Collections.singleton(resolve) : Collections.emptyList();
+ };
+
+ private static final NotNullFunction<PathReference, Collection<? extends GotoRelatedItem>> PATH_REFERENCE_GOTO_RELATED_ITEM_PROVIDER =
+ pathReference -> {
+ final PsiElement resolve = pathReference.resolve();
+ return resolve != null ? Collections.singleton(new GotoRelatedItem(resolve) {
+ @Override
+ public Icon getCustomIcon() {
+ return pathReference.getIcon();
+ }
+
+ @Override
+ public String getCustomName() {
+ return pathReference.getPath();
+ }
+ }) : Collections.emptyList();
+ };
+
+ /**
+ * Determine the Action-PsiClass.
+ *
+ * @param psiElement Passed from annotator.
+ * @return null if PsiClass cannot be determined or is not suitable.
+ */
+ @Nullable
+ protected abstract PsiClass getActionPsiClass(@NotNull final PsiElement psiElement);
+
+ @Override
+ protected void collectNavigationMarkers(final @NotNull PsiElement element,
+ final @NotNull Collection<? super RelatedItemLineMarkerInfo<?>> lineMarkerInfos) {
+ if (!(element instanceof PsiIdentifier)) return;
+ final PsiClass clazz = getActionPsiClass(element.getParent());
+ if (clazz == null || clazz.getNameIdentifier() != element) {
+ return;
+ }
+
+ // do not run on non-public, abstract classes or interfaces
+ if (clazz.isInterface() ||
+ clazz.isAnnotationType() ||
+ !clazz.hasModifierProperty(PsiModifier.PUBLIC) ||
+ clazz.hasModifierProperty(PsiModifier.ABSTRACT)) {
+ return;
+ }
+
+ // short exit if Struts Facet not present
+ final Module module = ModuleUtilCore.findModuleForPsiElement(clazz);
+ if (module == null ||
+ StrutsFacet.getInstance(module) == null) {
+ return;
+ }
+
+ final StrutsManager strutsManager = StrutsManager.getInstance(element.getProject());
+ final StrutsModel strutsModel = strutsManager.getCombinedModel(module);
+ if (strutsModel == null) {
+ return;
+ }
+
+ installValidationTargets(element, lineMarkerInfos, clazz);
+
+ final List<Action> actions = strutsModel.findActionsByClass(clazz);
+ if (actions.isEmpty()) {
+ return;
+ }
+
+ installActionTargets(element, lineMarkerInfos, actions);
+ installActionMethods(lineMarkerInfos, clazz, actions);
+ }
+
+ /**
+ * Annotate action class to {@code <action>}-declarations.
+ *
+ * @param element Class element to annotate.
+ * @param lineMarkerInfos Current line markers.
+ * @param actions Corresponding Actions.
+ */
+ private static void installActionTargets(final PsiElement element,
+ final Collection<? super RelatedItemLineMarkerInfo<?>> lineMarkerInfos,
+ final List<? extends Action> actions) {
+ final String tooltip = actions.size() == 1 ? StrutsBundle.message("annotators.action.goto.tooltip.single") :
+ StrutsBundle.message("annotators.action.goto.tooltip");
+ final NavigationGutterIconBuilder<DomElement> gutterIconBuilder =
+ NavigationGutterIconBuilder.create(Struts2Icons.Action, NavigationGutterIconBuilder.DEFAULT_DOM_CONVERTOR,
+ NavigationGutterIconBuilder.DOM_GOTO_RELATED_ITEM_PROVIDER)
+ .setAlignment(GutterIconRenderer.Alignment.LEFT)
+ .setPopupTitle(StrutsBundle.message("annotators.action.goto.declaration"))
+ .setTargets(actions)
+ .setTooltipTitle(tooltip)
+ .setCellRenderer(ActionAnnotatorBase::getActionRenderer);
+ lineMarkerInfos.add(gutterIconBuilder.createLineMarkerInfo(element));
+ }
+
+ /**
+ * Annotate action-methods of this class with result(s).
+ *
+ * @param lineMarkerInfos Current line markers.
+ * @param clazz Class to annotate.
+ * @param actions Corresponding Actions.
+ */
+ private static void installActionMethods(final Collection<? super RelatedItemLineMarkerInfo<?>> lineMarkerInfos,
+ final PsiClass clazz,
+ final List<? extends Action> actions) {
+ final Map<PsiMethod, Set<PathReference>> pathReferenceMap = new HashMap<>();
+ for (final Action action : actions) {
+ final PsiMethod method = action.searchActionMethod();
+ if (method == null || !clazz.equals(method.getContainingClass())) {
+ continue;
+ }
+
+ final Set<PathReference> pathReferences = new HashSet<>();
+ final List<Result> results = action.getResults();
+ for (Result result : results) {
+ ContainerUtil.addIfNotNull(pathReferences, result.getValue());
+ }
+
+ Set<PathReference> toStore = pathReferenceMap.computeIfAbsent(method, __ -> new HashSet<>());
+ toStore.addAll(pathReferences);
+ pathReferenceMap.put(method, toStore);
+ }
+
+ for (final Map.Entry<PsiMethod, Set<PathReference>> entries : pathReferenceMap.entrySet()) {
+ final NavigationGutterIconBuilder<PathReference> gutterIconBuilder =
+ NavigationGutterIconBuilder.create(AllIcons.Actions.Forward, PATH_REFERENCE_CONVERTER,
+ PATH_REFERENCE_GOTO_RELATED_ITEM_PROVIDER)
+ .setAlignment(GutterIconRenderer.Alignment.LEFT)
+ .setPopupTitle(StrutsBundle.message("annotators.action.goto.result"))
+ .setTargets(entries.getValue())
+ .setTooltipTitle(StrutsBundle.message("annotators.action.goto.result.tooltip"));
+
+ PsiMethod method = entries.getKey();
+ PsiIdentifier identifier = method.getNameIdentifier();
+ if (identifier != null) {
+ lineMarkerInfos.add(gutterIconBuilder.createLineMarkerInfo(identifier));
+ }
+ }
+ }
+
+ /**
+ * Related {@code validation.xml} files.
+ *
+ * @param element Class element to annotate.
+ * @param lineMarkerInfos Current line markers.
+ * @param clazz Class to find validation files for.
+ */
+ private static void installValidationTargets(final PsiElement element,
+ final Collection<? super RelatedItemLineMarkerInfo<?>> lineMarkerInfos,
+ final PsiClass clazz) {
+ final List<XmlFile> files = ValidatorManager.getInstance(element.getProject()).findValidationFilesFor(clazz);
+ if (files.isEmpty()) {
+ return;
+ }
+
+ final NavigationGutterIconBuilder<PsiElement> validatorBuilder =
+ NavigationGutterIconBuilder.create(StrutsIcons.VALIDATION_CONFIG_FILE)
+ .setAlignment(GutterIconRenderer.Alignment.LEFT)
+ .setTargets(files)
+ .setPopupTitle(StrutsBundle.message("annotators.action.goto.validation"))
+ .setTooltipTitle(StrutsBundle.message("annotators.action.goto.validation.tooltip"));
+ lineMarkerInfos.add(validatorBuilder.createLineMarkerInfo(element));
+ }
+
+}
diff --git a/src/main/java/com/intellij/struts2/annotators/ActionJavaAnnotator.java b/src/main/java/com/intellij/struts2/annotators/ActionJavaAnnotator.java
new file mode 100644
index 0000000..391bf70
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/annotators/ActionJavaAnnotator.java
@@ -0,0 +1,64 @@
+/*
+ * 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.struts2.annotators;
+
+import com.intellij.ide.highlighter.JavaFileType;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import com.intellij.struts2.Struts2Icons;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+
+/**
+ * Annotator for JAVA-Action-classes.
+ * Provides gutter icon navigation to <action> declaration(s).
+ *
+ * @author Yann Cébron
+ */
+public class ActionJavaAnnotator extends ActionAnnotatorBase {
+
+ @Override
+ public String getId() {
+ return "ActionJavaAnnotator";
+ }
+
+ @Override
+ public String getName() {
+ return "Action (Java)";
+ }
+
+ @Nullable
+ @Override
+ public Icon getIcon() {
+ return Struts2Icons.Action;
+ }
+
+ @Override
+ protected PsiClass getActionPsiClass(@NotNull final PsiElement psiElement) {
+ if (!(psiElement instanceof PsiClass)) {
+ return null;
+ }
+
+ // do not run on classes within JSPs
+ if (psiElement.getContainingFile().getFileType() != JavaFileType.INSTANCE) {
+ return null;
+ }
+
+ return (PsiClass)psiElement;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/intellij/struts2/annotators/DomElementListCellRenderer.java b/src/main/java/com/intellij/struts2/annotators/DomElementListCellRenderer.java
new file mode 100644
index 0000000..77b81dd
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/annotators/DomElementListCellRenderer.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2007 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.struts2.annotators;
+
+import com.intellij.ide.util.PsiElementListCellRenderer;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.xml.XmlTag;
+import com.intellij.util.xml.DomElement;
+import com.intellij.util.xml.DomManager;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+
+/**
+ * Renderer for "GoTo"-gutter-popups.
+ *
+ * @param <T> Navigation target DOM element type.
+ * @author Dmitry Avdeev
+ * @author Yann Cébron
+ */
+abstract class DomElementListCellRenderer<T extends DomElement> extends PsiElementListCellRenderer<XmlTag> {
+
+ private final String unknownElementText;
+
+ protected DomElementListCellRenderer(@Nls final String unknownElementText) {
+ this.unknownElementText = unknownElementText;
+ }
+
+ /**
+ * Gets an additional location string.
+ *
+ * @param domElement Target navigation element.
+ * @return Empty String if not suitable.
+ */
+ @NotNull
+ @NonNls
+ public abstract String getAdditionalLocation(final T domElement);
+
+ @Override
+ public String getElementText(final XmlTag element) {
+ final DomElement domElement = getDomElement(element);
+ if (domElement == null) {
+ return element.getName();
+ }
+
+ final String elementName = domElement.getPresentation().getElementName();
+ return elementName == null ? unknownElementText : elementName;
+ }
+
+ @Override
+ protected String getContainerText(final XmlTag element, final String name) {
+ final String containingFile = " (" + element.getContainingFile().getName() + ')';
+
+ final T domElement = getDomElement(element);
+ if (domElement == null) {
+ return containingFile;
+ }
+
+ return getAdditionalLocation(domElement) + containingFile;
+ }
+
+ @Override
+ protected Icon getIcon(final PsiElement element) {
+ final DomElement domElement = getDomElement((XmlTag) element);
+ if (domElement != null) {
+ final Icon icon = domElement.getPresentation().getIcon();
+ if (icon != null) {
+ return icon;
+ }
+ }
+
+ return super.getIcon(element);
+ }
+
+ @SuppressWarnings({"unchecked"})
+ @Nullable
+ private T getDomElement(@NotNull final XmlTag tag) {
+ return (T) DomManager.getDomManager(tag.getProject()).getDomElement(tag);
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/intellij/struts2/annotators/JspActionAnnotator.java b/src/main/java/com/intellij/struts2/annotators/JspActionAnnotator.java
new file mode 100644
index 0000000..f81a01c
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/annotators/JspActionAnnotator.java
@@ -0,0 +1,149 @@
+/*
+ * 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.struts2.annotators;
+
+import com.intellij.codeInsight.daemon.LineMarkerInfo;
+import com.intellij.codeInsight.daemon.LineMarkerProviderDescriptor;
+import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder;
+import com.intellij.openapi.editor.markup.GutterIconRenderer;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleUtilCore;
+import com.intellij.openapi.util.NotNullLazyValue;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.xml.XmlTag;
+import com.intellij.psi.xml.XmlToken;
+import com.intellij.struts2.Struts2Icons;
+import com.intellij.struts2.StrutsBundle;
+import com.intellij.struts2.StrutsConstants;
+import com.intellij.struts2.StrutsIcons;
+import com.intellij.struts2.dom.struts.action.Action;
+import com.intellij.struts2.dom.struts.model.StrutsManager;
+import com.intellij.struts2.dom.struts.model.StrutsModel;
+import com.intellij.struts2.facet.StrutsFacet;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.xml.util.XmlTagUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Annotates custom tags with "action" attribute.
+ *
+ * @author Yann Cébron
+ */
+public final class JspActionAnnotator extends LineMarkerProviderDescriptor {
+ @NonNls
+ private static final String ACTION_ATTRIBUTE_NAME = "action";
+
+ @NonNls
+ private static final String[] TAGS_WITH_ACTION_ATTRIBUTE = {"action", "form", "reset", "submit", "url"};
+
+ @Override
+ public String getId() {
+ return "JspActionAnnotator";
+ }
+
+ @NotNull
+ @Override
+ public String getName() {
+ return "Action (JSP)";
+ }
+
+ @Override
+ public @NotNull Icon getIcon() {
+ return Struts2Icons.Action;
+ }
+
+ @Override
+ public LineMarkerInfo<?> getLineMarkerInfo(final @NotNull PsiElement psiElement) {
+ return null;
+ }
+
+ @Override
+ public void collectSlowLineMarkers(final @NotNull List<? extends PsiElement> psiElements,
+ final @NotNull Collection<? super LineMarkerInfo<?>> lineMarkerInfos) {
+ if (psiElements.isEmpty()) {
+ return;
+ }
+
+ for (final PsiElement element : psiElements) {
+ annotate(element, lineMarkerInfos);
+ }
+ }
+
+ private static void annotate(@NotNull final PsiElement element,
+ final @NotNull Collection<? super LineMarkerInfo<?>> lineMarkerInfos) {
+ if (!(element instanceof XmlTag xmlTag)) {
+ return;
+ }
+
+ // any of our tags?
+ final String tagName = xmlTag.getLocalName();
+ if (Arrays.binarySearch(TAGS_WITH_ACTION_ATTRIBUTE, tagName) < 0) {
+ return;
+ }
+
+ if (!Objects.equals(xmlTag.getNamespace(), StrutsConstants.TAGLIB_STRUTS_UI_URI)) {
+ return;
+ }
+
+ // short exit when Struts 2 facet not present
+ final Module module = ModuleUtilCore.findModuleForPsiElement(element);
+ if (module == null) {
+ return;
+ }
+
+ if (StrutsFacet.getInstance(module) == null) {
+ return;
+ }
+
+ // special case for <action>
+ final String actionPath = Objects.equals(tagName, ACTION_ATTRIBUTE_NAME) ?
+ xmlTag.getAttributeValue("name") :
+ xmlTag.getAttributeValue(ACTION_ATTRIBUTE_NAME);
+ if (actionPath == null) {
+ return;
+ }
+
+ final StrutsModel strutsModel = StrutsManager.getInstance(element.getProject()).getCombinedModel(module);
+ if (strutsModel == null) {
+ return;
+ }
+
+ final String namespace = xmlTag.getAttributeValue("namespace");
+ final List<Action> actions = strutsModel.findActionsByName(actionPath, namespace);
+ if (actions.isEmpty()) {
+ return;
+ }
+
+ // resolve to action method should be exactly 1
+ final NavigationGutterIconBuilder<PsiElement> gutterIconBuilder =
+ NavigationGutterIconBuilder.create(StrutsIcons.ACTION_CLASS).
+ setAlignment(GutterIconRenderer.Alignment.LEFT).
+ setTooltipText(StrutsBundle.message("annotators.jsp.goto.action.method")).
+ setEmptyPopupText(StrutsBundle.message("annotators.jsp.goto.action.method.not.found")).
+ setTargets(NotNullLazyValue.lazy(() -> ContainerUtil.mapNotNull(actions, Action::searchActionMethod)));
+
+ XmlToken identifier = XmlTagUtil.getStartTagNameElement(xmlTag);
+ if (identifier != null) {
+ lineMarkerInfos.add(gutterIconBuilder.createLineMarkerInfo(identifier));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/intellij/struts2/annotators/StrutsConventionImplicitUsageProvider.java b/src/main/java/com/intellij/struts2/annotators/StrutsConventionImplicitUsageProvider.java
new file mode 100644
index 0000000..35d5ca4
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/annotators/StrutsConventionImplicitUsageProvider.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2013 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.struts2.annotators;
+
+import com.intellij.codeInsight.AnnotationUtil;
+import com.intellij.codeInsight.daemon.ImplicitUsageProvider;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.*;
+import com.intellij.psi.util.InheritanceUtil;
+import com.intellij.struts2.StrutsConstants;
+import com.intellij.struts2.model.jam.convention.StrutsConventionConstants;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Yann Cébron
+ */
+public class StrutsConventionImplicitUsageProvider implements ImplicitUsageProvider {
+
+ @Override
+ public boolean isImplicitUsage(@NotNull PsiElement element) {
+ if (element instanceof PsiClass) {
+ return isConventionActionClass((PsiClass)element);
+ }
+
+ if (element instanceof PsiMethod psiMethod) {
+ if (!checkMethod(psiMethod)) {
+ return false;
+ }
+
+ return isAnnotatedWithAction(psiMethod) ||
+ isConventionActionClass(psiMethod.getContainingClass());
+ }
+ return false;
+ }
+
+ @Override
+ public boolean isImplicitRead(@NotNull PsiElement element) {
+ return false;
+ }
+
+ @Override
+ public boolean isImplicitWrite(@NotNull PsiElement element) {
+ return false;
+ }
+
+ private static boolean checkMethod(PsiMethod psiMethod) {
+ return psiMethod.hasModifierProperty(PsiModifier.PUBLIC) &&
+ !psiMethod.isConstructor() &&
+ !psiMethod.hasModifierProperty(PsiModifier.STATIC) &&
+ !psiMethod.hasModifierProperty(PsiModifier.ABSTRACT);
+ }
+
+ private static boolean isAnnotatedWithAction(PsiModifierListOwner psiModifierListOwner) {
+ return AnnotationUtil.isAnnotated(psiModifierListOwner, StrutsConventionConstants.ACTION, 0);
+ }
+
+ private static boolean isConventionActionClass(@Nullable PsiClass psiClass) {
+ if (psiClass == null ||
+ psiClass.isInterface() ||
+ psiClass.isEnum() ||
+ psiClass.isAnnotationType() ||
+ !psiClass.hasModifierProperty(PsiModifier.PUBLIC) ||
+ psiClass.hasModifierProperty(PsiModifier.ABSTRACT)) {
+ return false;
+ }
+
+ if (isAnnotatedWithAction(psiClass)) {
+ return true;
+ }
+
+ if (AnnotationUtil.isAnnotated(psiClass, StrutsConventionConstants.ACTIONS, 0)) {
+ return true;
+ }
+
+ if (!isConventionPluginPresent(psiClass)) {
+ return false;
+ }
+
+ if (StringUtil.endsWith(psiClass.getName(), "Action")) {
+ return true;
+ }
+
+ return InheritanceUtil.isInheritor(psiClass, StrutsConstants.XWORK_ACTION_CLASS);
+ }
+
+ private static boolean isConventionPluginPresent(PsiElement element) {
+ final PsiClass conventionService = JavaPsiFacade.getInstance(element.getProject()).
+ findClass(StrutsConventionConstants.CONVENTIONS_SERVICE, element.getResolveScope());
+ return conventionService != null;
+ }
+}
diff --git a/src/main/java/com/intellij/struts2/annotators/StrutsFileSetCheckingAnnotator.java b/src/main/java/com/intellij/struts2/annotators/StrutsFileSetCheckingAnnotator.java
new file mode 100644
index 0000000..8f051d5
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/annotators/StrutsFileSetCheckingAnnotator.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright 2013 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.struts2.annotators;
+
+import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
+import com.intellij.codeInsight.intention.IntentionAction;
+import com.intellij.codeInsight.intention.impl.BaseIntentionAction;
+import com.intellij.lang.annotation.AnnotationHolder;
+import com.intellij.lang.annotation.Annotator;
+import com.intellij.lang.annotation.HighlightSeverity;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleUtilCore;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.roots.ex.ProjectRootManagerEx;
+import com.intellij.openapi.roots.ui.configuration.ModulesConfigurator;
+import com.intellij.openapi.ui.popup.JBPopupFactory;
+import com.intellij.openapi.ui.popup.PopupStep;
+import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
+import com.intellij.openapi.util.EmptyRunnable;
+import com.intellij.openapi.util.Iconable;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.jsp.JspFile;
+import com.intellij.psi.xml.XmlFile;
+import com.intellij.struts2.Struts2Icons;
+import com.intellij.struts2.StrutsBundle;
+import com.intellij.struts2.StrutsIcons;
+import com.intellij.struts2.dom.struts.model.StrutsManager;
+import com.intellij.struts2.facet.StrutsFacet;
+import com.intellij.struts2.facet.ui.StrutsFileSet;
+import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.indexing.BuildableRootsChangeRescanningInfo;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.util.ArrayList;
+import java.util.Set;
+
+/**
+ * Checks if {@code struts.xml} is registered in any of the file sets in the current module.
+ *
+ * @author Yann Cébron
+ */
+public class StrutsFileSetCheckingAnnotator implements Annotator {
+
+ @Override
+ public void annotate(@NotNull final PsiElement psiElement, @NotNull final AnnotationHolder holder) {
+ if (!(psiElement instanceof XmlFile xmlFile)) {
+ return;
+ }
+
+ if (psiElement instanceof JspFile) {
+ return;
+ }
+
+ final Module module = ModuleUtilCore.findModuleForPsiElement(psiElement);
+ if (module == null) {
+ return;
+ }
+
+ // do not run when facet not enabled
+ if (StrutsFacet.getInstance(module) == null) {
+ return;
+ }
+
+ final Project project = psiElement.getProject();
+
+ final StrutsManager strutsManager = StrutsManager.getInstance(project);
+ if (!strutsManager.isStruts2ConfigFile(xmlFile)) {
+ return;
+ }
+
+ final VirtualFile currentVirtualFile = xmlFile.getVirtualFile();
+ assert currentVirtualFile != null;
+
+ final Set<StrutsFileSet> allConfigFileSets = strutsManager.getAllConfigFileSets(module);
+ for (final StrutsFileSet configFileSet : allConfigFileSets) {
+ if (configFileSet.hasFile(currentVirtualFile)) {
+ return;
+ }
+ }
+
+ final boolean fileSetAvailable = allConfigFileSets.size() != 0;
+
+ IntentionAction fix;
+ if (fileSetAvailable) {
+ fix = new AddToFileSetFix(xmlFile.getName());
+ }
+ else {
+ fix = new IntentionAction() {
+ @Override
+ @NotNull
+ public String getText() {
+ return StrutsBundle.message("annotators.fileset.edit.facet.settings");
+ }
+
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return StrutsBundle.message("intentions.family.name");
+ }
+
+ @Override
+ public boolean isAvailable(@NotNull final Project project, final Editor editor, final PsiFile psiFile) {
+ return true;
+ }
+
+ @Override
+ public void invoke(@NotNull final Project project,
+ final Editor editor,
+ final PsiFile psiFile) throws IncorrectOperationException {
+ final StrutsFacet strutsFacet = StrutsFacet.getInstance(module);
+ assert strutsFacet != null;
+ ModulesConfigurator.showFacetSettingsDialog(strutsFacet, null);
+ }
+
+ @Override
+ public boolean startInWriteAction() {
+ return false;
+ }
+ };
+ }
+ holder.newAnnotation(HighlightSeverity.WARNING,
+ fileSetAvailable ?
+ StrutsBundle.message("annotators.fileset.file.not.registered") :
+ StrutsBundle.message("annotators.fileset.no.file.sets"))
+ .range(xmlFile)
+ .fileLevel().withFix(fix).create();
+ }
+
+
+ /**
+ * Adds the current struts.xml file to an existing file set.
+ */
+ private static final class AddToFileSetFix extends BaseIntentionAction implements Iconable {
+
+ private AddToFileSetFix(final String filename) {
+ setText(StrutsBundle.message("annotators.fileset.fix.add.to.fileset", filename));
+ }
+
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return StrutsBundle.message("intentions.family.name");
+ }
+
+ @Override
+ public Icon getIcon(final int flags) {
+ return Struts2Icons.Action;
+ }
+
+ @Override
+ public boolean isAvailable(@NotNull final Project project, final Editor editor, final PsiFile file) {
+ return true;
+ }
+
+ @Override
+ public void invoke(@NotNull final Project project,
+ final Editor editor,
+ final PsiFile file) throws IncorrectOperationException {
+ final StrutsFacet strutsFacet = StrutsFacet.getInstance(file);
+ assert strutsFacet != null;
+
+ final Set<StrutsFileSet> strutsFileSets = strutsFacet.getConfiguration().getFileSets();
+ final BaseListPopupStep<StrutsFileSet> step =
+ new BaseListPopupStep<>(StrutsBundle.message("annotators.fileset.fix.choose.fileset"),
+ new ArrayList<>(strutsFileSets)) {
+
+ @Override
+ public Icon getIconFor(final StrutsFileSet aValue) {
+ return StrutsIcons.STRUTS_CONFIG_FILE;
+ }
+
+ @Override
+ public PopupStep onChosen(final StrutsFileSet selectedValue, final boolean finalChoice) {
+ selectedValue.addFile(file.getVirtualFile());
+ ApplicationManager.getApplication()
+ .runWriteAction(() -> {
+ Module module = strutsFacet.getModule();
+ BuildableRootsChangeRescanningInfo info = BuildableRootsChangeRescanningInfo.newInstance().addModule(module);
+ Module[] dependencies = ModuleRootManager.getInstance(module).getDependencies();
+ for (Module dependency : dependencies) {
+ info.addModule(dependency);
+ }
+ ProjectRootManagerEx.getInstanceEx(project).makeRootsChange(EmptyRunnable.getInstance(), info);
+ });
+
+ // re-highlight (remove annotation)
+ DaemonCodeAnalyzer.getInstance(project).restart();
+
+ return super.onChosen(selectedValue, finalChoice);
+ }
+ };
+ JBPopupFactory.getInstance()
+ .createListPopup(step)
+ .showInBestPositionFor(editor);
+ }
+ }
+}
diff --git a/src/main/java/com/intellij/struts2/annotators/package-info.java b/src/main/java/com/intellij/struts2/annotators/package-info.java
new file mode 100644
index 0000000..6f3020e
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/annotators/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2007 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.
+ */
+
+/**
+ * Provides editor gutter mark navigation and other functionality.
+ */
+package com.intellij.struts2.annotators;
\ No newline at end of file
diff --git a/src/main/java/com/intellij/struts2/dom/BeanPropertyPathConverterBase.java b/src/main/java/com/intellij/struts2/dom/BeanPropertyPathConverterBase.java
new file mode 100644
index 0000000..721b2b3
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/dom/BeanPropertyPathConverterBase.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2013 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.struts2.dom;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiReference;
+import com.intellij.psi.impl.beanProperties.BeanProperty;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.xml.*;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * DOM-Converter for resolving path to (nested) bean property.
+ * <p/>
+ * See {@code BeanPropertyPathReference}.
+ *
+ * @author Yann Cébron
+ */
+public abstract class BeanPropertyPathConverterBase extends Converter<List<BeanProperty>>
+ implements CustomReferenceConverter<List<BeanProperty>> {
+
+ /**
+ * Returns the class to search bean properties for.
+ *
+ * @param domElement Parent element.
+ * @return Class or {@code null} if not determinable.
+ */
+ @Nullable
+ protected abstract PsiClass findBeanPropertyClass(@NotNull final DomElement domElement);
+
+ @Override
+ public String toString(@Nullable final List<BeanProperty> beanProperties, final ConvertContext convertContext) {
+ return null;
+ }
+
+ @Override
+ public List<BeanProperty> fromString(@Nullable final String s, final ConvertContext convertContext) {
+ if (s == null) {
+ return null;
+ }
+
+ @SuppressWarnings("unchecked")
+ final GenericAttributeValue<List<BeanProperty>> value =
+ (GenericAttributeValue<List<BeanProperty>>) convertContext.getInvocationElement();
+
+ final PsiReference[] references = createReferences(value, value.getXmlAttributeValue(), convertContext);
+ final ArrayList<BeanProperty> list = new ArrayList<>(references.length);
+ for (final PsiReference reference : references) {
+ final PsiElement resolve = reference.resolve();
+ if (resolve instanceof PsiMethod method) { // can be non-PsiMethod via ParamNameCustomConverter
+ final BeanProperty beanProperty = BeanProperty.createBeanProperty(method);
+ ContainerUtil.addIfNotNull(list, beanProperty);
+ }
+ }
+ return list;
+ }
+
+ /**
+ * Gets the enclosing Tag-DomElement.
+ *
+ * @param context Current context.
+ * @return Parent element or {@code null} if none found (should not happen in valid XML).
+ */
+ @Nullable
+ protected static DomElement findEnclosingTag(final ConvertContext context) {
+ final DomElement current = context.getInvocationElement();
+ final DomElement parent = current.getParent();
+ return parent != null ? parent.getParent() : null;
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/intellij/struts2/dom/ConverterUtil.java b/src/main/java/com/intellij/struts2/dom/ConverterUtil.java
new file mode 100644
index 0000000..be094a3
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/dom/ConverterUtil.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2016 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.struts2.dom;
+
+import com.intellij.psi.xml.XmlFile;
+import com.intellij.struts2.dom.struts.model.StrutsManager;
+import com.intellij.struts2.dom.struts.model.StrutsModel;
+import com.intellij.struts2.dom.struts.strutspackage.StrutsPackage;
+import com.intellij.util.xml.ConvertContext;
+import com.intellij.util.xml.DomUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.regex.Pattern;
+
+/**
+ * Utility methods for DOM-Converters.
+ *
+ * @author Yann Cébron
+ */
+public final class ConverterUtil {
+
+ // "{0}" through "{9}"
+ private static final Pattern WILDCARD_PATTERN = Pattern.compile("\\{\\d}");
+
+ private ConverterUtil() {
+ }
+
+ /**
+ * Gets the StrutsModel for the current context (=file).
+ *
+ * @param context Invoking context.
+ * @return {@code null} if no StrutsModel found by current file (e.g. not in any fileset).
+ */
+ @Nullable
+ public static StrutsModel getStrutsModel(final ConvertContext context) {
+ final XmlFile xmlFile = context.getFile();
+ return StrutsManager.getInstance(xmlFile.getProject()).getModelByFile(xmlFile);
+ }
+
+ /**
+ * Gets the StrutsModel for the current context (=file) or combined model for current module.
+ *
+ * @param context Invoking context.
+ * @return {@code null} if no StrutsModel found in current file/module.
+ */
+ @Nullable
+ public static StrutsModel getStrutsModelOrCombined(final ConvertContext context) {
+ final StrutsModel modelByFile = getStrutsModel(context);
+ if (modelByFile != null) {
+ return modelByFile;
+ }
+
+ return StrutsManager.getInstance(context.getFile().getProject()).getCombinedModel(context.getModule());
+ }
+
+ /**
+ * Returns the current (parent) {@code <package>} element.
+ *
+ * @param context Invoking context.
+ * @return Parent package.
+ */
+ @NotNull
+ public static StrutsPackage getCurrentStrutsPackage(final ConvertContext context) {
+ final StrutsPackage strutsPackage = DomUtil.getParentOfType(context.getInvocationElement(),
+ StrutsPackage.class,
+ true);
+ assert strutsPackage != null : context.getInvocationElement();
+ return strutsPackage;
+ }
+
+ /**
+ * Returns whether the value contains a wildcard-reference.
+ *
+ * @param value Value to check for wildcard pattern.
+ * @return {@code true} if contains wildcard value.
+ */
+ public static boolean hasWildcardReference(@Nullable final String value) {
+ return value != null && WILDCARD_PATTERN.matcher(value).find();
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/intellij/struts2/dom/ExtendableClassConverter.java b/src/main/java/com/intellij/struts2/dom/ExtendableClassConverter.java
new file mode 100644
index 0000000..a1f140e
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/dom/ExtendableClassConverter.java
@@ -0,0 +1,91 @@
+/*
+ * 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.struts2.dom;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.util.Key;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiReference;
+import com.intellij.util.xml.ConvertContext;
+import com.intellij.util.xml.Converter;
+import com.intellij.util.xml.CustomReferenceConverter;
+import com.intellij.util.xml.ExtendClass;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Converter for "class" attribute. Must be used in conjunction with {@link ExtendClass} to
+ * determine valid references (interface allowed, non-public class allowed, ..).
+ *
+ * @author Yann Cébron
+ */
+public abstract class ExtendableClassConverter extends Converter<PsiClass>
+ implements CustomReferenceConverter<PsiClass> {
+
+ /**
+ * Stores the reference type display name(s).
+ */
+ public static final Key<String[]> REFERENCES_TYPES = Key.create("STRUTS2_REFERENCE_TYPES");
+
+ /**
+ * References from this EP will be added automatically.
+ */
+ public static final ExtensionPointName<ExtendableClassConverterContributor> EP_NAME =
+ new ExtensionPointName<>("com.intellij.struts2.classContributor");
+
+
+ /**
+ * Contributes results to {@link ExtendableClassConverter}.
+ * <p/>
+ * If the provided reference implements {@link com.intellij.codeInspection.LocalQuickFixProvider}
+ * its fixes will be added automatically.
+ *
+ * @author Yann Cébron
+ */
+ public abstract static class ExtendableClassConverterContributor {
+
+ /**
+ * Returns this contributor's type name for display in messages.
+ *
+ * @return Type name.
+ */
+ @NotNull
+ public abstract String getTypeName();
+
+ /**
+ * Is this contributor suitable in the current resolving context.
+ *
+ * @param convertContext Current context.
+ * @return true if yes, false otherwise.
+ */
+ public abstract boolean isSuitable(@NotNull final ConvertContext convertContext);
+
+ /**
+ * Creates references if this contributor is suitable.
+ *
+ * @param convertContext Current context.
+ * @param psiElement Reference element.
+ * @param extendClass Extend class definition for this element.
+ * @return References.
+ */
+ public abstract PsiReference @NotNull [] getReferences(@NotNull final ConvertContext convertContext,
+ @NotNull final PsiElement psiElement,
+ @NotNull final ExtendClass extendClass);
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/intellij/struts2/dom/StrutsDomConstants.java b/src/main/java/com/intellij/struts2/dom/StrutsDomConstants.java
new file mode 100644
index 0000000..0c042f6
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/dom/StrutsDomConstants.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2011 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.struts2.dom;
+
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * DOM-related constants.
+ *
+ * @author Yann Cébron
+ */
+public final class StrutsDomConstants {
+
+ private StrutsDomConstants() {
+ }
+
+ /**
+ * DOM-Namespace-Key for struts.xml
+ */
+ @NonNls
+ public static final String STRUTS_NAMESPACE_KEY = "struts namespace";
+
+ /**
+ * DOM-Namespace-Key for validation.xml
+ */
+ @NonNls
+ public static final String VALIDATOR_NAMESPACE_KEY = "validator namespace";
+
+ /**
+ * DOM-Namespace-Key for validator-config.xml
+ */
+ @NonNls
+ public static final String VALIDATOR_CONFIG_NAMESPACE_KEY = "validator config namespace";
+}
\ No newline at end of file
diff --git a/src/main/java/com/intellij/struts2/dom/inspection/Struts2ModelInspection.java b/src/main/java/com/intellij/struts2/dom/inspection/Struts2ModelInspection.java
new file mode 100644
index 0000000..f318593
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/dom/inspection/Struts2ModelInspection.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright 2013 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.struts2.dom.inspection;
+
+import com.intellij.codeInspection.options.OptPane;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.xml.XmlFile;
+import com.intellij.struts2.StrutsBundle;
+import com.intellij.struts2.dom.ConverterUtil;
+import com.intellij.struts2.dom.ExtendableClassConverter;
+import com.intellij.struts2.dom.params.ParamNameConverter;
+import com.intellij.struts2.dom.params.ParamsElement;
+import com.intellij.struts2.dom.struts.HasResultType;
+import com.intellij.struts2.dom.struts.StrutsRoot;
+import com.intellij.struts2.dom.struts.action.Action;
+import com.intellij.struts2.dom.struts.action.ActionMethodConverter;
+import com.intellij.struts2.dom.struts.action.Result;
+import com.intellij.struts2.dom.struts.action.StrutsPathReferenceConverter;
+import com.intellij.struts2.dom.struts.impl.path.ResultTypeResolver;
+import com.intellij.struts2.dom.struts.model.StrutsManager;
+import com.intellij.struts2.dom.struts.strutspackage.ResultType;
+import com.intellij.struts2.facet.ui.StrutsFileSet;
+import com.intellij.util.io.URLUtil;
+import com.intellij.util.xml.*;
+import com.intellij.util.xml.highlighting.BasicDomElementsInspection;
+import com.intellij.util.xml.highlighting.DomElementAnnotationHolder;
+import com.intellij.util.xml.highlighting.DomHighlightingHelper;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Set;
+
+import static com.intellij.codeInspection.options.OptPane.checkbox;
+import static com.intellij.codeInspection.options.OptPane.pane;
+
+/**
+ * Default DOM-Model inspection for struts.xml files.
+ *
+ * @author Yann Cébron
+ */
+public class Struts2ModelInspection extends BasicDomElementsInspection<StrutsRoot> {
+
+ /**
+ * @noinspection PublicField
+ */
+ public boolean ignoreExtendableClass;
+
+ public Struts2ModelInspection() {
+ super(StrutsRoot.class);
+ }
+
+ @Override
+ public @NotNull OptPane getOptionsPane() {
+ return pane(
+ checkbox("ignoreExtendableClass", StrutsBundle.message("inspections.struts2.model.do.not.check.extendable.class")));
+ }
+
+ /**
+ * Only inspect struts.xml files configured in fileset.
+ *
+ * @param strutsRootDomFileElement Root element of file to inspect.
+ * @param holder Holder.
+ */
+ @Override
+ public void checkFileElement(final @NotNull DomFileElement<StrutsRoot> strutsRootDomFileElement,
+ final @NotNull DomElementAnnotationHolder holder) {
+ final Module module = strutsRootDomFileElement.getModule();
+ if (module == null) {
+ return;
+ }
+
+ final XmlFile xmlFile = strutsRootDomFileElement.getFile();
+ final VirtualFile virtualFile = xmlFile.getVirtualFile();
+
+ final Set<StrutsFileSet> fileSets = StrutsManager.getInstance(xmlFile.getProject()).getAllConfigFileSets(module);
+ for (final StrutsFileSet strutsFileSet : fileSets) {
+ if (strutsFileSet.hasFile(virtualFile)) {
+ super.checkFileElement(strutsRootDomFileElement, holder);
+ break;
+ }
+ }
+ }
+
+ @Override
+ protected boolean shouldCheckResolveProblems(final GenericDomValue value) {
+ final Converter converter = value.getConverter();
+
+ // we roll our own checking for "class" in Struts2ModelInspectionVisitor
+ if (converter instanceof ExtendableClassConverter) {
+ return false;
+ }
+
+ // hack for STRPL-85: suppress <param>-highlighting within <result> for certain result-types
+ if (converter instanceof ParamNameConverter) {
+ final Result result = DomUtil.getParentOfType(value, Result.class, false);
+ if (result != null) {
+ final ResultType resultType = result.getEffectiveResultType();
+ if (resultType == null) {
+ return false; // error
+ }
+
+ final String resultTypeValue = resultType.getName().getStringValue();
+ if (resultTypeValue != null && ResultTypeResolver.isChainOrRedirectType(resultTypeValue)) {
+ return false;
+ }
+ }
+ }
+
+ final String stringValue = value.getStringValue();
+
+ // suppress <action> "method" when using wildcards
+ if (converter instanceof ActionMethodConverter &&
+ ConverterUtil.hasWildcardReference(stringValue)) {
+ return false;
+ }
+
+ // suppress <result> path
+ if (converter instanceof StrutsPathReferenceConverter) {
+
+ if (stringValue == null) {
+ return false;
+ }
+
+ // nested <param>-tags are present
+ if (!((ParamsElement)value).getParams().isEmpty()) {
+ return false;
+ }
+
+ // unsupported result-type
+ final ResultType resultType = ((HasResultType)value).getEffectiveResultType();
+ if (resultType == null) {
+ return false;
+ }
+
+ if (!ResultTypeResolver.hasResultTypeContributor(resultType.getName().getStringValue())) {
+ return false;
+ }
+
+ // suppress paths with wildcard reference
+ if (ConverterUtil.hasWildcardReference(stringValue)) {
+ final Action action = DomUtil.getParentOfType(value, Action.class, true);
+ return action != null && !action.isWildcardMapping();
+ }
+
+ // "${actionProperty}"
+ if (StringUtil.startsWith(stringValue, "${")) {
+ return false;
+ }
+
+ // global URLs
+ if (URLUtil.containsScheme(stringValue)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ protected void checkDomElement(final @NotNull DomElement element,
+ final @NotNull DomElementAnnotationHolder holder,
+ final @NotNull DomHighlightingHelper helper) {
+ final int oldSize = holder.getSize();
+
+ element.accept(new Struts2ModelInspectionVisitor(holder, ignoreExtendableClass));
+
+ if (oldSize == holder.getSize()) {
+ super.checkDomElement(element, holder, helper);
+ }
+ }
+
+ @Override
+ public String @NotNull [] getGroupPath() {
+ return new String[]{StrutsBundle.message("inspections.group.path.name"), getGroupDisplayName()};
+ }
+
+ @Override
+ @NotNull
+ @NonNls
+ public String getShortName() {
+ return "Struts2ModelInspection";
+ }
+}
diff --git a/src/main/java/com/intellij/struts2/dom/inspection/Struts2ModelInspectionVisitor.java b/src/main/java/com/intellij/struts2/dom/inspection/Struts2ModelInspectionVisitor.java
new file mode 100644
index 0000000..703f4b6
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/dom/inspection/Struts2ModelInspectionVisitor.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2019 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.struts2.dom.inspection;
+
+import com.intellij.codeInspection.LocalQuickFix;
+import com.intellij.codeInspection.LocalQuickFixProvider;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiReference;
+import com.intellij.psi.xml.XmlElement;
+import com.intellij.struts2.StrutsBundle;
+import com.intellij.struts2.dom.ConverterUtil;
+import com.intellij.struts2.dom.ExtendableClassConverter;
+import com.intellij.struts2.dom.struts.Bean;
+import com.intellij.struts2.dom.struts.action.Action;
+import com.intellij.struts2.dom.struts.action.Result;
+import com.intellij.struts2.dom.struts.strutspackage.DefaultClassRef;
+import com.intellij.struts2.dom.struts.strutspackage.Interceptor;
+import com.intellij.struts2.dom.struts.strutspackage.ResultType;
+import com.intellij.struts2.dom.struts.strutspackage.StrutsPackage;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.containers.MultiMap;
+import com.intellij.util.xml.*;
+import com.intellij.util.xml.highlighting.DomElementAnnotationHolder;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * Provides extended highlighting for various elements.
+ *
+ * @author Yann Cébron
+ */
+class Struts2ModelInspectionVisitor implements DomElementVisitor {
+
+ private final DomElementAnnotationHolder holder;
+ private final boolean myIgnoreExtendableClass;
+
+ Struts2ModelInspectionVisitor(final DomElementAnnotationHolder holder,
+ boolean ignoreExtendableClass) {
+ this.holder = holder;
+ myIgnoreExtendableClass = ignoreExtendableClass;
+ }
+
+ @Override
+ public void visitDomElement(final DomElement element) {
+ }
+
+ public void visitAction(final Action action) {
+ final GenericAttributeValue<PsiClass> actionClass = action.getActionClass();
+ if (action.isWildcardMapping() &&
+ ConverterUtil.hasWildcardReference(actionClass.getStringValue())) {
+ return;
+ }
+
+ checkExtendableClassConverter(actionClass);
+
+ // default DOM duplicate highlighting works only for "plain" @NameValue
+ MultiMap<String, Result> duplicatedResultNames = MultiMap.create();
+ for (Result result : action.getResults()) {
+ duplicatedResultNames.putValue(result.getNameOrDefault(), result);
+ }
+
+ for (Map.Entry<String, Collection<Result>> entry : duplicatedResultNames.entrySet()) {
+ if (entry.getValue().size() == 1) continue;
+
+ for (Result result : entry.getValue()) {
+ holder.createProblem(result.getName(), XmlDomBundle.message("dom.inspections.identity",
+ ElementPresentationManager.getTypeNameForObject(result)));
+ }
+ }
+ }
+
+ public void visitBean(final Bean bean) {
+ checkExtendableClassConverter(bean.getBeanClass());
+ }
+
+ public void visitDefaultClassRef(final DefaultClassRef defaultClassRef) {
+ checkExtendableClassConverter(defaultClassRef.getDefaultClass());
+ }
+
+ public void visitInterceptor(final Interceptor interceptor) {
+ checkExtendableClassConverter(interceptor.getInterceptorClass());
+ }
+
+ public void visitResultType(final ResultType resultType) {
+ checkExtendableClassConverter(resultType.getResultTypeClass());
+ }
+
+ public void visitStrutsPackage(final StrutsPackage strutsPackage) {
+ final String namespace = strutsPackage.getNamespace().getStringValue();
+ if (namespace != null && !StringUtil.startsWithChar(namespace, '/')) {
+ holder.createProblem(strutsPackage.getNamespace(),
+ StrutsBundle.message("dom.highlighting.struts.package.must.start.with.slash"));
+ }
+ }
+
+ private void checkExtendableClassConverter(final GenericAttributeValue clazzAttributeValue) {
+ if (myIgnoreExtendableClass) return;
+
+ final XmlElement xmlElement = DomUtil.getValueElement(clazzAttributeValue);
+ if (xmlElement == null) {
+ return;
+ }
+
+ final PsiReference[] psiReferences = xmlElement.getReferences();
+ for (final PsiReference psiReference : psiReferences) {
+ final PsiElement resolveElement = psiReference.resolve();
+ if (resolveElement instanceof PsiClass) {
+ return;
+ }
+ }
+
+ final String[] referenceTypesUserData = clazzAttributeValue.getUserData(ExtendableClassConverter.REFERENCES_TYPES);
+ final String referenceTypes = referenceTypesUserData != null ?
+ StringUtil.join(referenceTypesUserData, "|") :
+ StrutsBundle.message("dom.extendable.class.converter.type.class");
+
+ final String message = StrutsBundle.message("dom.extendable.class.converter.cannot.resolve",
+ referenceTypes,
+ clazzAttributeValue.getStringValue());
+
+ // merge all available QuickFixes (create class/package(s)..)
+ LocalQuickFix[] quickFixes = LocalQuickFix.EMPTY_ARRAY;
+ for (final PsiReference psiReference : psiReferences) {
+ if (psiReference instanceof LocalQuickFixProvider) {
+ final LocalQuickFix[] fixes = ((LocalQuickFixProvider)psiReference).getQuickFixes();
+ if (fixes != null) {
+ quickFixes = ArrayUtil.mergeArrays(fixes, quickFixes);
+ }
+ }
+ }
+
+ holder.createProblem(clazzAttributeValue, message, quickFixes);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/intellij/struts2/dom/inspection/Struts2ModelValidator.java b/src/main/java/com/intellij/struts2/dom/inspection/Struts2ModelValidator.java
new file mode 100644
index 0000000..3cf63ca
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/dom/inspection/Struts2ModelValidator.java
@@ -0,0 +1,86 @@
+/*
+ * 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.struts2.dom.inspection;
+
+import com.intellij.codeInspection.LocalInspectionTool;
+import com.intellij.ide.highlighter.XmlFileType;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.util.InspectionValidatorUtil;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiManager;
+import com.intellij.psi.xml.XmlFile;
+import com.intellij.struts2.StrutsBundle;
+import com.intellij.struts2.dom.struts.model.StrutsManager;
+import com.intellij.struts2.dom.struts.model.StrutsModel;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.FactoryMap;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Validator for struts.xml files when running "Build Project".
+ *
+ * @author Yann Cébron
+ */
+final class Struts2ModelValidator extends ValidatorBase {
+ public Struts2ModelValidator() {
+ super("Struts 2 Model Validator", StrutsBundle.message("inspections.struts2.model.validator"),
+ StrutsBundle.message("inspections.struts2.model.validator.progress"));
+ }
+
+ @Override
+ public Collection<VirtualFile> getFilesToProcess(final Project project, final CompileContext context) {
+ final StrutsManager strutsManager = StrutsManager.getInstance(project);
+ final PsiManager psiManager = PsiManager.getInstance(project);
+
+ // cache validation settings per module
+ final Map<Module, Boolean> enabledForModule =
+ FactoryMap.create(module1 -> isEnabledForModule(module1));
+
+ final Set<VirtualFile> files = new HashSet<>();
+ for (final VirtualFile file : context.getCompileScope().getFiles(XmlFileType.INSTANCE, false)) {
+ final Module module = context.getModuleByFile(file);
+ if (module != null &&
+ enabledForModule.get(module)) {
+ final PsiFile psiFile = psiManager.findFile(file);
+ if (psiFile instanceof XmlFile) {
+ final StrutsModel model = strutsManager.getModelByFile((XmlFile)psiFile);
+ if (model != null) {
+ for (final XmlFile configFile : model.getConfigFiles()) {
+ ContainerUtil.addIfNotNull(files, configFile.getVirtualFile());
+ }
+ }
+ }
+ }
+ }
+
+ InspectionValidatorUtil.expandCompileScopeIfNeeded(files, context);
+ return files;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Class<? extends LocalInspectionTool> @NotNull [] getInspectionToolClasses(CompileContext context) {
+ return new Class[]{Struts2ModelInspection.class};
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/intellij/struts2/dom/inspection/ValidatorBase.java b/src/main/java/com/intellij/struts2/dom/inspection/ValidatorBase.java
new file mode 100644
index 0000000..9de4036
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/dom/inspection/ValidatorBase.java
@@ -0,0 +1,52 @@
+/*
+ * 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.struts2.dom.inspection;
+
+import com.intellij.compiler.options.ValidationConfiguration;
+import com.intellij.openapi.compiler.CompileScope;
+import com.intellij.openapi.compiler.util.InspectionValidator;
+import com.intellij.openapi.module.Module;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Base-class for validators.
+ *
+ * @author Yann Cébron
+ */
+abstract class ValidatorBase extends InspectionValidator {
+
+ protected ValidatorBase(@NonNls @NotNull String id, @NotNull String description,
+ @NotNull String progressIndicatorText) {
+ super(id, description, progressIndicatorText);
+ }
+
+ protected final boolean isEnabledForModule(final Module module) {
+ return ValidationConfiguration.getInstance(module.getProject()).isSelected(getId());
+ }
+
+ @Override
+ public final boolean isAvailableOnScope(@NotNull final CompileScope scope) {
+ for (final Module module : scope.getAffectedModules()) {
+ if (isEnabledForModule(module)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/intellij/struts2/dom/inspection/ValidatorConfigModelInspection.java b/src/main/java/com/intellij/struts2/dom/inspection/ValidatorConfigModelInspection.java
new file mode 100644
index 0000000..4be99ec
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/dom/inspection/ValidatorConfigModelInspection.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2012 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.struts2.dom.inspection;
+
+import com.intellij.struts2.StrutsBundle;
+import com.intellij.struts2.dom.validator.config.ValidatorsConfig;
+import com.intellij.util.xml.highlighting.BasicDomElementsInspection;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Yann Cébron
+ */
+public class ValidatorConfigModelInspection extends BasicDomElementsInspection<ValidatorsConfig> {
+
+ public ValidatorConfigModelInspection() {
+ super(ValidatorsConfig.class);
+ }
+
+ @Override
+ public String @NotNull [] getGroupPath() {
+ return new String[]{StrutsBundle.message("inspections.group.path.name"), getGroupDisplayName()};
+ }
+
+ @Override
+ @NotNull
+ @NonNls
+ public String getShortName() {
+ return "ValidatorConfigModelInspection";
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/intellij/struts2/dom/inspection/ValidatorModelInspection.java b/src/main/java/com/intellij/struts2/dom/inspection/ValidatorModelInspection.java
new file mode 100644
index 0000000..0f80423
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/dom/inspection/ValidatorModelInspection.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2012 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.struts2.dom.inspection;
+
+import com.intellij.struts2.StrutsBundle;
+import com.intellij.struts2.dom.validator.Validators;
+import com.intellij.util.xml.highlighting.BasicDomElementsInspection;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Default DOM-Model inspection for validator.xml files.
+ *
+ * @author Yann Cébron
+ */
+public class ValidatorModelInspection extends BasicDomElementsInspection<Validators> {
+
+ public ValidatorModelInspection() {
+ super(Validators.class);
+ }
+
+ @Override
+ public String @NotNull [] getGroupPath() {
+ return new String[]{StrutsBundle.message("inspections.group.path.name"), getGroupDisplayName()};
+ }
+
+ @Override
+ @NotNull
+ @NonNls
+ public String getShortName() {
+ return "ValidatorModelInspection";
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/intellij/struts2/dom/inspection/ValidatorModelValidator.java b/src/main/java/com/intellij/struts2/dom/inspection/ValidatorModelValidator.java
new file mode 100644
index 0000000..19fdd1f
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/dom/inspection/ValidatorModelValidator.java
@@ -0,0 +1,104 @@
+/*
+ * 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.struts2.dom.inspection;
+
+import com.intellij.codeInspection.LocalInspectionTool;
+import com.intellij.ide.highlighter.XmlFileType;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.util.InspectionValidatorUtil;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.module.ModuleUtilCore;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiManager;
+import com.intellij.psi.xml.XmlFile;
+import com.intellij.struts2.StrutsBundle;
+import com.intellij.struts2.dom.validator.ValidatorManager;
+import com.intellij.struts2.facet.StrutsFacet;
+import com.intellij.util.containers.FactoryMap;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Validator for validation.xml/validators.xml files when running "Build Project".
+ *
+ * @author Yann Cébron
+ */
+final class ValidatorModelValidator extends ValidatorBase {
+ @NonNls
+ private static final String FILENAME_EXTENSION_VALIDATION_XML = "-validation.xml";
+
+ public ValidatorModelValidator() {
+ super("Struts 2 Validation Model Validator", StrutsBundle.message("inspections.validator.model.validator"),
+ StrutsBundle.message("inspections.validator.model.validator.progress")
+ );
+ }
+
+ @Override
+ public Collection<VirtualFile> getFilesToProcess(final Project project, final CompileContext context) {
+ final PsiManager psiManager = PsiManager.getInstance(project);
+ final ValidatorManager validatorManager = ValidatorManager.getInstance(project);
+
+ // cache S2facet/validation settings per module
+ final Map<Module, Boolean> enabledForModule =
+ FactoryMap.create(module1 -> isEnabledForModule(module1) &&
+ StrutsFacet.getInstance(module1) != null);
+
+ // collect all validation.xml files located in sources of S2-modules
+ final Set<VirtualFile> files = new HashSet<>();
+ for (final VirtualFile file : context.getProjectCompileScope().getFiles(XmlFileType.INSTANCE, true)) {
+ if (StringUtil.endsWith(file.getName(), FILENAME_EXTENSION_VALIDATION_XML)) {
+ final PsiFile psiFile = psiManager.findFile(file);
+ if (psiFile instanceof XmlFile &&
+ validatorManager.isValidatorsFile((XmlFile)psiFile)) {
+ final Module module = ModuleUtilCore.findModuleForFile(file, project);
+ if (module != null &&
+ enabledForModule.get(module)) {
+ files.add(file);
+ }
+ }
+ }
+ }
+
+ // add validator-config.xml if not default one from xwork.jar
+ final Set<VirtualFile> descriptorFiles = new HashSet<>();
+ for (final Module module : ModuleManager.getInstance(project).getModules()) {
+ if (enabledForModule.get(module)) {
+ final PsiFile psiFile = validatorManager.getValidatorConfigFile(module);
+ if (psiFile != null &&
+ validatorManager.isCustomValidatorConfigFile(psiFile)) {
+ InspectionValidatorUtil.addFile(descriptorFiles, psiFile);
+ }
+ }
+ }
+ files.addAll(InspectionValidatorUtil.expandCompileScopeIfNeeded(descriptorFiles, context));
+
+ return files;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Class<? extends LocalInspectionTool> @NotNull [] getInspectionToolClasses(CompileContext context) {
+ return new Class[]{ValidatorModelInspection.class, ValidatorConfigModelInspection.class};
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/intellij/struts2/dom/inspection/package-info.java b/src/main/java/com/intellij/struts2/dom/inspection/package-info.java
new file mode 100644
index 0000000..5deb1c5
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/dom/inspection/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2008 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.
+ */
+
+/**
+ * DOM-model inspections and validators.
+ */
+package com.intellij.struts2.dom.inspection;
\ No newline at end of file
diff --git a/src/main/java/com/intellij/struts2/dom/params/Param.java b/src/main/java/com/intellij/struts2/dom/params/Param.java
new file mode 100644
index 0000000..bd39153
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/dom/params/Param.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2013 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.struts2.dom.params;
+
+import com.intellij.ide.presentation.Presentation;
+import com.intellij.psi.impl.beanProperties.BeanProperty;
+import com.intellij.util.xml.*;
+
+import java.util.List;
+
+/**
+ * {@code param}
+ *
+ * @author Yann Cébron
+ */
+@Presentation(typeName = "Parameter", icon = "AllIcons.Actions.Properties")
+@Convert(ParamValueConverter.class)
+public interface Param extends DomElement, GenericDomValue<String> {
+
+ @Attribute(value = "name")
+ @Required
+ @NameValue
+ @Convert(ParamNameConverter.class)
+ GenericAttributeValue<List<BeanProperty>> getName();
+}
diff --git a/src/main/java/com/intellij/struts2/dom/params/ParamNameConverter.java b/src/main/java/com/intellij/struts2/dom/params/ParamNameConverter.java
new file mode 100644
index 0000000..35bd93e
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/dom/params/ParamNameConverter.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2011 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.struts2.dom.params;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.psi.PsiReference;
+import com.intellij.psi.xml.XmlAttributeValue;
+import com.intellij.struts2.dom.BeanPropertyPathConverterBase;
+import com.intellij.util.xml.DomElement;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Converter for {@link Param#getName()}.
+ * <p/>
+ * Based on Spring plugin.
+ *
+ * @author Yann Cébron
+ */
+public abstract class ParamNameConverter extends BeanPropertyPathConverterBase {
+
+ public static final ExtensionPointName<ParamNameCustomConverter> EP_NAME =
+ new ExtensionPointName<>("com.intellij.struts2.paramNameCustomConverter");
+
+ /**
+ * Provides custom "name" resolving. Replaces the basic bean property resolving.
+ */
+ public abstract static class ParamNameCustomConverter {
+
+ /**
+ * Returns custom references or empty array if not applicable.
+ *
+ * @param nameAttributeValue "name" attribute.
+ */
+ public abstract PsiReference @NotNull [] getCustomReferences(final XmlAttributeValue nameAttributeValue, final DomElement paramsElement);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/intellij/struts2/dom/params/ParamNameConverterImpl.java b/src/main/java/com/intellij/struts2/dom/params/ParamNameConverterImpl.java
new file mode 100644
index 0000000..3bfd180
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/dom/params/ParamNameConverterImpl.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2011 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.struts2.dom.params;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiReference;
+import com.intellij.psi.impl.beanProperties.BeanProperty;
+import com.intellij.psi.xml.XmlAttributeValue;
+import com.intellij.struts2.reference.common.BeanPropertyPathReferenceSet;
+import com.intellij.util.xml.ConvertContext;
+import com.intellij.util.xml.DomElement;
+import com.intellij.util.xml.GenericDomValue;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+/**
+ * @author Yann Cébron
+ */
+public class ParamNameConverterImpl extends ParamNameConverter {
+
+ @Override
+ protected PsiClass findBeanPropertyClass(@NotNull final DomElement domElement) {
+ return ((ParamsElement) domElement).getParamsClass();
+ }
+
+ @Override
+ public PsiReference @NotNull [] createReferences(final GenericDomValue<List<BeanProperty>> listGenericDomValue,
+ final PsiElement psiElement,
+ final ConvertContext convertContext) {
+ final DomElement paramsElement = findEnclosingTag(convertContext);
+ if (paramsElement == null) {
+ return PsiReference.EMPTY_ARRAY;
+ }
+
+ for (ParamNameCustomConverter customConverter : EP_NAME.getExtensionList()) {
+ final PsiReference[] customReferences = customConverter.getCustomReferences((XmlAttributeValue) psiElement,
+ paramsElement);
+ if (customReferences.length > 0) {
+ return customReferences;
+ }
+ }
+
+ final PsiClass rootPsiClass = findBeanPropertyClass(paramsElement);
+ return new BeanPropertyPathReferenceSet(psiElement, rootPsiClass, false).getPsiReferences();
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/intellij/struts2/dom/params/ParamValueConverter.java b/src/main/java/com/intellij/struts2/dom/params/ParamValueConverter.java
new file mode 100644
index 0000000..de49735
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/dom/params/ParamValueConverter.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2017 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.struts2.dom.params;
+
+import com.intellij.psi.PsiType;
+import com.intellij.psi.impl.beanProperties.BeanProperty;
+import com.intellij.util.xml.Converter;
+import com.intellij.util.xml.GenericDomValue;
+import com.intellij.util.xml.WrappingConverter;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
+ * @author Yann Cébron
+ * @see ParamValueConvertersRegistry
+ */
+public class ParamValueConverter extends WrappingConverter {
+
+ @Nullable
+ @Override
+ public Converter getConverter(@NotNull GenericDomValue domElement) {
+ final Param param = domElement.getParentOfType(Param.class, false);
+ if (param == null) {
+ return null;
+ }
+
+ // skip values containing expressions
+ final String text = domElement.getRawText();
+ if (text == null || text.contains("${")) {
+ return null;
+ }
+
+ final List<BeanProperty> beanProperties = param.getName().getValue();
+ if (beanProperties == null || beanProperties.isEmpty()) {
+ return null;
+ }
+
+ final BeanProperty property = beanProperties.get(beanProperties.size() - 1);
+ final PsiType type = property.getPropertyType();
+ return ParamValueConvertersRegistry.getInstance().getConverter(domElement, type);
+ }
+}
diff --git a/src/main/java/com/intellij/struts2/dom/params/ParamValueConvertersRegistry.java b/src/main/java/com/intellij/struts2/dom/params/ParamValueConvertersRegistry.java
new file mode 100644
index 0000000..4e51e91
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/dom/params/ParamValueConvertersRegistry.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2013 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.struts2.dom.params;
+
+import com.intellij.util.xml.converters.values.GenericDomValueConvertersRegistry;
+
+/**
+ * Registry of all converters used by {@link ParamValueConverter}.
+ *
+ * @author Yann Cébron
+ */
+public final class ParamValueConvertersRegistry extends GenericDomValueConvertersRegistry {
+
+ private static final ParamValueConvertersRegistry INSTANCE = new ParamValueConvertersRegistry();
+
+ public static ParamValueConvertersRegistry getInstance() {
+ return INSTANCE;
+ }
+
+ private ParamValueConvertersRegistry() {
+ registerBuiltinValueConverters();
+ }
+
+ private void registerBuiltinValueConverters() {
+ registerDefaultConverters();
+ }
+}
diff --git a/src/main/java/com/intellij/struts2/dom/params/ParamsElement.java b/src/main/java/com/intellij/struts2/dom/params/ParamsElement.java
new file mode 100644
index 0000000..ba60b9e
--- /dev/null
+++ b/src/main/java/com/intellij/struts2/dom/params/ParamsElement.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2013 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.struts2.dom.params;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.util.xml.DomElement;
+import com.intellij.util.xml.SubTagList;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
... 37094 lines suppressed ...