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 *******************************************************************************/
29package gov.nist.javax.sip.message;
30
31import java.text.ParseException;
32import javax.sip.header.*;
33
34import java.util.LinkedList;
35import java.util.List;
36import gov.nist.javax.sip.header.*;
37
38import javax.sip.message.*;
39import javax.sip.address.*;
40import 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")
53public 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
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     */
82    public void setTest(boolean flag) {
83        this.testing = flag;
84    }
85
86    /**
87     * Creates a new instance of MessageFactoryImpl
88     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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
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
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     */
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     */
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     */
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
826    public static String getDefaultContentEncodingCharset() {
827        return MessageFactoryImpl.defaultContentEncodingCharset;
828    }
829
830
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