Package com.intellij.javaee.util

Source Code of com.intellij.javaee.util.JamCommonUtil

/*
* Copyright 2000-2007 JetBrains s.r.o.
*
* 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.javaee.util;

import com.intellij.javaee.model.annotations.JamElement;
import com.intellij.javaee.model.annotations.JamMemberElement;
import com.intellij.javaee.model.annotations.JamModuleManager;
import com.intellij.javaee.model.annotations.JamRootElement;
import com.intellij.javaee.model.common.CommonModelElement;
import com.intellij.javaee.model.xml.CommonDomModelElement;
import com.intellij.javaee.model.xml.impl.RootBaseImpl;
import com.intellij.lang.StdLanguages;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.roots.ModuleOrderEntry;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.OrderEntry;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.psi.*;
import com.intellij.psi.util.CachedValue;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.Processor;
import com.intellij.util.ReflectionCache;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.xml.*;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.*;

/**
* @author Gregory.Shrago
*/
public class JamCommonUtil {
  @NonNls public static final String VALUE_PARAMETER = "value";

  @Nullable
  public static Object computeMemberValue(final PsiElement value) {
    if (value instanceof PsiExpression) {
      try {
        return value.getManager().getConstantEvaluationHelper().computeConstantExpression((PsiExpression)value, false);
      }
      catch (UnsupportedOperationException e) {
        // nothing
      }
    }
    else if (value instanceof XmlAttributeValue) {
      final GenericAttributeValue genericValue =
        DomManager.getDomManager(value.getProject()).getDomElement((XmlAttribute)value.getParent());
      return genericValue != null ? genericValue.getValue() : ((XmlAttributeValue)value).getValue();
    }
    return null;
  }

  public static boolean isSuperClass(@Nullable final PsiClass firstClass, final String superClassQName) {
    return !processSuperClassList(firstClass, new SmartList<PsiClass>(), new Processor<PsiClass>() {
      public boolean process(final PsiClass superClass) {
        return !Comparing.equal(superClass.getQualifiedName(), superClassQName);
      }
    });
  }

  @NotNull
  public static List<PsiClass> getSuperClassList(@Nullable final PsiClass firstClass) {
    final SmartList<PsiClass> list = new SmartList<PsiClass>();
    processSuperClassList(firstClass, list, new Processor<PsiClass>() {
      public boolean process(final PsiClass psiClass) {
        return true;
      }
    });
    return list;
  }

  public static boolean processSuperClassList(@Nullable final PsiClass firstClass, @NotNull final Collection<PsiClass> supers, final Processor<PsiClass> processor) {
    for (PsiClass curClass = firstClass;
         curClass != null
         && !CommonClassNames.JAVA_LANG_OBJECT.equals(curClass.getQualifiedName())
         && !supers.contains(curClass);
         curClass = curClass.getSuperClass()) {
      ProgressManager.getInstance().checkCanceled();
      if (!processor.process(curClass)) return false;
      supers.add(curClass);
    }
    return true;
  }

  @Nullable
  public static <T> T getRootElement(final PsiFile file, final Class<T> domClass, final Module module) {
    if (!(file instanceof XmlFile)) return null;
    final DomManager domManager = DomManager.getDomManager(file.getProject());
    final DomFileElement<DomElement> element = domManager.getFileElement((XmlFile)file, DomElement.class);
    if (element == null) return null;
    final DomElement root = element.getRootElement();
    if (!ReflectionCache.isAssignable(domClass, root.getClass())) return null;
    if (module != null && root instanceof RootBaseImpl) {
      ((RootBaseImpl)root).registerDomModule(module);
    }
    return (T)root;
  }

  @NotNull
  public static <T extends JamRootElement> List<T> getRootElements(final PsiElement psiElement, final Class<T> rootClass) {
    final Module module = ModuleUtil.findModuleForPsiElement(psiElement);
    if (module == null) {
      return Collections.emptyList();
    }
    final SmartList<T> result = new SmartList<T>();
    for (Module depModule : getAllDependentModules(module)) {
      ContainerUtil.addIfNotNull(JamModuleManager.getInstance(depModule).getRootElement(rootClass), result);
    }
    return result;
  }


  @Nullable
  public static String getDisplayName(final Object element) {
    if (element instanceof CommonModelElement) {
      final CommonModelElement javaeeModelElement = (CommonModelElement)element;
      String name = getElementName(javaeeModelElement);
      if (name == null) name = "";
      return getClassName(javaeeModelElement) + " '" + name + "'";
    }
    return null;
  }

  @Nullable
  public static String getElementName(final CommonModelElement element) {
    return ElementPresentationManager.getElementName(element);
  }

  public static String getClassName(final CommonModelElement element) {
    return ElementPresentationManager.getTypeNameForObject(element);
  }

  @Nullable
  public static Module findModuleForPsiElement(final PsiElement element) {
    PsiFile psiFile = element.getContainingFile();
    if (psiFile == null) {
      final VirtualFile virtualFile = PsiUtil.getVirtualFile(element);
      return virtualFile == null ? null : ProjectRootManager.getInstance(element.getProject()).getFileIndex().getModuleForFile(virtualFile);
    }

    final PsiFile originalFile = psiFile.getOriginalFile();
    if (originalFile != null) {
      psiFile = originalFile;
    }
    if (psiFile instanceof XmlFile) {
      final DomFileElement<CommonDomModelElement> domFileElement =
        DomManager.getDomManager(element.getProject()).getFileElement((XmlFile)psiFile, CommonDomModelElement.class);
      if (domFileElement != null) {
        Module module = domFileElement.getRootElement().getModule();
        if (module != null) {
          return module;
        }
      }
    }

    return ModuleUtil.findModuleForPsiElement(psiFile);
  }

