Изолированная default-фабрика и проверка допуска Привести string → SKU

Учебные задачи

Создаем настоящую фабрику по умолчанию и отдельную фабрику собственной UUID-схемы. Проверяем допустимое приведение предка string к ограниченному Sku и отказ нарушающей фасеты строки; не выдумываем контракт возвращаемого значения.

Где и как запускать

Полный серверный модуль собственной файловой ИБ; две отдельные локальные фабрики, без изменения пакетов конфигурации. Runtime0.

Подготовка

  1. Не открывайте УНФ, КА2, БП или УТ: создайте отдельную новую пустую файловую ИБ на платформе ровно8.5.1.1343. Пример не предназначен для production и не меняет конфигурации пользователя.

  2. В Конфигураторе установите имя корня конфигурации УчебныеСкалярныеXDTO85, управляемое приложение и совместимость Не использовать. В конфигурации не должно быть справочников, документов, регистров, общих реквизитов, фоновых заданий, подписок или внешних источников.

  3. Не устанавливайте расширения ни в базу, ни в сеанс. Полный ПроверитьСвойПустойСтенд в каждом основном модуле проверяет все три native-источника расширений, отсутствие активной транзакции.

  4. Создайте общий модуль УчебныеXDTO85: СерверИстина, ВызовСервераЛожь, ГлобальныйЛожь, Клиент(управляемое приложение)Ложь, Клиент(обычное приложение)Ложь, ВнешнееСоединениеЛожь, ПривилегированныйЛожь. Поместите весь основной код этого урока в этот пустой модуль.

  5. Создайте обработку УчебныеXDTO85 с собственной основной управляемой формой. Добавьте команду Выполнить, обработчик Выполнить и кнопку на форме. Поместите полный вспомогательный модуль формы из этого урока; он передаёт только итоговую строку, не фабрику/DOM/XDTO-объект между клиентом и сервером.

  6. Уроки самостоятельны: для следующего урока замените весь собственный общий модуль соответствующим полным основным кодом. Одновременное склеивание модулей с одинаковым ВыполнитьПример85 запрещено.

  7. UUID создается локально для каждого опыта. URI urn:guide:xdto-scalars85:<UUID> и дополнительный URI с :extra — имена пространств, не URL. Схема, DOM, фабрика и XML создаются лишь в памяти: нет import/include, DTD, чтения файлов, сети, обращения к базам или глобальной ФабрикаXDTO конфигурации.

  8. Собственная XSD полностью включена в код: Sku — строка ровно4символа с прописной латинской буквой и3цифрами; SkuList — список Sku; QtyOrSku — union positiveInteger/Sku; Envelope — открытая wildcard-структура; Closed — закрытая структура.

  9. Обновите только свою учебную конфигурацию базы данных. Запустите собственную обработку в тонком управляемом клиенте; API построения схем выполняется на серверном контексте файловой ИБ, а не в клиентском модуле.

  10. Это подготовленный пример, проверенный статически и по установленной справке. Фактических запусков 1С здесь0; если ручной тест выдает исключение, сохраните его текст и не убирайте защитные проверки ради продолжения.

Функция ВыполнитьПример85() Экспорт
    Опыт = ПодготовитьСвойКонтракт85();
    ИсходнаяФабрика = Новый ФабрикаXDTO();
    Если ИсходнаяФабрика.Тип(Опыт.URI, "Sku") <> Неопределено Тогда
        ВызватьИсключение "Новая default-фабрика неожиданно содержит собственный свежий UUID-тип";
    КонецЕсли;
    Фабрика = Опыт.Фабрика;
    ТипСтроки = Фабрика.Тип("http://www.w3.org/2001/XMLSchema", "string");
    ТипАртикула = Фабрика.Тип(Опыт.URI, "Sku");
    Если ТипЗнч(ТипСтроки) <> Тип("ТипЗначенияXDTO") Или ТипЗнч(ТипАртикула) <> Тип("ТипЗначенияXDTO") Тогда
        ВызватьИсключение "Типы преобразования должны быть реально получены из собственной фабрики";
    КонецЕсли;
    Исходное = Фабрика.Создать(ТипСтроки, "A001");
    Если Исходное.Тип() <> ТипСтроки Или Исходное.ЛексическоеЗначение <> "A001" Тогда
        ВызватьИсключение "Исходная типизированная строка не соответствует собственной задаче";
    КонецЕсли;
    Фабрика.Привести(ТипАртикула, Исходное);
    Артикул = Фабрика.Создать(ТипАртикула, "A001");
    Если Артикул.Тип() <> ТипАртикула Или Артикул.Значение <> "A001" Тогда
        ВызватьИсключение "Отдельно созданный типизированный SKU не подтвержден";
    КонецЕсли;
    Неверное = Фабрика.Создать(ТипСтроки, "bad");
    Отказ = Ложь;
    Попытка
        Фабрика.Привести(ТипАртикула, Неверное);
    Исключение
        Отказ = Истина;
    КонецПопытки;
    Если Не Отказ Тогда
        ВызватьИсключение "Привести обязан соблюдать собственные length4 и pattern SKU";
    КонецЕсли;
    Если ИсходнаяФабрика.Тип(Опыт.URI, "Sku") <> Неопределено Тогда
        ВызватьИсключение "Изолированная default-фабрика не должна измениться от операций собственной схемной фабрики";
    КонецЕсли;
    Возврат "UUID " + Опыт.UUIDОпыта + ": default-фабрика изолирована; Привести принимает A001 и отказывает bad; отдельный Создать дает SKU A001. Возвращаемое значение Привести намеренно не используется";
