All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.intellij.psi.impl.source.html.dtd.HtmlNSDescriptorImpl Maven / Gradle / Ivy

Go to download

A packaging of the IntelliJ Community Edition xml-psi-impl library. This is release number 1 of trunk branch 142.

The newest version!
/*
 * Copyright 2000-2014 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.psi.impl.source.html.dtd;

import com.intellij.html.RelaxedHtmlNSDescriptor;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.util.SimpleFieldCache;
import com.intellij.psi.PsiElement;
import com.intellij.psi.xml.XmlDocument;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.xml.XmlAttributeDescriptor;
import com.intellij.xml.XmlElementDescriptor;
import com.intellij.xml.XmlNSDescriptor;
import com.intellij.xml.impl.schema.TypeDescriptor;
import com.intellij.xml.impl.schema.XmlNSTypeDescriptorProvider;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.HashMap;
import java.util.Map;

/**
 * @author Maxim.Mossienko
 */
public class HtmlNSDescriptorImpl implements XmlNSDescriptor, DumbAware, XmlNSTypeDescriptorProvider {
  private final XmlNSDescriptor myDelegate;
  private final boolean myRelaxed;
  private final boolean myCaseSensitive;

  private static final SimpleFieldCache, HtmlNSDescriptorImpl> myCachedDeclsCache = new SimpleFieldCache, HtmlNSDescriptorImpl>() {
    @Override
    protected Map compute(final HtmlNSDescriptorImpl htmlNSDescriptor) {
      return htmlNSDescriptor.doBuildCachedMap();
    }

    @Override
    protected Map getValue(final HtmlNSDescriptorImpl htmlNSDescriptor) {
      return htmlNSDescriptor.myCachedDecls;
    }

    @Override
    protected void putValue(final Map map, final HtmlNSDescriptorImpl htmlNSDescriptor) {
      htmlNSDescriptor.myCachedDecls = map;
    }
  };

  private volatile Map myCachedDecls;

  public HtmlNSDescriptorImpl(XmlNSDescriptor _delegate) {
    this(_delegate, _delegate instanceof RelaxedHtmlNSDescriptor, false);
  }

  public HtmlNSDescriptorImpl(XmlNSDescriptor _delegate, boolean relaxed, boolean caseSensitive) {
    myDelegate = _delegate;
    myRelaxed = relaxed;
    myCaseSensitive = caseSensitive;
  }

  public static XmlAttributeDescriptor[] getCommonAttributeDescriptors(XmlTag context) {
    final XmlNSDescriptor nsDescriptor = context != null ? context.getNSDescriptor(context.getNamespace(), false) : null;
    if (nsDescriptor instanceof HtmlNSDescriptorImpl) {
      XmlElementDescriptor descriptor = ((HtmlNSDescriptorImpl)nsDescriptor).getElementDescriptorByName("div");
      descriptor = descriptor == null ? ((HtmlNSDescriptorImpl)nsDescriptor).getElementDescriptorByName("span") : descriptor;
      if (descriptor != null) {
        return descriptor.getAttributesDescriptors(context);
      }
    }
    return XmlAttributeDescriptor.EMPTY;
  }

  private Map buildDeclarationMap() {
    return myCachedDeclsCache.get(this);
  }

  // Read-only calculation
  private HashMap doBuildCachedMap() {
    HashMap decls = new HashMap();
    XmlElementDescriptor[] elements = myDelegate == null ? XmlElementDescriptor.EMPTY_ARRAY : myDelegate.getRootElementsDescriptors(null);

    for (XmlElementDescriptor element : elements) {
      decls.put(
        element.getName(),
        new HtmlElementDescriptorImpl(element, myRelaxed, myCaseSensitive)
      );
    }
    return decls;
  }

  @Override
  public XmlElementDescriptor getElementDescriptor(@NotNull XmlTag tag) {
    XmlElementDescriptor xmlElementDescriptor = getElementDescriptorByName(tag.getLocalName());
    if (xmlElementDescriptor == null && myRelaxed) {
      xmlElementDescriptor = myDelegate.getElementDescriptor(tag);
    }
    return xmlElementDescriptor;
  }

  private XmlElementDescriptor getElementDescriptorByName(String name) {
    if (!myCaseSensitive) name = name.toLowerCase();

    return buildDeclarationMap().get(name);
  }

  @Override
  @NotNull
  public XmlElementDescriptor[] getRootElementsDescriptors(@Nullable final XmlDocument document) {
    return myDelegate == null ? XmlElementDescriptor.EMPTY_ARRAY : myDelegate.getRootElementsDescriptors(document);
  }

  @Override
  @Nullable
  public XmlFile getDescriptorFile() {
    return myDelegate == null ? null : myDelegate.getDescriptorFile();
  }

  @Override
  public boolean isHierarhyEnabled() {
    return false;
  }

  @Override
  public PsiElement getDeclaration() {
    return myDelegate == null ? null : myDelegate.getDeclaration();
  }

  @Override
  public String getName(PsiElement context) {
    return myDelegate == null ? "" : myDelegate.getName(context);
  }

  @Override
  public String getName() {
    return myDelegate == null ? "" : myDelegate.getName();
  }

  @Override
  public void init(PsiElement element) {
    myDelegate.init(element);
  }

  @Override
  public Object[] getDependences() {
    return myDelegate == null ? null : myDelegate.getDependences();
  }

  @Override
  public TypeDescriptor getTypeDescriptor(String name, XmlTag context) {
    return myDelegate instanceof XmlNSTypeDescriptorProvider ?
           ((XmlNSTypeDescriptorProvider)myDelegate).getTypeDescriptor(name, context) : null;
  }

  @Override
  public TypeDescriptor getTypeDescriptor(XmlTag descriptorTag) {
    return myDelegate instanceof XmlNSTypeDescriptorProvider ?
           ((XmlNSTypeDescriptorProvider)myDelegate).getTypeDescriptor(descriptorTag) : null;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy