1 /*
2  * Conditions Of Use
3  *
4  * This software was developed by employees of the National Institute of
5  * Standards and Technology (NIST), an agency of the Federal Government.
6  * Pursuant to title 15 Untied States Code Section 105, works of NIST
7  * employees are not subject to copyright protection in the United States
8  * and are considered to be in the public domain.  As a result, a formal
9  * license is not needed to use the software.
10  *
11  * This software is provided by NIST as a service and is expressly
12  * provided "AS IS."  NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED
13  * OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF
14  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT
15  * AND DATA ACCURACY.  NIST does not warrant or make any representations
16  * regarding the use of the software or the results thereof, including but
17  * not limited to the correctness, accuracy, reliability or usefulness of
18  * the software.
19  *
20  * Permission to use this software is contingent upon your acceptance
21  * of the terms of this agreement
22  *
23  * .
24  *
25  */
26 /*******************************************************************************
27  * Product of NIST/ITL Advanced Networking Technologies Division (ANTD).        *
28  *******************************************************************************/
29 package gov.nist.javax.sip.message;
30 
31 import java.text.ParseException;
32 import javax.sip.header.*;
33 
34 import java.util.LinkedList;
35 import java.util.List;
36 import gov.nist.javax.sip.header.*;
37 
38 import javax.sip.message.*;
39 import javax.sip.address.*;
40 import gov.nist.javax.sip.parser.*;
41 
42 /**
43  * Message Factory implementation
44  *
45  * @version 1.2 $Revision: 1.23 $ $Date: 2009/09/08 01:58:40 $
46  * @since 1.1
47  *
48  * @author M. Ranganathan <br/>
49  * @author Olivier Deruelle <br/>
50  *
51  */
52 @SuppressWarnings("unchecked")
53 public class MessageFactoryImpl implements MessageFactory, MessageFactoryExt {
54 
55     private boolean testing = false;
56 
57     private boolean strict  = true;
58 
59     private static String defaultContentEncodingCharset = "UTF-8";
60 
61 
62     /*
63      * The UserAgent header to include for all requests created from this message factory.
64      */
65     private static UserAgentHeader userAgent;
66 
67     /*
68      * The Server header to include
69      */
70     private static ServerHeader server;
71 
72 
setStrict(boolean strict)73     public void setStrict(boolean strict) {
74         this.strict = strict;
75     }
76 
77 
78 
79     /**
80      * This is for testing -- allows you to generate invalid requests
81      */
setTest(boolean flag)82     public void setTest(boolean flag) {
83         this.testing = flag;
84     }
85 
86     /**
87      * Creates a new instance of MessageFactoryImpl
88      */
MessageFactoryImpl()89     public MessageFactoryImpl() {
90     }
91 
92     /**
93      * Creates a new Request message of type specified by the method paramater,
94      * containing the URI of the Request, the mandatory headers of the message
95      * with a body in the form of a Java object and the body content type.
96      *
97      * @param requestURI -
98      *            the new URI object of the requestURI value of this Message.
99      * @param method -
100      *            the new string of the method value of this Message.
101      * @param callId -
102      *            the new CallIdHeader object of the callId value of this
103      *            Message.
104      * @param cSeq -
105      *            the new CSeqHeader object of the cSeq value of this Message.
106      * @param from -
107      *            the new FromHeader object of the from value of this Message.
108      * @param to -
109      *            the new ToHeader object of the to value of this Message.
110      * @param via -
111      *            the new List object of the ViaHeaders of this Message.
112      * @param content -
113      *            the new Object of the body content value of this Message.
114      * @param contentType -
115      *            the new ContentTypeHeader object of the content type value of
116      *            this Message.
117      * @throws ParseException
118      *             which signals that an error has been reached unexpectedly
119      *             while parsing the method or the body.
120      */
createRequest(javax.sip.address.URI requestURI, String method, CallIdHeader callId, CSeqHeader cSeq, FromHeader from, ToHeader to, List via, MaxForwardsHeader maxForwards, ContentTypeHeader contentType, Object content)121     public Request createRequest(javax.sip.address.URI requestURI,
122             String method, CallIdHeader callId, CSeqHeader cSeq,
123             FromHeader from, ToHeader to, List via,
124             MaxForwardsHeader maxForwards, ContentTypeHeader contentType,
125             Object content) throws ParseException {
126         if (requestURI == null || method == null || callId == null
127                 || cSeq == null || from == null || to == null || via == null
128                 || maxForwards == null || content == null
129                 || contentType == null)
130             throw new NullPointerException("Null parameters");
131 
132         SIPRequest sipRequest = new SIPRequest();
133         sipRequest.setRequestURI(requestURI);
134         sipRequest.setMethod(method);
135         sipRequest.setCallId(callId);
136         sipRequest.setCSeq(cSeq);
137         sipRequest.setFrom(from);
138         sipRequest.setTo(to);
139         sipRequest.setVia(via);
140         sipRequest.setMaxForwards(maxForwards);
141         sipRequest.setContent(content, contentType);
142         if ( userAgent != null ) {
143             sipRequest.setHeader(userAgent);
144         }
145 
146         return sipRequest;
147     }
148 
149     /**
150      * Creates a new Request message of type specified by the method paramater,
151      * containing the URI of the Request, the mandatory headers of the message
152      * with a body in the form of a byte array and body content type.
153      *
154      * @param requestURI -
155      *            the new URI object of the requestURI value of this Message.
156      * @param method -
157      *            the new string of the method value of this Message.
158      * @param callId -
159      *            the new CallIdHeader object of the callId value of this
160      *            Message.
161      * @param cSeq -
162      *            the new CSeqHeader object of the cSeq value of this Message.
163      * @param from -
164      *            the new FromHeader object of the from value of this Message.
165      * @param to -
166      *            the new ToHeader object of the to value of this Message.
167      * @param via -
168      *            the new List object of the ViaHeaders of this Message.
169      * @param content -
170      *            the new byte array of the body content value of this Message.
171      * @param contentType -
172      *            the new ContentTypeHeader object of the content type value of
173      *            this Message.
174      * @throws ParseException
175      *             which signals that an error has been reached unexpectedly
176      *             while parsing the method or the body.
177      */
createRequest(URI requestURI, String method, CallIdHeader callId, CSeqHeader cSeq, FromHeader from, ToHeader to, List via, MaxForwardsHeader maxForwards, byte[] content, ContentTypeHeader contentType)178     public Request createRequest(URI requestURI, String method,
179             CallIdHeader callId, CSeqHeader cSeq, FromHeader from, ToHeader to,
180             List via, MaxForwardsHeader maxForwards, byte[] content,
181             ContentTypeHeader contentType) throws ParseException {
182         if (requestURI == null || method == null || callId == null
183                 || cSeq == null || from == null || to == null || via == null
184                 || maxForwards == null || content == null
185                 || contentType == null)
186             throw new ParseException(
187                     "JAIN-SIP Exception, some parameters are missing"
188                             + ", unable to create the request", 0);
189 
190         SIPRequest sipRequest = new SIPRequest();
191         sipRequest.setRequestURI(requestURI);
192         sipRequest.setMethod(method);
193         sipRequest.setCallId(callId);
194         sipRequest.setCSeq(cSeq);
195         sipRequest.setFrom(from);
196         sipRequest.setTo(to);
197         sipRequest.setVia(via);
198         sipRequest.setMaxForwards(maxForwards);
199         sipRequest.setHeader((ContentType) contentType);
200         sipRequest.setMessageContent(content);
201         if ( userAgent != null ) {
202             sipRequest.setHeader(userAgent);
203         }
204         return sipRequest;
205     }
206 
207     /**
208      * Creates a new Request message of type specified by the method paramater,
209      * containing the URI of the Request, the mandatory headers of the message.
210      * This new Request does not contain a body.
211      *
212      * @param requestURI -
213      *            the new URI object of the requestURI value of this Message.
214      * @param method -
215      *            the new string of the method value of this Message.
216      * @param callId -
217      *            the new CallIdHeader object of the callId value of this
218      *            Message.
219      * @param cSeq -
220      *            the new CSeqHeader object of the cSeq value of this Message.
221      * @param from -
222      *            the new FromHeader object of the from value of this Message.
223      * @param to -
224      *            the new ToHeader object of the to value of this Message.
225      * @param via -
226      *            the new List object of the ViaHeaders of this Message.
227      * @throws ParseException
228      *             which signals that an error has been reached unexpectedly
229      *             while parsing the method.
230      */
createRequest(URI requestURI, String method, CallIdHeader callId, CSeqHeader cSeq, FromHeader from, ToHeader to, List via, MaxForwardsHeader maxForwards)231     public Request createRequest(URI requestURI, String method,
232             CallIdHeader callId, CSeqHeader cSeq, FromHeader from, ToHeader to,
233             List via, MaxForwardsHeader maxForwards) throws ParseException {
234         if (requestURI == null || method == null || callId == null
235                 || cSeq == null || from == null || to == null || via == null
236                 || maxForwards == null)
237             throw new ParseException(
238                     "JAIN-SIP Exception, some parameters are missing"
239                             + ", unable to create the request", 0);
240 
241         SIPRequest sipRequest = new SIPRequest();
242         sipRequest.setRequestURI(requestURI);
243         sipRequest.setMethod(method);
244         sipRequest.setCallId(callId);
245         sipRequest.setCSeq(cSeq);
246         sipRequest.setFrom(from);
247         sipRequest.setTo(to);
248         sipRequest.setVia(via);
249         sipRequest.setMaxForwards(maxForwards);
250         if (userAgent != null) {
251             sipRequest.setHeader(userAgent);
252         }
253 
254         return sipRequest;
255     }
256 
257     // Standard Response Creation methods
258 
259     /**
260      * Creates a new Response message of type specified by the statusCode
261      * paramater, containing the mandatory headers of the message with a body in
262      * the form of a Java object and the body content type.
263      *
264      * @param statusCode -
265      *            the new integer of the statusCode value of this Message.
266      * @param callId -
267      *            the new CallIdHeader object of the callId value of this
268      *            Message.
269      * @param cSeq -
270      *            the new CSeqHeader object of the cSeq value of this Message.
271      * @param from -
272      *            the new FromHeader object of the from value of this Message.
273      * @param to -
274      *            the new ToHeader object of the to value of this Message.
275      * @param via -
276      *            the new List object of the ViaHeaders of this Message.
277      * @param content -
278      *            the new Object of the body content value of this Message.
279      * @param contentType -
280      *            the new ContentTypeHeader object of the content type value of
281      *            this Message.
282      * @throws ParseException
283      *             which signals that an error has been reached unexpectedly
284      *             while parsing the statusCode or the body.
285      */
createResponse(int statusCode, CallIdHeader callId, CSeqHeader cSeq, FromHeader from, ToHeader to, List via, MaxForwardsHeader maxForwards, Object content, ContentTypeHeader contentType)286     public Response createResponse(int statusCode, CallIdHeader callId,
287             CSeqHeader cSeq, FromHeader from, ToHeader to, List via,
288             MaxForwardsHeader maxForwards, Object content,
289             ContentTypeHeader contentType) throws ParseException {
290         if (callId == null || cSeq == null || from == null || to == null
291                 || via == null || maxForwards == null || content == null
292                 || contentType == null)
293             throw new NullPointerException(" unable to create the response");
294 
295         SIPResponse sipResponse = new SIPResponse();
296         StatusLine statusLine = new StatusLine();
297         statusLine.setStatusCode(statusCode);
298         String reasonPhrase = SIPResponse.getReasonPhrase(statusCode);
299         //if (reasonPhrase == null)
300         //  throw new ParseException(statusCode + " Unkown  ", 0);
301         statusLine.setReasonPhrase(reasonPhrase);
302         sipResponse.setStatusLine(statusLine);
303         sipResponse.setCallId(callId);
304         sipResponse.setCSeq(cSeq);
305         sipResponse.setFrom(from);
306         sipResponse.setTo(to);
307         sipResponse.setVia(via);
308         sipResponse.setMaxForwards(maxForwards);
309         sipResponse.setContent(content, contentType);
310         if (userAgent != null) {
311             sipResponse.setHeader(userAgent);
312         }
313         return sipResponse;
314     }
315 
316     /**
317      * Creates a new Response message of type specified by the statusCode
318      * paramater, containing the mandatory headers of the message with a body in
319      * the form of a byte array and the body content type.
320      *
321      * @param statusCode -
322      *            the new integer of the statusCode value of this Message.
323      * @param callId -
324      *            the new CallIdHeader object of the callId value of this
325      *            Message.
326      * @param cSeq -
327      *            the new CSeqHeader object of the cSeq value of this Message.
328      * @param from -
329      *            the new FromHeader object of the from value of this Message.
330      * @param to -
331      *            the new ToHeader object of the to value of this Message.
332      * @param via -
333      *            the new List object of the ViaHeaders of this Message.
334      * @param content -
335      *            the new byte array of the body content value of this Message.
336      * @param contentType -
337      *            the new ContentTypeHeader object of the content type value of
338      *            this Message.
339      * @throws ParseException
340      *             which signals that an error has been reached unexpectedly
341      *             while parsing the statusCode or the body.
342      */
createResponse(int statusCode, CallIdHeader callId, CSeqHeader cSeq, FromHeader from, ToHeader to, List via, MaxForwardsHeader maxForwards, byte[] content, ContentTypeHeader contentType)343     public Response createResponse(int statusCode, CallIdHeader callId,
344             CSeqHeader cSeq, FromHeader from, ToHeader to, List via,
345             MaxForwardsHeader maxForwards, byte[] content,
346             ContentTypeHeader contentType) throws ParseException {
347         if (callId == null || cSeq == null || from == null || to == null
348                 || via == null || maxForwards == null || content == null
349                 || contentType == null)
350             throw new NullPointerException("Null params ");
351 
352         SIPResponse sipResponse = new SIPResponse();
353         sipResponse.setStatusCode(statusCode);
354         sipResponse.setCallId(callId);
355         sipResponse.setCSeq(cSeq);
356         sipResponse.setFrom(from);
357         sipResponse.setTo(to);
358         sipResponse.setVia(via);
359         sipResponse.setMaxForwards(maxForwards);
360         sipResponse.setHeader((ContentType) contentType);
361         sipResponse.setMessageContent(content);
362         if (userAgent != null) {
363             sipResponse.setHeader(userAgent);
364         }
365         return sipResponse;
366     }
367 
368     /**
369      * Creates a new Response message of type specified by the statusCode
370      * paramater, containing the mandatory headers of the message. This new
371      * Response does not contain a body.
372      *
373      * @param statusCode -
374      *            the new integer of the statusCode value of this Message.
375      * @param callId -
376      *            the new CallIdHeader object of the callId value of this
377      *            Message.
378      * @param cSeq -
379      *            the new CSeqHeader object of the cSeq value of this Message.
380      * @param from -
381      *            the new FromHeader object of the from value of this Message.
382      * @param to -
383      *            the new ToHeader object of the to value of this Message.
384      * @param via -
385      *            the new List object of the ViaHeaders of this Message.
386      * @throws ParseException
387      *             which signals that an error has been reached unexpectedly
388      *             while parsing the statusCode.
389      */
createResponse(int statusCode, CallIdHeader callId, CSeqHeader cSeq, FromHeader from, ToHeader to, List via, MaxForwardsHeader maxForwards)390     public Response createResponse(int statusCode, CallIdHeader callId,
391             CSeqHeader cSeq, FromHeader from, ToHeader to, List via,
392             MaxForwardsHeader maxForwards) throws ParseException {
393         if (callId == null || cSeq == null || from == null || to == null
394                 || via == null || maxForwards == null)
395             throw new ParseException(
396                     "JAIN-SIP Exception, some parameters are missing"
397                             + ", unable to create the response", 0);
398 
399         SIPResponse sipResponse = new SIPResponse();
400         sipResponse.setStatusCode(statusCode);
401         sipResponse.setCallId(callId);
402         sipResponse.setCSeq(cSeq);
403         sipResponse.setFrom(from);
404         sipResponse.setTo(to);
405         sipResponse.setVia(via);
406         sipResponse.setMaxForwards(maxForwards);
407         if (userAgent != null) {
408             sipResponse.setHeader(userAgent);
409         }
410         return sipResponse;
411     }
412 
413     // Response Creation methods based on a Request
414 
415     /**
416      * Creates a new Response message of type specified by the statusCode
417      * paramater, based on a specific Request with a new body in the form of a
418      * Java object and the body content type.
419      *
420      * @param statusCode -
421      *            the new integer of the statusCode value of this Message.
422      * @param request -
423      *            the received Reqest object upon which to base the Response.
424      * @param content -
425      *            the new Object of the body content value of this Message.
426      * @param contentType -
427      *            the new ContentTypeHeader object of the content type value of
428      *            this Message.
429      * @throws ParseException
430      *             which signals that an error has been reached unexpectedly
431      *             while parsing the statusCode or the body.
432      */
createResponse(int statusCode, Request request, ContentTypeHeader contentType, Object content)433     public Response createResponse(int statusCode, Request request,
434             ContentTypeHeader contentType, Object content)
435             throws ParseException {
436         if (request == null || content == null || contentType == null)
437             throw new NullPointerException("null parameters");
438 
439         SIPRequest sipRequest = (SIPRequest) request;
440         SIPResponse sipResponse = sipRequest.createResponse(statusCode);
441         sipResponse.setContent(content, contentType);
442         if (server != null) {
443             sipResponse.setHeader(server);
444         }
445         return sipResponse;
446     }
447 
448     /**
449      * Creates a new Response message of type specified by the statusCode
450      * paramater, based on a specific Request with a new body in the form of a
451      * byte array and the body content type.
452      *
453      * @param statusCode -
454      *            the new integer of the statusCode value of this Message.
455      * @param request -
456      *            the received Reqest object upon which to base the Response.
457      * @param content -
458      *            the new byte array of the body content value of this Message.
459      * @param contentType -
460      *            the new ContentTypeHeader object of the content type value of
461      *            this Message.
462      * @throws ParseException
463      *             which signals that an error has been reached unexpectedly
464      *             while parsing the statusCode or the body.
465      */
createResponse(int statusCode, Request request, ContentTypeHeader contentType, byte[] content)466     public Response createResponse(int statusCode, Request request,
467             ContentTypeHeader contentType, byte[] content)
468             throws ParseException {
469         if (request == null || content == null || contentType == null)
470             throw new NullPointerException("null Parameters");
471 
472         SIPRequest sipRequest = (SIPRequest) request;
473         SIPResponse sipResponse = sipRequest.createResponse(statusCode);
474         sipResponse.setHeader((ContentType) contentType);
475         sipResponse.setMessageContent(content);
476         if (server != null) {
477             sipResponse.setHeader(server);
478         }
479         return sipResponse;
480     }
481 
482     /**
483      * Creates a new Response message of type specified by the statusCode
484      * paramater, based on a specific Request message. This new Response does
485      * not contain a body.
486      *
487      * @param statusCode -
488      *            the new integer of the statusCode value of this Message.
489      * @param request -
490      *            the received Reqest object upon which to base the Response.
491      * @throws ParseException
492      *             which signals that an error has been reached unexpectedly
493      *             while parsing the statusCode.
494      */
createResponse(int statusCode, Request request)495     public Response createResponse(int statusCode, Request request)
496             throws ParseException {
497         if (request == null)
498             throw new NullPointerException("null parameters");
499 
500         // if (LogWriter.needsLogging)
501         // LogWriter.logMessage("createResponse " + request);
502 
503         SIPRequest sipRequest = (SIPRequest) request;
504         SIPResponse sipResponse = sipRequest.createResponse(statusCode);
505         // Remove the content from the message (Bug report from
506         // Antonis Karydas.
507         sipResponse.removeContent();
508         sipResponse.removeHeader(ContentTypeHeader.NAME);
509         if (server != null) {
510             sipResponse.setHeader(server);
511         }
512         return sipResponse;
513     }
514 
515     /**
516      * Creates a new Request message of type specified by the method paramater,
517      * containing the URI of the Request, the mandatory headers of the message
518      * with a body in the form of a byte array and body content type.
519      *
520      * @param requestURI -
521      *            the new URI object of the requestURI value of this Message.
522      * @param method -
523      *            the new string of the method value of this Message.
524      * @param callId -
525      *            the new CallIdHeader object of the callId value of this
526      *            Message.
527      * @param cSeq -
528      *            the new CSeqHeader object of the cSeq value of this Message.
529      * @param from -
530      *            the new FromHeader object of the from value of this Message.
531      * @param to -
532      *            the new ToHeader object of the to value of this Message.
533      * @param via -
534      *            the new List object of the ViaHeaders of this Message.
535      * @param contentType -
536      *            the new ContentTypeHeader object of the content type value of
537      *            this Message.
538      * @param content -
539      *            the new byte array of the body content value of this Message.
540      * @throws ParseException
541      *             which signals that an error has been reached unexpectedly
542      *             while parsing the method or the body.
543      */
createRequest(javax.sip.address.URI requestURI, String method, CallIdHeader callId, CSeqHeader cSeq, FromHeader from, ToHeader to, List via, MaxForwardsHeader maxForwards, ContentTypeHeader contentType, byte[] content)544     public Request createRequest(javax.sip.address.URI requestURI,
545             String method, CallIdHeader callId, CSeqHeader cSeq,
546             FromHeader from, ToHeader to, List via,
547             MaxForwardsHeader maxForwards, ContentTypeHeader contentType,
548             byte[] content) throws ParseException {
549         if (requestURI == null || method == null || callId == null
550                 || cSeq == null || from == null || to == null || via == null
551                 || maxForwards == null || content == null
552                 || contentType == null)
553             throw new NullPointerException("missing parameters");
554 
555         SIPRequest sipRequest = new SIPRequest();
556         sipRequest.setRequestURI(requestURI);
557         sipRequest.setMethod(method);
558         sipRequest.setCallId(callId);
559         sipRequest.setCSeq(cSeq);
560         sipRequest.setFrom(from);
561         sipRequest.setTo(to);
562         sipRequest.setVia(via);
563         sipRequest.setMaxForwards(maxForwards);
564         sipRequest.setContent(content, contentType);
565         if (userAgent != null) {
566             sipRequest.setHeader(userAgent);
567         }
568         return sipRequest;
569     }
570 
571     /**
572      * Creates a new Response message of type specified by the statusCode
573      * paramater, containing the mandatory headers of the message with a body in
574      * the form of a Java object and the body content type.
575      *
576      * @param statusCode
577      *            the new integer of the statusCode value of this Message.
578      * @param callId
579      *            the new CallIdHeader object of the callId value of this
580      *            Message.
581      * @param cSeq
582      *            the new CSeqHeader object of the cSeq value of this Message.
583      * @param from
584      *            the new FromHeader object of the from value of this Message.
585      * @param to
586      *            the new ToHeader object of the to value of this Message.
587      * @param via
588      *            the new List object of the ViaHeaders of this Message.
589      * @param contentType
590      *            the new ContentTypeHeader object of the content type value of
591      *            this Message.
592      * @param content
593      *            the new Object of the body content value of this Message.
594      * @throws ParseException
595      *             which signals that an error has been reached unexpectedly
596      *             while parsing the statusCode or the body.
597      */
createResponse(int statusCode, CallIdHeader callId, CSeqHeader cSeq, FromHeader from, ToHeader to, List via, MaxForwardsHeader maxForwards, ContentTypeHeader contentType, Object content)598     public Response createResponse(int statusCode, CallIdHeader callId,
599             CSeqHeader cSeq, FromHeader from, ToHeader to, List via,
600             MaxForwardsHeader maxForwards, ContentTypeHeader contentType,
601             Object content) throws ParseException {
602         if (callId == null || cSeq == null || from == null || to == null
603                 || via == null || maxForwards == null || content == null
604                 || contentType == null)
605             throw new NullPointerException("missing parameters");
606         SIPResponse sipResponse = new SIPResponse();
607         StatusLine statusLine = new StatusLine();
608         statusLine.setStatusCode(statusCode);
609         String reason = SIPResponse.getReasonPhrase(statusCode);
610         if (reason == null)
611             throw new ParseException(statusCode + " Unknown", 0);
612         statusLine.setReasonPhrase(reason);
613         sipResponse.setStatusLine(statusLine);
614         sipResponse.setCallId(callId);
615         sipResponse.setCSeq(cSeq);
616         sipResponse.setFrom(from);
617         sipResponse.setTo(to);
618         sipResponse.setVia(via);
619         sipResponse.setContent(content, contentType);
620         if ( userAgent != null) {
621             sipResponse.setHeader(userAgent);
622         }
623         return sipResponse;
624 
625     }
626 
627     /**
628      * Creates a new Response message of type specified by the statusCode
629      * paramater, containing the mandatory headers of the message with a body in
630      * the form of a byte array and the body content type.
631      *
632      * @param statusCode
633      *            the new integer of the statusCode value of this Message.
634      * @param callId
635      *            the new CallIdHeader object of the callId value of this
636      *            Message.
637      * @param cSeq
638      *            the new CSeqHeader object of the cSeq value of this Message.
639      * @param from
640      *            the new FromHeader object of the from value of this Message.
641      * @param to
642      *            the new ToHeader object of the to value of this Message.
643      * @param via
644      *            the new List object of the ViaHeaders of this Message.
645      * @param contentType
646      *            the new ContentTypeHeader object of the content type value of
647      *            this Message.
648      * @param content
649      *            the new byte array of the body content value of this Message.
650      * @throws ParseException
651      *             which signals that an error has been reached unexpectedly
652      *             while parsing the statusCode or the body.
653      */
createResponse(int statusCode, CallIdHeader callId, CSeqHeader cSeq, FromHeader from, ToHeader to, List via, MaxForwardsHeader maxForwards, ContentTypeHeader contentType, byte[] content)654     public Response createResponse(int statusCode, CallIdHeader callId,
655             CSeqHeader cSeq, FromHeader from, ToHeader to, List via,
656             MaxForwardsHeader maxForwards, ContentTypeHeader contentType,
657             byte[] content) throws ParseException {
658         if (callId == null || cSeq == null || from == null || to == null
659                 || via == null || maxForwards == null || content == null
660                 || contentType == null)
661             throw new NullPointerException("missing parameters");
662         SIPResponse sipResponse = new SIPResponse();
663         StatusLine statusLine = new StatusLine();
664         statusLine.setStatusCode(statusCode);
665         String reason = SIPResponse.getReasonPhrase(statusCode);
666         if (reason == null)
667             throw new ParseException(statusCode + " : Unknown", 0);
668         statusLine.setReasonPhrase(reason);
669         sipResponse.setStatusLine(statusLine);
670         sipResponse.setCallId(callId);
671         sipResponse.setCSeq(cSeq);
672         sipResponse.setFrom(from);
673         sipResponse.setTo(to);
674         sipResponse.setVia(via);
675         sipResponse.setContent(content, contentType);
676         if ( userAgent != null) {
677             sipResponse.setHeader(userAgent);
678         }
679         return sipResponse;
680     }
681 
682     /**
683      * Create a request from a string. Conveniance method for UACs that want to
684      * create an outgoing request from a string. Only the headers of the request
685      * should be included in the String that is supplied to this method.
686      *
687      * @param requestString --
688      *            string from which to create the message null string returns an
689      *            empty message.
690      */
createRequest(String requestString)691     public javax.sip.message.Request createRequest(String requestString)
692             throws java.text.ParseException {
693         if (requestString == null || requestString.equals("")) {
694             SIPRequest retval = new SIPRequest();
695             retval.setNullRequest();
696             return retval;
697         }
698 
699         StringMsgParser smp = new StringMsgParser();
700         smp.setStrict(this.strict);
701 
702         /*
703          * This allows you to catch parse exceptions and create invalid messages
704          * if you want.
705          */
706         ParseExceptionListener parseExceptionListener = new ParseExceptionListener() {
707 
708             public void handleException(ParseException ex,
709                     SIPMessage sipMessage, Class headerClass,
710                     String headerText, String messageText)
711                     throws ParseException {
712                 // Rethrow the error for the essential headers. Otherwise bad
713                 // headers are simply
714                 // recorded in the message.
715                 if (testing) {
716                     if (headerClass == From.class || headerClass == To.class
717                             || headerClass == CallID.class
718                             || headerClass == MaxForwards.class
719                             || headerClass == Via.class
720                             || headerClass == RequestLine.class
721                             || headerClass == StatusLine.class
722                             || headerClass == CSeq.class)
723                         throw ex;
724 
725                     sipMessage.addUnparsed(headerText);
726                 }
727 
728             }
729 
730         };
731 
732         if (this.testing)
733             smp.setParseExceptionListener(parseExceptionListener);
734 
735         SIPMessage sipMessage = smp.parseSIPMessage(requestString);
736 
737         if (!(sipMessage instanceof SIPRequest))
738             throw new ParseException(requestString, 0);
739 
740         return (SIPRequest) sipMessage;
741     }
742 
743     /**
744      * Create a response from a string
745      *
746      * @param responseString --
747      *            string from which to create the message null string returns an
748      *            empty message.
749      *
750      */
createResponse(String responseString)751     public Response createResponse(String responseString)
752             throws java.text.ParseException {
753         if (responseString == null)
754             return new SIPResponse();
755 
756         StringMsgParser smp = new StringMsgParser();
757 
758         SIPMessage sipMessage = smp.parseSIPMessage(responseString);
759 
760         if (!(sipMessage instanceof SIPResponse))
761             throw new ParseException(responseString, 0);
762 
763         return (SIPResponse) sipMessage;
764     }
765 
766     /**
767      * Set the common UserAgent header for all requests created from this message factory.
768      * This header is applied to all Messages created from this Factory object except those
769      * that take String for an argument and create Message from the given String.
770      *
771      * @param userAgent -- the user agent header to set.
772      *
773      * @since 2.0
774      */
775 
setDefaultUserAgentHeader(UserAgentHeader userAgent)776     public void setDefaultUserAgentHeader(UserAgentHeader userAgent) {
777         MessageFactoryImpl.userAgent = userAgent;
778     }
779 
780     /**
781      * Set the common Server header for all responses created from this message factory.
782      * This header is applied to all Messages created from this Factory object except those
783      * that take String for an argument and create Message from the given String.
784      *
785      * @param userAgent -- the user agent header to set.
786      *
787      * @since 2.0
788      */
789 
setDefaultServerHeader(ServerHeader server)790     public void setDefaultServerHeader(ServerHeader server) {
791         MessageFactoryImpl.server = server;
792     }
793     /**
794      * Get the default common UserAgentHeader.
795      *
796      * @return the user agent header.
797      *
798      * @since 2.0
799      */
getDefaultUserAgentHeader()800     public static UserAgentHeader getDefaultUserAgentHeader() {
801         return userAgent;
802     }
803 
804 
805     /**
806      * Get the default common server header.
807      *
808      * @return the server header.
809      */
getDefaultServerHeader()810     public static ServerHeader getDefaultServerHeader() {
811         return server;
812     }
813 
814 
815     /**
816      * Set default charset used for encoding String content.
817      * @param charset
818      */
setDefaultContentEncodingCharset(String charset)819     public  void setDefaultContentEncodingCharset(String charset) throws NullPointerException,
820     IllegalArgumentException {
821         if (charset == null ) throw new NullPointerException ("Null argument!");
822         MessageFactoryImpl.defaultContentEncodingCharset = charset;
823 
824     }
825 
getDefaultContentEncodingCharset()826     public static String getDefaultContentEncodingCharset() {
827         return MessageFactoryImpl.defaultContentEncodingCharset;
828     }
829 
830 
createMultipartMimeContent(ContentTypeHeader multipartMimeCth, String[] contentType, String[] contentSubtype, String[] contentBody)831     public MultipartMimeContent createMultipartMimeContent(ContentTypeHeader multipartMimeCth,
832             String[] contentType,
833             String[] contentSubtype,
834             String[] contentBody) {
835         String boundary = multipartMimeCth.getParameter("boundary");
836         MultipartMimeContentImpl retval = new MultipartMimeContentImpl(multipartMimeCth);
837         for (int i = 0 ;  i < contentType.length; i++ ) {
838             ContentTypeHeader cth = new ContentType(contentType[i],contentSubtype[i]);
839             ContentImpl contentImpl  = new ContentImpl(contentBody[i],boundary);
840             contentImpl.setContentTypeHeader(cth);
841             retval.add(contentImpl);
842         }
843         return retval;
844     }
845 
846 
847 
848 
849 }
850