КонецФункции

Процедура ПроверитьСвойПустойСтенд()
    Если Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
        ВызватьИсключение "Нужен только свой новый пустой учебный стенд";
    КонецЕсли;
    Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
        ВызватьИсключение "Свой сеанс не должен изменяться расширениями";
    КонецЕсли;
    Источники = Новый Массив;
    Источники.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
    Источники.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
    Источники.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
    Для Каждого Источник Из Источники Цикл
        Расширения = РасширенияКонфигурации.Получить(, Источник);
        Если ТипЗнч(Расширения) <> Тип("Массив") Тогда
            ВызватьИсключение "Native список расширений должен иметь тип Массив";
        КонецЕсли;
        Если Расширения.Количество() <> 0 Тогда
            ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
        КонецЕсли;
    КонецЦикла;
    Если ТранзакцияАктивна() Тогда
        ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
    КонецЕсли;
КонецПроцедуры

Функция ПодготовитьСвойКонтракт85()
    ПроверитьСвойПустойСтенд();
    UUIDОпыта = Строка(Новый УникальныйИдентификатор);
    Если UUIDОпыта = "00000000-0000-0000-0000-000000000000" Тогда
        ВызватьИсключение "Нужен собственный ненулевой UUID опыта";
    КонецЕсли;
    URI = "urn:guide:xdto-scalars85:" + UUIDОпыта;
    XSD = "<xs:schema xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:g=""urn:guide:xdto-scalars85:__UUID__"" targetNamespace=""urn:guide:xdto-scalars85:__UUID__"" elementFormDefault=""qualified"">
    |<xs:simpleType name=""Sku""><xs:restriction base=""xs:string""><xs:length value=""4""/><xs:pattern value=""[A-Z][0-9]{3}""/></xs:restriction></xs:simpleType>
    |<xs:simpleType name=""SkuList""><xs:list itemType=""g:Sku""/></xs:simpleType>
    |<xs:simpleType name=""QtyOrSku""><xs:union memberTypes=""xs:positiveInteger g:Sku""/></xs:simpleType>
    |<xs:complexType name=""Envelope""><xs:sequence><xs:any namespace=""##other"" processContents=""lax"" minOccurs=""0"" maxOccurs=""unbounded""/></xs:sequence><xs:attribute name=""code"" type=""g:Sku"" use=""required""/><xs:attribute name=""status"" type=""xs:string"" default=""draft""/><xs:anyAttribute namespace=""##other"" processContents=""lax""/></xs:complexType>
    |<xs:complexType name=""Closed""><xs:attribute name=""code"" type=""g:Sku"" use=""required""/></xs:complexType>
    |<xs:element name=""sku"" type=""g:Sku""/><xs:element name=""skuList"" type=""g:SkuList""/><xs:element name=""qtyOrSku"" type=""g:QtyOrSku""/><xs:element name=""envelope"" type=""g:Envelope""/><xs:element name=""closed"" type=""g:Closed""/>
    |</xs:schema>";
    XSD = СтрЗаменить(XSD, "__UUID__", UUIDОпыта);
    ЧтениеСхемы = Новый ЧтениеXML;
    ЧтениеСхемы.УстановитьСтроку(XSD);
    Попытка
        Дерево = Новый ПостроительDOM;
        ДокументСхемы = Дерево.Прочитать(ЧтениеСхемы);
    Исключение
        ОшибкаСхемы = ОписаниеОшибки();
        Попытка
            ЧтениеСхемы.Закрыть();
        Исключение
            ВызватьИсключение ОшибкаСхемы + Символы.ПС + "Закрытие XML: " + ОписаниеОшибки();
        КонецПопытки;
        ВызватьИсключение ОшибкаСхемы;
    КонецПопытки;
    ЧтениеСхемы.Закрыть();
    ПостроительСхем = Новый ПостроительСхемXML;
    Схема = ПостроительСхем.СоздатьСхемуXML(ДокументСхемы.ЭлементДокумента);
    Набор = Новый НаборСхемXML;
    Набор.Добавить(Схема);
    Если Набор.Количество() <> 1 Или Не Набор.Проверить() Тогда
        ВызватьИсключение "Не подтверждена единственная собственная схема без внешних ссылок";
    КонецЕсли;
    Фабрика = Новый ФабрикаXDTO(Набор);
    Для Каждого Имя Из СтрРазделить("Sku,SkuList,QtyOrSku,Envelope,Closed", ",") Цикл
        Если Фабрика.Тип(URI, Имя) = Неопределено Тогда
            ВызватьИсключение "Собственный тип схемы не создан: " + Имя;
        КонецЕсли;
    КонецЦикла;
    Возврат Новый Структура("UUIDОпыта,URI,XSD,ДокументСхемы,Схема,Набор,Фабрика",
        UUIDОпыта, URI, XSD, ДокументСхемы, Схема, Набор, Фабрика);
