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

com.github._1c_syntax.bsl.reader.MDOReader Maven / Gradle / Ivy

/*
 * This file is a part of MDClasses.
 *
 * Copyright (c) 2019 - 2024
 * Tymko Oleg , Maximov Valery  and contributors
 *
 * SPDX-License-Identifier: LGPL-3.0-or-later
 *
 * MDClasses is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3.0 of the License, or (at your option) any later version.
 *
 * MDClasses is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with MDClasses.
 */
package com.github._1c_syntax.bsl.reader;

import com.github._1c_syntax.bsl.mdclasses.MDClass;
import com.github._1c_syntax.bsl.mdo.MDObject;
import com.github._1c_syntax.bsl.reader.common.xstream.ExtendReaderWrapper;
import com.github._1c_syntax.bsl.reader.designer.DesignerPaths;
import com.github._1c_syntax.bsl.reader.designer.DesignerReader;
import com.github._1c_syntax.bsl.reader.edt.EDTPaths;
import com.github._1c_syntax.bsl.reader.edt.EDTReader;
import com.github._1c_syntax.bsl.types.ConfigurationSource;
import com.github._1c_syntax.bsl.types.MDOType;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import lombok.NonNull;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;

import javax.annotation.Nullable;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Читатель MDO файлов (описаний метаданных)
 */
@UtilityClass
@Slf4j
public class MDOReader {

  /**
   * Ридеры для проектов
   */
  private final Map READERS = new ConcurrentHashMap<>();

  /**
   * Возвращает читатель исходников по каталогу проекта
   *
   * @param rootPath Каталог проекта
   * @return Читатель
   */
  public MDReader getReader(@NonNull Path rootPath) {
    return getReader(rootPath, false);
  }

  /**
   * Возвращает читатель исходников по каталогу проекта
   *
   * @param path        Каталог проекта
   * @param skipSupport Флаг управления необходимостью читать информацию о поддержке
   * @return Читатель
   */
  public MDReader getReader(@NonNull Path path, boolean skipSupport) {
    for (Map.Entry reader : READERS.entrySet()) {
      if (path.startsWith(reader.getKey())) {
        return reader.getValue();
      }
    }
    var rootPathFile = path.toFile();
    if (rootPathFile.isFile() && rootPathFile.exists()) {
      return getReader(rootPathByFile(path), skipSupport);
    }

    var reader = createReader(path, skipSupport, MDOType.CONFIGURATION);
    READERS.put(path, reader);
    return reader;
  }

  /**
   * Производит чтение контейнера метаданных (конфигурации) по каталогу исходников
   *
   * @param rootPath Каталог исходников
   * @return Прочитанный контейнер метаданных (конфигурация)
   */
  public MDClass readConfiguration(@NonNull Path rootPath) {
    return readConfiguration(rootPath, false);
  }

  /**
   * Производит чтение контейнера метаданных (конфигурации) по каталогу исходников
   *
   * @param rootPath    Каталог исходников
   * @param skipSupport Флаг управления необходимостью читать информацию о поддержке
   * @return Прочитанный контейнер метаданных (конфигурация)
   */
  public MDClass readConfiguration(@NonNull Path rootPath, boolean skipSupport) {
    return getReader(rootPath, skipSupport).readConfiguration();
  }

  /**
   * Производит чтение указанного объекта метаданных по каталогу исходников и полному имени
   *
   * @param folder Каталог исходников
   * @return Прочитанный объект метаданных
   */
  public Object readMDObject(@NonNull Path folder, @NonNull String fullName) {
    return readMDObject(folder, fullName, false);
  }

  /**
   * Производит чтение указанного объекта метаданных по каталогу исходников и полному имени
   *
   * @param folder      Каталог исходников
   * @param skipSupport Управление чтением поддержки
   * @return Прочитанный объект метаданных
   */
  public Object readMDObject(@NonNull Path folder, @NonNull String fullName, boolean skipSupport) {
    var reader = getReader(folder, skipSupport);
    if (folder.toFile().isFile()) {
      return reader.read(fullName);
    } else {
      return reader.read(folder, fullName);
    }
  }

  /**
   * Производит чтение указанного объекта метаданных по каталогу исходников и полному имени
   *
   * @param fullMdoPath Путь к MDO файлу
   * @return Прочитанный объект метаданных
   */
  @Nullable
  public MDObject readMDObject(@NonNull Path fullMdoPath) {
    var data = read(fullMdoPath);
    if (data instanceof MDObject mdObject) {
      return mdObject;
    } else if (data == null) {
      LOGGER.warn("Missing file " + fullMdoPath);
      return null;
    } else {
      throw new IllegalArgumentException("Wrong mdo file " + fullMdoPath);
    }
  }

  /**
   * Производит чтение внешнего контейнера метаданных (внешней обработки или отчета) по файлу описания
   *
   * @param mdoPath Путь к файлу описания
   * @return Прочитанный контейнер метаданных (внешний отчет или обработка)
   */
  public MDClass readExternalSource(@NonNull Path mdoPath) {
    var reader = createReader(mdoPath, true, MDOType.EXTERNAL_REPORT);
    if (reader.getConfigurationSource() == ConfigurationSource.EDT) {
      READERS.put(mdoPath.getParent().getParent(), reader);
    } else if (reader.getConfigurationSource() == ConfigurationSource.DESIGNER) {
      READERS.put(mdoPath.getParent(), reader);
    }
    return reader.readExternalSource();
  }

