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

org.jetbrains.jps.model.serialization.module.JpsModuleRootModelSerializer Maven / Gradle / Ivy

/*
 * Copyright 2000-2012 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 org.jetbrains.jps.model.serialization.module;

import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.text.UniqueNameGenerator;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.model.JpsCompositeElement;
import org.jetbrains.jps.model.JpsElement;
import org.jetbrains.jps.model.JpsElementFactory;
import org.jetbrains.jps.model.JpsElementReference;
import org.jetbrains.jps.model.java.JpsJavaSdkType;
import org.jetbrains.jps.model.java.JpsJavaSdkTypeWrapper;
import org.jetbrains.jps.model.library.JpsLibrary;
import org.jetbrains.jps.model.library.JpsLibraryReference;
import org.jetbrains.jps.model.library.sdk.JpsSdkReference;
import org.jetbrains.jps.model.library.sdk.JpsSdkType;
import org.jetbrains.jps.model.module.*;
import org.jetbrains.jps.model.serialization.JpsModelSerializerExtension;
import org.jetbrains.jps.model.serialization.java.JpsJavaModelSerializerExtension;
import org.jetbrains.jps.model.serialization.library.JpsLibraryTableSerializer;
import org.jetbrains.jps.model.serialization.library.JpsSdkTableSerializer;

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

import static com.intellij.openapi.util.JDOMUtil.getChildren;

/**
 * @author nik
 */
public class JpsModuleRootModelSerializer {
  private static final Logger LOG = Logger.getInstance(JpsModuleRootModelSerializer.class);
  public static final String URL_ATTRIBUTE = "url";
  public static final String CONTENT_TAG = "content";
  public static final String SOURCE_FOLDER_TAG = "sourceFolder";
  public static final String PACKAGE_PREFIX_ATTRIBUTE = "packagePrefix";
  public static final String IS_TEST_SOURCE_ATTRIBUTE = "isTestSource";
  public static final String EXCLUDE_FOLDER_TAG = "excludeFolder";
  public static final String ORDER_ENTRY_TAG = "orderEntry";
  public static final String TYPE_ATTRIBUTE = "type";
  public static final String SOURCE_FOLDER_TYPE = "sourceFolder";
  public static final String JDK_TYPE = "jdk";
  public static final String JDK_NAME_ATTRIBUTE = "jdkName";
  public static final String JDK_TYPE_ATTRIBUTE = "jdkType";
  public static final String INHERITED_JDK_TYPE = "inheritedJdk";
  public static final String LIBRARY_TYPE = "library";
  public static final String NAME_ATTRIBUTE = "name";
  public static final String LEVEL_ATTRIBUTE = "level";
  public static final String LIBRARY_TAG = "library";
  public static final String MODULE_LIBRARY_TYPE = "module-library";
  public static final String MODULE_TYPE = "module";
  public static final String MODULE_NAME_ATTRIBUTE = "module-name";
  private static final String SOURCE_ROOT_TYPE_ATTRIBUTE = "type";
  public static final String JAVA_SOURCE_ROOT_TYPE_ID = "java-source";
  public static final String JAVA_TEST_ROOT_TYPE_ID = "java-test";
  private static final String GENERATED_LIBRARY_NAME_PREFIX = "#";

