Monday, September 26, 2011

Collections Ontology v.2... list of persons [1]

Back in 2008 I've published a couple of posts explaining my need of creating an ontology for collections:
After some months of work with Silvio Peroni we are almost done with v.2 of Collections Ontology (CO) expressed in OWL2.  Following is a simple example that illustrates some of the features of CO2. Before that here is how to set up the environment for testing the features yourself. First of all I would suggest you to install Protege 4.1 and to make sure to install the Pellet plugin for it.

With Protege up and running, I performed the import of the development version of the Collection Ontology v.2 with URL: http://collections-ontology.googlecode.com/svn/trunk/collections.owl.

Figure 1 - Import of the development version of the Collections Ontology (CO) with Protege

Figure 2 - Collections Ontology (CO) is imported

After that I've created a class person - note that I haven't reused classes such as foaf:Person to keep the example simple - and the instances in figure 3 in order to model a list of persons (you can download the file here).

Figure 3 - Collections Ontology (CO) example instances (ovals)

After triggering the reasoner, it is immediate to notice inferred properties (figure 4 in light yellow).

Figure 4 - Inferred types and properties for item instance itemOne. For instance itemOne has been defined as instance of item, the reasoner infers itemOne (i) is a list item (ii) is follwed by both itemTwo and itemThree (iii) is item of and is first item of persons.

Figure 5 - Explanation of itemOne type 'list item' obtaining by clicking the highlighted button

We can now proceed with some DL Queries.

Query 1
For instance we can ask for all the items that have item content (has item content) persons with name "Paolo Ciccarese":
item and 'has item content' some (person and (name value "Paolo Ciccarese"))
In the Protege tab named 'DL Query' we can enter the query above and, if we select on the right side the option 'Individuals' we are going to  retrieve one item (itemOne):


Query 2
We can ask for all the lists where the first person is named 'Paolo Ciccarese' (answer 'persons'):
list and 'has first item' some (
     item and 'has item content' some (person and (name value "Paolo Ciccarese"))
)
Query 3
Similarly we can ask more complex queries such as: find all the persons lists where the first item points to a person named 'Paolo Ciccarese' and the last item points to a person named 'Silvio Peroni' (answer 'persons'):
list and (
    'has first item' some (item and 'has item content' some
           (person and (name value "Paolo Ciccarese")))
    and
    'has last item' some (item and 'has item content' some
           (person and (name value "Silvio Peroni")))
)
Query 4
Another query can be: give me all the lists where the first person is named 'Paolo Ciccarese' and the second is 'Marco Ocana' (given the transitive nature of the property 'is followed by' the answer is 'persons'):
list and (
      'has first item' some (item and
            'has item content' some (person and (name value "Paolo Ciccarese"))
            and
            'is followed by' some (item  and
                    ('has item content' some(person and(name value "Marco Ocana"))))
      )
)
Query 5
Returns all the lists containing a person named 'Paolo Ciccarese' (answer 'persons'):
list and 'has item' some (
     item and 'has item content' some (person and (name value "Paolo Ciccarese"))
)
Query 6
Returns any list where a person named 'Paolo Ciccarese' is followed by a person named 'Silvio Peroni' (answer 'persons'):
list and (
    'has item' some (item and
            'has item content' some (person and (name value "Paolo Ciccarese"))
            and
            'is followed by' some (item  and
                    ('has item content' some(person and(name value "Silvio Peroni"))))
      )
)
Query 7
Returns all the lists where a person named 'Silvio Peroni' is preceeded by a person named 'Paolo Ciccarese' (answer 'persons'):
list and (
    'has item' some (item and
            'has item content' some (person and (name value "Silvio Peroni"))
            and
            'is preceded by' some (item  and
                    ('has item content' some(person and(name value "Paolo Ciccarese"))))
      )
)

Thursday, September 22, 2011

SWAN, AlzSWAN, HyQue and Nanopublications

