>  >  

Open Xerox Java Library

If you are writing a Java Swing application, on any other type of Java Application, that interacts with Open Xerox, the Open Xerox Java Library will prove useful.

This Java library provides helper functions for user authentication with OAuth2, as well as for calling Open Xerox REST services from an Android application, and OData helpers.

The JAR library can be downloaded here, and the javadoc is accessible here. This library depends on the common Java Library, available via maven. To use this lib without maven, you need to include the commun Xerox Java library, available here.

 

Authentication

A token is stored into system properties. Depending to the current OS, it can be stored into Database, Files, or Registrers, transparently for the developper.

The SimpleWebToken class manages this storage and you can load a astored token thanks to the function:

SimpleWebToken token = SimpleWebToken.restore();

If no token has been found, the token will be null. Thanks to this method, you can then know if a user is logged or not.
Each token has a short period of validity. To test if this one needs to be refreshed, please use the function

token.isExpired()

Then, you'll know if you need to refresh the token, or if it is valid.

 

Log in user

If you want to log in, you need to put a username and a password to the authentication server.
Those information are transmitted via a UserCredentials object.

Everything can be done automatically thanks to the method:

Authentication.login(defaultUsername, defaultPassword, proxyUrl, proxyPort, authUrl, true, new AsyncListener() {
  @Override
  public void onResponseOK(byte[] datas) {
    updateDisplay();
  }
  @Override
  public void onError(String description, Exception error) {
    updateDisplay();
  }
});

If the defaultUsername or defaultPassword is null or wrong, a popup will ask the user to put those informations to try to log in.
If the proxy URL or the port is null, the proxy will not be set.
If the authUrl is null, the default auth URL will be used.
If the boolean is set to true, the login popup will appear while the authentications fails or the user doesn't press the cancel button. If false, it will appear just one time.
If you dislike this process, you can manage your own authentication process, as described in the advanced section.

 

Log in the user - Advanced

Customize authentication process

If you prefer use your own authentication process, first, test you are not yet logged in:

token = SimpleWebToken.restore();
if (token != null)
  throw new Exception(...);

Then, create your authenticator object:

OAuth2Authenticator oauth2 = new OAuth2Authenticator(authServerUrl);
credentials = new UserCredentials(false, username, password);
if (!credential.readCredentials(false))
  throw new Exception(...); // username or password is null
token = oauth2.getSimpleWebToken(credentials);

If the received token isn't null, then the authentication succeded.
The false boolean indicated to not display the authentication window.

How to ask for username/password ?

The credential is built thanks to known username and password. If you don't know it and would like to prompt the user those datas, you will prefer to use the call of UserCredential with the first boolean to true, and username and/or password set to null.

OAuth2Authenticator oauth2 = new OAuth2Authenticator(authServerUrl);
credentials = new UserCredentials(true, username, null, OnCredentialListener);
if (!credential.readCredentials(true))
  // username or password is null
  // thanks to the "true" boolean, a window will prompt the user login and password
  // the code is locked until the input window isn't closed.
  // if you enter into this "if" condition, then the user clicked on cancel and never succeded to login
  onError();

The OnCredentialListener object waits for the user validates his username/password. Its onContinue() method is then called.
Here then you need to try to login with this credential.

token = oauth2.getSimpleWebToken(credentials);

If the new token is not null, you succeded to log in! Then you can store the token with

token.persist();
How to show the authentication window while authentication fails?

If you don't have a new token, you can re display the authentication windonw to allow the user to prompt again his username/password.

The full code for this second log in function would then be:

OAuth2Authenticator oauth2 = new OAuth2Authenticator(authServerUrl);
OnCredentialListener oncred = new OnCredentialListener(){
  @Override
  public void onContinue(){
    //called when the user validates the authentication popup
    try { token = oauth2.getSimpleWebToken(credentials); }
    catch (Exception e){ e.printStackTrace(); }
    if (token!=null)
      token.persist(); // succed!!!
    else {
      credentials.askForLoginPassword(); // if you want to re-ask for username/pasword
    }
  }
}
credentials = new UserCredentials(true, username, null, oncred);
if (!credential.readCredentials(true))
  onError(); // called when none authentication try succeded

 

Log out user

If you need to log out, you just need to delete the stored token.
Please use this code to ensure there the token will be deleted:

Authentication.logout(new AsyncListener() {
  @Override
  public void onResponseOK(byte[] datas) {
    updateDisplay();
  }
  @Override
  public void onError(String description, Exception error) {
    updateDisplay();
  }
});

 

Refresh the token

To refresh the token, you first need to check a token is stored.
Once this verification is done, you just have to call the getSimpleWebToken from OAuth2Authenticator with the current token, tu try to refresh it.
Then, just persist this new token.

Authentication.refreshToken(null, null, null, new AsyncListener() {
  @Override
  public void onResponseOK(byte[] datas) {
    updateDisplay();
  }
  @Override
  public void onError(String description, Exception error) {
    updateDisplay()
  }
});

 

 

Web Services

Thanks to the WebServiceClient class, you can create custom webservices requests.

Once instanciated, you can set some parameters or header to you web service object. When you have put all your datas, you can execute a POST, a GET, or some other HTTP methods.

The services are, by default, authenticated with the default current token (the one stored).

Put data into your request

Change the token

You have three possibilities for the access token. You can call web services staying anonymous, you can use your own token, or you can let the library use the stored token and then manage itself the authentication.

You can change the authentication mode thanks to methods setAnonymous() and setAccessToken(String). The first just tells the request object that the call will be anonymous. The second method allow you to use your own token. If its parameter value is null, it is equivalent to setAnonymous(). If its parameter value is "", then the request will use the default token.

Add headers and change the Content-Type

Simply use the addHeader(String,String) method to add custom headers.
The default content-type is determinated dynamically thanks to set parameters: if the body is set, then the content type will be text/plain. Else the content-type will be application/x-www-form-urlencoded (or a multipart/* if multipart POST). You can erase this default content-type by adding your own "Content-Type" to the headers. Your curstom value will erase the generated value.

Add parameters

Depending on the method you will use, some methods will be useless. Please ensure you use the right method with corresponding methods.

 

GET

Simple POST

Multipart POST

Custom/other

addDataParameter

Used as a url-encoded parameter into URL

- If setStringBody  called, then ignored.

- Else, used as a url-encoded parameter into the body

Used as a multipart value

if position = in URL, then cf. GET.
Else if position = in BODY, cf. POST

addBinaryParameter

Ignored

Ignored

Used as a multipart value

addFileParameter

Ignored

Ignored

Used as a multipart value

setStringBody

Added to other URL encoded parameters, named “body” into the URL

Defines the body content

Ignored

Executing the service

One your parameters, headers, token are correctly set, you can call yout web service thanks to some standard HTTP methods, or use your own.
Please refer to the previous table to know which parameters are valid for your method.
Those functions are available:
- executeGet()
- executePost()
- executeMultipartPost()
- executeCustomRequest(String,int), the String being the wanted method (can be standard like "DELETE", "PATCH", or your own like "PREVIEW" for example), and the integer beeing a WebServiceClient constant (POSITION_IN_URL or POSITION_IN_BODY).

Those functions return the response data into a byte array.

Example

WebServiceClient client = new WebServiceClient(new URL("http://posttestserver.com/post.php"));
client.setAnonymous(); // no token to send in headers
client.addHeader("customheader", "BBB"); // creates a custom header
client.addDataParameter("param1", "value1");
client.addDataParameter("param2", "value2");
client.addDataParameter("param3", "value3");
System.out.println(new String(client.executeCustomRequest(WebServiceClient.METHOD_POST, WebServiceClient.POSITION_IN_BODY)));
//this last line is equivalent to do a simple POST

 

OData Services

An OData service is called thanks to an ODataRequest object.

Building the ODataRequest

The ODataRequest constructor needs a call ID, and the service URL, that permit to identify the answer when received and then do many calls in differents threads. Once your object is created, you can put some parameters to describe the request.

Parameters

You can access some methods permitting to build the request:
- setFilterParam(BooleanItem), which permits to receive only the objects corresponding to the given conditions
- setOrderParam(OrderByParam[]), to reorder the results
- setSelectParam(String[]), to receive for each item only the selected part of attributes
- setTopParam(int), to receive a maximum item count
- setSkipParam(int), to skip the first items into the result list

Ordering results

An OrderParam is an abstract class. The two implemetations are AscendantOrder and DescendantOrder. Those two classes have a simple constructor with the attribute name to sort. For example, if you want to sort a user list by ascendant first name, and descendant last loggin date, you can use this code:

params.setOrderParam(new OrderByParam[] { new AscendantOrder("Name"), new DescendantOrder("LogginDate") });

Filtering results

The filter parameter needs a final BooleanItem, corresponding to a condition to be checked. A boolean item can be obtained directly with a boolean item, or by comparing some items, like for each language. You can then start your filter expression with the FilterFactory which will simplify you the access of the different classes. You can then create a String, an Integer, a Date. Methods can create inner values, or get attributes values thanks to *Column methods. Example:

FilterFactory.createNumeric(12)

will correspond to the integer value : 12.

FilterFactory.getNumericColumn("Age")

will correspond to the numeric value of the "Age" attribute.

FilterFactory.createString("String")

will correspond to the text 'String' (with quotes into the request).

FilterFactory.getTextColumn("Comment")

will correspond to the text value of the "Comment" attribute. Into the request, the "Comment" name will not be quoted.

etc.

Once you have your first item is created, some functions permits you to contruct a full and complex filter.

String items can access to functions:
- StartsWith returning a booleanItem
- EndsWith returning a booleanItem
- Concat returning a String
- IndexOf returning a numericItem
- Lengthreturning a numericItem
- Replace returning a String
- SubString returning a String
- ToLower returning a String
- ToUpper returning a String
- Trim returning a String

Numeric items can access to the functions:
- Ceiling returning a numeric item
- Floor returning a numeric item
- Add returning a numeric item
- Sub returning a numeric item
- Mul returning a numeric item
- Div returning a numeric item
- Mod returning a numeric item
- Round returning a numeric item
- greaterOrEquals returning a booleanItem
- lowerOrEquals returning a booleanItem
- greaterThan returning a booleanItem
- lowerThan returning a booleanItem

Date items can access to the functions:
- Day/Days returning a numeric item
- Hour/Hours returning a numeric item
- Minutes/Minutes returning a numeric item
- Month/Months returning a numeric item
- Second/Seconds returning a numeric item
- Year/Years returning a numeric item

Boolean item can access to the functions:
- and returning a booleanItem
- or returning a booleanItem
- not returning a booleanItem

All Items can access to the functions:
- equals returning a booleanItem
- notEquals returning a booleanItem

 

Thanks to all those functions you can create a request with multiple conditions. For a call example:

ODataRequest caller= new ODataRequest(MYWEBSERVICE,"https://mywebserviceurl/Accounts");
caller.setFilterParam(FilterFactory.getTextColumn("Name").startsWithString("Xerox").or(FilterFactory.getTextColumn("Address").trim().length().gt(20)));
String response = caller.executeHTTPGet(token);
JSONArray json = new JSONArray(response);

With this filter, the request will call for all items with their "Name" attribute starting with "Xerox", or having an "Address" attribute with more than 20 characters (once trimmed). The answer is then converted to a JSON object to be easy to use.

 

Maven Compilation

 

Please declare the jar in your pom.xml (in the dependencies section) if you want to compile with maven.

<dependency>
  <groupId>com.xerox.esp</groupId>
  <artifactId>utils</artifactId>
  <version>1.0.0</version>
</dependency>