miércoles, 8 de febrero de 2012

Tutorial Servicios Web Semanticos

Tutorial

En este tutorial aprenderemos como hacer un servicio web compuesto que recomienda robots para una determinada tarea, y a marcarlo semánticamente

Herramientas:



Nuestro primer paso será crear la Ontología que representa a los robots. Algunos de los conceptos básicos de una Ontología son las clases, las instancias y las propiedades, estas ultimas se dividen en propiedades de objetos y propiedades de datos; si tratamos de relacionar estos conceptos con el mundo de la programación orientada a objetos podemos ver las clases de una Ontología como clases de la programación, las propiedades de objetos como atributos que son punteros a otros objetos, las propiedades de datos como atributos de tipos de datos primitivos (String, int, float, etc.) y las instancias como instancias de una clase (Objetos)

Abrimos Protégé y creamos un nuevo proyecto tipo OWL / RDF Files


Luego nos pedirá una URI que será la dirección donde estará almacenada la Ontología, en este caso la guardaremos en glassfish por lo que la dirección será localhost


Luego nos pedirá seleccionar un lenguaje, seleccionaremos OWL DL y luego le damos finish

En la pestaña OWL Classes creamos las clases, en OWL toda clase extiende de la clase Thing, los botones encerrados en el recuadro rojo de la imagen siguiente son en orden de izquierda a derecha: Crear una nueva subclase (Una clase que hereda de la clase que se encuentre seleccionada), crear clase hermana (Una clase que esta en el mismo nivel de jerarquía que la que esté seleccionada) y borrar clase


Así creamos diferentes clases que extienden de Robot: Androide, Zoomorfico, Poliarticulado, Movil e Hibrido; y una clase Dispositivo de la cual extienden: Comunicación, Energía, Extremidades, Motor, Sensor y Transporte, de cada una de ellas podemos crear mas subclases y así sucesivamente hasta crear una Ontología bien definida, para ver el funcionamiento del sistema de recomendación y la creación de los servicios web es suficiente con llegar hasta el nivel de jerarquía que se muestra en la imagen


Notemos que un Robot Híbrido puede ser cualquier combinación de los demás robots, por lo cual podemos modelar este hecho de tal forma que Híbrido extienda de todas sus clases hermanas, para esto diremos que tiene como superclases a Androide, Zoomorfico, Robot, Movil y Poliarticulado, nos aseguramos de cambiar a la vista de Propiedades (recuadro azul) y damos clic en agregar una clase (recuadro rojo) y luego seleccionamos toda las clases mencionadas anteriormente


Luego procederemos a crear las propiedades, a la clase robot le adicionaremos una propiedad de objeto llamada "dispositivos" y podrá contener todas las instancias de la clase dispositivos que tiene un robot. Como las clases Zoomorfico, Androide, etc. heredan de la clase Robot, también heredan sus propiedades, así que cualquier robot tendrá dispositivos. En el campo de Propiedades y Restricciones agregaremos una nueva propiedad de Objeto (recuadro rojo); notemos que para esta propiedad el dominio es la clase Robot y el rango es la clase Dispositivo.


En una Ontología podemos crear condiciones y restricciones, por ejemplo, podemos asumir que un robot dentro de sus dispositivos tiene que tener al menos uno de Energía, uno de Comunicación y un Motor. Para crear esta restricción seleccionamos la clase Robot y nos aseguramos de tener activada la vista lógica (recuadro azul), luego damos clic en el botón crear nueva restricción (recuadro rojo), seleccionamos la propiedad sobre la cual haremos la restriccion, en ese caso dispositivos, luego el tipo de restricciones, en este caso "SomeValuesFrom" y en el campo Filler tenemos varias herramientas para crear una expresión lógica, seleccionaremos el botón "Insert class" (recuadro verde) y seleccionamos la clase Comunicación:


Luego en el campo Filler presionamos el botón "and" (recuadro rojo) y luego insertamos una nueva clase, hasta crear la expresion que se muestra en la imagen


Así logramos crear una expresión lógica que obliga a que un Robot tenga al menos una fuente de Energía, un dispositivo de Comunicación y un Motor. Así podemos crear una serie de restricciones en cada uno de los subniveles de la jerarquía. Por ejemplo, podemos decir que un robot Móvil tiene que tener un GPS y un dispositivo de Transporte, además de la restricción heredada de la clase Robot, por lo que se vería algo como:


