Skip to content

Commit f45d240

Browse files
author
Tom
authored
Merge pull request #317 from twilio/bug/issue-11/undocumented-options
Ability to add undocumented options to requests
2 parents 9550c95 + 494f1be commit f45d240

File tree

6 files changed

+185
-6
lines changed

6 files changed

+185
-6
lines changed

src/main/java/com/twilio/twiml/Conference.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,18 @@
33
import com.google.common.base.Function;
44
import com.google.common.base.Joiner;
55
import com.google.common.collect.Lists;
6+
import com.google.common.collect.Maps;
67

8+
import javax.xml.bind.annotation.XmlAnyAttribute;
79
import javax.xml.bind.annotation.XmlAttribute;
810
import javax.xml.bind.annotation.XmlRootElement;
911
import javax.xml.bind.annotation.XmlValue;
1012
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
13+
import javax.xml.namespace.QName;
14+
import java.util.HashMap;
1115
import java.util.List;
16+
import java.util.Map;
17+
import java.util.Set;
1218

1319
/**
1420
* TwiML wrapper for @see https://www.twilio.com/docs/api/twiml/conference.
@@ -128,6 +134,9 @@ public String apply(ConferenceEvent event) {
128134
@XmlValue
129135
private final String name;
130136

137+
@XmlAnyAttribute
138+
private Map<QName, String> options;
139+
131140
private final List<ConferenceEvent> statusCallbackEvents;
132141

133142
// For XML Serialization
@@ -152,6 +161,7 @@ private Conference(Builder b) {
152161
this.statusCallback = b.statusCallback;
153162
this.recordingStatusCallback = b.recordingStatusCallback;
154163
this.recordingStatusCallbackMethod = b.recordingStatusCallbackMethod;
164+
this.options = Maps.newHashMap(b.options);
155165

156166
if (this.statusCallbackEvents != null) {
157167
this.statusCallbackEvent = Joiner.on(" ").join(Lists.transform(this.statusCallbackEvents, ConferenceEvent.TO_STRING));
@@ -224,6 +234,16 @@ public String getName() {
224234
return name;
225235
}
226236

237+
public Map<String, String> getOptions() {
238+
Map<String, String> convertedMap = new HashMap<>();
239+
240+
Set<QName> keys = options.keySet();
241+
for (QName key : keys) {
242+
convertedMap.put(key.getNamespaceURI(), options.get(key));
243+
}
244+
return convertedMap;
245+
}
246+
227247
public static class Builder {
228248
private Boolean muted;
229249
private Boolean startConferenceOnEnter;
@@ -241,6 +261,7 @@ public static class Builder {
241261
private String recordingStatusCallback;
242262
private Method recordingStatusCallbackMethod;
243263
private String name;
264+
private Map<QName, String> options = Maps.newHashMap();
244265

245266
public Builder(String name) {
246267
this.name = name;
@@ -321,6 +342,11 @@ public Builder recordingStatusCallbackMethod(Method recordingStatusCallbackMetho
321342
return this;
322343
}
323344

345+
public Builder options(String key, String value) {
346+
this.options.put(new QName(key), value);
347+
return this;
348+
}
349+
324350
public Conference build() {
325351
return new Conference(this);
326352
}

src/main/java/com/twilio/twiml/Dial.java

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
package com.twilio.twiml;
22

33
import com.google.common.collect.Lists;
4+
import com.google.common.collect.Maps;
45

5-
import javax.xml.bind.annotation.XmlAttribute;
6-
import javax.xml.bind.annotation.XmlElement;
7-
import javax.xml.bind.annotation.XmlElements;
8-
import javax.xml.bind.annotation.XmlRootElement;
6+
import javax.xml.bind.annotation.*;
97
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
8+
import javax.xml.namespace.QName;
9+
import java.util.HashMap;
1010
import java.util.List;
11+
import java.util.Map;
12+
import java.util.Set;
1113

1214
/**
1315
* TwiML wrapper for @see https://www.twilio.com/docs/api/twiml/dial.
@@ -84,13 +86,13 @@ public String toString() {
8486

8587
@SuppressWarnings("checkstyle:indentation")
8688
@XmlElements({
87-
@XmlElement(name = "Number", type = Number.class)
89+
@XmlElement(name = "Number", type = Number.class)
8890
})
8991
private final List<Number> numbers;
9092

9193
@SuppressWarnings("checkstyle:indentation")
9294
@XmlElements({
93-
@XmlElement(name = "Client", type = Client.class)
95+
@XmlElement(name = "Client", type = Client.class)
9496
})
9597
private final List<Client> clients;
9698

@@ -103,6 +105,9 @@ public String toString() {
103105
@XmlElement(name = "Sip")
104106
private final Sip sip;
105107

108+
@XmlAnyAttribute
109+
private Map<QName, String> options;
110+
106111
// For XML Serialization
107112
private Dial() {
108113
this(new Builder());
@@ -124,6 +129,7 @@ private Dial(Builder b) {
124129
this.conference = b.conference;
125130
this.queue = b.queue;
126131
this.sip = b.sip;
132+
this.options = Maps.newHashMap(b.options);
127133
}
128134

129135
public Boolean isHangupOnStar() {
@@ -186,6 +192,16 @@ public Sip getSip() {
186192
return sip;
187193
}
188194

195+
public Map<String, String> getOptions() {
196+
Map<String, String> convertedMap = new HashMap<>();
197+
198+
Set<QName> keys = options.keySet();
199+
for (QName key : keys) {
200+
convertedMap.put(key.getNamespaceURI(), options.get(key));
201+
}
202+
return convertedMap;
203+
}
204+
189205
public static class Builder {
190206
private Boolean hangupOnStar;
191207
private Integer timeout;
@@ -202,6 +218,7 @@ public static class Builder {
202218
private Conference conference;
203219
private Queue queue;
204220
private Sip sip;
221+
private Map<QName, String> options = Maps.newHashMap();
205222

206223
public Builder hangupOnStar(boolean hangupOnStar) {
207224
this.hangupOnStar = hangupOnStar;
@@ -278,6 +295,11 @@ public Builder sip(Sip sip) {
278295
return this;
279296
}
280297

298+
public Builder options(String key, String value) {
299+
this.options.put(new QName(key), value);
300+
return this;
301+
}
302+
281303
public Dial build() {
282304
return new Dial(this);
283305
}

src/main/java/com/twilio/twiml/Pause.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
package com.twilio.twiml;
22

3+
import com.google.common.collect.Maps;
4+
5+
import javax.xml.bind.annotation.XmlAnyAttribute;
36
import javax.xml.bind.annotation.XmlAttribute;
47
import javax.xml.bind.annotation.XmlRootElement;
8+
import javax.xml.namespace.QName;
9+
import java.util.HashMap;
10+
import java.util.Map;
11+
import java.util.Set;
512

613
/**
714
* TwiML wrapper for @see https://www.twilio.com/docs/api/twiml/pause.
@@ -12,27 +19,47 @@ public class Pause extends TwiML {
1219
@XmlAttribute
1320
private final Integer length;
1421

22+
@XmlAnyAttribute
23+
private Map<QName, String> options;
24+
1525
// For XML Serialization
1626
private Pause() {
1727
this(new Builder());
1828
}
1929

2030
private Pause(Builder b) {
2131
this.length = b.length;
32+
this.options = Maps.newHashMap(b.options);
2233
}
2334

2435
public Integer getLength() {
2536
return length;
2637
}
2738

39+
public Map<String, String> getOptions() {
40+
Map<String, String> convertedMap = new HashMap<>();
41+
42+
Set<QName> keys = options.keySet();
43+
for (QName key : keys) {
44+
convertedMap.put(key.getNamespaceURI(), options.get(key));
45+
}
46+
return convertedMap;
47+
}
48+
2849
public static class Builder {
2950
private Integer length;
51+
private Map<QName, String> options = Maps.newHashMap();
3052

3153
public Builder length(int length) {
3254
this.length = length;
3355
return this;
3456
}
3557

58+
public Builder options(String key, String value) {
59+
this.options.put(new QName(key), value);
60+
return this;
61+
}
62+
3663
public Pause build() {
3764
return new Pause(this);
3865
}

src/test/java/com/twilio/twiml/ConferenceTest.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,40 @@ public void testUrl() throws TwiMLException {
4141

4242
Assert.assertEquals("%3CConference+muted%3D%22true%22+startConferenceOnEnter%3D%22true%22+endConferenceOnExit%3D%22false%22+maxParticipants%3D%2210%22+beep%3D%22false%22+record%3D%22do-not-record%22+trim%3D%22do-not-trim%22+waitMethod%3D%22POST%22+waitUrl%3D%22http%3A%2F%2Ftwilio.ca%22%3Emy+conference%3C%2FConference%3E", conference.toUrl());
4343
}
44+
45+
@Test
46+
public void testOptionsXml() throws TwiMLException {
47+
Conference conference = new Conference.Builder("my conference")
48+
.muted(true)
49+
.startConferenceOnEnter(true)
50+
.endConferenceOnExit(false)
51+
.maxParticipants(10)
52+
.beep(Conference.Beep.FALSE)
53+
.record(Conference.Record.DO_NOT_RECORD)
54+
.trim(Trim.DO_NOT_TRIM)
55+
.waitMethod(Method.POST)
56+
.waitUrl("http://twilio.ca")
57+
.options("foo", "bar")
58+
.build();
59+
60+
Assert.assertEquals("<Conference muted=\"true\" startConferenceOnEnter=\"true\" endConferenceOnExit=\"false\" maxParticipants=\"10\" beep=\"false\" record=\"do-not-record\" trim=\"do-not-trim\" waitMethod=\"POST\" waitUrl=\"http://twilio.ca\" foo=\"bar\">my conference</Conference>", conference.toXml());
61+
}
62+
63+
@Test
64+
public void testOptionsUrl() throws TwiMLException {
65+
Conference conference = new Conference.Builder("my conference")
66+
.muted(true)
67+
.startConferenceOnEnter(true)
68+
.endConferenceOnExit(false)
69+
.maxParticipants(10)
70+
.beep(Conference.Beep.FALSE)
71+
.record(Conference.Record.DO_NOT_RECORD)
72+
.trim(Trim.DO_NOT_TRIM)
73+
.waitMethod(Method.POST)
74+
.waitUrl("http://twilio.ca")
75+
.options("foo", "bar")
76+
.build();
77+
78+
Assert.assertEquals("%3CConference+muted%3D%22true%22+startConferenceOnEnter%3D%22true%22+endConferenceOnExit%3D%22false%22+maxParticipants%3D%2210%22+beep%3D%22false%22+record%3D%22do-not-record%22+trim%3D%22do-not-trim%22+waitMethod%3D%22POST%22+waitUrl%3D%22http%3A%2F%2Ftwilio.ca%22+foo%3D%22bar%22%3Emy+conference%3C%2FConference%3E", conference.toUrl());
79+
}
4480
}

src/test/java/com/twilio/twiml/DialTest.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,52 @@ public void testUrl() throws TwiMLException {
5050

5151
Assert.assertEquals("%3CDial+hangupOnStar%3D%22true%22+timeout%3D%228%22+action%3D%22%2Fdial%22+method%3D%22POST%22+callerId%3D%22%2B14155550000%22+trim%3D%22trim-silence%22%3E%3CConference%3Econference%3C%2FConference%3E%3C%2FDial%3E", dial.toUrl());
5252
}
53+
54+
@Test
55+
public void testOptionsXML() throws TwiMLException {
56+
Conference conference = new Conference.Builder("conference")
57+
.build();
58+
59+
Number number = new Number.Builder("+18885551234").build();
60+
61+
Dial dial = new Dial.Builder()
62+
.action("/dial")
63+
.callerId("+14155550000")
64+
.hangupOnStar(true)
65+
.method(Method.POST)
66+
.trim(Dial.Trim.TRIM_SILENCE)
67+
.timeout(8)
68+
.conference(conference)
69+
.options("foo", "bar")
70+
.number(number)
71+
.build();
72+
73+
74+
Assert.assertEquals(
75+
"<Dial hangupOnStar=\"true\" timeout=\"8\" action=\"/dial\" method=\"POST\" callerId=\"+14155550000\" trim=\"trim-silence\" foo=\"bar\">" +
76+
"<Number>+18885551234</Number>" +
77+
"<Conference>conference</Conference>" +
78+
"</Dial>", dial.toXml());
79+
80+
}
81+
82+
@Test
83+
public void testOptionsUrl() throws TwiMLException {
84+
Conference conference = new Conference.Builder("conference")
85+
.build();
86+
87+
Dial dial = new Dial.Builder()
88+
.action("/dial")
89+
.callerId("+14155550000")
90+
.hangupOnStar(true)
91+
.method(Method.POST)
92+
.trim(Dial.Trim.TRIM_SILENCE)
93+
.timeout(8)
94+
.conference(conference)
95+
.options("foo", "bar")
96+
.build();
97+
98+
Assert.assertEquals("%3CDial+hangupOnStar%3D%22true%22+timeout%3D%228%22+action%3D%22%2Fdial%22+method%3D%22POST%22+callerId%3D%22%2B14155550000%22+trim%3D%22trim-silence%22+foo%3D%22bar%22%3E%3CConference%3Econference%3C%2FConference%3E%3C%2FDial%3E", dial.toUrl());
99+
100+
}
53101
}

src/test/java/com/twilio/twiml/PauseTest.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,24 @@ public void testUrl() throws TwiMLException {
2525

2626
Assert.assertEquals("%3CPause+length%3D%225%22%2F%3E", pause.toUrl());
2727
}
28+
29+
@Test
30+
public void testOptionsXml() throws TwiMLException {
31+
Pause pause = new Pause.Builder()
32+
.length(5)
33+
.options("foo", "bar")
34+
.build();
35+
36+
Assert.assertEquals("<Pause length=\"5\" foo=\"bar\"/>", pause.toXml());
37+
}
38+
39+
@Test
40+
public void testOptionsUrl() throws TwiMLException {
41+
Pause pause = new Pause.Builder()
42+
.length(5)
43+
.options("foo", "bar")
44+
.build();
45+
46+
Assert.assertEquals("%3CPause+length%3D%225%22+foo%3D%22bar%22%2F%3E", pause.toUrl());
47+
}
2848
}

0 commit comments

Comments
 (0)