PageRenderTime 51ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/servers/sip-presence/xdm/server/tests/src/test/java/org/openxdm/xcap/client/test/subscription/SubscribeDocumentTest.java

http://mobicents.googlecode.com/
Java | 586 lines | 375 code | 118 blank | 93 comment | 38 complexity | 87b592edbd33da42f52990633269e725 MD5 | raw file
Possible License(s): LGPL-3.0, GPL-3.0, LGPL-2.1, GPL-2.0, CC-BY-SA-3.0, CC0-1.0, Apache-2.0, BSD-3-Clause
  1. /*
  2. * JBoss, Home of Professional Open Source
  3. * Copyright 2011, Red Hat, Inc. and individual contributors
  4. * by the @authors tag. See the copyright.txt in the distribution for a
  5. * full listing of individual contributors.
  6. *
  7. * This is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU Lesser General Public License as
  9. * published by the Free Software Foundation; either version 2.1 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * This software is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this software; if not, write to the Free
  19. * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  20. * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  21. */
  22. package org.openxdm.xcap.client.test.subscription;
  23. import static org.junit.Assert.assertTrue;
  24. import gov.nist.javax.sip.Utils;
  25. import java.io.IOException;
  26. import java.io.StringReader;
  27. import java.net.URI;
  28. import java.net.URISyntaxException;
  29. import java.text.ParseException;
  30. import java.util.ArrayList;
  31. import java.util.Properties;
  32. import java.util.concurrent.Semaphore;
  33. import javax.management.InstanceNotFoundException;
  34. import javax.management.MBeanException;
  35. import javax.management.MalformedObjectNameException;
  36. import javax.management.ReflectionException;
  37. import javax.naming.NamingException;
  38. import javax.sip.ClientTransaction;
  39. import javax.sip.Dialog;
  40. import javax.sip.DialogTerminatedEvent;
  41. import javax.sip.IOExceptionEvent;
  42. import javax.sip.InvalidArgumentException;
  43. import javax.sip.ListeningPoint;
  44. import javax.sip.RequestEvent;
  45. import javax.sip.ResponseEvent;
  46. import javax.sip.SipException;
  47. import javax.sip.SipFactory;
  48. import javax.sip.SipListener;
  49. import javax.sip.SipProvider;
  50. import javax.sip.SipStack;
  51. import javax.sip.TimeoutEvent;
  52. import javax.sip.TransactionTerminatedEvent;
  53. import javax.sip.address.Address;
  54. import javax.sip.address.AddressFactory;
  55. import javax.sip.address.SipURI;
  56. import javax.sip.header.CSeqHeader;
  57. import javax.sip.header.CallIdHeader;
  58. import javax.sip.header.ContactHeader;
  59. import javax.sip.header.EventHeader;
  60. import javax.sip.header.FromHeader;
  61. import javax.sip.header.HeaderFactory;
  62. import javax.sip.header.MaxForwardsHeader;
  63. import javax.sip.header.SubscriptionStateHeader;
  64. import javax.sip.header.ToHeader;
  65. import javax.sip.header.ViaHeader;
  66. import javax.sip.message.MessageFactory;
  67. import javax.sip.message.Request;
  68. import javax.xml.bind.JAXBContext;
  69. import javax.xml.bind.JAXBException;
  70. import junit.framework.JUnit4TestAdapter;
  71. import org.apache.commons.httpclient.HttpException;
  72. import org.apache.log4j.Logger;
  73. import org.junit.After;
  74. import org.junit.Before;
  75. import org.junit.Test;
  76. import org.mobicents.xcap.client.XcapResponse;
  77. import org.mobicents.xcap.client.uri.DocumentSelectorBuilder;
  78. import org.mobicents.xcap.client.uri.UriBuilder;
  79. import org.openxdm.xcap.client.test.AbstractXDMJunitTest;
  80. import org.openxdm.xcap.client.test.ServerConfiguration;
  81. import org.openxdm.xcap.common.xcapdiff.DocumentType;
  82. import org.openxdm.xcap.common.xcapdiff.XcapDiff;
  83. /**
  84. * first puts a new doc through xcap then subscribes it through sip, etag from xcap put response and notify must match.
  85. * Then update document through xcap and a notify with old and new etag should arrive.
  86. * Finally delete document and a notify with old etag should arrive.
  87. * Unsubscribe to clean up.
  88. */
  89. public class SubscribeDocumentTest extends AbstractXDMJunitTest implements SipListener {
  90. private static Logger logger = Logger.getLogger(SubscribeDocumentTest.class);
  91. public static junit.framework.Test suite() {
  92. return new JUnit4TestAdapter(SubscribeDocumentTest.class);
  93. }
  94. protected enum Tests {
  95. test1,
  96. test2,
  97. test3,
  98. test4
  99. }
  100. protected Tests testRunning;
  101. protected String subscriberUsername = "eduardo";
  102. protected String domain = "openxdm.org";
  103. protected String subscriberSipUri = "sip:"+subscriberUsername+"@" + domain;
  104. protected SipProvider sipProvider;
  105. protected AddressFactory addressFactory;
  106. protected MessageFactory messageFactory;
  107. protected HeaderFactory headerFactory;
  108. protected SipStack sipStack;
  109. protected ContactHeader contactHeader;
  110. protected String notifierPort;
  111. protected String transport;
  112. protected ListeningPoint listeningPoint;
  113. protected Dialog subscriberDialog;
  114. protected String subscriberToTag;
  115. protected String newEtag;
  116. protected String previousEtag;
  117. // a sempahore to control processing using async events
  118. protected Semaphore semaphore = new Semaphore(1);
  119. protected String getDocumentSelector() {
  120. return DocumentSelectorBuilder.getUserDocumentSelectorBuilder(appUsage.getAUID(),user,documentName).toPercentEncodedString();
  121. }
  122. protected URI getDocumentXcapURI() throws URISyntaxException {
  123. // create uri to put doc
  124. UriBuilder uriBuilder = new UriBuilder()
  125. .setSchemeAndAuthority("http://"+ServerConfiguration.SERVER_HOST+":"+ServerConfiguration.SERVER_PORT)
  126. .setXcapRoot(ServerConfiguration.SERVER_XCAP_ROOT+"/")
  127. .setDocumentSelector(getDocumentSelector());
  128. return uriBuilder.toURI();
  129. }
  130. protected String getTest1XcapContent() {
  131. return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
  132. "<resource-lists xmlns=\"urn:ietf:params:xml:ns:resource-lists\">" +
  133. "<list>" +
  134. "<entry uri=\""+appUsage.getAUID()+"/users/"+user+"/"+documentName+"\"/>" +
  135. "</list>" +
  136. "</resource-lists>";
  137. }
  138. protected void sendTest1XcapRequest() throws IOException, URISyntaxException {
  139. // ensure doc does not exists
  140. client.delete(getDocumentXcapURI(),getAssertedUserIdHeaders(client.getHeaderFactory(), user),null);
  141. // send put request and get response
  142. XcapResponse putResponse = client.put(getDocumentXcapURI(),appUsage.getMimetype(),getTest1XcapContent(),getAssertedUserIdHeaders(client.getHeaderFactory(), user),null);
  143. // check put response
  144. assertTrue("Put response must exists",putResponse != null);
  145. assertTrue("Put response code should be 200 or 201",putResponse.getCode() == 201 || putResponse.getCode() == 200);
  146. // set initial etag
  147. newEtag = putResponse.getETag();
  148. }
  149. protected void sendTest2XcapRequest() throws IOException, URISyntaxException {
  150. String content =
  151. "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
  152. "<resource-lists xmlns=\"urn:ietf:params:xml:ns:resource-lists\">" +
  153. "<list/>" +
  154. "</resource-lists>";
  155. // send put request and get response
  156. XcapResponse putResponse = client.put(getDocumentXcapURI(),appUsage.getMimetype(),content,getAssertedUserIdHeaders(client.getHeaderFactory(), user),null);
  157. // check put response
  158. assertTrue("Put response must exists",putResponse != null);
  159. assertTrue("Put response code should be 200",putResponse.getCode() == 200);
  160. // set etags
  161. previousEtag = newEtag;
  162. newEtag = putResponse.getETag();
  163. }
  164. protected void sendTest3XcapRequest() throws IOException, URISyntaxException {
  165. // send put request and get response
  166. XcapResponse deleteResponse = client.delete(getDocumentXcapURI(),getAssertedUserIdHeaders(client.getHeaderFactory(), user),null);
  167. // set previous etag
  168. previousEtag = newEtag;
  169. // check put response
  170. assertTrue("Delete response must exists",deleteResponse != null);
  171. assertTrue("Delete response code should be 200",deleteResponse.getCode() == 200);
  172. }
  173. /**
  174. * puts a new doc through xcap, store etag of response and then subscribes doc through sip
  175. * @throws InvalidArgumentException
  176. * @throws ParseException
  177. * @throws SipException
  178. * @throws URISyntaxException
  179. */
  180. @Test
  181. public void test() throws HttpException, IOException, JAXBException, InterruptedException, ParseException, InvalidArgumentException, SipException, URISyntaxException {
  182. // set test state machine
  183. testRunning = Tests.test1;
  184. sendTest1XcapRequest();
  185. // send subscribe
  186. sendInitialSubscribe();
  187. // let's wait for test to succeed or timeout
  188. synchronized (this) {
  189. this.wait(15000);
  190. }
  191. assertTrue("Test timer expired (15 secs)",passed);
  192. }
  193. @SuppressWarnings({ "rawtypes", "unchecked" })
  194. private void sendInitialSubscribe() throws ParseException, InvalidArgumentException, SipException {
  195. // create >From Header
  196. Address address = addressFactory.createAddress(subscriberSipUri);
  197. FromHeader fromHeader = headerFactory.createFromHeader(
  198. address, Utils.getInstance().generateTag());
  199. // create To Header
  200. ToHeader toHeader = headerFactory.createToHeader(address,
  201. null);
  202. // Create ViaHeaders
  203. ArrayList viaHeaders = new ArrayList();
  204. int port = sipProvider.getListeningPoint(transport).getPort();
  205. ViaHeader viaHeader = headerFactory.createViaHeader(ServerConfiguration.SERVER_HOST,
  206. port, transport, null);
  207. viaHeaders.add(viaHeader);
  208. // Create a new CallId header
  209. CallIdHeader callIdHeader = sipProvider.getNewCallId();
  210. // Create a new Cseq header
  211. CSeqHeader cSeqHeader = headerFactory.createCSeqHeader(1L,
  212. Request.SUBSCRIBE);
  213. // Create a new MaxForwardsHeader
  214. MaxForwardsHeader maxForwards = headerFactory
  215. .createMaxForwardsHeader(70);
  216. // Create the request.
  217. Request request = messageFactory.createRequest(address.getURI(),
  218. Request.SUBSCRIBE, callIdHeader, cSeqHeader, fromHeader,
  219. toHeader, viaHeaders, maxForwards);
  220. // Create contact headers
  221. SipURI contactURI = addressFactory.createSipURI(subscriberUsername, listeningPoint.getIPAddress());
  222. contactURI.setTransportParam(transport);
  223. contactURI.setPort(port);
  224. // add the contact address.
  225. Address contactAddress = addressFactory.createAddress(contactURI);
  226. // create and save contact header
  227. contactHeader = headerFactory.createContactHeader(contactAddress);
  228. request.addHeader(contactHeader);
  229. // add route
  230. request.addHeader(headerFactory.createRouteHeader(addressFactory
  231. .createAddress("<sip:"+ServerConfiguration.SERVER_HOST+":" + notifierPort
  232. + ";transport=" + transport + ";lr>")));
  233. // Create an event header for the subscription.
  234. EventHeader eventHeader = headerFactory.createEventHeader("xcap-diff");
  235. eventHeader.setParameter("diff-processing", "aggregate");
  236. request.addHeader(eventHeader);
  237. // add content
  238. request.setContent(getTest1XcapContent(), headerFactory.createContentTypeHeader("application", "resource-lists+xml"));
  239. // create the client transaction.
  240. ClientTransaction clientTransaction = sipProvider.getNewClientTransaction(request);
  241. // save the dialog
  242. this.subscriberDialog = clientTransaction.getDialog();
  243. // send the request out.
  244. clientTransaction.sendRequest();
  245. }
  246. protected XcapDiff processNotify(RequestEvent requestEvent) throws ParseException, SipException, InvalidArgumentException, JAXBException {
  247. Request notify = requestEvent.getRequest();
  248. javax.sip.message.Response response = messageFactory.createResponse(200, notify);
  249. // SHOULD add a Contact
  250. ContactHeader contact = (ContactHeader) contactHeader.clone();
  251. ((SipURI)contact.getAddress().getURI()).setParameter( "id", "sub" );
  252. response.addHeader( contact );
  253. requestEvent.getServerTransaction().sendResponse(response);
  254. SubscriptionStateHeader subscriptionState = (SubscriptionStateHeader) requestEvent.getRequest().getHeader(SubscriptionStateHeader.NAME);
  255. assertTrue("subscription not active", subscriptionState.getState().equalsIgnoreCase(SubscriptionStateHeader.ACTIVE));
  256. // unmarshall content
  257. StringReader stringReader = new StringReader(new String(requestEvent.getRequest().getRawContent()));
  258. XcapDiff xcapDiff = (XcapDiff) jaxbContext.createUnmarshaller().unmarshal(stringReader);
  259. assertTrue("unexpected xcap root in xcap diff",xcapDiff.getXcapRoot().equals("http://"+ServerConfiguration.SERVER_HOST+":"+ServerConfiguration.SERVER_PORT+ServerConfiguration.SERVER_XCAP_ROOT+"/"));
  260. stringReader.close();
  261. return xcapDiff;
  262. }
  263. /*
  264. * etag from xcap put response and notify must match.
  265. */
  266. protected void processTest1Notify(RequestEvent requestEvent) throws JAXBException, ParseException, SipException, InvalidArgumentException {
  267. XcapDiff xcapDiff = processNotify(requestEvent);
  268. assertTrue("not a single document element inside xcap diff document received", xcapDiff.getDocumentOrElementOrAttribute().size() == 1 && xcapDiff.getDocumentOrElementOrAttribute().get(0) instanceof DocumentType);
  269. DocumentType documentType = (DocumentType) xcapDiff.getDocumentOrElementOrAttribute().get(0);
  270. assertTrue("doc selector is not "+getDocumentSelector(), documentType.getSel() != null && documentType.getSel().equals(getDocumentSelector()));
  271. assertTrue("previous etag is set", documentType.getPreviousEtag() == null || documentType.getPreviousEtag().equals(""));
  272. assertTrue("new etag ("+documentType.getNewEtag()+") doesn't match one received in XCAP PUT response ("+newEtag+")", documentType.getNewEtag() != null && documentType.getNewEtag().equals(newEtag));
  273. }
  274. // ---- TEST 2
  275. private void doTest2() throws InterruptedException, HttpException, IOException, URISyntaxException {
  276. testRunning = Tests.test2;
  277. sendTest2XcapRequest();
  278. }
  279. protected void processTest2Notify(RequestEvent requestEvent) throws ParseException, SipException, InvalidArgumentException, JAXBException {
  280. XcapDiff xcapDiff = processNotify(requestEvent);
  281. assertTrue("not a single document element inside xcap diff document received", xcapDiff.getDocumentOrElementOrAttribute().size() == 1 && xcapDiff.getDocumentOrElementOrAttribute().get(0) instanceof DocumentType);
  282. DocumentType documentType = (DocumentType) xcapDiff.getDocumentOrElementOrAttribute().get(0);
  283. assertTrue("doc selector is not "+getDocumentSelector(), documentType.getSel() != null && documentType.getSel().equals(getDocumentSelector()));
  284. assertTrue("previous etag ("+documentType.getPreviousEtag()+") doesn't match one received in first XCAP PUT response ("+previousEtag+")", documentType.getPreviousEtag() != null && documentType.getPreviousEtag().equals(previousEtag));
  285. assertTrue("new etag ("+documentType.getNewEtag()+") doesn't match one received in XCAP PUT response ("+newEtag+")", documentType.getNewEtag() != null && documentType.getNewEtag().equals(newEtag));
  286. }
  287. // ---- TEST 3
  288. private void doTest3() throws InterruptedException, HttpException, IOException, URISyntaxException {
  289. testRunning = Tests.test3;
  290. sendTest3XcapRequest();
  291. }
  292. protected void processTest3Notify(RequestEvent requestEvent) throws ParseException, SipException, InvalidArgumentException, JAXBException {
  293. XcapDiff xcapDiff = processNotify(requestEvent);
  294. assertTrue("not a single document element inside xcap diff document received", xcapDiff.getDocumentOrElementOrAttribute().size() == 1 && xcapDiff.getDocumentOrElementOrAttribute().get(0) instanceof DocumentType);
  295. DocumentType documentType = (DocumentType) xcapDiff.getDocumentOrElementOrAttribute().get(0);
  296. assertTrue("doc selector is not "+getDocumentSelector(), documentType.getSel() != null && documentType.getSel().equals(getDocumentSelector()));
  297. assertTrue("previous etag doesn't match one received in second XCAP PUT response", documentType.getPreviousEtag() != null && documentType.getPreviousEtag().equals(previousEtag));
  298. assertTrue("new etag is not null", documentType.getNewEtag() == null);
  299. }
  300. // ---- TEST 4
  301. private void doTest4() throws ParseException, SipException, InvalidArgumentException {
  302. testRunning = Tests.test4;
  303. unsubscribe();
  304. }
  305. private void unsubscribe() throws ParseException, SipException, InvalidArgumentException {
  306. Request request = this.subscriberDialog
  307. .createRequest(Request.SUBSCRIBE);
  308. ToHeader toHeader = (ToHeader)request.getHeader(ToHeader.NAME);
  309. if (toHeader.getTag() == null) {
  310. toHeader.setTag(subscriberToTag);
  311. }
  312. // Create a new MaxForwardsHeader
  313. request.setHeader(headerFactory
  314. .createMaxForwardsHeader(70));
  315. // Create an event header for the subscription.
  316. EventHeader eventHeader = headerFactory.createEventHeader("xcap-diff");
  317. eventHeader.setParameter("diff-processing", "aggregate");
  318. request.addHeader(eventHeader);
  319. // add expires header
  320. request.setExpires(headerFactory.createExpiresHeader(0));
  321. // create client transaction
  322. ClientTransaction clientTransaction = sipProvider.getNewClientTransaction(request);
  323. // send request
  324. clientTransaction.sendRequest();
  325. }
  326. protected void processTest4Notify(RequestEvent requestEvent) throws ParseException, SipException, InvalidArgumentException, JAXBException {
  327. Request notify = requestEvent.getRequest();
  328. javax.sip.message.Response response = messageFactory.createResponse(200, notify);
  329. // SHOULD add a Contact
  330. ContactHeader contact = (ContactHeader) contactHeader.clone();
  331. ((SipURI)contact.getAddress().getURI()).setParameter( "id", "sub" );
  332. response.addHeader( contact );
  333. requestEvent.getServerTransaction().sendResponse(response);
  334. SubscriptionStateHeader subscriptionState = (SubscriptionStateHeader) requestEvent.getRequest().getHeader(SubscriptionStateHeader.NAME);
  335. assertTrue("subscription didn't terminate", subscriptionState.getState().equalsIgnoreCase(SubscriptionStateHeader.TERMINATED));
  336. }
  337. // --- METHODS TO PROCESS SIP REQUESTS AND RESPONSES
  338. public void processRequest(RequestEvent requestEvent) {
  339. System.out.println("Request rcvd {\n"+requestEvent.getRequest()+"\n}");
  340. Request request = requestEvent.getRequest();
  341. if (request.getMethod().equals(Request.NOTIFY)) {
  342. try {
  343. switch (testRunning) {
  344. case test1:
  345. processTest1Notify(requestEvent);
  346. semaphore.acquire();
  347. doTest2();
  348. semaphore.release();
  349. break;
  350. case test2:
  351. semaphore.acquire();
  352. processTest2Notify(requestEvent);
  353. doTest3();
  354. semaphore.release();
  355. break;
  356. case test3:
  357. processTest3Notify(requestEvent);
  358. doTest4();
  359. break;
  360. case test4:
  361. processTest4Notify(requestEvent);
  362. setTestResult(true);
  363. break;
  364. default:
  365. System.err.println("unknown test");
  366. setTestResult(false);
  367. }
  368. }
  369. catch(Exception e) {
  370. e.printStackTrace();
  371. setTestResult(false);
  372. }
  373. }
  374. }
  375. public void processResponse(ResponseEvent responseReceivedEvent) {
  376. System.out.println("Response received:\n" + responseReceivedEvent.getResponse());
  377. assertTrue("received response to subscribe which signals that subscription was not approved", responseReceivedEvent.getResponse().getStatusCode() == 200);
  378. if (subscriberToTag == null) {
  379. subscriberToTag = ((ToHeader)responseReceivedEvent.getResponse().getHeader(ToHeader.NAME)).getTag();
  380. }
  381. }
  382. // --- UNUSED SIP LISTENER METHODS
  383. public void processDialogTerminated(DialogTerminatedEvent arg0) {
  384. // TODO Auto-generated method stub
  385. }
  386. public void processIOException(IOExceptionEvent arg0) {
  387. throw new RuntimeException("processIOException(IOExceptionEvent"+arg0+")");
  388. }
  389. public void processTimeout(TimeoutEvent arg0) {
  390. throw new RuntimeException("processTimeout(TimeoutEvent="+arg0+")");
  391. }
  392. public void processTransactionTerminated(TransactionTerminatedEvent arg0) {
  393. // TODO Auto-generated method stub
  394. }
  395. // ---- TEST setup/cleanup
  396. @Before
  397. public void runBefore() throws IOException, InterruptedException, MalformedObjectNameException, InstanceNotFoundException, NullPointerException, MBeanException, ReflectionException, NamingException {
  398. super.user = subscriberSipUri;
  399. super.runBefore();
  400. try {
  401. // init sip stack
  402. notifierPort = "5060";
  403. transport = "udp";
  404. SipFactory sipFactory = SipFactory.getInstance();
  405. sipFactory.setPathName("gov.nist");
  406. Properties properties = new Properties();
  407. properties.setProperty("javax.sip.USE_ROUTER_FOR_ALL_URIS", "false");
  408. properties.setProperty("javax.sip.STACK_NAME", "subscriber");
  409. properties.setProperty("gov.nist.javax.sip.DEBUG_LOG",
  410. "subscriberdebug.txt");
  411. properties.setProperty("gov.nist.javax.sip.SERVER_LOG",
  412. "subscriberlog.txt");
  413. properties.setProperty("javax.sip.FORKABLE_EVENTS", "foo");
  414. // Set to 0 in your production code for max speed.
  415. // You need 16 for logging traces. 32 for debug + traces.
  416. // Your code will limp at 32 but it is best for debugging.
  417. properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "0");
  418. sipStack = sipFactory.createSipStack(properties);
  419. logger.info("createSipStack " + sipStack);
  420. headerFactory = sipFactory.createHeaderFactory();
  421. addressFactory = sipFactory.createAddressFactory();
  422. messageFactory = sipFactory.createMessageFactory();
  423. this.listeningPoint = sipStack.createListeningPoint(ServerConfiguration.SERVER_HOST, 6060,
  424. transport);
  425. sipProvider = sipStack.createSipProvider(listeningPoint);
  426. sipProvider.addSipListener(this);
  427. }
  428. catch (Exception e) {
  429. throw new RuntimeException("Unable to start sip stack. Exception msg: "+e.getMessage());
  430. }
  431. }
  432. @After
  433. public void runAfter() throws IOException, InstanceNotFoundException, MBeanException, ReflectionException {
  434. super.runAfter();
  435. try {
  436. sipProvider.removeSipListener(this);
  437. sipStack.deleteSipProvider(sipProvider);
  438. sipStack.deleteListeningPoint(listeningPoint);
  439. sipStack.stop();
  440. }
  441. catch (Exception e) {
  442. throw new RuntimeException("Unable to stop sip stack. Exception msg: "+e.getMessage());
  443. }
  444. }
  445. private boolean passed = false;
  446. /**
  447. * sets test result
  448. * @param result
  449. */
  450. protected void setTestResult(boolean result) {
  451. passed = result;
  452. synchronized (this) {
  453. this.notifyAll();
  454. }
  455. }
  456. // ------ JAXB resource lists and xcap diff context
  457. protected static final JAXBContext jaxbContext = initJAXBContext();
  458. private static JAXBContext initJAXBContext() {
  459. try {
  460. return JAXBContext.newInstance(
  461. "org.openxdm.xcap.common.xcapdiff" +
  462. ":org.openxdm.xcap.client.appusage.resourcelists.jaxb");
  463. } catch (JAXBException e) {
  464. logger.error("failed to create jaxb context");
  465. return null;
  466. }
  467. }
  468. }