Crearemos propiedades de datos para cada uno de los dispositivos, vamos a la clase Wifi y creamos una nueva propiedad de datos (recuadro rojo), la cual llamaremos distancia, su rango es int (recuadro azul) y marcaremos la opción Functional (recuadro verde) la cual significa que esta propiedad podrá tener un único valor


Así crearemos una propiedad para cada uno de los dispositivos que indique alguna medición representable como un tipo de dato numérico.
Una vez terminada nuestra Ontología, guardamos el proyecto en File -> Save Project, seleccionaremos la ruta para guardar el proyecto (.pprj) y la Ontología (.owl)


Luego montaremos el archivo .owl al servidor de Glassfish, generalmente la carpeta del servidor es Carpeta del usuario -> .netbeans -> version -> config -> GF3 -> domain1 -> docroot . Allí crearemos una carpeta llamada Ontologías y pegaremos el archivo Robot.owl. 

Ahora crearemos un archivo wsdl en NotePad++ por cada uno de los tres servicios atómicos. Estos se dividirán así:
  • El primer servicio recibe un Array de Dispositivos y devuelve un objeto de la clase Paquete, el cual tiene dos atributos: Un Array de Robots y un array de Dispositivos, será el encargado de consultar en las Ontologías cuales instancias de la clase Robot tienen los dispositivos requeridos y devolverá dicha lista, notemos que no importa si la distancia del Wifi de un Robot A es 50m y dentro de mis requisitos está un Wifi de 80m, este servicio solo obtiene los robots que tengan los dispositivos sin importar sus propiedades de datos. El Paquete devuelto tiene como atributos el Array de robots obtenidos y el Array de dispositivos requeridos, los mismos que se ingresaron como parametro de entrada.
  • El segundo servicio recibirá una clase Paquete y devolverá una clase paquete. Este servicio será el encargado de eliminar los demás dispositivos que no nos interesan para poder aplicar el algoritmo de la correlación de Pearson en el tercer servicio, ya que este necesita que los objetos a comparar tengan las mismas características en común, es decir, si requerimos un robot con Wifi, Brazo y un Motor y encontramos un Robot con Wifi, Motor, Brazo y Bluetooth debemos ocultar el ultimo dispositivo para trabajar con los que son necesarios. Así que este servicio eliminará los dispositivos que no son necesarios.
  • El tercer servicio recibirá un Paquete y devolverá un Array de Robots, Aplicará la correlación de Pearson comparando cada robot con los valores de los dispositivos dados y luego los ordenará, dando así lugar a un Array con los robots que cumplen las caracteristicas solicitadas ordenados de forma tal que el primero es el que mas se parece al requerido.
Un buen tutorial sobre wsdl y servicios web es: http://www.ibm.com/developerworks/ssa/webservices/tutorials/ws-understand-web-services2/index.html

Aqui tenemos el .wsdl y el .xsd del primer servicio

DepuracionService.wsdl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions
    name="DepuracionService"
    targetNamespace="http://localhost:8080/Depuracion/DepuracionService"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:tns="http://localhost:8080/Depuracion/DepuracionService"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <wsdl:types>
        <xsd:schema>
  <xsd:import namespace="http://localhost:8080/Depuracion/DepuracionService"
  schemaLocation="DepuracionServiceXSD.xsd"/>
 </xsd:schema>
    </wsdl:types>
    <wsdl:message name="DispositivosMessage">
        <wsdl:part element="tns:ArrayDispositivos" name="DispositivosPart"/>
    </wsdl:message>
    <wsdl:message name="PaqueteMessage">
        <wsdl:part element="tns:Paquete" name="PaquetePart"/>
    </wsdl:message>
    <wsdl:portType name="DepuracionServicePortType">
        <wsdl:operation name="DepuracionServiceOperation">
            <wsdl:input message="tns:DispositivosMessage"/>
            <wsdl:output message="tns:PaqueteMessage"/>
        </wsdl:operation>
    </wsdl:portType>
    <wsdl:binding name="DepuracionServicePortBinding" 
 type="tns:DepuracionServicePortType">
        <soap:binding style="document" 
  transport="http://schemas.xmlsoap.org/soap/http"/>
        <wsdl:operation name="DepuracionServiceOperation">
            <soap:operation soapAction=""/>
            <wsdl:input>
                <soap:body use="literal"/>
            </wsdl:input>
            <wsdl:output>
                <soap:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>
 </wsdl:binding> 
    <wsdl:service name="DepuracionService">
        <wsdl:port binding="tns:DepuracionServicePortBinding" 
  name="DepuracionServicePort">
            <soap:address 
   location="http://localhost:8080/Depuracion/DepuracionService"/>
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>
DepuracionServiceXSD.xsd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<xs:schema version="1.0" 
targetNamespace="http://localhost:8080/Depuracion/DepuracionService" 
xmlns:tns="http://localhost:8080/Depuracion/DepuracionService" 
xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="DispositivoType">
 <xs:complexType>
  <xs:sequence>
   <xs:element name="nombreDispositivo" type="xs:string"/>
   <xs:element name="valorDispositivo" type="xs:int"/>  
  </xs:sequence>
 </xs:complexType>
