IBM®
Перейти к тексту
    в России и странах СНГ [изменить]    Условия использования
 
 
   
    Главная страница    Продукты    Услуги и решения    Поддержка и загрузка    Мой профиль    
Перейти к тексту

developerWorks Россия  >  XML | Open source | Технология Java | Information Management | SOA и Web-сервисы  >

Основы создания mashup -- Web-сервисы и семантический Web : Часть 6. Дайте пользователю возможность управления

Применение семантических методик позволяет дать пользователям mashup-приложений возможность управлять сервисами, информацией и ее представлением

developerWorks
На предыдущую страницуСтраница 3 из 11 На предыдущую страницу

Опции документа

Обсудить

Исходные тексты примера


Выскажите мнение об этом учебном пособии

Помогите нам улучшить содержание


Корректировка структуры

В первую очередь нам нужно внести в структуру изменения, учитывающие новые функциональные возможности.

Добавление выходного типа

Сначала давайте рассмотрим некоторые вопросы, касающиеся онтологии. Сейчас в ней определены перечисленные ниже классы. В случае примера Bookstore сам сервис, который является подклассом класса Service, возвращает одну или несколько позиций StockItems. У класса StockItem определено несколько свойств, в частности, itemPrice и stockedProduct. Однако, другой тип сервиса, например, NewsService, может возвращать другие типы записей. Например, вместо StockItem сервис новостей может возвращать одну или несколько статей NewsStory. Поэтому для того, чтобы система функционировала должным образом, она должна знать, какие записи возвращает класс в ответ на вызов сервиса. Для этого мы определим для сервиса свойство outputType (см. листинг 3).


Листинг 3. Добавление outputType
                    
...
<owl:DatatypeProperty  rdf:ID="endpoint">
   <rdfs:domain rdf:resource="#Service"/>
   <rdfs:range 
      rdf:resource="http://www.w3.org/2001/XMLSchema#anyURI"/>
</owl:DatatypeProperty>

<owl:ObjectProperty  rdf:ID="outputType">
   <rdfs:domain rdf:resource="#Service"/>
   <rdfs:range rdf:resource="&owl;Class"/>
</owl:ObjectProperty>

<owl:ObjectProperty  rdf:ID="inputparameter">
   <rdfs:domain rdf:resource="#Service"/>
   <rdfs:range rdf:resource="#ServiceParameterMap"/>
</owl:ObjectProperty>
...

Обратите внимание, это значением этого свойства может быть любой Class. Например, в Bookstore значение этого свойства будет StockItem. Это одна из сложностей, например, использование классов в качестве значений и экземпляров, которая осложняет написание блоков рассуждений OWL.



В начало


Открытие доступа к свойству

Конечно же, чтобы использовать свойство outputType, необходимо иметь к нему доступ. Наиболее логичным местом для его размещения будет метод obtainServiceInfo() класса MashupOntologyReader, который считывает информацию в класс Service (см. листинг 4).


Листинг 4. Открытие доступа к свойству
                    
