001: package javax.sdp;
002:
003: import gov.nist.javax.sdp.*;
004: import gov.nist.javax.sdp.fields.*;
005: import gov.nist.javax.sdp.parser.*;
006:
007: import java.util.*;
008: import java.net.*;
009: import java.text.*;
010:
011: /**
012: * The SdpFactory enables applications to encode and decode SDP messages.
013: * The SdpFactory can be used to construct a SessionDescription
014: * object programmatically.
015: * The SdpFactory can also be used to construct a
016: * SessionDescription based on the
017: * contents of a String. Acknowledgement:
018: * Bugs reported by Brian J. Collins <bjcollins@rockwellcollins.com>.
019: * and by Majdi Abuelbassal <majdi.abuelbassal@bbumail.com>.
020: * Please refer to IETF RFC 2327 for a description of SDP.
021: *
022: *@author Olivier Deruelle <olivier.deruelle@nist.gov>
023: *@author M. Ranganathan
024: *
025: *
026: * @version 1.0
027: *
028: */
029: public class SdpFactory extends Object {
030: private static final SdpFactory singletonInstance = new SdpFactory();
031:
032: /** Creates new SdpFactory */
033: private SdpFactory() {
034: }
035:
036: /** Obtain an instance of an SdpFactory.
037: *
038: * This static method returns a factory instance.
039: *
040: * Once an application has obtained a reference to an SdpFactory it can use
041: * the factory to configure and obtain parser instances and to create SDP objects.
042: * @return a factory instance
043: */
044: public static SdpFactory getInstance() {
045: return singletonInstance;
046: }
047:
048: /** Creates a new, empty SessionDescription. The session is set as follows:
049: *
050: * v=0
051: *
052: * o=this.createOrigin ("user",
053: * InetAddress.getLocalHost().toString());
054: *
055: * s=-
056: *
057: * t=0 0
058: * @throws SdpException SdpException, - if there is a problem constructing the
059: * SessionDescription.
060: * @return a new, empty SessionDescription.
061: */
062: public SessionDescription createSessionDescription()
063: throws SdpException {
064: SessionDescriptionImpl sessionDescriptionImpl = new SessionDescriptionImpl();
065:
066: ProtoVersionField ProtoVersionField = new ProtoVersionField();
067: ProtoVersionField.setVersion(0);
068: sessionDescriptionImpl.setVersion(ProtoVersionField);
069:
070: OriginField originImpl = null;
071: try {
072: originImpl = (OriginField) this .createOrigin("user",
073: InetAddress.getLocalHost().getHostAddress());
074: } catch (UnknownHostException e) {
075: e.printStackTrace();
076: }
077: sessionDescriptionImpl.setOrigin(originImpl);
078:
079: SessionNameField sessionNameImpl = new SessionNameField();
080: sessionNameImpl.setValue("-");
081: sessionDescriptionImpl.setSessionName(sessionNameImpl);
082:
083: TimeDescriptionImpl timeDescriptionImpl = new TimeDescriptionImpl();
084: TimeField timeImpl = new TimeField();
085: timeImpl.setZero();
086: timeDescriptionImpl.setTime(timeImpl);
087: Vector times = new Vector();
088: times.addElement(timeDescriptionImpl);
089: sessionDescriptionImpl.setTimeDescriptions(times);
090:
091: return sessionDescriptionImpl;
092: }
093:
094: /**
095: * Creates a new SessionDescription, deep copy of another SessionDescription.
096: *
097: * @param otherSessionDescription - the SessionDescription to copy from.
098: * @return a new SessionDescription, exact and deep copy of the otherSessionDescription.
099: * @throws SdpException - if there is a problem constructing the SessionDescription.
100: */
101: public SessionDescription createSessionDescription(
102: SessionDescription otherSessionDescription)
103: throws SdpException {
104: return new SessionDescriptionImpl(otherSessionDescription);
105: }
106:
107: /** Creates a SessionDescription populated with the information
108: * contained within the string parameter.
109: *
110: * Note: unknown field types should not cause exceptions.
111: * @param s s - the sdp message that is to be parsed.
112: * @throws SdpParseException SdpParseException - if there is a problem parsing the
113: * String.
114: * @return a populated SessionDescription object.
115: */
116: public SessionDescription createSessionDescription(String s)
117: throws SdpParseException {
118: try {
119:
120: SDPAnnounceParser sdpParser = new SDPAnnounceParser(s);
121: return sdpParser.parse();
122: } catch (ParseException e) {
123: e.printStackTrace();
124: throw new SdpParseException(0, 0, "Could not parse message");
125: }
126: }
127:
128: /** Returns Bandwidth object with the specified values.
129: * @param modifier modifier - the bandwidth type
130: * @param value the bandwidth value measured in kilobits per second
131: * @return bandwidth
132: */
133: public BandWidth createBandwidth(String modifier, int value) {
134: BandwidthField bandWidthImpl = new BandwidthField();
135: try {
136:
137: bandWidthImpl.setType(modifier);
138: bandWidthImpl.setValue(value);
139:
140: } catch (SdpException s) {
141: s.printStackTrace();
142: }
143: return bandWidthImpl;
144: }
145:
146: /** Returns Attribute object with the specified values.
147: * @param name the namee of the attribute
148: * @param value the value of the attribute
149: * @return Attribute
150: */
151: public Attribute createAttribute(String name, String value) {
152: AttributeField attributeImpl = new AttributeField();
153: try {
154:
155: attributeImpl.setName(name);
156: attributeImpl.setValueAllowNull(value);
157:
158: } catch (SdpException s) {
159: s.printStackTrace();
160: }
161: return attributeImpl;
162: }
163:
164: /** Returns Info object with the specified value.
165: * @param value the string containing the description.
166: * @return Info
167: */
168: public Info createInfo(String value) {
169: InformationField infoImpl = new InformationField();
170: try {
171:
172: infoImpl.setValue(value);
173:
174: } catch (SdpException s) {
175: s.printStackTrace();
176: }
177: return infoImpl;
178: }
179:
180: /** Returns Phone object with the specified value.
181: * @param value the string containing the description.
182: * @return Phone
183: */
184: public Phone createPhone(String value) {
185: PhoneField phoneImpl = new PhoneField();
186: try {
187:
188: phoneImpl.setValue(value);
189:
190: } catch (SdpException s) {
191: s.printStackTrace();
192: }
193: return phoneImpl;
194: }
195:
196: /** Returns EMail object with the specified value.
197: * @param value the string containing the description.
198: * @return EMail
199: */
200: public EMail createEMail(String value) {
201: EmailField emailImpl = new EmailField();
202: try {
203:
204: emailImpl.setValue(value);
205:
206: } catch (SdpException s) {
207: s.printStackTrace();
208: }
209: return emailImpl;
210: }
211:
212: /** Returns URI object with the specified value.
213: * @param value the URL containing the description.
214: * @throws SdpException
215: * @return URI
216: */
217: public javax.sdp.URI createURI(URL value) throws SdpException {
218:
219: URIField uriImpl = new URIField();
220: uriImpl.set(value);
221: return uriImpl;
222:
223: }
224:
225: /** Returns SessionName object with the specified name.
226: * @param name the string containing the name of the session.
227: * @return SessionName
228: */
229: public SessionName createSessionName(String name) {
230: SessionNameField sessionNameImpl = new SessionNameField();
231: try {
232:
233: sessionNameImpl.setValue(name);
234:
235: } catch (SdpException s) {
236: s.printStackTrace();
237: }
238: return sessionNameImpl;
239: }
240:
241: /** Returns Key object with the specified value.
242: * @param method the string containing the method type.
243: * @param key the key to set
244: * @return Key
245: */
246: public Key createKey(String method, String key) {
247: KeyField keyImpl = new KeyField();
248: try {
249:
250: keyImpl.setMethod(method);
251: keyImpl.setKey(key);
252:
253: } catch (SdpException s) {
254: s.printStackTrace();
255: return null;
256: }
257: return keyImpl;
258: }
259:
260: /** Returns Version object with the specified values.
261: * @param value the version number.
262: * @return Version
263: */
264: public Version createVersion(int value) {
265: ProtoVersionField protoVersionField = new ProtoVersionField();
266: try {
267:
268: protoVersionField.setVersion(value);
269:
270: } catch (SdpException s) {
271: s.printStackTrace();
272: return null;
273: }
274: return protoVersionField;
275: }
276:
277: /** Returns Media object with the specified properties.
278: * @param media the media type, eg "audio"
279: * @param port port number on which to receive media
280: * @param numPorts number of ports used for this media stream
281: * @param transport transport type, eg "RTP/AVP"
282: * @param staticRtpAvpTypes vector to set
283: * @throws SdpException
284: * @return Media
285: */
286: public Media createMedia(String media, int port, int numPorts,
287: String transport, Vector staticRtpAvpTypes)
288: throws SdpException {
289: MediaField mediaImpl = new MediaField();
290: mediaImpl.setMediaType(media);
291: mediaImpl.setMediaPort(port);
292: mediaImpl.setPortCount(numPorts);
293: mediaImpl.setProtocol(transport);
294: mediaImpl.setMediaFormats(staticRtpAvpTypes);
295: return mediaImpl;
296: }
297:
298: /** Returns Origin object with the specified properties.
299: * @param userName the user name.
300: * @param address the IP4 encoded address.
301: * @throws SdpException if the parameters are null
302: * @return Origin
303: */
304: public Origin createOrigin(String userName, String address)
305: throws SdpException {
306: OriginField originImpl = new OriginField();
307: originImpl.setUsername(userName);
308: originImpl.setAddress(address);
309: originImpl.setNetworkType(SDPKeywords.IN);
310: originImpl.setAddressType(SDPKeywords.IPV4);
311: return originImpl;
312: }
313:
314: /** Returns Origin object with the specified properties.
315: * @param userName String containing the user that created the
316: * string.
317: * @param sessionId long containing the session identifier.
318: * @param sessionVersion long containing the session version.
319: * @param networkType String network type for the origin (usually
320: * "IN").
321: * @param addrType String address type (usually "IP4").
322: * @param address String IP address usually the address of the
323: * host.
324: * @throws SdpException if the parameters are null
325: * @return Origin object with the specified properties.
326: */
327: public Origin createOrigin(String userName, long sessionId,
328: long sessionVersion, String networkType, String addrType,
329: String address) throws SdpException {
330: OriginField originImpl = new OriginField();
331: originImpl.setUsername(userName);
332: originImpl.setAddress(address);
333: originImpl.setSessionId(sessionId);
334: originImpl.setSessionVersion(sessionVersion);
335: originImpl.setAddressType(addrType);
336: originImpl.setNetworkType(networkType);
337: return originImpl;
338: }
339:
340: /** Returns MediaDescription object with the specified properties.
341: * The returned object will respond to
342: * Media.getMediaFormats(boolean) with a Vector of media formats.
343: * @param media media -
344: * @param port port number on which to receive media
345: * @param numPorts number of ports used for this media stream
346: * @param transport transport type, eg "RTP/AVP"
347: * @param staticRtpAvpTypes list of static RTP/AVP media payload
348: * types which should be specified by the returned MediaDescription
349: * throws IllegalArgumentException if passed
350: * an invalid RTP/AVP payload type
351: * @throws IllegalArgumentException
352: * @throws SdpException
353: * @return MediaDescription
354: */
355: public MediaDescription createMediaDescription(String media,
356: int port, int numPorts, String transport,
357: int[] staticRtpAvpTypes) throws IllegalArgumentException,
358: SdpException {
359: MediaDescriptionImpl mediaDescriptionImpl = new MediaDescriptionImpl();
360: MediaField mediaImpl = new MediaField();
361: mediaImpl.setMediaType(media);
362: mediaImpl.setMediaPort(port);
363: mediaImpl.setPortCount(numPorts);
364: mediaImpl.setProtocol(transport);
365: mediaDescriptionImpl.setMedia(mediaImpl);
366: // Bug fix contributed by Paloma Ortega.
367: Vector payload = new Vector();
368: for (int i = 0; i < staticRtpAvpTypes.length; i++)
369: payload.add(new Integer(staticRtpAvpTypes[i]).toString());
370: mediaImpl.setMediaFormats(payload);
371: return mediaDescriptionImpl;
372: }
373:
374: /** Returns MediaDescription object with the specified properties.
375: * The returned object will respond to
376: * Media.getMediaFormats(boolean) with a Vector of String objects
377: * specified by the 'formats argument.
378: * @param media the media type, eg "audio"
379: * @param port port number on which to receive media
380: * @param numPorts number of ports used for this media stream
381: * @param transport transport type, eg "RTP/AVP"
382: * @param formats list of formats which should be specified by the
383: * returned MediaDescription
384: * @return MediaDescription
385: */
386: public MediaDescription createMediaDescription(String media,
387: int port, int numPorts, String transport, String[] formats) {
388: MediaDescriptionImpl mediaDescriptionImpl = new MediaDescriptionImpl();
389: try {
390:
391: MediaField mediaImpl = new MediaField();
392: mediaImpl.setMediaType(media);
393: mediaImpl.setMediaPort(port);
394: mediaImpl.setPortCount(numPorts);
395: mediaImpl.setProtocol(transport);
396:
397: Vector formatsV = new Vector(formats.length);
398: for (int i = 0; i < formats.length; i++)
399: formatsV.add(formats[i]);
400: mediaImpl.setMediaFormats(formatsV);
401: mediaDescriptionImpl.setMedia(mediaImpl);
402: } catch (SdpException s) {
403: s.printStackTrace();
404: }
405: return mediaDescriptionImpl;
406: }
407:
408: /** Returns TimeDescription object with the specified properties.
409: * @param t the Time that the time description applies to. Returns
410: * TimeDescription object with the specified properties.
411: * @throws SdpException
412: * @return TimeDescription
413: */
414: public TimeDescription createTimeDescription(Time t)
415: throws SdpException {
416: TimeDescriptionImpl timeDescriptionImpl = new TimeDescriptionImpl();
417: timeDescriptionImpl.setTime(t);
418: return timeDescriptionImpl;
419: }
420:
421: /** Returns TimeDescription unbounded (i.e. "t=0 0");
422: * @throws SdpException
423: * @return TimeDescription unbounded (i.e. "t=0 0");
424: */
425: public TimeDescription createTimeDescription() throws SdpException {
426: TimeDescriptionImpl timeDescriptionImpl = new TimeDescriptionImpl();
427: TimeField timeImpl = new TimeField();
428: timeImpl.setZero();
429: timeDescriptionImpl.setTime(timeImpl);
430: return timeDescriptionImpl;
431: }
432:
433: /** Returns TimeDescription object with the specified properties.
434: * @param start start time.
435: * @param stop stop time.
436: * @throws SdpException if the parameters are null
437: * @return TimeDescription
438: */
439: public TimeDescription createTimeDescription(Date start, Date stop)
440: throws SdpException {
441: TimeDescriptionImpl timeDescriptionImpl = new TimeDescriptionImpl();
442: TimeField timeImpl = new TimeField();
443: timeImpl.setStart(start);
444: timeImpl.setStop(stop);
445: timeDescriptionImpl.setTime(timeImpl);
446: return timeDescriptionImpl;
447: }
448:
449: /** Returns a String containing the computed form for a
450: * multi-connection address.
451: * Parameters:
452: * addr - connection address
453: * ttl - time to live (TTL) for multicast
454: * addresses
455: * numAddrs - number of addresses used by the
456: * connection
457: * Returns:
458: * a String containing the computed form for a
459: * multi-connection address.
460: */
461: public String formatMulticastAddress(String addr, int ttl,
462: int numAddrs) {
463: String res = addr + "/" + ttl + "/" + numAddrs;
464: return res;
465: }
466:
467: /** Returns a Connection object with the specified properties a
468: * @param netType network type, eg "IN" for "Internet"
469: * @param addrType address type, eg "IP4" for IPv4 type addresses
470: * @param addr connection address
471: * @param ttl time to live (TTL) for multicast addresses
472: * @param numAddrs number of addresses used by the connection
473: * @return Connection
474: */
475: public Connection createConnection(String netType, String addrType,
476: String addr, int ttl, int numAddrs) throws SdpException {
477: ConnectionField connectionImpl = new ConnectionField();
478:
479: connectionImpl.setNetworkType(netType);
480: connectionImpl.setAddressType(addrType);
481: connectionImpl.setAddress(addr);
482:
483: return connectionImpl;
484: }
485:
486: /** Returns a Connection object with the specified properties and no
487: * TTL and a default number of addresses (1).
488: * @param netType network type, eg "IN" for "Internet"
489: * @param addrType address type, eg "IP4" for IPv4 type addresses
490: * @param addr connection address
491: * @throws SdpException if the parameters are null
492: * @return Connection
493: */
494: public Connection createConnection(String netType, String addrType,
495: String addr) throws SdpException {
496: ConnectionField connectionImpl = new ConnectionField();
497:
498: connectionImpl.setNetworkType(netType);
499: connectionImpl.setAddressType(addrType);
500: connectionImpl.setAddress(addr);
501:
502: return connectionImpl;
503: }
504:
505: /** Returns a Connection object with the specified properties and a
506: * network and address type of "IN" and "IP4" respectively.
507: * @param addr connection address
508: * @param ttl time to live (TTL) for multicast addresses
509: * @param numAddrs number of addresses used by the connection
510: * @return Connection
511: */
512: public Connection createConnection(String addr, int ttl,
513: int numAddrs) throws SdpException {
514: ConnectionField connectionImpl = new ConnectionField();
515:
516: connectionImpl.setAddress(addr);
517:
518: return connectionImpl;
519: }
520:
521: /** Returns a Connection object with the specified address. This is
522: * equivalent to
523: *
524: * createConnection("IN", "IP4", addr);
525: *
526: * @param addr connection address
527: * @throws SdpException if the parameter is null
528: * @return Connection
529: */
530: public Connection createConnection(String addr) throws SdpException {
531:
532: return createConnection("IN", "IP4", addr);
533:
534: }
535:
536: /** Returns a Time specification with the specified start and stop
537: * times.
538: * @param start start time
539: * @param stop stop time
540: * @throws SdpException if the parameters are null
541: * @return a Time specification with the specified start and stop
542: * times.
543: */
544: public Time createTime(Date start, Date stop) throws SdpException {
545: TimeField timeImpl = new TimeField();
546: timeImpl.setStart(start);
547: timeImpl.setStop(stop);
548: return timeImpl;
549: }
550:
551: /** Returns an unbounded Time specification (i.e., "t=0 0").
552: * @throws SdpException
553: * @return an unbounded Time specification (i.e., "t=0 0").
554: */
555: public Time createTime() throws SdpException {
556: TimeField timeImpl = new TimeField();
557: timeImpl.setZero();
558: return timeImpl;
559: }
560:
561: /** Returns a RepeatTime object with the specified interval,
562: * duration, and time offsets.
563: * @param repeatInterval the "repeat interval" in seconds
564: * @param activeDuration the "active duration" in seconds
565: * @param offsets the list of offsets relative to the start time of
566: * the Time object with which the returned RepeatTime will be
567: * associated
568: * @return RepeatTime
569: */
570: public RepeatTime createRepeatTime(int repeatInterval,
571: int activeDuration, int[] offsets) {
572: RepeatField repeatTimeField = new RepeatField();
573: try {
574:
575: repeatTimeField.setRepeatInterval(repeatInterval);
576: repeatTimeField.setActiveDuration(activeDuration);
577: repeatTimeField.setOffsetArray(offsets);
578:
579: } catch (SdpException s) {
580: s.printStackTrace();
581: }
582: return repeatTimeField;
583: }
584:
585: /** Constructs a timezone adjustment record.
586: * @param d the Date at which the adjustment is going to take
587: * place.
588: * @param offset the adjustment in number of seconds relative to
589: * the start time of the SessionDescription with which this
590: * object is associated.
591: * @return TimeZoneAdjustment
592: */
593: public TimeZoneAdjustment createTimeZoneAdjustment(Date d,
594: int offset) {
595: ZoneField timeZoneAdjustmentImpl = new ZoneField();
596: try {
597:
598: Hashtable map = new Hashtable();
599: map.put(d, new Integer(offset));
600: timeZoneAdjustmentImpl.setZoneAdjustments(map);
601: } catch (SdpException s) {
602: s.printStackTrace();
603: }
604: return timeZoneAdjustmentImpl;
605: }
606:
607: /**
608: * Test main.
609: * @param args
610: * @throws SdpException
611: public static void main(String[] args)
612: throws SdpException {
613:
614: }
615: */
616:
617: /**
618: * @param ntpTime long to set
619: * @return Returns a Date object for a given NTP date value.
620: */
621: public static Date getDateFromNtp(long ntpTime) {
622: return new Date((ntpTime - SdpConstants.NTP_CONST) * 1000);
623: }
624:
625: /** Returns a long containing the NTP value for a given Java Date.
626: * @param d Date to set
627: * @return long
628: */
629: public static long getNtpTime(Date d) throws SdpParseException {
630: if (d == null)
631: return -1;
632: return ((d.getTime() / 1000) + SdpConstants.NTP_CONST);
633: }
634:
635: /**
636: public static void main(String[] args)
637: throws SdpParseException , SdpException {
638: String sdpFields = "v=0\r\n"+
639: "o=phone 1057165447541 1057165447541 IN IP4 123.4.566.156\r\n"+
640: "s=-\r\n" +
641: "c=IN IP4 123.4.566.156\r\n"+
642: "t=0 0\r\n" +
643: "m=data 3011 tcp OSA\r\n";
644:
645: SdpFactory sdpFactory = new SdpFactory();
646: SessionDescription sessionDescription =
647: sdpFactory.createSessionDescription(sdpFields);
648:
649: System.out.println("sessionDescription = " + sessionDescription);
650: Vector mediaDescriptions =
651: sessionDescription.getMediaDescriptions(false);
652: for (int i = 0; i < mediaDescriptions.size(); i++) {
653: MediaDescription m = (MediaDescription)
654: mediaDescriptions.elementAt(i);
655: System.out.println("m = " + m.toString());
656: Media media = m.getMedia();
657: Vector formats = media.getMediaFormats(false);
658: System.out.println("formats = " + formats);
659: }
660: }
661: **/
662:
663: }
|