</xs:element>
  
<xs:element name="RobotsType">
 <xs:complexType>
  <xs:sequence>
   <xs:element name="nombre" type="xs:string"/>
   <xs:element ref="tns:ArrayDispositivos"/>
  </xs:sequence>
 </xs:complexType>
</xs:element>
  
<xs:element name="ArrayDispositivos">
  <xs:complexType>
    <xs:sequence minOccurs="0" maxOccurs="unbounded"> 
  <xs:element ref="tns:DispositivoType"/>
 </xs:sequence>
  </xs:complexType>
</xs:element>

<xs:element name="ArrayRobots">
  <xs:complexType>
    <xs:sequence minOccurs="0" maxOccurs="unbounded"> 
  <xs:element ref="tns:RobotsType"/>
 </xs:sequence>
  </xs:complexType>
</xs:element>

<xs:element name="Paquete">
 <xs:complexType> 
  <xs:sequence>
   <xs:element ref="tns:ArrayDispositivos"/>
   <xs:element ref="tns:ArrayRobots"/>
  </xs:sequence>
 </xs:complexType>
</xs:element>

</xs:schema>


Aqui tenemos el .wsdl y el .xsd del segundo servicio

ModificarCaracteristicasService.wsdl


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<wsdl:definitions
    name="ModificarCaracteristicasService"
    targetNamespace="http://localhost:8080/ModificarCaracteristicas
 /ModificarCaracteristicasService"
 xmlns="http://schemas.xmlsoap.org/wsdl/"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:tns="http://localhost:8080/ModificarCaracteristicas
 /ModificarCaracteristicasService"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata">
    <wsdl:types>
        <xsd:schema>
  <xsd:import namespace="http://localhost:8080/ModificarCaracteristicas
  /ModificarCaracteristicasService" 
  schemaLocation="ModificarCaracteristicasServiceXSD.xsd"/>
 </xsd:schema>
    </wsdl:types>
    <wsdl:message name="PaqueteInputMessage">
        <wsdl:part element="tns:Paquete" name="PaqueteInputPart"/>
    </wsdl:message>
    <wsdl:message name="PaqueteOutputMessage">
        <wsdl:part element="tns:Paquete" name="PaqueteOutputPart"/>
    </wsdl:message>
    <wsdl:portType name="ModificarCaracteristicasServicePortType">
        <wsdl:operation name="ModificarCaracteristicasServiceOperation">
            <wsdl:input message="tns:PaqueteInputMessage"/>
   <wsdl:output message="tns:PaqueteOutputMessage"/>
        </wsdl:operation>
    </wsdl:portType>
    <wsdl:binding name="ModificarCaracteristicasServicePortBinding" 
 type="tns:ModificarCaracteristicasServicePortType">
        <soap:binding style="document" 
  transport="http://schemas.xmlsoap.org/soap/http"/>
        <wsdl:operation name="ModificarCaracteristicasServiceOperation">
            <soap:operation soapAction=""/>
            <wsdl:input>
                <soap:body use="literal"/>
            </wsdl:input>
            <wsdl:output>
                <soap:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>
 </wsdl:binding> 
    <wsdl:service name="ModificarCaracteristicasService">
        <wsdl:port binding="tns:ModificarCaracteristicasServicePortBinding" 
  name="ModificarCaracteristicasServicePort">
            <soap:address 
   location="http://localhost:8080/ModificarCaracteristicas
   /ModificarCaracteristicasService"/>
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>