While developing the SWAN ontology and the SWAN platform (see AlzSWAN for Alzheimer disease) there have always been two open issues: (i) the use of named graphs and (ii) the translation of the textual discourse elements (claims such as: Intramembranous Aβ could behave as chaperones of other membrane proteins) into a formal representation made of triples.


(i) The use of named graphs is a useful way for wrapping some content and specifying its provenance. Basically the idea is to create an 'onion layers' model where each layer has its own provenance. At the time - back in 2006 - I have been investigating the usage of named graphs - and TriX - for representing SWAN content.  However, we decided not to implement such approach because the technological uncertainty in that uncharted territory - of developing an application like SWAN - was already high enough, named graphs usage was not homogeneous across the community and  their serialization was not standardized. This meant introducing de-facto reification for some of the SWAN relationships in order to be able to attach the appropriate provenance. As Graphs are the topic of one of the task forces of the RDF Working Group for updating the 2004 RDF Recommendations, I was starting to think of resuming the old plans.

(ii) The translation of the textual discourse elements into a formal representation made of triples is, for instance, possible through the HyBrow (now HyQue) approach. Translating narrative into triples is not easy job though. Many already found the SWAN manual creation process of narrative claims very labor intensive. In fact, the SWAN curators have been usually rephrasing each claims/hypothesis to make them simple and self contained (including the minimum necessary context). Translation into triples requires, even more, starting from neat hypothesis and claims. And these are not always that easy to obtain.

These two SWAN-related issues have been in my thoughts since a while when the Nanopublication [1] concept came out.

A Nanopublication is a "set of annotations that refers to the same statement and contains a minumum set of (community) agreed-upon annotations.
The concept itself is simple and in the above linked slideshow you can find a first attempt based on real SWAN data. With respect to the paper, the concept of 'statement' (triple) has to be updated to 'statements' (triples) as one single statement is not always enough to satisfy needs of real use cases.
 Statement --> statements
Starting from the above example, we are now trying to formalize a bit better what a Nanopublication architecture would look like... it is work in progress, but if you look at the slides you will get the drift.

[1] Paul Groth, Andrew Gibson, Jan Velterop. The anatomy of a nanopublication. Information Services and Use (2010). Volume: 30, Issue: 1, Publisher: IOS Press, Pages: 51-56 (on Mendeley)

Wednesday, September 21, 2011

UIBinder, CssResource and CSS (GWT)

Few month ago I blogged about ClientBundle, UIBinder and CSS (GWT). I just realized that an important use case was missing. And here it is.

4) Using CssResource for CSS expressed in the UIBinder. When creating a UI with the UIBinder it might happen to include some CSS rules in the ui.xml file.

<ui:UiBinder
  xmlns:ui='urn:ui:com.google.gwt.uibinder'
  xmlns:g='urn:import:com.google.gwt.user.client.ui'>

    <ui:style>
       .outer {
          width: 100%;
       }
    </ui:style>
    <g:SimplePanel ui:field='sideBar'>
    </g:SimplePanel>
</ui:UiBinder>

It is possible to refer to those CSS rules from the GWT code. For doing so we have to declare a 'type' for ui:style:

<ui:UiBinder
  xmlns:ui='urn:ui:com.google.gwt.uibinder'
  xmlns:g='urn:import:com.google.gwt.user.client.ui'>

    <ui:style type='org.example.Example.ExStyle'>
       .outer {
          width: 100%;
       }
    </ui:style>
   
    <g:SimplePanel ui:field='sideBar'>
    </g:SimplePanel>
</ui:UiBinder>


Now, in the class  org.example.Example, we can reference the CSS rules and use them:

public class Example extends Composite {

    interface Binder extends UiBinder { }    
    private static final Binder binder = GWT.create(Binder.class);
   
    @UiField SimplePanel sideBar;
    @UiField ExStyle style;

    interface ExStyle extends CssResource {
        String outer();
    }

