SDO API: как заставить XSDHelper.INSTANCE правильно определять схемы XSD с <include>? - PullRequest
0 голосов
/ 09 июня 2018

Я столкнулся со следующей проблемой.Мы используем объекты служебных данных, поскольку наша целевая среда выполнения - IBM WebSphere, которая предполагает быть нативной для этого API.Стек, который мы используем, - это Java EE, Eclipse Oxygen в качестве основной IDE, эталонная реализация SDO в соответствии со спецификацией SDO 2.1.0, IBM WebSphere 9 и JRE8.

В соответствии с javadoc SDO существует define(java.io.InputStream xsdInputStream, java.lang.String schemaLocation) метод класса XSDHelper, который загружает требуемую схему XSD в среду выполнения WAS.Как только схема загружается, ее тип становится доступным для других операций, включая создание DataObject. Способ определения схем выглядит следующим образом:

InputStream is = new BOStorage().getInputStreamXSD("/test.xsd"); 
XSDHelper.INSTANCE.define(is, null);

Метод define() вызывается из конструктора EJB,test.xsd находится в папке src моего проекта eclipse.

src
| test.xsd
| test1.xsd
|
|___ejb.package.name

Теперь немного о самом test.xsd.Он ссылается на другие XSD того же targetNamespace с использованием тега <include>:

test.xsd:

...
<xsd:schema
    targetNamespace="http://ejb/package/name"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:bons0="http://ejb/package/name">
    <xsd:include schemaLocation="test1.xsd"></xsd:include>
    <xsd:include schemaLocation="test2.xsd"></xsd:include>
    <xsd:complexType name="TestSDO">
...
<xsd:element minOccurs="0" name="RefObject"
                type="bons0:RefObject">
            </xsd:element>
...

test1.xsd содержит complexType named RefObject, на который есть ссылка в test.xsd.

test1.xsd:

...
<xsd:complexType name="RefObject">

          <xsd:simpleContent>
            <xsd:extension base="xsd:string">
                <xsd:attribute name="type"/>
            </xsd:extension>
        </xsd:simpleContent>

  </xsd:complexType>
...

В качестве официальной спецификации SDO Java для версии 2.1.0 говорит:

9,7 XSD Mapping Details

...

Все <group> ссылки, <attributeGroup> ссылки, <include> s и <import> s полностью расширены до эквивалентного XSD, как если бы эти объявления не присутствовали.

...

Для моего видения это означает, что в моем случае реализация SDO должна:

  1. Load test.xsd;

  2. Выясняет, что он ссылается на test1.xsd в своем разделе <include>;

  3. Как test1.xsd, расположенный в той же папке src, что иtest.xsd, я ожидаю, что он будет неявно загружен в среде выполнения WebSphere.

Но при попытке создать объект DataObject типа RefObject возникает ошибка:

CWSDO0001E: Невозможно создать объект данных типа {http://ejb/package/name}RefObject, так как тип не найден

Я могу сделать следующие выводы: SDO APIне предназначен для работы таким образом, или мои XSD, или любые другие не подходят или содержат некоторые ошибки.

Любая помощь будет очень полезнаciated.

ОБНОВЛЕНИЕ: Работает так же, как и ожидалось в случае использования «глобального» XSD, который включает все ссылки в строке.Все, что я упоминал ранее, выполняется из EJB-компонента без сохранения состояния.

Пример кода, приводящего к ошибке:

        @Stateless(mappedName = "TestSDO")
        @Remote(TestSDORemote.class)
        @Local(TestSDOLocal.class)

        public class TestSDO implements TestSDORemote, TestSDOLocal{
            ...


        // default EJB constructor

     public TestSDO() {
           String textInfo = "";

            try {
                defineSDOTypes();
            } catch (Exception e) {
                LOGGER.log(Level.WARNING, "Could not define SDO types");
            }
        }
             ...
      private void defineSDOTypes() {
            HelperContext hc =   
            SDO.getHelperContextFactory().createHelperContext("ScopeManagerTestID", 
            null);
            XSDHelper xsdHelper = hc.getXSDHelper();
            try (InputStream is = new BOStorage().getInputStreamXSD("/test.xsd")) {          
                 xsdHelper.define(is, null);    
            } catch (IOException e) { 
              LOGGER.logp(Level.WARNING, CLASS_NAME, METHOD_NAME, "Unable to load the 
              schema: " + 
              "test.xsd" + ": " + e.getMessage());      
               e.printStackTrace();     
            }
             ...
      // creates the target Data Object (here comes the error)
      private void createBO(){
            DataObject dob = DataFactory.INSTANCE.create("http://ejb/package/name", 
            "RefObject");
        }
             ...

1 Ответ

0 голосов
/ 13 июня 2018

Глядя на репозиторий Tuscany SDO , кажется, что вы хотите сделать что-то вроде:

    URL url = getClass().getResource("/test.xsd");
    InputStream inputStream = url.openStream();
    xsdHelper.define(inputStream, url.toString());
    inputStream.close();

То есть вместо выполнения xsdHelper.define(is, null) я думаю, что вам нужно пройти взначение для второго параметра: schemaLocation , поскольку javadoc предлагает:

schemaLocation - URI местоположения схемы, используемой для обработки относительного импортаи включает.Может быть нулевым, если не используется.

...