ModificarCaracteristicasServiceXSD.xsd


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<xs:schema version="1.0" 
targetNamespace="http://localhost:8080/ModificarCaracteristicas
/ModificarCaracteristicasService" 
xmlns:tns="http://localhost:8080/ModificarCaracteristicas
/ModificarCaracteristicasService" 
xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="DispositivoType">
 <xs:complexType>
  <xs:sequence>
   <xs:element name="nombreDispositivo" type="xs:string"/>
   <xs:element name="valorDispositivo" type="xs:int"/>  
  </xs:sequence>
 </xs:complexType>
</xs:element>
  
<xs:element name="RobotsType">
 <xs:complexType>
  <xs:sequence>
   <xs:element name="nombre" type="xs:string"/>
   <xs:element ref="tns:ArrayDispositivos"/>
  </xs:sequence>
 </xs:complexType>
</xs:element>
  
<xs:element name="ArrayDispositivos">
  <xs:complexType>
    <xs:sequence minOccurs="0" maxOccurs="unbounded"> 
  <xs:element ref="tns:DispositivoType"/>
 </xs:sequence>
  </xs:complexType>
</xs:element>

<xs:element name="ArrayRobots">
  <xs:complexType>
    <xs:sequence minOccurs="0" maxOccurs="unbounded"> 
  <xs:element ref="tns:RobotsType"/>
 </xs:sequence>
  </xs:complexType>
</xs:element>

<xs:element name="Paquete">
 <xs:complexType>
  <xs:sequence> 
   <xs:element ref="tns:ArrayDispositivos"/>
   <xs:element ref="tns:ArrayRobots"/>
  </xs:sequence>
 </xs:complexType>
</xs:element>

</xs:schema>

Aqui tenemos el .wsdl y el .xsd del tercer servicio

MejorRobot.wsl


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<wsdl:definitions
    name="MejorRobotService"
    targetNamespace="http://localhost:8080/MejorRobot/MejorRobotService"
 xmlns="http://schemas.xmlsoap.org/wsdl/"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:tns="http://localhost:8080/MejorRobot/MejorRobotService"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata">
    <wsdl:types>
        <xsd:schema>
   <xsd:import namespace="http://localhost:8080/MejorRobot/MejorRobotService" 
   schemaLocation="MejorRobotXSD.xsd"/>
  </xsd:schema>
    </wsdl:types>
    <wsdl:message name="PaqueteMessage">
        <wsdl:part element="tns:Paquete" name="PaquetePart"/>
    </wsdl:message>
    <wsdl:message name="MejorRobotMessage">
        <wsdl:part element="tns:ArrayRobots" name="MejorRobotPart"/>
    </wsdl:message>
    <wsdl:portType name="MejorRobotPortType">
        <wsdl:operation name="MejorRobotOperation">
            <wsdl:input message="tns:PaqueteMessage"/>
   <wsdl:output message="tns:MejorRobotMessage"/>
        </wsdl:operation>
    </wsdl:portType>
    <wsdl:binding name="MejorRobotPortBinding" type="tns:MejorRobotPortType">
        <soap:binding style="document" 
  transport="http://schemas.xmlsoap.org/soap/http"/>
        <wsdl:operation name="MejorRobotOperation">
            <soap:operation soapAction=""/>
            <wsdl:input>
                <soap:body use="literal"/>
            </wsdl:input>
            <wsdl:output>
                <soap:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>
 </wsdl:binding> 
    <wsdl:service name="MejorRobotService">
        <wsdl:port binding="tns:MejorRobotPortBinding" name="MejorRobotPort">
            <soap:address 
   location="http://localhost:8080/MejorRobot/MejorRobotService"/>
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>



MejorRobotXSD.xsd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<xs:schema version="1.0" 
targetNamespace="http://localhost:8080/MejorRobot/MejorRobotService" 
xmlns:tns="http://localhost:8080/MejorRobot/MejorRobotService" 
xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="DispositivoType">
 <xs:complexType>
  <xs:sequence>
   <xs:element name="nombreDispositivo" type="xs:string"/>
   <xs:element name="valorDispositivo" type="xs:int"/>  
  </xs:sequence>
 </xs:complexType>
</xs:element>
  