  /**
   * Производит чтение файла
   *
   * @param fullMdoPath Путь к файлу
   * @return Прочитанный объект
   */
  public Object read(@NonNull Path fullMdoPath) {
    var reader = getReader(fullMdoPath);
    if (reader != null) {
      return reader.read(fullMdoPath);
    }
    throw new IllegalArgumentException("Unknown file " + fullMdoPath);
  }

  /**
   * Определяет тип исходников по корню проекта
   *
   * @param rootPath - Путь к корню проекта
   * @return Тип исходников конфигурации
   */
  public ConfigurationSource getConfigurationSourceByPath(Path rootPath) {
    var configurationSource = ConfigurationSource.EMPTY;
    if (rootPath != null) {
      var rootPathString = rootPath.toString();

      var rootConfiguration = new File(rootPathString, DesignerPaths.CONFIGURATION_MDO_PATH);
      if (rootConfiguration.exists()) {
        configurationSource = ConfigurationSource.DESIGNER;
      } else {
        rootConfiguration = Paths.get(rootPathString, EDTPaths.CONFIGURATION_MDO_PATH).toFile();
        if (rootConfiguration.exists()) {
          configurationSource = ConfigurationSource.EDT;
        }
      }
    }
    return configurationSource;
  }

  /**
   * Определяет тип исходников по расширению файла
   *
   * @param mdoPath - Путь к файлу
   * @return Тип исходников конфигурации
   */
  public ConfigurationSource getConfigurationSourceByPathSimple(Path mdoPath) {
    var configurationSource = ConfigurationSource.EMPTY;
    if (mdoPath != null) {
      var mdoFile = mdoPath.toFile();
      if (mdoFile.exists()) {
        if (FilenameUtils.isExtension(mdoPath.toString(), EDTPaths.EXTENSION)) {
          configurationSource = ConfigurationSource.EDT;
        } else if (FilenameUtils.isExtension(mdoPath.toString(), DesignerPaths.EXTENSION)) {
          configurationSource = ConfigurationSource.DESIGNER;
        }
      }
    }
    return configurationSource;
  }

  /**
   * Определяет тип исходников по корню проекта
   *
   * @param path - Путь к корню проекта
   * @return Тип исходников конфигурации
   */
  public ConfigurationSource getConfigurationSourceByMDOPath(Path path) {
    var pathString = path.toString();
    if (pathString.endsWith(DesignerPaths.EXTENSION_DOT)) {
      return ConfigurationSource.DESIGNER;
    } else if (pathString.endsWith(EDTPaths.EXTENSION_DOT)) {
      return ConfigurationSource.EDT;
    } else {
      return ConfigurationSource.EMPTY;
    }
  }

  // TODO Времянки

  /**
   * Получает ReflectionConverter по пути к файлу
   *
   * @param reader Ридер XML
   * @return Найденный конвертер
   */
  public Converter getReflectionConverter(HierarchicalStreamReader reader) {
    return getReader(((ExtendReaderWrapper) reader).getPath()).getReflectionConverter();
  }

  private MDReader createReader(Path rootPath, boolean skipSupport, MDOType mdoType) {
    ConfigurationSource configurationSource;
    if (mdoType == MDOType.CONFIGURATION) {
      configurationSource = getConfigurationSourceByPath(rootPath);
    } else {
      configurationSource = getConfigurationSourceByPathSimple(rootPath);
    }

    if (configurationSource == ConfigurationSource.DESIGNER) {
      return new DesignerReader(rootPath, skipSupport);
    } else if (configurationSource == ConfigurationSource.EDT) {
      return new EDTReader(rootPath, skipSupport);
    } else {
      return new FakeReader();
    }
  }

  private Path rootPathByFile(Path configurationMDOPath) {
    // todo переписать все нафиг

    if (configurationMDOPath.toString().endsWith(".form")) {
      // todo костыль
      if (configurationMDOPath.toString().contains("/CommonForms/")) {
        return EDTPaths.rootPathByConfigurationMDO(configurationMDOPath.getParent());
      } else {
        return EDTPaths.rootPathByConfigurationMDO(configurationMDOPath.getParent().getParent().getParent());
      }
    } else if (configurationMDOPath.toString().endsWith("Form.xml")) {
      // todo костыль
      if (configurationMDOPath.toString().contains("/CommonForms/")) {
        return DesignerPaths.rootPathByConfigurationMDO(configurationMDOPath.getParent().getParent().getParent());
      } else {
        return DesignerPaths.rootPathByConfigurationMDO(
          configurationMDOPath.getParent().getParent().getParent().getParent().getParent());
      }
    } else if (configurationMDOPath.toString().endsWith(".xml")) {
      if (configurationMDOPath.toString().contains("/CommonAttributes/")) {
        return DesignerPaths.rootPathByConfigurationMDO(configurationMDOPath.getParent());
      } else {
        return DesignerPaths.rootPathByConfigurationMDO(configurationMDOPath);
      }
    } else {
      return EDTPaths.rootPathByConfigurationMDO(configurationMDOPath);
    }
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy