If you're just interested in using the library, the jar can be found here. We will be discontinuing the releases here on GitHub.
Either clone:
git clone https://github.com/adlnet/jxapi
run mvn package
or
Download directly from the Central Repository
import gov.adlnet.xapi.client.StatementClient;
To instantiate a new StatementClient you need the URL to an LRS, and a username/password combo that works for HTTP BasicAuth
StatementClient client = new StatementClient(url, username, password);
//URL example: https://lrs.adlnet.gov/xAPI
This has the possiblitiy of throwing a MalformedURLException
if an invalid URL is passed it.
import gov.adlnet.xapi.model.*;
This library has some overloaded model constructors to simplify building common parts of a statement.
// create an activity with just an id
Activity activity = new Activity("http://activity.com");
System.out.println("Activity");
System.out.println( "\t" + activity );
// prints...
// Activity
// http://activity.com
// create an agent with name and mbox
Agent agent = new Agent("tommy", "mailto:tommy@example.com");
System.out.println("Agent - name & mbox");
System.out.println("\t" + agent);
// prints...
// Agent - name & mbox
// tommy
// create an agent with just an mbox
Agent agent = new Agent(null, "mailto:tommy@example.com")
System.out.println("Agent - mbox");
System.out.println("\t" + agent);
// prints...
// Agent - mbox
// mailto:tommy@example.com
// create an agent with openid
Agent agent = new Agent(null, new URI("http://tom-is-me")));
System.out.println("Agent - openid");
System.out.println("\t" + agent);
// prints...
// Agent - openid
// http://tom-is-me
// create an agent with an account
Agent agent = new Agent("", new Account("joe", "http://joe.com"));
System.out.println("Agent - account");
System.out.println("\t" + agent);
// prints...
// Agent - account
// joe (http://joe.com)
// use an ADL verb
System.out.println("ADL verb");
System.out.println("\t" + Verbs.answered());
// prints...
// ADL verb
// answered
// create a verb
Verb verb = new Verb("http://my.verb/didsomething");
System.out.println("my verb");
System.out.println("\t" + verb);
// prints...
// my verb
// http://my.verb/didsomething
// create a verb with display
HashMap<String, String> disp = new HashMap<String, String>();
disp.put("fr", "le ran");
disp.put("en-US", "ran");
Verb verb = new Verb("http://my.verb/ran", disp);
System.out.println("my ran verb");
System.out.println("\t" + verb);
// prints...
// my ran verb
// ran
// create a basic statement
System.out.println("Statement ");
System.out.println("\t" + new Statement(new Agent("tom", "mailto:tom@example.com"),
new Verb("http://verb.com/did", getVerbDisp()),
new Activity("act:id")));
// prints...
// Statement
// 7fdbc0cc-aef8-47d6-97ad-b1929afc34b5: tom did act:id
To publish a statement you'll need a Verb (There is a predefined list of ADL verbs available in gov.adlnet.xapi.model.Verbs
class), an Actor who completed the activity the statement describes, and the Statement object, which can be an Activity, a SubStatement, or a StatementRef
StatementClient client = new StatementClient(LRS_URI, USERNAME,
PASSWORD);
Statement statement = new Statement();
Agent agent = new Agent();
Verb verb = Verbs.experienced();
agent.setMbox("mailto:test@example.com");
agent.setName("Tester McTesterson");
statement.setActor(agent);
statement.setId(UUID.randomUUID().toString());
statement.setVerb(verb);
Activity a = new Activity();
a.setId("http://example.com");
statement.setObject(a);
ActivityDefinition ad = new ActivityDefinition();
ad.setChoices(new ArrayList<InteractionComponent>());
InteractionComponent ic = new InteractionComponent();
ic.setId("http://example.com");
ic.setDescription(new HashMap<String, String>());
ic.getDescription().put("en-US", "test");
ad.getChoices().add(ic);
ad.setInteractionType("choice");
ad.setMoreInfo("http://example.com");
a.setDefinition(ad);
String publishedId = client.postStatement(statement);
Publishing a statement with an attachment follows the steps for publishing a statement seen above with the addition of adding an attachment. An attachment require a content type, URI usage type, and display. A file URL and a description can optionally be added.
Agent a = new Agent();
a.setMbox(mbox);
Verb v = new Verb("http://example.com/tested");
Activity act = new Activity(activity_id);
Statement statement = new Statement(a, v, act);
ActivityDefinition ad = new ActivityDefinition();
ad.setChoices(new ArrayList<InteractionComponent>());
InteractionComponent ic = new InteractionComponent();
ic.setId("http://example.com");
ic.setDescription(new HashMap<String, String>());
ic.getDescription().put("en-US", "test");
ad.getChoices().add(ic);
ad.setInteractionType("choice");
ArrayList<String> crp = new ArrayList<String>();
crp.add("http://example.com");
ad.setCorrectResponsesPattern(crp);
ad.setMoreInfo("http://example.com");
act.setDefinition(ad);
Attachment att = new Attachment();
HashMap<String, String> display = new HashMap<String, String>();
display.put("en-US", "Test Display.");
att.setDisplay(display);
HashMap<String, String> description = new HashMap<String, String>();
description.put("en-US", "Test Description.");
att.setDescription(description);
URI usageType = new URI("http://example.com/test/usage");
att.setUsageType(usageType);
String attachment = "This is a text/plain test.";
String contentType = "text/plain";
byte[] arr = att.addAttachment(attachment, contentType);
ArrayList<Attachment> attList = new ArrayList<Attachment>();
attList.add(att);
statement.setAttachments(attList);
ArrayList<byte[]> attachedData = new ArrayList<byte[]>();
attachedData.add(arr);
String publishedId = sc.postStatementWithAttachments(statement, contentType, attachedData);
A non text/plain example of an attachment.
Attachment att = new Attachment();
HashMap<String, String> display = new HashMap<String, String>();
display.put("en-US", "Test Display.");
att.setDisplay(display);
String attachment = "../jxapi/src/test/java/config/example.png";
String contentType = "image/png";
byte[] arr = att.addAttachment(attachment, contentType);
ArrayList<Attachment> attList = new ArrayList<Attachment>();
attList = new ArrayList<Attachment>();
attList.add(att);
statement.setAttachments(attList);
ArrayList<byte[]> attachedData = new ArrayList<byte[]>();
attachedData.add(arr);
String publishedId = sc.postStatementWithAttachments(statement, contentType, attachedData);
You can get all the statements from an LRS by calling the getStatements
method on the client
This will return a StatementResult
object, which will have a list of all returned statements along with a string needed to get the next page of results, the code below demonstrates how to get the first page of results.
StatementResult results = client.getStatements()
To get the next page of results call getStatements
with the value returned from getMore
StatementResult nextPage = client.getStatements(previousPage.getMore());
To query an LRS by verb you add a call to filterByVerb
to the above queries
StatementResult results = client.filterByVerb(Verbs.experienced()).getStatements();
Subsequent pages can then be queried as the above example.
There are a number of filters available that function similiarly to filterByVerb
, they are
filterByVerb
filterByActor
filterByActivity
filterByRegistration
filterBySince
filterByUntil
In addition to these preset filters, you can add non-standard filters to the statements query by using addFilter
. For example:
client.addFilter('context.extensions.yourExtension', 'customExtensionValue').getStatements();
These filters can be chained together to created more complex queries, such as
StatementResult results = client.filterByVerb(verb).filterByActivity(activity).getStatements();
You can also specify what data is brought back from the LRS, by calling the include*
methods, the available methods are
includeRelatedActivities
includeRelatedAgents
includeAttachments
To bring back only statement ids from the LRS, include the ids
method call when chaining filters/include methods
Getting statements with attachments.
AttachmentResult attachmntResult = sc.getStatementsWithAttachments();
Statement s = attachmntResult.getXapiStatements().getStatements().get(0);
//Get the attached file.
byte[] actualArray = attachmntResult.getAttachment().get(sha2).getAttachment().get(i);
Getting a statement with a statement ID.
AttachmentResult attachmntResult = sc.getStatementWithAttachments(statementId);
Note: Before testing, please change the config properties in test/config to your own endpoint and credentials.
We welcome contributions to this project. Fork this repository, make changes, and submit pull requests. If you're not comfortable with editing the code, please submit an issue and we'll be happy to address it.
Copyright ©2016 Advanced Distributed Learning
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.