<xs:element name="RobotsType">
 <xs:complexType>
  <xs:sequence>
   <xs:element name="nombre" type="xs:string"/>
   <xs:element ref="tns:ArrayDispositivos"/>
  </xs:sequence>
 </xs:complexType>
</xs:element>
  
<xs:element name="ArrayDispositivos">
  <xs:complexType>
    <xs:sequence minOccurs="0" maxOccurs="unbounded"> 
  <xs:element ref="tns:DispositivoType"/>
 </xs:sequence>
  </xs:complexType>
</xs:element>

<xs:element name="ArrayRobots">
  <xs:complexType>
    <xs:sequence minOccurs="0" maxOccurs="unbounded"> 
  <xs:element ref="tns:RobotsType"/>
 </xs:sequence>
  </xs:complexType>
</xs:element>

<xs:element name="Paquete">
 <xs:complexType>
  <xs:sequence> 
   <xs:element ref="tns:ArrayDispositivos"/>
   <xs:element ref="tns:ArrayRobots"/>
  </xs:sequence>
 </xs:complexType>
</xs:element>

</xs:schema>

Ahora crearemos en Netbeans tres proyectos diferentes para cada uno de los proyectos, el poryecto debe ser tipo Java Web -> Web Application


El proyecto lo llamaremos "Depuracion", Luego en el proyecto crearemos un nuevo servicio a partir del WSDL, para ellos vamos a file -> new File, seleccionamos Web Services y luego Web Service from WSDL


Llamaremos al servicio "DepuracionService", seleccionamos un paquete donde se crearán las clases definidas en el .xsd y la direccion del wsdl



Creamos un nuevo paquete llamado "clases" y una clase llamada Main, la cual tendrá el siguiente código:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package clases;

import com.hp.hpl.jena.ontology.DatatypeProperty;
import com.hp.hpl.jena.ontology.Individual;
import com.hp.hpl.jena.ontology.ObjectProperty;
import com.hp.hpl.jena.ontology.OntClass;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.util.iterator.ExtendedIterator;
import java.util.ArrayList;
import java.util.List;
import localhost._8080.depuracion.depuracionservice.ArrayDispositivos;
import localhost._8080.depuracion.depuracionservice.ArrayRobots;
import localhost._8080.depuracion.depuracionservice.DispositivoType;
import localhost._8080.depuracion.depuracionservice.Paquete;
import localhost._8080.depuracion.depuracionservice.RobotsType;

public class Main {

    private static final String NS = 
            "http://localhost:8080/Ontologias/robot.owl#";
    private static final String ruta = 
            "http://localhost:8080/Ontologias/robot.owl#";
    private OntModel model;

    public Main() {
        model = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, null);
        model.read(ruta, "RDF/XML");
    }

    private static boolean estanTodos(List<DispositivoType> req, 
            List<Statement> prop) {
        for (int i = 0; i < req.size(); i++) {
            boolean esta = false;
            for (int j = 0; j < prop.size(); j++) {
                if (req.get(i).getNombreDispositivo().equals(
                        getTipoDisp(prop.get(j).getObject().asResource()))) {
                    esta = true;
                    break;
                }
            }
            if (esta == false) {
                return false;
            }
        }
        return true;
    }
    
    private static String getTipoDisp(Resource r) {
        return r.getPropertyResourceValue(null).getLocalName();
    }

    private List<DispositivoType> toDispositivos(List<Statement> propiedades) {
        List<DispositivoType> disp = new ArrayList<DispositivoType>();
        for (int i = 0; i < propiedades.size() - 1; i++) {
            Resource objeto = propiedades.get(i).getObject().asResource();
            List<Statement> prop = objeto.listProperties().toList();
            for (int j = 0; j < prop.size() - 1; j++) {
                if (!prop.get(j).getPredicate().getLocalName().
                        equals("nombre")) {
                    DispositivoType d = new DispositivoType();
                    d.setNombreDispositivo(getTipoDisp(objeto));
                    d.setValorDispositivo(prop.get(j).getLiteral().getInt());
                    disp.add(d);
                }
            }
        }
        return disp;
    }

    public Paquete ejecutar(ArrayDispositivos aDisp) {
        List<DispositivoType> dispReq = aDisp.getDispositivoType();
        Paquete paq = new Paquete();
        OntClass claseRaiz = model.getOntClass(NS + "Robot");
        List<RobotsType> robots = new ArrayList<RobotsType>();
        for (ExtendedIterator<OntClass> i = claseRaiz.listSubClasses(); 
                i.hasNext();) {
            OntClass clase = i.next();
            List<Individual> objetos = model.listIndividuals(clase).toList();
            for (int j = 0; j < objetos.size(); j++) {
                Individual robot = objetos.get(j);
                List<Statement> propiedades = robot.listProperties().toList();
                if (estanTodos(dispReq, propiedades)) {
                    RobotsType r = new RobotsType();
                    r.setNombre(robot.getLocalName());
                    ArrayDispositivos dd = new ArrayDispositivos();
                    dd.getDispositivoType().addAll(toDispositivos(propiedades));
                    r.setArrayDispositivos(dd);
                    robots.add(r);
                }
            }
        }
        paq.setArrayDispositivos(aDisp);
        ArrayRobots aRob = new ArrayRobots();
        aRob.getRobotsType().addAll(robots);
        paq.setArrayRobots(aRob);
        return paq;
    }}


