/* * 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.custom; import com.intellij.codeInsight.daemon.EmptyResolveMessageProvider; import com.intellij.codeInspection.LocalQuickFix; import com.intellij.codeInspection.LocalQuickFixProvider; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiReference; import com.intellij.psi.PsiReferenceBase; import com.intellij.psi.xml.XmlAttributeValue; import com.intellij.struts2.dom.params.ParamNameConverter; import com.intellij.struts2.dom.params.ParamsElement; import com.intellij.struts2.dom.struts.action.Action; import com.intellij.struts2.dom.struts.action.Result; import com.intellij.struts2.reference.common.BeanPropertyPathReference; import com.intellij.struts2.reference.common.BeanPropertyPathReferenceSet; import com.intellij.util.ArrayUtil; import com.intellij.util.SmartList; import com.intellij.util.xml.DomElement; import com.intellij.util.xml.DomUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Collections; import java.util.List; /** * Resolves additionally to Action class properties. * * @author Yann Cébron */ public class ResultParamNameCustomConverter extends ParamNameConverter.ParamNameCustomConverter { @NotNull @Override public PsiReference[] getCustomReferences(XmlAttributeValue nameAttributeValue, DomElement paramsElement) { if (!(paramsElement instanceof Result)) { return PsiReference.EMPTY_ARRAY; } Result result = (Result)paramsElement; Action action = DomUtil.getParentOfType(result, Action.class, true); assert action != null; return new PsiReference[]{new MergingBeanPropertyPathReference(nameAttributeValue, action, result)}; } private static class MergingBeanPropertyPathReference extends PsiReferenceBase<PsiElement> implements EmptyResolveMessageProvider, LocalQuickFixProvider { private final List<BeanPropertyPathReference[]> allReferences = new SmartList<>(); /** * @param element XML element. * @param paramsElements First element will be used for quickfixes. */ private MergingBeanPropertyPathReference(@NotNull XmlAttributeValue element, @NotNull ParamsElement... paramsElements) { super(element, true); for (ParamsElement paramsElement : paramsElements) { allReferences.add(getBeanPropertyReferences(element, paramsElement)); } } private static BeanPropertyPathReference[] getBeanPropertyReferences(XmlAttributeValue element, ParamsElement paramsElement) { return new BeanPropertyPathReferenceSet(element, paramsElement.getParamsClass(), false).getPsiReferences(); } @Nullable @Override public PsiElement resolve() { for (BeanPropertyPathReference[] reference : allReferences) { for (BeanPropertyPathReference pathReference : reference) { final PsiMethod resolve = pathReference.resolve(); if (resolve != null) { return resolve; } } } return null; } @NotNull @Override public Object[] getVariants() { List<Object> variants = new SmartList<>(); for (BeanPropertyPathReference[] reference : allReferences) { for (BeanPropertyPathReference pathReference : reference) { Collections.addAll(variants, pathReference.getVariants()); } } return ArrayUtil.toObjectArray(variants); } @NotNull @Override public String getUnresolvedMessagePattern() { return "Cannot resolve property '" + getValue() + "'"; } @Nullable @Override public LocalQuickFix[] getQuickFixes() { List<LocalQuickFix> quickFixes = new SmartList<>(); for (BeanPropertyPathReference[] reference : allReferences) { for (BeanPropertyPathReference pathReference : reference) { final LocalQuickFix[] fixes = pathReference.getQuickFixes(); if (fixes != null) { Collections.addAll(quickFixes, fixes); } } } return ArrayUtil.toObjectArray(quickFixes, LocalQuickFix.class); } } }