  @NotNull
  public static PsiElement[] getTargetPsiElements(final CommonModelElement element) {
    ArrayList<PsiElement> list = new ArrayList<PsiElement>();
    for (CommonModelElement modelElement : ModelMergerUtil.getFilteredImplementations(element)) {
      if (modelElement instanceof DomElement) {
        final DomElement domModelElement = (DomElement)modelElement;
        if (domModelElement.getXmlTag() != null) {
          list.add(domModelElement.getXmlTag());
        }
      }
      else if (modelElement instanceof JamElement) {
        final JamElement annotationModelElement = (JamElement)modelElement;
        if (annotationModelElement instanceof JamMemberElement) {
          final JamMemberElement annotatedElement = (JamMemberElement)annotationModelElement;
          list.add(annotatedElement.getPsiMember());
        }
        else {
          ContainerUtil.addIfNotNull(annotationModelElement.getIdentifyingAnnotation(), list);
        }
      }
      else {
        ContainerUtil.addIfNotNull(modelElement.getIdentifyingPsiElement(), list);
      }
    }
    final PsiElement[] result = list.toArray(PsiElement.EMPTY_ARRAY);
    Arrays.sort(result, new Comparator<PsiElement>() {
      public int compare(final PsiElement o1, final PsiElement o2) {
        return getWeight(o1) - getWeight(o2);
      }
      private int getWeight(PsiElement o) {
        if (o instanceof XmlTag) return 0;
        if (o instanceof PsiMember) return 1;
        if (o instanceof PsiAnnotation) return 2;
        return 3;
      }
    });
    return result;
  }

  public static boolean isInLibrary(final CommonModelElement modelElement) {
    if (modelElement == null) return false;
    final PsiElement psiElement = modelElement.getIdentifyingPsiElement();
    if (psiElement == null) return false;
    final PsiFile psiFile = psiElement.getContainingFile();
    if (psiFile == null) return false;
    final VirtualFile virtualFile = psiFile.getVirtualFile();
    if (virtualFile == null) return false;
    return ProjectRootManager.getInstance(modelElement.getPsiManager().getProject()).getFileIndex().isInLibraryClasses(virtualFile);
  }

  public static boolean isPlainJavaFile(final PsiElement element) {
    return element instanceof PsiJavaFile && element.getLanguage() == StdLanguages.JAVA;
  }

  public static boolean isPlainXmlFile(final PsiElement element) {
    return element instanceof XmlFile && element.getLanguage() == StdLanguages.XML;
  }

  private static Key<CachedValue<Module[]>> MODULE_DEPENDENCIES = Key.create("MODULE_DEPENDENCIES");
  private static Key<CachedValue<Module[]>> MODULE_DEPENDENTS = Key.create("MODULE_DEPENDENTS");

  @NotNull
  public static Module[] getAllModuleDependencies(final Module module) {
    CachedValue<Module[]> value = module.getUserData(MODULE_DEPENDENCIES);
    if (value == null) {
      module.putUserData(MODULE_DEPENDENCIES, value = PsiManager.getInstance(module.getProject()).getCachedValuesManager().createCachedValue(new CachedValueProvider<Module[]>() {
        public Result<Module[]> compute() {
          final Set<Module> result = addModuleDependencies(module, new THashSet<Module>(), false);
          return new Result<Module[]>(result.toArray(new Module[result.size()]), ProjectRootManager.getInstance(module.getProject()));
        }
      }, false));
    }
    return value.getValue();
  }

  @NotNull
  public static Module[] getAllDependentModules(final Module module) {
    CachedValue<Module[]> value = module.getUserData(MODULE_DEPENDENTS);
    if (value == null) {
      module.putUserData(MODULE_DEPENDENTS, value = PsiManager.getInstance(module.getProject()).getCachedValuesManager().createCachedValue(new CachedValueProvider<Module[]>() {
        public Result<Module[]> compute() {
          final Module[] modules = ModuleManager.getInstance(module.getProject()).getModules();
          final Set<Module> result = addModuleDependents(module, new THashSet<Module>(), modules);
          return new Result<Module[]>(result.toArray(new Module[result.size()]), ProjectRootManager.getInstance(module.getProject()));
        }
      }, false));
    }
    return value.getValue();
  }

  public static Set<Module> addModuleDependencies(final Module module, final Set<Module> result, final boolean exported) {
    final OrderEntry[] orderEntries = ModuleRootManager.getInstance(module).getOrderEntries();
    for (OrderEntry orderEntry : orderEntries) {
      if (orderEntry.isValid() && orderEntry instanceof ModuleOrderEntry && (!exported || ((ModuleOrderEntry)orderEntry).isExported())) {
        final Module exportedModule = ((ModuleOrderEntry)orderEntry).getModule();
        if (result.add(exportedModule)) {
          addModuleDependencies(exportedModule, result, true);
        }
      }
    }
    return result;
  }

  public static Set<Module> addModuleDependents(final Module module, final Set<Module> result, final Module[] modules) {
    if (!result.add(module)) return result;
    for (Module allModule : modules) {
      final OrderEntry[] orderEntries = ModuleRootManager.getInstance(allModule).getOrderEntries();
      for (OrderEntry orderEntry : orderEntries) {
        if (orderEntry.isValid() && orderEntry instanceof ModuleOrderEntry) {
          final Module exportedModule = ((ModuleOrderEntry)orderEntry).getModule();
          if (exportedModule == module && result.add(allModule)) {
            if (((ModuleOrderEntry)orderEntry).isExported()) {
              addModuleDependents(allModule, result, modules);
            }
          }
        }
      }
    }
    return result;
  }
}
TOP

Related Classes of com.intellij.javaee.util.JamCommonUtil

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.