КонецФункции
Полный модуль собственной управляемой формы

Обработка УчебныеXDTO85: полный модуль собственной управляемой формы

Управляемая форма обработки УчебныеXDTO85: единственная команда и кнопка Выполнить; общий модуль только серверный.

&НаКлиенте
Процедура Выполнить(Команда)
    Результат = ВыполнитьНаСервере();
    Сообщить(Результат);
КонецПроцедуры

&НаСервереБезКонтекста
Функция ВыполнитьНаСервере()
    Возврат УчебныеXDTO85.ВыполнитьПример85();
КонецФункции

Разбор по шагам

  1. Подготавливаем свою схему с новым UUID. Затем вызываем именно безаргументный Новый ФабрикаXDTO(), не глобальную фабрику конфигурации.

  2. В default-фабрике поиск Sku свежего собственного namespace возвращает Неопределено; у отдельной схемной фабрики свой тип действительно есть.

  3. Получаем встроенный string и собственный Sku из одной схемной фабрики. XSD Sku ограничивает предка string, а значит соответствует native условию допуска Привести.

  4. Создаем настоящее ЗначениеXDTO типа string с A001 и проверяем исходный тип и лексему, а не передаем строку вместо typed значения.

  5. Выполняем Фабрика.Привести(ТипАртикула, Исходное) как вызов для проверки допуска. Установленная справка8.5.1.1343 не определяет тип возвращаемого значения; результат намеренно не присваивается и изменение исходного не обещается.

  6. Для последующей прикладной работы независимо создаем Sku через документированный Создать(ТипАртикула,"A001"). Это отдельное создание, не выданное за результат предыдущего Привести.

  7. Передаем реально созданную string bad в Привести к Sku: собственные length4/pattern требуют исключения. Если его нет, отчет об успехе запрещен.

  8. Повторный поиск своего типа в default-фабрике доказывает изоляцию: работа схемной фабрики не импортирует туда авторские пакеты. Никакого утверждения о произвольном числе встроенных пакетов нет.

Как проверить результат

  1. Конструктор default без аргументов; оба typed исходных значения получены той же фабрикой, что и целевой тип.

  2. Допуск A001 проверен без выдуманного возвращаемого типа/побочного изменения; bad должен вызвать отказ.

  3. Отдельный Артикул от Создать подтверждает реальный целевой тип и A001.

  4. Фабрика по умолчанию до/после не знает свежий UUID-тип; глобальные пакеты и база не меняются.

Ожидаемый результат

Будущий ручной отчет подтверждает изоляцию default-фабрики, допуск A001 и отказ bad. Получение Артикул показано отдельным native Создать, не присвоением неизвестного return Привести.

На что обратить внимание

  1. Отсутствие return-типа в справке не доказывает ни in-place mutation, ни конкретный возвращаемый объект. Код не делает ни того, ни другого предположения.

  2. Не передавайте ЗначениеXDTO другой фабрики или произвольный строковый параметр вместо настоящего typed значения. Здесь оба типа и исходные значения собственные.

Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.