  public static void loadRootModel(JpsModule module, @Nullable Element rootModelComponent, @Nullable JpsSdkType projectSdkType) {
    if (rootModelComponent == null) return;

    for (Element contentElement : getChildren(rootModelComponent, CONTENT_TAG)) {
      final String url = contentElement.getAttributeValue(URL_ATTRIBUTE);
      module.getContentRootsList().addUrl(url);
      for (Element sourceElement : getChildren(contentElement, SOURCE_FOLDER_TAG)) {
        module.addSourceRoot(loadSourceRoot(sourceElement));
      }
      for (Element excludeElement : getChildren(contentElement, EXCLUDE_FOLDER_TAG)) {
        module.getExcludeRootsList().addUrl(excludeElement.getAttributeValue(URL_ATTRIBUTE));
      }
    }

    final JpsDependenciesList dependenciesList = module.getDependenciesList();
    dependenciesList.clear();
    final JpsElementFactory elementFactory = JpsElementFactory.getInstance();
    UniqueNameGenerator nameGenerator = new UniqueNameGenerator();
    for (Element orderEntry : getChildren(rootModelComponent, ORDER_ENTRY_TAG)) {
      String type = orderEntry.getAttributeValue(TYPE_ATTRIBUTE);
      if (SOURCE_FOLDER_TYPE.equals(type)) {
        dependenciesList.addModuleSourceDependency();
      }
      else if (JDK_TYPE.equals(type)) {
        String sdkName = orderEntry.getAttributeValue(JDK_NAME_ATTRIBUTE);
        String sdkTypeId = orderEntry.getAttributeValue(JDK_TYPE_ATTRIBUTE);
        final JpsSdkType sdkType = JpsSdkTableSerializer.getSdkType(sdkTypeId);
        dependenciesList.addSdkDependency(sdkType);
        JpsSdkTableSerializer.setSdkReference(module.getSdkReferencesTable(), sdkName, sdkType);
        if (sdkType instanceof JpsJavaSdkTypeWrapper) {
          dependenciesList.addSdkDependency(JpsJavaSdkType.INSTANCE);
        }
      }
      else if (INHERITED_JDK_TYPE.equals(type)) {
        final JpsSdkType sdkType = projectSdkType != null? projectSdkType : JpsJavaSdkType.INSTANCE;
        dependenciesList.addSdkDependency(sdkType);
        if (sdkType instanceof JpsJavaSdkTypeWrapper) {
          dependenciesList.addSdkDependency(JpsJavaSdkType.INSTANCE);
        }
      }
      else if (LIBRARY_TYPE.equals(type)) {
        String name = orderEntry.getAttributeValue(NAME_ATTRIBUTE);
        String level = orderEntry.getAttributeValue(LEVEL_ATTRIBUTE);
        final JpsLibraryDependency dependency =
          dependenciesList.addLibraryDependency(elementFactory.createLibraryReference(name, JpsLibraryTableSerializer
            .createLibraryTableReference(level)));
        loadModuleDependencyProperties(dependency, orderEntry);
      }
      else if (MODULE_LIBRARY_TYPE.equals(type)) {
        final Element moduleLibraryElement = orderEntry.getChild(LIBRARY_TAG);
        String name = moduleLibraryElement.getAttributeValue(NAME_ATTRIBUTE);
        if (name == null) {
          name = GENERATED_LIBRARY_NAME_PREFIX;
        }
        String uniqueName = nameGenerator.generateUniqueName(name);
        final JpsLibrary library = JpsLibraryTableSerializer.loadLibrary(moduleLibraryElement, uniqueName);
        module.addModuleLibrary(library);

        final JpsLibraryDependency dependency = dependenciesList.addLibraryDependency(library);
        loadModuleDependencyProperties(dependency, orderEntry);
      }
      else if (MODULE_TYPE.equals(type)) {
        String name = orderEntry.getAttributeValue(MODULE_NAME_ATTRIBUTE);
        final JpsModuleDependency dependency = dependenciesList.addModuleDependency(elementFactory.createModuleReference(name));
        loadModuleDependencyProperties(dependency, orderEntry);
      }
    }

    for (JpsModelSerializerExtension extension : JpsModelSerializerExtension.getExtensions()) {
      extension.loadRootModel(module, rootModelComponent);
    }
  }

  @NotNull
  public static JpsModuleSourceRoot loadSourceRoot(Element sourceElement) {
    final String sourceUrl = sourceElement.getAttributeValue(URL_ATTRIBUTE);
    JpsModuleSourceRootPropertiesSerializer serializer = getSourceRootPropertiesSerializer(sourceElement);
    return createSourceRoot(sourceUrl, serializer, sourceElement);
  }