Jena es una API que nos permite extraer la información de una Ontología y utilizarla en Java.
Un tutorial sobre Jena se encuentra en: http://jena.sourceforge.net/ontology/index.html

Básicamente lo que hacemos es obtener la clase raíz de la Ontología, en este caso la clase Robot, se recorre las subclases y se obtienen las instancias de cada una de estas, luego podemos proceder a obtener las propiedades que cada instancia tiene y así comparar cada Robot con las condiciones dadas obteniendo los que cumplan con los requerimientos necesarios.
Este proyecto requiere importar la librería de Jena, por lo cual creamos una libreria en netbeans y agregamos todos los .jar que se encuentran en la carpeta lib del archivo descargado de Jena.



El código de la clase DepuracionService.java quedaría como sigue:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package services;

import clases.Main;
import javax.jws.WebService;

@WebService(serviceName = "DepuracionService", 
        portName = "DepuracionServicePort", 
        endpointInterface = "localhost._8080.depuracion.depuracionservice."
        + "DepuracionServicePortType", 
        targetNamespace = "http://localhost:8080/Depuracion/DepuracionService", 
        wsdlLocation = "WEB-INF/wsdl/DepuracionService/DepuracionService.wsdl")
public class DepuracionService {

    public localhost._8080.depuracion.depuracionservice.Paquete 
            depuracionServiceOperation(localhost._8080.depuracion.
                    depuracionservice.ArrayDispositivos dispositivosPart) {
        return new Main().ejecutar(dispositivosPart);
    }}


Similarmente crearemos otros dos proyectos, el segundo servicio llamado "ModificarCaracteristicas" y un servicio llamada "ModificarCaracteristicasService", el código de la clase Main.java y ModificarCaracteristicasService.java de se muestran a continuación


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package clases;

import java.util.ArrayList;
import java.util.List;
import localhost._8080.modificarcaracteristicas.
        modificarcaracteristicasservice.*;

public class Main {

    public static Paquete depurar(Paquete paquete) {
        List<RobotsType> robots = paquete.getArrayRobots().getRobotsType();
        List<DispositivoType> disps = paquete.getArrayDispositivos().
                getDispositivoType();
        for (int i = 0; i < robots.size(); i++) {
            RobotsType robot = robots.get(i);
            List<DispositivoType> dispR = robot.getArrayDispositivos().
                    getDispositivoType();
            List<DispositivoType> dispN = new ArrayList<DispositivoType>();
            for (int j = 0; j < disps.size(); j++) {
                for (int k = 0; k < dispR.size(); k++) {
                    if (dispR.get(k).getNombreDispositivo().equals(disps.get(j).
                            getNombreDispositivo())) {
                        dispN.add(dispR.get(k));
                        break;
                    }
                }
            }
            dispR.clear();
            dispR.addAll(dispN);
        }
        return paquete;
    }}




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package services;

import clases.Main;
import javax.jws.WebService;

@WebService(serviceName = "ModificarCaracteristicasService", 
        portName = "ModificarCaracteristicasServicePort", 
        endpointInterface = "localhost._8080.modificarcaracteristicas.modifi"
        + "carcaracteristicasservice.ModificarCaracteristicasServicePortType", 
        targetNamespace = "http://localhost:8080/ModificarCaracteristicas"
        + "/ModificarCaracteristicasService", 
        wsdlLocation = "WEB-INF/wsdl/ModificarCaracteristicasService"
        + "/ModificarCaracteristicasService.wsdl")
