<commit_before>// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.ide.plugins;

import com.intellij.AbstractBundle;
import com.intellij.CommonBundle;
import com.intellij.diagnostic.PluginException;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ComponentConfig;
import com.intellij.openapi.components.OldComponentConfig;
import com.intellij.openapi.components.ServiceDescriptor;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.ExtensionPoint;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.extensions.ExtensionsArea;
import com.intellij.openapi.extensions.PluginId;
import com.intellij.openapi.extensions.impl.ExtensionPointImpl;
import com.intellij.openapi.extensions.impl.ExtensionsAreaImpl;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.util.text.StringUtilRt;
import com.intellij.util.ObjectUtils;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashSetInterner;
import com.intellij.util.containers.Interner;
import com.intellij.util.containers.MultiMap;
import com.intellij.util.xmlb.BeanBinding;
import com.intellij.util.xmlb.JDOMXIncluder;
import com.intellij.util.xmlb.XmlSerializer;
import org.jdom.Content;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.picocontainer.MutablePicoContainer;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author mike
 */
public class IdeaPluginDescriptorImpl implements IdeaPluginDescriptor {
  public static final IdeaPluginDescriptorImpl[] EMPTY_ARRAY = new IdeaPluginDescriptorImpl[0];

  private static final Logger LOG = Logger.getInstance("#com.intellij.ide.plugins.PluginDescriptor");

  private static final String APPLICATION_SERVICE = "com.intellij.applicationService";
  private static final String PROJECT_SERVICE = "com.intellij.projectService";
  private static final String MODULE_SERVICE = "com.intellij.moduleService";

  @SuppressWarnings("SSBasedInspection")
  public static final List<String> SERVICE_QUALIFIED_ELEMENT_NAMES = Arrays.asList(APPLICATION_SERVICE, PROJECT_SERVICE, MODULE_SERVICE);

  private final File myPath;
  private final boolean myBundled;
  private String myName;
  private PluginId myId;
  private final NullableLazyValue<String> myDescription = NullableLazyValue.createValue(() -> computeDescription());
  private @Nullable String myProductCode;
  private @Nullable Date myReleaseDate;
  private int myReleaseVersion;
  private String myResourceBundleBaseName;
  private String myChangeNotes;
  private String myVersion;
  private String myVendor;
  private String myVendorEmail;
  private String myVendorUrl;
  private String myVendorLogoPath;
  private String myCategory;
  private String myUrl;
  private PluginId[] myDependencies = PluginId.EMPTY_ARRAY;
  private PluginId[] myOptionalDependencies = PluginId.EMPTY_ARRAY;
  private Map<PluginId, List<String>> myOptionalConfigs;
  private Map<PluginId, List<IdeaPluginDescriptorImpl>> myOptionalDescriptors;
  private @Nullable List<Element> myActionElements;
  private @Nullable List<ComponentConfig> myAppComponents;
  private @Nullable List<ComponentConfig> myProjectComponents;
  private @Nullable List<ComponentConfig> myModuleComponents;
  private @Nullable MultiMap<String, Element> myExtensions;  // extension point name -> list of extension elements
  private @Nullable List<ServiceDescriptor> myAppServices;
  private @Nullable List<ServiceDescriptor> myProjectServices;
  private @Nullable List<ServiceDescriptor> myModuleServices;
  private @Nullable MultiMap<String, Element> myExtensionsPoints;
  private List<String> myModules;
  private ClassLoader myLoader;
  private String myDescriptionChildText;
  private boolean myUseIdeaClassLoader;
  private boolean myUseCoreClassLoader;
  private boolean myAllowBundledUpdate;
  private boolean myImplementationDetail;
  private String mySinceBuild;
  private String myUntilBuild;

  private boolean myEnabled = true;
  private boolean myDeleted;
  private Boolean mySkipped;

  public IdeaPluginDescriptorImpl(@NotNull File pluginPath, boolean bundled) {
    myPath = pluginPath;
    myBundled = bundled;
  }

  @Override
  public File getPath() {
    return myPath;
  }

  public void readExternal(@NotNull Element element,
                           @NotNull URL url,
                           @NotNull JDOMXIncluder.PathResolver pathResolver,
                           @Nullable Interner<String> stringInterner) throws InvalidDataException, MalformedURLException {
    Application app = ApplicationManager.getApplication();
    readExternal(element, url, app != null && app.isUnitTestMode(), pathResolver, stringInterner);
  }

  public void loadFromFile(@NotNull File file, @Nullable SafeJdomFactory factory) throws IOException, JDOMException {
    Application app = ApplicationManager.getApplication();
    readExternal(JDOMUtil.load(file, factory), file.toURI().toURL(), app != null && app.isUnitTestMode(),
                 JDOMXIncluder.DEFAULT_PATH_RESOLVER, factory == null ? null : factory.stringInterner());
  }

