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