...
    public Service obtainServiceInfo(String serviceURI){
...
            if (p.canAs(OntProperty.class)){
                              
                Resource r;
                Literal l;
                if (p.getLocalName().equals("endpoint")){
                    l = s.getLiteral();
                    svc.baseURL=l.getString();
                    System.out.println( p.getLocalName() + " ==> " 
                                      + l.getString() );                    
                }
                else if (p.getLocalName().equals("outputType")){
                    l = s.getLiteral();
                    svc.recordExp=l.getString();
                    System.out.println( p.getLocalName() + " ==> " 
                                      + l.getString() ); 
                }
                else if (p.getLocalName().equals("rootoutputnode")){
                    l = s.getLiteral();
                    svc.recordExp=l.getString();
                    System.out.println( p.getLocalName() + " ==> " 
                                      + l.getString() );                    
                }
...

    public static void main(String[] args) {

      MashupOntologyReader reader = new MashupOntologyReader();
      reader.obtainServiceInfo(
                        "http://example.com/store#Amazon.com");
    }

}

В этом случае (см. листинг 4), мы просто обрабатываем свойство outputType так же, как и любые другие строковые свойства, получая к ним доступ посредством Literal для содержащего его оператора.

Результат работы метода obtainServiceInfo() можно увидеть в листинге 5.


Листинг 5. Запуск obtainServiceInfo() method
                    
rootoutputnode ==> //Book
xsltTransformationString ==> 
            <xsl:stylesheet version="1.0" xmlns="" ...>
...
            </xsl:stylesheet>
Service ==> AWSECommerceService
AWSAccessKeyId ==> 000000000000000
template ==>  <p><a value='href'><value/></a> 
by <value/></p> 
endpoint ==> http://localhost/xml.xml
outputType ==> http://example.com/store#StockItem
elementValue ==> Author!itemDescription
attributeValue ==> itemDetailURL
SearchIndex ==> Books
queryParameter ==> Title
Operation ==> ItemSearch



В начало


Перечисление всех свойств

Нам нужно дополнить все остальные функции MashupOntologyReader. Например, в некоторый момент вам понадобиться получить список всех свойств класса, в частности, класса, представленного outputType. Для этого нам нужно создать новый метод (см. листинг 6).


Листинг 6. Метод showAllProperties()
...
import com.hp.hpl.jena.util.iterator.*; 
import com.hp.hpl.jena.ontology.*;

public class MashupOntologyReader {

    private OntModel serviceOntModel;
       
    public OntModel getOnt(){
       return serviceOntModel;
    }

    public MashupOntologyReader(){
...
    }

 
    public void showAllProperties(OntClass theClass){
       
        String thisClassURI = theClass.getURI();
       
        for (ExtendedIterator i = theClass.listDeclaredProperties(); 
             i.hasNext(); ) {

            OntProperty thisProp = (OntProperty)i.next();
            System.out.println("Property (raw): "
                        +thisProp.getLocalName());
         }   
    }
    
   
    public static void main(String[] args) {

       MashupOntologyReader reader = new MashupOntologyReader();
       reader.showAllProperties(reader.getOnt().getOntClass(
                             "http://example.com/store#StockItem"));
   
    }

}

В листинге 6, в методе main(), мы вызываем новую функцию, однако обратите внимание, что для того, чтобы получить новые свойства класса, нам нужна ссылка на сам класс. Для этого нам нужна ссылка на саму модель онтологии, а не просто на объект MashupOntologyReader, поэтому мы также создаем метод для получения ссылки на модель. После этого мы можем получить ссылку на класс из его URI. В данном случае мы ищем свойства класса StockItem.

Для фактического получения свойств используется метод listProperties(), который возвращает ExtendedIterator. После этого мы можем последовательно пройти по свойствам, в этом случае извлекая localName.

Вы должны получить результат, похожий на представленный в листинге 7.


Листинг 7. Свойства класса StockItem
Property (raw): writerOf
Property (raw): itemDescription
Property (raw): itemDetailURL
Property (raw): authorOf
Property (raw): stockedProduct
Property (raw): itemPrice

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



В начало


Улучшения

Хотя представленная выше информация очень полезна, это не совсем то, что мы хотели бы показывать пользователю. К счастью, RDF позволяет нам добавить метку к каждому классу и свойству. Все, что нам нужно сделать - это вывести эту метку, а не просто «сырой» результат localName (см. листинг 8).


Листинг 8. Использование метки вместо localName
...
    public void showAllProperties(OntClass theClass){
       
        String thisClassURI = theClass.getURI();
       
        for (ExtendedIterator i = theClass.listDeclaredProperties(); 
             i.hasNext(); ) {

            OntProperty thisProp = (OntProperty)i.next();
            Property labelProp = 
                  (Property)serviceOntModel.getProperty(
                      "http://www.w3.org/2000/01/rdf-schema#label");
            if (thisProp.hasProperty(labelProp)){
               System.out.println("Property: "
                   +thisProp.getProperty(labelProp).getLiteral()
                   //+thisProp.getLabel(null)
                   );
            } else {
               System.out.println("Property (raw): "
                        +thisProp.getLocalName());
            }
         }   
    }
...

Результат применения нового подхода можно видеть в листинге 8. Для запроса определенного объекта свойства мы используем метод getProperty(), после чего проверяем, есть ли данное свойство у каждого из свойств. (Да, у свойств тоже могут быть свойства!) Если это так, мы выводим label, в противном случае выводим localName. Обратите внимание, что метод getLabel() позволяет выбирать метки в зависимости от языка.

Теперь результат должен быть похож на приведенный в листинег 9.


Листинг 9. Использование меток
                    
Property (raw): writerOf
Property: Item Description
Property: Item Detail Page URL
Property (raw): authorOf
Property: Stocked Product
Property: Item Price

У некоторых свойств нет меток, потому что они не предназначены для их отображения пользователям.



В начало


Ограничение вывода свойств по типу данных

В реальном приложении вам придется выводить свойства не только одного объекта, но и всех свойств, которые у него есть. Например, в этом случае мы создали позицию StockItem, у которой есть свойства продукта, который она представляет. В реальном приложении вам, вероятно, придется выводить автора книги, которую представляет собой продукт, и так далее. Как бы то ни было, для того, чтобы сделать это, нам нужно выполнить рекурсивный вызов метода showAllProperties().

Само по себе это не является проблемой, однако, как будет видно в данном случае, это создает некоторые сложности. Причина такова: у вашей StockItem есть в качестве свойства значение Product, в данном случае Book. У Book в качестве свойства есть writtenBy, который является объектом Author. У объекта Author в качестве свойства выступают все книги (Book), написанные этим автором, что приводит к тому, что мы возвращаемся к объекту Author, что снова приводит нас к Books и так далее.

Эту ситуацию можно разрешить, но мы, чтобы упростить пример, ограничимся значениями DatatypeProperty. К счастью, указать разницу между DatatypeProperty и ObjectProperty очень просто (см. листинг 10).


Листинг 10. Ограничение по DatatypeProperties
...
    public void showAllProperties(OntClass theClass){
       
        String thisClassURI = theClass.getURI();
       
        for (ExtendedIterator i = theClass.listDeclaredProperties(); 
             i.hasNext(); ) {

           OntProperty thisProp = (OntProperty)i.next();
            if (thisProp.isObjectProperty()){
                //System.out.println("This is an object property.");
            } else {
               Property labelProp = 
                     (Property)serviceOntModel.getProperty(
                         "http://www.w3.org/2000/01/rdf-schema#label");
               if (thisProp.hasProperty(labelProp)){
                  System.out.println("Property: "
                      +thisProp.getProperty(labelProp).getLiteral()
                      //+thisProp.getLabel(null)
                      );
               } else {
                  System.out.println("Property (raw): "
                        +thisProp.getLocalName());
               }
            }
         }   
    }
...

Внеся это изменение, вы увидите результат, похожий на представленный в листинге 11).


Листинг 11. Результат
                    
Property: Item Description
Property: Item Detail Page URL
Property: Item Price



В начало



На предыдущую страницуСтраница 3 из 11 На предыдущую страницу

    IBM в России Конфиденциальность Контакты