public class ModificarCaracteristicasService {

    public localhost._8080.modificarcaracteristicas.
            modificarcaracteristicasservice.Paquete 
            modificarCaracteristicasServiceOperation(localhost._8080.
                    modificarcaracteristicas.modificarcaracteristicasservice.
                    Paquete paqueteInputPart) {
        return Main.depurar(paqueteInputPart);
    }
    }



El tercer servicio lo llamamos "MejorRobot", a continuacion el codigo de la clase Main.java y de MejorRobotService.java


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package clases;

import java.util.ArrayList;
import localhost._8080.mejorrobot.mejorrobotservice.Paquete;
import localhost._8080.mejorrobot.mejorrobotservice.RobotsType;
import java.util.List;
import localhost._8080.mejorrobot.mejorrobotservice.ArrayDispositivos;
import localhost._8080.mejorrobot.mejorrobotservice.ArrayRobots;
import localhost._8080.mejorrobot.mejorrobotservice.DispositivoType;

public class Main {

    private Paquete paquete;

    public Main(Paquete paquete) {
        this.paquete = paquete;
    }

    private double pearson(RobotsType robot, List<DispositivoType> disps) {
        List<DispositivoType> dispRobot = robot.getArrayDispositivos().
                getDispositivoType();
        int n = disps.size();
        double sumX = 0, sumY = 0, sumXY = 0, sumX2 = 0, sumY2 = 0,
                xA = 0, yA = 0;
        for (int i = 0; i < n; i++) {
            xA = dispRobot.get(i).getValorDispositivo();
            yA = disps.get(i).getValorDispositivo();
            sumX += xA;
            sumY += yA;
            sumXY += xA * yA;
            sumX2 += xA * xA;
            sumY2 += yA * yA;
        }
        return (n * sumXY - sumX * sumY) / ((Math.sqrt(n * sumX2 - sumX * sumX))
                * Math.sqrt(n * sumY2 - sumY * sumY));
    }

    public ArrayRobots getPearson() {
        List<RobotsType> robots = paquete.getArrayRobots().getRobotsType();
        List<DispositivoType> disp = paquete.getArrayDispositivos()
                .getDispositivoType();
        List<RobotPearson> robotsPer = new ArrayList<RobotPearson>();
        for (int i = 0; i < robots.size(); i++) {
            robotsPer.add(new RobotPearson(robots.get(i),
                    pearson(robots.get(i), disp)));
        }
        ordenarArray(robotsPer);
        ArrayRobots array = new ArrayRobots();
        List<RobotsType> robotsO = new ArrayList<RobotsType>();
        for (int i = 0; i < robotsPer.size(); i++) {
            robotsO.add(robotsPer.get(i).getRobot());
        }
        array.getRobotsType().addAll(robotsO);
        return array;
    }

    private void ordenarArray(List<RobotPearson> robots) {
        for (int i = 0; i < robots.size(); i++) {
            for (int j = i; j < robots.size(); j++) {
                if (robots.get(i).getPearson() < robots.get(j).getPearson()) {
                    RobotPearson aux = robots.get(i);
                    robots.set(i, robots.get(j));
                    robots.set(j, aux);
                }
            }
        }
    }}

class RobotPearson {

    private RobotsType robot;
    private double pearson;

    public RobotPearson(RobotsType robot, double pearson) {
        this.robot = robot;
        this.pearson = pearson;
    }

    public RobotsType getRobot() {
        return robot;
    }

    public void setRobot(RobotsType robot) {
        this.robot = robot;
    }

    public double getPearson() {
        return pearson;
    }

    public void setPearson(double pearson) {
        this.pearson = pearson;
    }}




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package services;

import clases.Main;
import javax.jws.WebService;

@WebService(serviceName = "MejorRobotService",
        portName = "MejorRobotPort", 
        endpointInterface = "localhost._8080.mejorrobot.mejorrobotservice."
        + "MejorRobotPortType", 
        targetNamespace = "http://localhost:8080/MejorRobot/MejorRobotService", 
        wsdlLocation = "WEB-INF/wsdl/MejorRobotService/MejorRobot.wsdl")
public class MejorRobotService {

