Package com.intellij.struts2.dom.params.custom

Source Code of com.intellij.struts2.dom.params.custom.InterceptorRefInStackParamNameCustomConverter$InterceptorRefPsiReference

/*
* 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.custom;

import com.intellij.codeInsight.daemon.EmptyResolveMessageProvider;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.references.PomService;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
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.struts.strutspackage.InterceptorOrStackBase;
import com.intellij.struts2.dom.struts.strutspackage.InterceptorRef;
import com.intellij.struts2.dom.struts.strutspackage.InterceptorStack;
import com.intellij.struts2.reference.common.BeanPropertyPathReferenceSet;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.DomTarget;
import com.intellij.util.xml.ElementPresentationManager;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
* Resolves to {@code interceptorName.interceptorProperty} when referencing {@link InterceptorStack}.
*
* @author Yann Cébron
*/
public class InterceptorRefInStackParamNameCustomConverter extends ParamNameConverter.ParamNameCustomConverter {

  @NotNull
  @Override
  public PsiReference[] getCustomReferences(final XmlAttributeValue nameAttributeValue,
                                            final DomElement paramsElement) {
    if (!(paramsElement instanceof InterceptorRef)) {
      return PsiReference.EMPTY_ARRAY;
    }

    InterceptorRef interceptorRef = (InterceptorRef) paramsElement;
    final InterceptorOrStackBase value = interceptorRef.getName().getValue();
    if (!(value instanceof InterceptorStack)) {
      return PsiReference.EMPTY_ARRAY;
    }

    final String text = nameAttributeValue.getValue();
    final boolean hasDot = StringUtil.containsChar(text, '.');
    final int idx = hasDot ? text.indexOf('.') : text.length();
    final String refName = text.substring(0, idx);

    final InterceptorStack stack = (InterceptorStack) value;
    final InterceptorRef resolvedInterceptorRef =
        ContainerUtil.find(stack.getInterceptorRefs(), new Condition<InterceptorRef>() {
          @Override
          public boolean value(final InterceptorRef ref) {
            return Comparing.strEqual(refName, ref.getName().getStringValue());
          }
        });

    final List<PsiReference> customReferences = new ArrayList<PsiReference>(2);
    customReferences.add(new InterceptorRefPsiReference(nameAttributeValue,
                                                        TextRange.from(1, idx),
                                                        resolvedInterceptorRef,
                                                        stack));

    if (resolvedInterceptorRef == null) {
      return ArrayUtil.toObjectArray(customReferences, PsiReference.class);
    }

    final String propertyText = text.substring(idx + 1, text.length());
    final PsiClass paramsClass = resolvedInterceptorRef.getParamsClass();
    final BeanPropertyPathReferenceSet beanPropertyPathReferenceSet =
        new BeanPropertyPathReferenceSet(propertyText, nameAttributeValue, idx + 2, '.', paramsClass, false);

    Collections.addAll(customReferences, beanPropertyPathReferenceSet.getPsiReferences());

    return ArrayUtil.toObjectArray(customReferences, PsiReference.class);
  }


  private static class InterceptorRefPsiReference extends PsiReferenceBase<PsiElement>
      implements EmptyResolveMessageProvider {

    private final InterceptorRef resolvedInterceptorRef;
    private final InterceptorStack interceptorStack;

    private InterceptorRefPsiReference(final XmlAttributeValue psiElement,
                                       final TextRange textRange,
                                       final InterceptorRef resolvedInterceptorRef,
                                       final InterceptorStack interceptorStack) {
      super(psiElement, textRange, true);
      this.resolvedInterceptorRef = resolvedInterceptorRef;
      this.interceptorStack = interceptorStack;
    }

    @Override
    public PsiElement resolve() {
      if (resolvedInterceptorRef == null) {
        return null;
      }

      final InterceptorOrStackBase interceptorDeclaration = resolvedInterceptorRef.getName().getValue();
      if (interceptorDeclaration == null) {
        return null;
      }

      final DomTarget domTarget = DomTarget.getTarget(interceptorDeclaration);
      return domTarget == null ? null : PomService.convertToPsi(domTarget);
    }

    @NotNull
    @Override
    public Object[] getVariants() {
      final List<InterceptorRef> allInterceptorRefs = interceptorStack.getInterceptorRefs();
      List<LookupElement> names = new ArrayList<LookupElement>(allInterceptorRefs.size());
      for (InterceptorRef interceptorRef : allInterceptorRefs) {
        final InterceptorOrStackBase resolvedInterceptor = interceptorRef.getName().getValue();
        if (resolvedInterceptor == null) {
          continue;
        }

        final String interceptorName = StringUtil.notNullize(resolvedInterceptor.getName().getStringValue());
        names.add(LookupElementBuilder.create(resolvedInterceptor, interceptorName)
                                      .withIcon(ElementPresentationManager.getIcon(resolvedInterceptor)));
      }
      return ArrayUtil.toObjectArray(names, LookupElement.class);
    }

    @NotNull
    @Override
    public String getUnresolvedMessagePattern() {
      return "Cannot resolve interceptor '" + getValue() + "' " +
             "in interceptor-stack '" + interceptorStack.getName().getStringValue() + "'";
    }
  }

}
TOP

Related Classes of com.intellij.struts2.dom.params.custom.InterceptorRefInStackParamNameCustomConverter$InterceptorRefPsiReference

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.