  private void readExternal(@NotNull Element element,
                            @NotNull URL url,
                            boolean ignoreMissingInclude,
                            @NotNull JDOMXIncluder.PathResolver pathResolver,
                            @Nullable Interner<String> stringInterner) throws InvalidDataException, MalformedURLException {
    // root element always `!isIncludeElement` and it means that result always is a singleton list
    // (also, plugin xml describes one plugin, this descriptor is not able to represent several plugins)
    if (JDOMUtil.isEmpty(element)) {
      return;
    }

    JDOMXIncluder.resolveNonXIncludeElement(element, url, ignoreMissingInclude, pathResolver);
    readExternal(element, stringInterner);
  }

  // used in upsource
  protected void readExternal(@NotNull Element element, @Nullable Interner<String> stringInterner) {
    OptimizedPluginBean pluginBean = XmlSerializer.deserialize(element, OptimizedPluginBean.class);
    myUrl = pluginBean.url;

    String idString = StringUtil.nullize(pluginBean.id, true);
    String nameString = StringUtil.nullize(pluginBean.name, true);
    myId = idString != null ? PluginId.getId(idString) : nameString != null ? PluginId.getId(nameString) : null;
    myName = ObjectUtils.chooseNotNull(nameString, idString);

    ProductDescriptor pd = pluginBean.productDescriptor;
    myProductCode = pd != null? pd.code : null;
    myReleaseDate = parseReleaseDate(pluginBean);
    myReleaseVersion = pd != null? pd.releaseVersion : 0;

    String internalVersionString = pluginBean.formatVersion;
    if (internalVersionString != null) {
      try {
        Integer.parseInt(internalVersionString);
      }
      catch (NumberFormatException e) {
        LOG.error(new PluginException("Invalid value in plugin.xml format version: '" + internalVersionString + "'", e, myId));<commit_msg>skip resolving XIncludes in disabled plugins<commit_after>// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.ide.plugins;

import com.intellij.AbstractBundle;
import com.intellij.CommonBundle;
import com.intellij.diagnostic.PluginException;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ComponentConfig;
import com.intellij.openapi.components.OldComponentConfig;
import com.intellij.openapi.components.ServiceDescriptor;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.ExtensionPoint;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.extensions.ExtensionsArea;
import com.intellij.openapi.extensions.PluginId;
import com.intellij.openapi.extensions.impl.ExtensionPointImpl;
import com.intellij.openapi.extensions.impl.ExtensionsAreaImpl;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.util.text.StringUtilRt;
import com.intellij.util.ObjectUtils;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashSetInterner;
import com.intellij.util.containers.Interner;
import com.intellij.util.containers.MultiMap;
import com.intellij.util.xmlb.BeanBinding;
import com.intellij.util.xmlb.JDOMXIncluder;
import com.intellij.util.xmlb.XmlSerializer;
import org.jdom.Content;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.picocontainer.MutablePicoContainer;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author mike
 */
public class IdeaPluginDescriptorImpl implements IdeaPluginDescriptor {
  public static final IdeaPluginDescriptorImpl[] EMPTY_ARRAY = new IdeaPluginDescriptorImpl[0];

  private static final Logger LOG = Logger.getInstance("#com.intellij.ide.plugins.PluginDescriptor");

  private static final String APPLICATION_SERVICE = "com.intellij.applicationService";
  private static final String PROJECT_SERVICE = "com.intellij.projectService";
  private static final String MODULE_SERVICE = "com.intellij.moduleService";

  @SuppressWarnings("SSBasedInspection")
  public static final List<String> SERVICE_QUALIFIED_ELEMENT_NAMES = Arrays.asList(APPLICATION_SERVICE, PROJECT_SERVICE, MODULE_SERVICE);

  private final File myPath;
  private final boolean myBundled;
  private String myName;
  private PluginId myId;
  private final NullableLazyValue<String> myDescription = NullableLazyValue.createValue(() -> computeDescription());
  private @Nullable String myProductCode;
  private @Nullable Date myReleaseDate;
  private int myReleaseVersion;
  private String myResourceBundleBaseName;
  private String myChangeNotes;
  private String myVersion;
  private String myVendor;
  private String myVendorEmail;
  private String myVendorUrl;
  private String myVendorLogoPath;
  private String myCategory;
  private String myUrl;
  private PluginId[] myDependencies = PluginId.EMPTY_ARRAY;
  private PluginId[] myOptionalDependencies = PluginId.EMPTY_ARRAY;
  private Map<PluginId, List<String>> myOptionalConfigs;
  private Map<PluginId, List<IdeaPluginDescriptorImpl>> myOptionalDescriptors;
  private @Nullable List<Element> myActionElements;
  private @Nullable List<ComponentConfig> myAppComponents;
  private @Nullable List<ComponentConfig> myProjectComponents;
  private @Nullable List<ComponentConfig> myModuleComponents;
  private @Nullable MultiMap<String, Element> myExtensions;  // extension point name -> list of extension elements
  private @Nullable List<ServiceDescriptor> myAppServices;
  private @Nullable List<ServiceDescriptor> myProjectServices;
  private @Nullable List<ServiceDescriptor> myModuleServices;
  private @Nullable MultiMap<String, Element> myExtensionsPoints;
  private List<String> myModules;
  private ClassLoader myLoader;
  private String myDescriptionChildText;
  private boolean myUseIdeaClassLoader;
  private boolean myUseCoreClassLoader;
  private boolean myAllowBundledUpdate;
  private boolean myImplementationDetail;
  private String mySinceBuild;
  private String myUntilBuild;

  private boolean myEnabled = true;
  private boolean myDeleted;
  private Boolean mySkipped;

  public IdeaPluginDescriptorImpl(@NotNull File pluginPath, boolean bundled) {
    myPath = pluginPath;
    myBundled = bundled;
  }

  @Override
  public File getPath() {
    return myPath;
  }

  public void readExternal(@NotNull Element element,
                           @NotNull URL url,
                           @NotNull JDOMXIncluder.PathResolver pathResolver,
                           @Nullable Interner<String> stringInterner) throws InvalidDataException, MalformedURLException {
    Application app = ApplicationManager.getApplication();
    readExternal(element, url, app != null && app.isUnitTestMode(), pathResolver, stringInterner);
  }

  public void loadFromFile(@NotNull File file, @Nullable SafeJdomFactory factory) throws IOException, JDOMException {
    Application app = ApplicationManager.getApplication();
    readExternal(JDOMUtil.load(file, factory), file.toURI().toURL(), app != null && app.isUnitTestMode(),
                 JDOMXIncluder.DEFAULT_PATH_RESOLVER, factory == null ? null : factory.stringInterner());
  }

  private void readExternal(@NotNull Element element,
                            @NotNull URL url,
                            boolean ignoreMissingInclude,
                            @NotNull JDOMXIncluder.PathResolver pathResolver,
                            @Nullable Interner<String> stringInterner) throws InvalidDataException, MalformedURLException {
    // root element always `!isIncludeElement` and it means that result always is a singleton list
    // (also, plugin xml describes one plugin, this descriptor is not able to represent several plugins)
    if (JDOMUtil.isEmpty(element)) {
      return;
    }

    Element id = element.getChild("id");
    if (id == null || !PluginManagerCore.disabledPlugins().contains(id.getTextTrim())) {
      JDOMXIncluder.resolveNonXIncludeElement(element, url, ignoreMissingInclude, pathResolver);
    } else {
      if (LOG.isDebugEnabled()) LOG.debug("Skipping resolving of " + id.getTextTrim() + " from " + url);
    }
    readExternal(element, stringInterner);
  }

  // used in upsource
  protected void readExternal(@NotNull Element element, @Nullable Interner<String> stringInterner) {
    OptimizedPluginBean pluginBean = XmlSerializer.deserialize(element, OptimizedPluginBean.class);
    myUrl = pluginBean.url;

    String idString = StringUtil.nullize(pluginBean.id, true);
    String nameString = StringUtil.nullize(pluginBean.name, true);
    myId = idString != null ? PluginId.getId(idString) : nameString != null ? PluginId.getId(nameString) : null;
    myName = ObjectUtils.chooseNotNull(nameString, idString);

    ProductDescriptor pd = pluginBean.productDescriptor;
    myProductCode = pd != null? pd.code : null;
    myReleaseDate = parseReleaseDate(pluginBean);
    myReleaseVersion = pd != null? pd.releaseVersion : 0;

    String internalVersionString = pluginBean.formatVersion;
    if (internalVersionString != null) {
      try {
        Integer.parseInt(internalVersionString);
      }
      catch (NumberFormatException e) {
        LOG.error(new PluginException("Invalid value in plugin.xml format version: '" + internalVersionString + "'", e, myId));
{'fraction_non_alphanumeric': 0.08320912448966367, 'fraction_numerical': 0.0015553107381245544, 'mean_word_length': 4.849886277482941, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 10}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5220060', 'n_tokens_mistral': 4270, 'n_tokens_neox': 4199, 'n_words': 1042}