PageRenderTime 86ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/src/org/zoolu/sip/message/BaseMessageOtp.java

https://github.com/sortir/sipdroid
Java | 480 lines | 310 code | 53 blank | 117 comment | 70 complexity | 436d44ba8d3afed34a549eb17bf7513f MD5 | raw file
Possible License(s): GPL-3.0, BSD-3-Clause
  1. /*
  2. * Copyright (C) 2005 Luca Veltri - University of Parma - Italy
  3. *
  4. * This file is part of MjSip (http://www.mjsip.org)
  5. *
  6. * MjSip is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * MjSip is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with MjSip; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. *
  20. * Author(s):
  21. * Luca Veltri (luca.veltri@unipr.it)
  22. * Nitin Khanna, Hughes Systique Corp. (Reason: Android specific change, optmization, bug fix)
  23. */
  24. package org.zoolu.sip.message;
  25. import org.zoolu.sip.provider.*;
  26. import org.zoolu.sip.header.*;
  27. import org.zoolu.net.UdpPacket;
  28. import java.util.*;
  29. /**
  30. * Class BaseMessageOtp implements a generic SIP Message. It extends class
  31. * BaseMessage adding one-time-parsing functionality (it parses the entire
  32. * Message just when it is costructed). <p/> At the contrary, class BaseMessage
  33. * works in a just-in-time manner (it parses the message each time a particular
  34. * header field is requested).
  35. */
  36. public abstract class BaseMessageOtp extends BaseMessage {
  37. protected RequestLine request_line;
  38. protected StatusLine status_line;
  39. protected Vector<Header> headers;
  40. protected String body;
  41. /** Inits empty Message */
  42. private void init() {
  43. request_line = null;
  44. status_line = null;
  45. headers = null;
  46. body = null;
  47. }
  48. /** Costructs a new empty Message */
  49. public BaseMessageOtp() {
  50. init();
  51. headers = new Vector<Header>();
  52. }
  53. /** Costructs a new Message */
  54. public BaseMessageOtp(byte[] data, int offset, int len) {
  55. init();
  56. parseIt(new String(data, offset, len));
  57. }
  58. /** Costructs a new Message */
  59. public BaseMessageOtp(UdpPacket packet) {
  60. init();
  61. parseIt(new String(packet.getData(), packet.getOffset(), packet
  62. .getLength()));
  63. }
  64. /** Costructs a new Message */
  65. public BaseMessageOtp(String str) {
  66. init();
  67. parseIt(str);
  68. }
  69. /** Costructs a new Message */
  70. public BaseMessageOtp(BaseMessageOtp msg) {
  71. init();
  72. remote_addr = msg.remote_addr;
  73. remote_port = msg.remote_port;
  74. transport_proto = msg.transport_proto;
  75. connection_id = msg.connection_id;
  76. // packet_length=msg.packet_length;
  77. request_line = msg.request_line;
  78. status_line = msg.status_line;
  79. headers = new Vector<Header>();
  80. for (int i = 0; i < msg.headers.size(); i++)
  81. headers.addElement(msg.headers.elementAt(i));
  82. body = msg.body;
  83. }
  84. /** Sets the entire message */
  85. public void setMessage(String str) {
  86. parseIt(str);
  87. }
  88. /** Parses the Message from a String. */
  89. private void parseIt(String str) {
  90. SipParser par = new SipParser(str);
  91. String version = str.substring(0, 4);
  92. if (version.equalsIgnoreCase("SIP/"))
  93. status_line = par.getStatusLine();
  94. else
  95. request_line = par.getRequestLine();
  96. headers = new Vector<Header>();
  97. Header h = par.getHeader();
  98. while (h != null) {
  99. headers.addElement(h);
  100. h = par.getHeader();
  101. }
  102. ContentLengthHeader clh = getContentLengthHeader();
  103. if (clh != null) {
  104. int len = clh.getContentLength();
  105. body = par.getString(len);
  106. } else if (getContentTypeHeader() != null) {
  107. body = par.getRemainingString();
  108. if (body.length() == 0)
  109. body = null;
  110. }
  111. }
  112. /** Gets string representation of Message */
  113. public String toString() {
  114. StringBuffer str = new StringBuffer();
  115. if (request_line != null)
  116. str.append(request_line.toString());
  117. else if (status_line != null)
  118. str.append(status_line.toString());
  119. for (int i = 0; i < headers.size(); i++)
  120. str.append(((Header) headers.elementAt(i)).toString());
  121. str.append("\r\n");
  122. if (body != null)
  123. str.append(body);
  124. return str.toString();
  125. }
  126. /** Gets message length */
  127. public int getLength() {
  128. return toString().length();
  129. }
  130. // **************************** Requests ****************************/
  131. /** Whether Message is a Request */
  132. public boolean isRequest() {
  133. if (request_line != null)
  134. return true;
  135. else
  136. return false;
  137. }
  138. /** Whether Message is a <i>method</i> request */
  139. public boolean isRequest(String method) {
  140. if (request_line != null
  141. && request_line.getMethod().equalsIgnoreCase(method))
  142. return true;
  143. else
  144. return false;
  145. }
  146. /** Whether Message has Request-line */
  147. protected boolean hasRequestLine() {
  148. return request_line != null;
  149. }
  150. /**
  151. * Gets RequestLine in Message (Returns null if called for no request
  152. * message)
  153. */
  154. public RequestLine getRequestLine() {
  155. return request_line;
  156. }
  157. /** Sets RequestLine of the Message */
  158. public void setRequestLine(RequestLine rl) {
  159. request_line = rl;
  160. }
  161. /** Removes RequestLine of the Message */
  162. public void removeRequestLine() {
  163. request_line = null;
  164. }
  165. // **************************** Responses ****************************/
  166. /** Whether Message is a Response */
  167. public boolean isResponse() throws NullPointerException {
  168. if (status_line != null)
  169. return true;
  170. else
  171. return false;
  172. }
  173. /** Whether Message has Status-line */
  174. protected boolean hasStatusLine() {
  175. return status_line != null;
  176. }
  177. /**
  178. * Gets StautsLine in Message (Returns null if called for no response
  179. * message)
  180. */
  181. public StatusLine getStatusLine() {
  182. return status_line;
  183. }
  184. /** Sets StatusLine of the Message */
  185. public void setStatusLine(StatusLine sl) {
  186. status_line = sl;
  187. }
  188. /** Removes StatusLine of the Message */
  189. public void removeStatusLine() {
  190. status_line = null;
  191. }
  192. // **************************** Generic Headers
  193. // ****************************/
  194. /** Removes Request\Status Line of the Message */
  195. protected void removeFirstLine() {
  196. removeRequestLine();
  197. removeStatusLine();
  198. }
  199. /** Gets the position of header <i>hname</i>. */
  200. protected int indexOfHeader(String hname) {
  201. for (int i = 0; i < headers.size(); i++) {
  202. Header h = (Header) headers.elementAt(i);
  203. if (hname.equalsIgnoreCase(h.getName()))
  204. return i;
  205. }
  206. return -1;
  207. }
  208. /**
  209. * Gets the first Header of specified name (Returns null if no Header is
  210. * found)
  211. */
  212. public Header getHeader(String hname) {
  213. int i = indexOfHeader(hname);
  214. if (i < 0)
  215. return null;
  216. else
  217. return (Header) headers.elementAt(i);
  218. }
  219. /**
  220. * Gets a Vector of all Headers of specified name (Returns empty Vector if
  221. * no Header is found)
  222. */
  223. public Vector<Header> getHeaders(String hname) {
  224. Vector<Header> v = new Vector<Header>();
  225. for (int i = 0; i < headers.size(); i++) {
  226. Header h = (Header) headers.elementAt(i);
  227. if (hname.equalsIgnoreCase(h.getName()))
  228. v.addElement(h);
  229. }
  230. return v;
  231. }
  232. /**
  233. * Adds Header at the top/bottom. The bottom is considered before the
  234. * Content-Length and Content-Type headers
  235. */
  236. public void addHeader(Header header, boolean top) {
  237. if (top)
  238. headers.insertElementAt(header, 0);
  239. else
  240. headers.addElement(header);
  241. }
  242. /** Adds a Vector of Headers at the top/bottom */
  243. public void addHeaders(Vector<Header> headers, boolean top) {
  244. for (int i = 0; i < headers.size(); i++)
  245. if (top)
  246. this.headers.insertElementAt(headers.elementAt(i), i);
  247. else
  248. this.headers.addElement(headers.elementAt(i));
  249. }
  250. /** Adds MultipleHeader(s) <i>mheader</i> at the top/bottom */
  251. public void addHeaders(MultipleHeader mheader, boolean top) {
  252. if (mheader.isCommaSeparated())
  253. addHeader(mheader.toHeader(), top);
  254. else
  255. addHeaders(mheader.getHeaders(), top);
  256. }
  257. /**
  258. * Adds Header before the first header <i>refer_hname</i> .
  259. * <p>
  260. * If there is no header of such type, it is added at top
  261. */
  262. public void addHeaderBefore(Header new_header, String refer_hname) {
  263. int i = indexOfHeader(refer_hname);
  264. if (i < 0)
  265. i = 0;
  266. headers.insertElementAt(new_header, i);
  267. }
  268. /**
  269. * Adds MultipleHeader(s) before the first header <i>refer_hname</i> .
  270. * <p>
  271. * If there is no header of such type, they are added at top
  272. */
  273. public void addHeadersBefore(MultipleHeader mheader, String refer_hname) {
  274. if (mheader.isCommaSeparated())
  275. addHeaderBefore(mheader.toHeader(), refer_hname);
  276. else {
  277. int index = indexOfHeader(refer_hname);
  278. if (index < 0)
  279. index = 0;
  280. Vector<Header> hs = mheader.getHeaders();
  281. for (int k = 0; k < hs.size(); k++)
  282. headers.insertElementAt(hs.elementAt(k), index + k);
  283. }
  284. }
  285. /**
  286. * Adds Header after the first header <i>refer_hname</i> .
  287. * <p>
  288. * If there is no header of such type, it is added at bottom
  289. */
  290. public void addHeaderAfter(Header new_header, String refer_hname) {
  291. int i = indexOfHeader(refer_hname);
  292. if (i >= 0)
  293. i++;
  294. else
  295. i = headers.size();
  296. headers.insertElementAt(new_header, i);
  297. }
  298. /**
  299. * Adds MultipleHeader(s) after the first header <i>refer_hname</i> .
  300. * <p>
  301. * If there is no header of such type, they are added at bottom
  302. */
  303. public void addHeadersAfter(MultipleHeader mheader, String refer_hname) {
  304. if (mheader.isCommaSeparated())
  305. addHeaderAfter(mheader.toHeader(), refer_hname);
  306. else {
  307. int index = indexOfHeader(refer_hname);
  308. if (index >= 0)
  309. index++;
  310. else
  311. index = headers.size();
  312. Vector<Header> hs = mheader.getHeaders();
  313. for (int k = 0; k < hs.size(); k++)
  314. headers.insertElementAt(hs.elementAt(k), index + k);
  315. }
  316. }
  317. /** Removes first Header of specified name */
  318. public void removeHeader(String hname) {
  319. removeHeader(hname, true);
  320. }
  321. /** Removes first (or last) Header of specified name. */
  322. public void removeHeader(String hname, boolean first) {
  323. int index = -1;
  324. for (int i = 0; i < headers.size(); i++) {
  325. Header h = (Header) headers.elementAt(i);
  326. if (hname.equalsIgnoreCase(h.getName())) {
  327. index = i;
  328. if (first)
  329. i = headers.size();
  330. }
  331. }
  332. if (index >= 0)
  333. headers.removeElementAt(index);
  334. }
  335. /** Removes all Headers of specified name */
  336. public void removeAllHeaders(String hname) {
  337. for (int i = 0; i < headers.size(); i++) {
  338. Header h = (Header) headers.elementAt(i);
  339. if (hname.equalsIgnoreCase(h.getName())) {
  340. headers.removeElementAt(i);
  341. i--;
  342. }
  343. }
  344. }
  345. /**
  346. * Sets the Header <i>hd</i> removing any previous headers of the same
  347. * type.
  348. */
  349. public void setHeader(Header hd) {
  350. boolean first = true;
  351. String hname = hd.getName();
  352. for (int i = 0; i < headers.size(); i++) {
  353. Header h = (Header) headers.elementAt(i);
  354. if (hname.equalsIgnoreCase(h.getName())) {
  355. if (first) { // replace it
  356. headers.setElementAt(h, i);
  357. first = false;
  358. } else { // remove it
  359. headers.removeElementAt(i);
  360. i--;
  361. }
  362. }
  363. }
  364. if (first)
  365. headers.addElement(hd);
  366. }
  367. /** Sets MultipleHeader <i>mheader</i> */
  368. public void setHeaders(MultipleHeader mheader) {
  369. if (mheader.isCommaSeparated())
  370. setHeader(mheader.toHeader());
  371. else {
  372. boolean first = true;
  373. String hname = mheader.getName();
  374. for (int i = 0; i < headers.size(); i++) {
  375. Header h = (Header) headers.elementAt(i);
  376. if (hname.equalsIgnoreCase(h.getName())) {
  377. if (first) { // replace it
  378. Vector<Header> hs = mheader.getHeaders();
  379. for (int k = 0; k < hs.size(); k++)
  380. headers.insertElementAt(hs.elementAt(k), i + k);
  381. first = false;
  382. i += hs.size() - 1;
  383. } else { // remove it
  384. headers.removeElementAt(i);
  385. i--;
  386. }
  387. }
  388. }
  389. }
  390. }
  391. // **************************** Specific Headers
  392. // ****************************/
  393. /** Whether Message has Body */
  394. public boolean hasBody() {
  395. return this.body != null;
  396. }
  397. /** Gets body(content) type */
  398. public String getBodyType() {
  399. return getContentTypeHeader().getContentType();
  400. }
  401. /** Sets the message body */
  402. public void setBody(String content_type, String body) {
  403. removeBody();
  404. if (body != null && body.length() > 0) {
  405. setContentTypeHeader(new ContentTypeHeader(content_type));
  406. setContentLengthHeader(new ContentLengthHeader(body.length()));
  407. this.body = body;
  408. } else {
  409. setContentLengthHeader(new ContentLengthHeader(0));
  410. this.body = null;
  411. }
  412. }
  413. /**
  414. * Gets message body. The end of body is evaluated from the Content-Length
  415. * header if present (SIP-RFC compliant), or from the end of message if no
  416. * Content-Length header is present (non-SIP-RFC compliant)
  417. */
  418. public String getBody() {
  419. return this.body;
  420. }
  421. /** Removes the message body (if it exists) and the final empty line */
  422. public void removeBody() {
  423. removeContentLengthHeader();
  424. removeContentTypeHeader();
  425. this.body = null;
  426. }
  427. }