    public Example() {
        initWidget(binder.createAndBindUi(this)); 
        sideBar.setStyleName(style.outer()); 
    }
   ...

Wednesday, September 14, 2011

Grails 1.3.7, Spring Security and OpenID... with exception

Here is the list of steps I performed to set up OpenID authentication with Spring Security:

1) Create Project with Grails 1.3.7
grails create-project UserManagement 
The file application.properties will look something like this:
app.grails.version=1.3.7
app.name=UsersManagement
app.servlet.version=2.4
app.version=0.1
plugins.hibernate=1.3.7
plugins.tomcat=1.3.7 

2) Installing the Spring Security plugin (website and documentation)
grails install-plugin spring-security-core
The file application.properties will now look something like this:
app.grails.version=1.3.7
app.name=UsersManagement
app.servlet.version=2.4
app.version=0.1
plugins.hibernate=1.3.7
plugins.spring-security-core=1.2.1
plugins.tomcat=1.3.7

3) Creating Controller and template classes
grails s2-quickstart org.commonsemantics.scigrails.module.users.security User Role
You will notice the following new files
controllers/LoginController.groovy
controllers/LogoutController.groovy
domain/org.commonsemantics.scigrails.module.users.security.User.groovy
domain/org.commonsemantics.scigrails.module.users.security.Role.groovy
domain/org.commonsemantics.scigrails.module.users.security.UserRole.groovy
views/login/auth.gsp
views/login/denied.gsp
The Config.groovy will be updated with the following lines:
grails.plugins.springsecurity.userLookup.userDomainClassName =
      'org.commonsemantics.scigrails.module.users.security.User'
grails.plugins.springsecurity.userLookup.authorityJoinClassName = 
      'org.commonsemantics.scigrails.module.users.security.UserRole'
grails.plugins.springsecurity.authority.className = 
      'org.commonsemantics.scigrails.module.users.security.Role'
If you are going to change the package of the above classes, just remember to update the above properties.

4) Move controllers to the desired package - org.commonsemantics.scigrails.module.users.security

5) Install the OpenID module (website and documentation)
grails install-plugin spring-security-openid
The file application.properties will now look something like this:
app.grails.version=1.3.7
app.name=UsersManagement
app.servlet.version=2.4
app.version=0.1
plugins.hibernate=1.3.7
plugins.spring-security-core=1.2.1
plugins.spring-security-openid=1.0.3
plugins.tomcat=1.3.7

6) Creates OpenId Controller and templates for it.
grails s2-init-openid
This script adds the following files:
controllers/OpenIdController.groovy
views/openId/auth.gsp
views/openId/createAccount.gsp
views/openId/linkAccount.gsp

7) Move OpenIdController to the desired package - org.commonsemantics.scigrails.module.users.security

8) Add support for the remember-me checkbox
grails s2-create-persistent-token 
     org.commonsemantics.scigrails.module.users.security.PersistentLogin
It adds the file:
domain/org.commonsemantics.scigrails.module.users.security.PersistentLogin.groovy
The Config.groovy is updated with the following lines:
grails.plugins.springsecurity.rememberMe.persistent = true
grails.plugins.springsecurity.rememberMe.persistentToken.domainClassName =
     'org.commonsemantics.scigrails.module.users.security.PersistentLogin'
Once again, if you are going to change the package of the above classe, just remember to update the correspontend property.

9) Creating the OpenID domain class
grails s2-create-openid 
     org.commonsemantics.scigrails.module.users.security.OpenID 
The script creates on file:
domain/org.commonsemantics.scigrails.module.users.security.OpenID.groovy
The Config.groovy is updated with the following line:
grails.plugins.springsecurity.openid.domainClass =       
     'org.commonsemantics.scigrails.module.users.security.OpenID'
Once again, if you are going to change the package of the above classe, just remember to update the correspontend property.

10) Adding OpenIDs to the User domain class

The following line of code has to be added to the existing User.groovy class:
static hasMany = [openIds: OpenID]

