Email: dev@concena.com       Twitter: @dbrucegrant
«Back

GWT and Nuxeo Integration - Code Example

I have finally found a little bit of time to get back to the subject of my GWT integration with Nuxeo. I use GWT as a presentation layer for a number of document-centric applications. Here is a simple example of the code that makes the integration work. Keep in mind this article is meant only to demonstrate some key concepts - it is not a complete example or a step by step tutorial!

There are four main parts of code to the solution

  1. A typical custom Nuxeo plugin to model the backend document management application, document types, workflow, etc. This code provides the custom content/relationships that will be used in the GWT front-end, but is not of direct interest in this example.
  2. A rest API that implements the rest calls used by GWT to pass data to and from Nuxeo.
  3. GWT code that makes the rest calls, parses returning data, etc.
  4. GWT code that registers the necessary callback to something with data when it's returned

In the sample code, users in the front-end application log-in using a simplified login page, where all they have to is click on the icon with their name. In order to make this work the list of available users needs to be seeded. This is done by creating a special group in Nuxeo called "visual". Users added to the visual group will have an icon on the login page.

Starting with Nuxeo...

The list of available users is served up by Nuxeo using the GetVisualUsers api call. A call to GetVisualUsers returns an XML list of available user names. The list of available user names is built using the names in the visual group.

public class GetVisualUsers extends BaseStatelessNuxeoRestlet {
    @Override
    public void handle(Request req, Response res) {
      
        super.handle(req, res);
      
        UserManager userManager;
        DocumentModel userDocModel;
        ArrayList<String> userList;
      
        // setup repository access ... this sets up the session
        Boolean init = initRepository(res, Resources.DEFAULT_REPO);
        Boolean isRoot=false;
       
        try {
            userManager = Framework.getService(UserManager.class);
        } catch (Exception e) {
            Utils.handleError(res, Resources.RS_USERMANAGER_SERVICE_FAILED, Resources.EM_VISUAL_USERS_NOT_FOUND + " (group missing)");
            return;
        }
      
        try {
            userDocModel = userManager.getGroupModel("visual");
        } catch (ClientException e) {
            Utils.handleError(res, Resources.RS_VISUAL_USERS_NOT_FOUND, Resources.EM_VISUAL_USERS_NOT_FOUND + " (group missing)");
            return;
        }

        try {
            userList = (ArrayList<String>) userDocModel.getProperty("group", "members");
        } catch (ClientException e) {
            Utils.handleError(res, Resources.RS_VISUAL_USERS_NOT_FOUND, Resources.EM_VISUAL_USERS_NOT_FOUND + " (members missing)");
            return;
        }
      
        if (userList.size() == 0) {
            Utils.handleError(res, Resources.RS_VISUAL_USERS_NOT_FOUND, Resources.EM_VISUAL_USERS_NOT_FOUND + " (no members)");
            return;
        } 
      
        // now need to return the XML result to caller in the documented structure
        XmlResponse xmlResponse = new XmlResponse();
        xmlResponse.createResponseStatusTag(Resources.RS_OK);
        xmlResponse.createDataTag();
       
        for (int i = 0; i < userList.size(); i++) {
            xmlResponse.createTagAtCurrentElement("user", userList.get(i));
        }

        // write the response
        res.setEntity(xmlResponse.asXML(), MediaType.TEXT_XML);
    }

The XML returned from Nuxeo looks as follows...

<?xml version="1.0" encoding="utf-8" ?>
<response>
     <result>OK</result>
     <data>
            <user>Bruce</user>
            <user>Joe</user>
            <user>Sarah</user>
      </data>
</response>

And now on to GWT

Nuxeo produces the list of visual users in response to a Rest request made from the GWT code. The results, if successful, are rendered by a callback method. The end result: the user see a list of icons with names and can login to the system by clicking the appropriate icon.

When the GWT application starts up it calls showVisualLogin(...). showVisualLogin receives a reference to the base display panel, which is used to initialize the display and show the icons/names representing the available users.

Since the call to get the visual users is asynchronous, the most important part of showVisualLogin is setting the callback. The callback takes the results passed from Nuxeo and displays the login page!

Here's the code for showVisualLogin...

    private void showVisualLogin(final Panel panel) {
       
        setCurrentUserName("");
        userIsLoggedIn = false;
        basePresenter.getView().getLoginDataLine1().setText("");
        basePresenter.getView().getLoginDataLine2().setText("");
       
        modelSystemCache.loadCache();

        // GWT RPC: service call to get visual users
        LoginServiceAsync loginService = model.getRemoteLoginService();
        loginService.getVisualUsers(new SimpleCallback<String[]>() {

            @Override
            public void goBack(String[] result) {
                @SuppressWarnings("unused")
                String deleteMe = "";
               
                // GWT CALLBACK: on callback now is the time to build the login screen, display it and await for a click
                // on one of the user icons, at which time the history token will be set to 'search'
                final VisualLoginPresenter visualLoginForm = new VisualLoginPresenter(Environment.this, "", result,
                        new SimpleCallback<String>() {

                            @Override
                            public void goBack(String result) {
                                if (!result.equals("")) {
                                    userIsLoggedIn = true;
                                    startingToken = "search";
                                    setCurrentUserName(result);
                                    getMostRecent(result);
                                    timerActive = true;
                                    resetSessionTimer();
                                    showFirstPage();
                                } else {
                                    // need to handle error - display message and then let user try again!
                                    userIsLoggedIn = false;
                                    startingToken = "login";
                                    showAlert("Login failed. User no longer exists, password has changed, or system is down.");
                                }
                            }
                        });
            }});
       
        panel.clear();
    }

getVisualUsers is implemented in the GWT server package. The code is fairly straightforward, it creates a Nuxeo server object (defines connection details), sets up a rest call object, makes the rest call, and then confirms that the resulting XML returned an OK status (meaning there are no errors and the list of users is included in the returned XML).

Here's the code...

    @Override
    public String isVisualUserValid(final String name, final String password) {

        String baseUrl = getNuxeoUrl();
        // initialize the Nuxeo server and then make a rest call to pick up some real documents
        NuxeoServer ns = new NuxeoServer(baseUrl);
        NuxeoRestCall nrc = new NuxeoRestCall(ns); // setup a rest call
       
        String restCall = "sentiovaliduser";
        Representation myResult = nrc.doRestletGetCall(restCall, null, name, password);
       
        if (myResult == null) {
            return "0";                                    // call failed
        } else {
            // parse the result
            return parseStatus(myResult);                // call succeeded, but need to parse real status from XML
        }
    }

I have left out a lot of details, however, my intent is to give a sense of how to make GWT talk to Nuxeo, not (at least at this point) to provide a full tutorial on the subject.

Cheers,
Bruce.

Comments
No comments yet. Be the first.

Recent Entries Recent Entries

RSS (Opens New Window)
Showing 1 - 5 of 15 results.
of 3