    public localhost._8080.mejorrobot.mejorrobotservice.ArrayRobots
            mejorRobotOperation(localhost._8080.mejorrobot.mejorrobotservice.
                    Paquete paquetePart) {
        return new Main(paquetePart).getPearson();
    }
    }



Asi tenemos los tres servicios atomicos programados, damos en cada uno clic derecho -> Deploy para ponerlos a correr en GlassFish


Luego procederemos a marcar cada uno de los servicios atómicos y a la composición del servicio web

Abrimos Protege y realizamos los pasos mencionados anteriormente.


Hacemos click en el botón que está dentro del marco rojo e importamos nuestra ontología de dominio.


Si señalamos la pestaña OWLClasses, podremos ver cada una de las clases de nuestra ontología importada.

Luego iremos menú en barra, señalamos project/configure y seleccionamos owlstab; de ésta manera estaremos importando el plug-in de owl-s editor para Protégé y a su vez la ontología para describir servicios web OWL-S.

Al realizar los pasos anteriores tendremos la siguiente vista en nuestro Protégé.



Para realizar el marcado semántico a nuestros servicios web, creamos una nueva instancia de la clase Process declarada en la ontología OWL-S como subclase de ServiceModel.


Observemos el marco rojo, con ese botón crearemos la instacia, luego aparecerá el cuadro que en la anterior imágen tiene como título Choose a Class. En este cuadro seleccionamos Atomic Process.

Luego creamos una nueva instancia de hasInput y tendrémos la siguiente vista.


Luego de darle un identificador a la entrada, especificamos su tipo de dato haciendo click en el botón amarillo con el símbolo de suma.


En nuestro caso señalamos la clase ArrayDispositivos, indicando que el servicio recibe una entrada de este tipo.

Para especificar las salidas, hacemos este mismo proceso pero creando una instancia de hasOutput.

Ahora, supondremos que hemos creado 3 procesos atómicos y crearémos un nuevo process pero señalaremos esta vez Composite Process, para indicar que este es compuesto.


Para realizar este paso es necesario tener instalado el software Graphviz para visualizar un esquema del servicio compuesto. Uno de los botones que tiene forma de rombo rosado, tiene una letra 'S', con este botón crearémos un sequence, ya que nuestro servicio compuesto se comporta como una secuencia.
Creamos varios Perform con el botón que tiene la 'P', un perform por cada atomic process.


Al crear un perform, en la pestaña properties, le damos un nombre al perform y seleccionamos el atomic process correspondiente.

En la siguiente imágen veremos como se especifica que la salida de un atomic process es exactamente la misma entrada del siguiente proceso.


Luego de realizar estos pasos con cada perform, nuestro esquema será de la siguiente manera.


Luego crearemos nuestro grounding, creando una instancia de WsdlGrounding, al crearla, aparecerá un recuadro rojo enmarcando a supportedBy, en la cual se debe especificar el servicio al cual se le está haciendo el grounding. Por el momento no será importante.
Crearemos una instancia de hasAtomicProcessGrounding y allí especificaremos todo acerca de la ubicación de ciertos elementos en el wsdl de cada servicio.
Vamos a tomar como ejemplo el servicio web ModificarCaracteristicasService. El wsdl en nuestro caso está ubicado en nuestro localhost, accediendo a él con la siguiente dirección: http://localhost:8080/ModificarCaracteristicas/ModificarCaracteristicasService?WSDL

Observemos ahora la siguiente imágen.


Cada elemento del wsdl será especificado utilizando la dirección de este último añadiendo # y el nombre del elemento en el wsdl.

Ejemplo: http://localhost:8080/ModificarCaracteristicas/ModificarCaracteristicasService?WSDL#Paquete

De esta manera estaríamos especificando, en este caso, que las salidas de el servicio son de tipo Paquete.

Posteriormente crearemos el serviceProfile, creando una instancia.


En este definiremos las entradas del servicio compuesto y las salidas, indicaremos el procesos que tiene, damos el servicio al cual pertenece, y de manera opcional darémos una breve descripción del servicio en texto.

Luego creamos una instancia de Service e indicamos añadiendo instancias en los respectivos recuadros, el grounding, el profile y el proceso compuesto.


Finalmente, salvámos nuestro proyecto, el cual generará un archivo .owl.

Para más detalles visita: http://owlseditor.semwebcentral.org/documents/tutorial.pdf