11) Creating some test users

As suggested by the documentation we can now create some test users by editing the Bootstrap.groovy file as follows
import org.commonsemantics.scigrails.module.users.security.Role
import org.commonsemantics.scigrails.module.users.security.User
import org.commonsemantics.scigrails.module.users.security.UserRole

class BootStrap {

    def springSecurityService

    def init = { servletContext -> 

        String password = springSecurityService.encodePassword('password')
        
        def roleAdmin = new Role(authority: 'ROLE_ADMIN').save() 
        def roleUser = new Role(authority: 'ROLE_USER').save()

        def user = new User(username: 'user', 
            password: password, enabled: true).save() 
        def admin = new User(username: 'admin', 
            password: password, enabled: true).save()

        UserRole.create user, roleUser 
        UserRole.create admin, roleUser 
        UserRole.create admin, roleAdmin, true 
    } 
}


12) Redirect the login requests

It is now necessary to direct the authentication calls to the new Controller that manages also the OpenIDs. We can add to the UrlMappings.groovy file the following:
"/login/auth" {
         controller = 'openId'
         action = 'auth'
      }
      "/login/openIdCreateAccount" {
         controller = 'openId'
         action = 'createAccount'
      }

13) Running Grails and testing
grails run-app 
Welcome to Grails 1.3.7 - http://grails.org/
Licensed under Apache Standard License 2.0
...
...
Configuring Spring Security ...
Configuring Spring Security OpenID ...
Server running. Browse to http://localhost:8080/UsersManagement

When accessing the page you should see something like this:
I will try it yourself but the authentication did not work for me right away. I logged in with my Google OpenID and I got sent to the screen for creating an account.
I then selected the 'link this OpenID' option.
After introducing the testing credential 'user' and 'password' I got a 'user not found' back.

14) Turning on the logging

First thing I wanted to see if there were any weird things happening by turning on the logging in the Config.groovy file:
debug 'org.springframework.security'
No exceptions emerged when repeating the process.

15) Making sure the User is stored in the DB

We can inspect the default HSQLDB by adding at the end of Bootstrap.groovy init the following:
org.hsqldb.util.DatabaseManager.main()'
this will open the in memory database inspector. Just remember that if you close the inspector that will also shutdown your Grails app. Read more about the inspector here and remember to take out that line once the debugging is done..

The users resulted stored in the database.

16) Making sure the encoding process works correctly

After editing the Bootstrap.groovy file with:
String password = springSecurityService.encodePassword('password')
println 'a ' + password
def admin = new User(username: 'admin', password: password, 
     enabled: true).save(failOnError: true)
println 'b ' + User.findByUsername('admin').password
and a restart, I obtained:
a 5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8
b 113459eb7bb31bddee85ade5230d6ad5d8b2fb52879e00a84ff6ae1067a210d3

It is clear that the login process is not performing correctly. After investigating I found out that the User domain class includes the methods:
def beforeInsert() {
          encodePassword()
     }

     def beforeUpdate() {
          if (isDirty('password')) {
                encodePassword()
          }
     }

17) Updating the Bootstrap.groovy file

As the User domain class is already performing the encoding, we have to edit the Bootstrap.groovy file line:
String password = springSecurityService.encodePassword('password')
Into
String password = 'password'

And now the login process works for me. We can now remove org.hsqldb.util.DatabaseManager.main() from the end of the Bootstrap.groovy and maybe comment out the logging (see point #14).

18) Remove the unused views and controllers?

It is not possible to remove any of the generated controllers. As far as I know the only file that can be removed is
views/login/auth.gsp
as the new auth.gsp file provided by the OpenID plugin is now in use (see point #12).


You can check out the code as follows:
svn checkout 
     https://common-semantics.googlecode.com/svn/tags/UsersManagement20110914  
     UsersManagement

Resources
OpenID website
Spring Security Plugin for Grails website
OpenID Plugin for Spring Security website