  @NotNull 
  private static 

JpsModuleSourceRoot createSourceRoot(@NotNull String url, @NotNull JpsModuleSourceRootPropertiesSerializer

serializer, @NotNull Element sourceElement) { return JpsElementFactory.getInstance().createModuleSourceRoot(url, serializer.getType(), serializer.loadProperties(sourceElement)); } @NotNull private static JpsModuleSourceRootPropertiesSerializer getSourceRootPropertiesSerializer(@NotNull Element sourceElement) { String typeAttribute = sourceElement.getAttributeValue(SOURCE_ROOT_TYPE_ATTRIBUTE); if (typeAttribute == null) { typeAttribute = Boolean.parseBoolean(sourceElement.getAttributeValue(IS_TEST_SOURCE_ATTRIBUTE)) ? JAVA_TEST_ROOT_TYPE_ID : JAVA_SOURCE_ROOT_TYPE_ID; } for (JpsModelSerializerExtension extension : JpsModelSerializerExtension.getExtensions()) { for (JpsModuleSourceRootPropertiesSerializer serializer : extension.getModuleSourceRootPropertiesSerializers()) { if (serializer.getTypeId().equals(typeAttribute)) { return serializer; } } } LOG.warn("Unknown module source root type " + typeAttribute); return JpsJavaModelSerializerExtension.JAVA_SOURCE_ROOT_PROPERTIES_SERIALIZER; } public static void saveRootModel(JpsModule module, Element rootModelElement) { List sourceRoots = module.getSourceRoots(); List excludedUrls = getSortedList(module.getExcludeRootsList().getUrls()); for (String url : getSortedList(module.getContentRootsList().getUrls())) { Element contentElement = new Element(CONTENT_TAG); contentElement.setAttribute(URL_ATTRIBUTE, url); rootModelElement.addContent(contentElement); for (JpsModuleSourceRoot root : sourceRoots) { if (FileUtil.startsWith(root.getUrl(), url)) { saveSourceRoot(contentElement, root.asTyped().getUrl(), root.asTyped()); } } for (String excludedUrl : excludedUrls) { if (FileUtil.startsWith(excludedUrl, url)) { Element element = new Element(EXCLUDE_FOLDER_TAG).setAttribute(URL_ATTRIBUTE, excludedUrl); contentElement.addContent(element); } } } for (JpsDependencyElement dependency : module.getDependenciesList().getDependencies()) { if (dependency instanceof JpsModuleSourceDependency) { rootModelElement.addContent(createDependencyElement(SOURCE_FOLDER_TYPE).setAttribute("forTests", "false")); } else if (dependency instanceof JpsSdkDependency) { JpsSdkType sdkType = ((JpsSdkDependency)dependency).getSdkType(); JpsSdkReferencesTable table = module.getSdkReferencesTable(); JpsSdkReference reference = table.getSdkReference(sdkType); if (reference == null) { rootModelElement.addContent(createDependencyElement(INHERITED_JDK_TYPE)); } else { Element element = createDependencyElement(JDK_TYPE); element.setAttribute(JDK_NAME_ATTRIBUTE, reference.getSdkName()); element.setAttribute(JDK_TYPE_ATTRIBUTE, JpsSdkTableSerializer.getLoader(sdkType).getTypeId()); rootModelElement.addContent(element); } } else if (dependency instanceof JpsLibraryDependency) { JpsLibraryReference reference = ((JpsLibraryDependency)dependency).getLibraryReference(); JpsElementReference parentReference = reference.getParentReference(); Element element; if (parentReference instanceof JpsModuleReference) { element = createDependencyElement(MODULE_LIBRARY_TYPE); saveModuleDependencyProperties(dependency, element); Element libraryElement = new Element(LIBRARY_TAG); JpsLibrary library = reference.resolve(); String libraryName = library.getName(); JpsLibraryTableSerializer.saveLibrary(library, libraryElement, isGeneratedName(libraryName) ? null : libraryName); element.addContent(libraryElement); } else { element = createDependencyElement(LIBRARY_TYPE); saveModuleDependencyProperties(dependency, element); element.setAttribute(NAME_ATTRIBUTE, reference.getLibraryName()); element.setAttribute(LEVEL_ATTRIBUTE, JpsLibraryTableSerializer.getLevelId(parentReference)); } rootModelElement.addContent(element); } else if (dependency instanceof JpsModuleDependency) { Element element = createDependencyElement(MODULE_TYPE); element.setAttribute(MODULE_NAME_ATTRIBUTE, ((JpsModuleDependency)dependency).getModuleReference().getModuleName()); saveModuleDependencyProperties(dependency, element); rootModelElement.addContent(element); } } for (JpsModelSerializerExtension extension : JpsModelSerializerExtension.getExtensions()) { extension.saveRootModel(module, rootModelElement); } } public static

void saveSourceRoot(@NotNull Element contentElement, final @NotNull String rootUrl, @NotNull JpsTypedModuleSourceRoot

root) { Element sourceElement = new Element(SOURCE_FOLDER_TAG); sourceElement.setAttribute(URL_ATTRIBUTE, rootUrl); JpsModuleSourceRootPropertiesSerializer

serializer = getSerializer(root.getRootType()); if (serializer != null) { String typeId = serializer.getTypeId(); if (!typeId.equals(JAVA_SOURCE_ROOT_TYPE_ID) && !typeId.equals(JAVA_TEST_ROOT_TYPE_ID)) { sourceElement.setAttribute(SOURCE_ROOT_TYPE_ATTRIBUTE, typeId); } serializer.saveProperties(root.getProperties(), sourceElement); } contentElement.addContent(sourceElement); } @Nullable private static

JpsModuleSourceRootPropertiesSerializer

getSerializer(JpsModuleSourceRootType

type) { for (JpsModelSerializerExtension extension : JpsModelSerializerExtension.getExtensions()) { for (JpsModuleSourceRootPropertiesSerializer serializer : extension.getModuleSourceRootPropertiesSerializers()) { if (serializer.getType().equals(type)) { return (JpsModuleSourceRootPropertiesSerializer

)serializer; } } } return null; } private static boolean isGeneratedName(String libraryName) { return libraryName.startsWith(GENERATED_LIBRARY_NAME_PREFIX); } private static Element createDependencyElement(final String type) { return new Element(ORDER_ENTRY_TAG).setAttribute(TYPE_ATTRIBUTE, type); } private static List getSortedList(final List list) { List strings = new ArrayList(list); Collections.sort(strings); return strings; } private static void loadModuleDependencyProperties(JpsDependencyElement dependency, Element orderEntry) { for (JpsModelSerializerExtension extension : JpsModelSerializerExtension.getExtensions()) { extension.loadModuleDependencyProperties(dependency, orderEntry); } } private static void saveModuleDependencyProperties(JpsDependencyElement dependency, Element orderEntry) { for (JpsModelSerializerExtension extension : JpsModelSerializerExtension.getExtensions()) { extension.saveModuleDependencyProperties(dependency, orderEntry); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy