CI-Client API Examples and Q&A
CI-Server Framework
This document contains example code and answers to questions concerning the CI-Client API
Cyber-ShARE
4/27/2011
This is a working document. There was not time to create a COMPLETE document based on all the
features of the API. Information is added as time is available.
VERSION DESCRIPTION DATE BY
1.0 Initial version April 28, 2011 Aída Gándara
Contents
Q&A ........................................................................................................................................................ 4
What is a resource? ............................................................................................................................. 4
What is a CIReturnObject? ................................................................................................................... 4
What methods can be called? .............................................................................................................. 4
How do I register another server so it is known by the client?.............................................................. 4
Examples ................................................................................................................................................. 6
Connecting to a CI Server ..................................................................................................................... 6
Creating a project ................................................................................................................................ 7
Creating a resource.............................................................................................................................. 7
Downloading a resource: ..................................................................................................................... 9
Q&A
What is a resource?
In the CI-Server Framework, a resource is an attachment to a node. Node’s hold additional data,
metadata, that will have meaning to the website, thus an administrator can add fields to a node and
create views for the node. This is seen on the pages of the website. There are special forms on a
website to create a resource and add an attachment. The attachment is the resource. When a resource
is uploaded or downloaded, the attachment is uploaded and downloaded.
What is a CIReturnObject?
In order to assure that the tools that integrate with the CI Client API could have a decent level of
stability, and not require that they modify code after every API release, a standard return type is
returned from most API calls. The standard return type is the CIReturnObject class. In the example
above, ciAuthenticateSession returns this type of object. In all cases, when this object is returned,
gStatus will reflect the success or failure of the call and gMessage will hold the message. The rest of the
values are set based on the call itself. The exact content of the object, based on the calls, is documented
with the methods themselves. More importantly, if this object changes and additional or different
values must be returned with the return object, the calling function still works with a CIReturnObject
and pulls out of the object what is needed.
What methods can be called?
The JavaDoc API reference has a list of all public methods available in the API. Let us know if additional
examples or clarifications are needed. Examples from previous integrations are what built up the
content of this document.
How do I register another server so it is known by the client?
When the CI-Client API first initializes, it makes an attempt to read the ciclientconfig.xml file, located in
the same directory as the ciclient.jar file. If this file is found, this is used to set the servers known by the
client. To register a CI Server, the following is needed:
Server’s url
Server’s xmlrpc path
The Drupal domain string
The Drupal server’s api key
A server alias
This is specified in rdf statements. A ciclientconfig.xml file that only registers the default rio server
would be formatted as:
services/xmlrpc
ciserver
44cf96f16d5a225e8ce181a3f3980dc0
CIServerRio
Additional servers can be added by specifying a new Description block in the ciclientconfig.xml file and
assuring that the file is located in the same directory as the ciclient.jar file. An application would need
to be restarted in order to have the ciclient.jar read the modified config file.
Examples
Connecting to a CI Server
CI Servers require that client tools authenticate if they are going to access data via the API. This is
because the API is using services available at the server and they are protected through authentication
and an API key. The CI Client API maintains a table of servers that it knows about, there is internal
information about the default CI Server on http://rio.cs.utep.edu/ciserver , but users can access any CI
Server as long as the server has been configured and the client has the needed server authentication
information. For a specific server, the API requires the following information:
The url to the CI Server
The user name to authenticate with at the CI Server
The password to authenticate with
The API has functions to help make the connection based on this information. For example, assuming
for user tom with password tompass, the sequence of commands to connect to the server on rio is:
1. Get the KnownServerTable and determine the server id from the url
CIKnownServerTable _kst = CIKnownServerTable.getInstance();
int serverId = _kst.ciGetServerEntryFromURL(_serverURL);
if(serverId==-1){
System.out.println("Server "+_serverURL+" not known to this client");
}
2. Establish a connection – requires exception handling
try{
CIClient _ciClient = new CIClient(serverId);
}
catch(Exception e){
System.out.println("Connection Failed: "+e.getMessage());
e.printStackTrace();
}
3. Authenticate and check results
CIReturnObject ro = _ciClient.ciAuthenticateSession(_userName, _password);
if(!ro.gStatus.equals("0")){
System.out.println("Authentication failed: "+ro.gMessage);
}else{
System.out.println("Authentication successful for "+_userName+" on _serverURL");
}
Creating a project
In order to create a project on the server, the user authenticated must have the ‘create projects’
permission. In order to create a project, call the CreateProject admin function and check the results:
CIReturnObject ro = CIAdmin.ciCreateProject(_ciClient, "tomsproject");
if(!ro.gStatus.equals("0")){
System.out.println("Error creating project: tomsproject");
System.out.println(ro.gMessage);
}
Creating a resource
The expectation using this API is that if a resource is created, it has a file attachment. The instructions
for creating a resource involve creating the server node that will describe the attached file. In the CI-
Client API, the type maps to the content type name on the server. For the rio server, this could be ‘saw’,
‘wdo’, ‘pmlp’, ‘pmlj’, ‘udata’ and ‘sdata’. On other servers it might be other type names. Here are a few
examples, probably the most common, on creating resources.
Scenario 1: To upload a new WDO file to the rio server, use the ‘wdo’ content type and specify that the
resource should be created if it is not found. Specify a project because all resources are created and
placed in at least one project initially. Let’s assume that a file called tomography.owl, found on the local
filesystem, will be created in the Tomography project on rio. First, read in the file contents to a string :
try{
String file = CIUtils.ciReadFileAsString("tomography.owl");
if(file.isEmpty()){
System.out.println("Error, could not read file: tomography.owl");
}
}
catch(Exception e){
System.out.println("Reading tomography.owl failed: "+e.getMessage());
e.printStackTrace();
}
Then upload the file to a project. For this to work Tomography must already exist on rio, that is,
someone already created it either through the CI Client API or on the rio Website. The resource name
should be unique in the project. If a resource is found within the project, the file is overwritten. Again,
use CIReturnObject to check the results:
CIReturnObject ro = CIPut.ciUploadFile(_ciClient, "Tomography", "tomography.owl",
data, "wdo", true, false);
if(ro.gStatus.equals("0")){
System.out.println("Object uploaded, referenced via url : "+ro.gFileURL);
}else{
System.out.println("Upload failed: "+ro.gMessage);
}
Notice that you can get additional information like the new resources URL.
WDO files are OWL files, thus they are text files. Sometimes there is a need to upload binary files, e.g.,
pdf files or binary data files. To do this, first read in the content to a byte array:
try{
File file = new File("tomography.pdf");
bdata = CIUtils.ciGetBytesFromFile(file);
if(bdata.length==0){
System.out.println("Error, could not read file: tomography.pdf");
}
}
catch(Exception e){
System.out.println("Reading tomography.owl failed: "+e.getMessage());
e.printStackTrace();
}
Then upload the file to a project. In this case, the tomography.pdf file was uploaded to the Tomography
project.
CIReturnObject ro = CIPut.ciUploadFile(_ciClient, "Tomography", "tomography.pdf", bdata, "udata",
true, true);
if(ro.gStatus.equals("0")){
System.out.println("Object uploaded, referenced via url : "+ro.gFileURL);
}else{
System.out.println("Upload failed: "+ro.gMessage);
}
This time, notice the last parameter of the uploadFile method. This parameter specifies that this will be
a binary upload. The CI Client API will … the file’s contents and upload them to the server. The server
will then perform the same, but inverse, transformation and place the contents on the server.
NOTE: On the CI Server website there are instructions describing the requirements of the server, i.e.,
what modules should be installed as well as instructions setting up content types on a CI Server. The CI
Client API can check some of these and we do, but others we can’t. It is highly advisable that the server
be setup appropriately to avoid issues with creating new resources on the server.
There are other options to the uploadFile method. Look at the JavaDoc API reference for more
information.
Downloading a resource:
In order to download a resource, specify the project and resource name that uniquely identifies the
resource. In addition, specify if the resource download will be binary or not.
To download a text file, perform the following:
1. Download the file, setting binary to false:
CIReturnObject ro = CIGet.ciDownloadFile(_ciClient, "testproj", "tomography.owl", false, false);
The first false argument specifies that the resource should NOT be checked out, set it to true if
the resource should be checked out, i.e., reserved for the current user.
The second false argument specifies that the resource download is not a binary download, that
is, there should be no encryption done to protect the values in the resource.
2. Obtain the content in a String variable from the return object’s gFile variable:
if(ro.gStatus.equals("0")){
System.out.println(“The file was: “+ro.gFile);
}else{
System.out.println("Download failed: "+ro.gMessage);
}
To download a binary file, perform the following:
1. Download the file, setting binary to true:
CIReturnObject ro = CIGet.ciDownloadFile(_ciClient, "testproj", "tomography.pdf", true, true);
The first true argument specifies that the resource should be checked out. After running this,
the resource is reserved for this user until it is checked in or the checkout is released. Set this
variable to false if the file should not be reserved upon download.
The second true argument specifies that the download is a binary download, it should be
encrypted.
3. Obtain the content in a byte array from the return object’s gBinaryFile variable:
try{
FileOutputStream fos = null;
String strFilePath = "C:\\tomograpy.pdf";
fos = new FileOutputStream(strFilePath);
if(ro.gStatus.equals("0")){
fos.write(ro.gBinaryFile);
System.out.println(“Download succeeded”);
}else{
System.out.println("Download failed: "+ro.gMessage);
}
}
catch(FileNotFoundException fnf_ex){
System.out.println("FileNotFoundException : " + fnf_ex);
}
catch(IOException io_ex){
System.out.println("IOException : " + io_ex);
}
A text download, non-binary, takes less memory space to download. In some cases, users will never
download binary files. If this is the case, they should always set the download binary argument to false.
If a user is not sure, it would be better to download as binary because this will assure that the
appropriate encryption is performed to maintain the content of the resource.