1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.asteriskjava.fastagi.internal;
18
19 import org.asteriskjava.fastagi.AgiRequest;
20 import org.asteriskjava.util.AstUtil;
21 import org.asteriskjava.util.Log;
22 import org.asteriskjava.util.LogFactory;
23
24 import java.io.UnsupportedEncodingException;
25 import java.net.InetAddress;
26 import java.net.URLDecoder;
27 import java.util.*;
28 import java.util.regex.Matcher;
29 import java.util.regex.Pattern;
30
31
32
33
34
35
36
37
38 public class AgiRequestImpl implements AgiRequest
39 {
40 private final Log logger = LogFactory.getLog(getClass());
41 private static final Pattern SCRIPT_PATTERN = Pattern.compile("^([^\\?]*)\\?(.*)$");
42 private static final Pattern PARAMETER_PATTERN = Pattern.compile("^(.*)=(.*)$");
43
44 private String rawCallerId;
45
46 private Map<String, String> request;
47
48
49
50
51
52 private Map<String, String[]> parameterMap;
53
54 private String[] arguments;
55
56 private String parameters;
57 private String script;
58 private boolean callerIdCreated;
59 private InetAddress localAddress;
60 private int localPort;
61 private InetAddress remoteAddress;
62 private int remotePort;
63
64
65
66
67
68
69
70 AgiRequestImpl(final List<String> environment)
71 {
72 this(buildMap(environment));
73 }
74
75
76
77
78
79
80
81 private AgiRequestImpl(final Map<String, String> request)
82 {
83 this.request = request;
84
85 script = request.get("network_script");
86 if (script != null)
87 {
88 Matcher scriptMatcher = SCRIPT_PATTERN.matcher(script);
89 if (scriptMatcher.matches())
90 {
91 script = scriptMatcher.group(1);
92 parameters = scriptMatcher.group(2);
93 }
94 }
95 }
96
97
98
99
100
101
102
103
104
105
106 private static Map<String, String> buildMap(final Collection<String> lines) throws IllegalArgumentException
107 {
108 final Map<String, String> map;
109
110 if (lines == null)
111 {
112 throw new IllegalArgumentException("Environment must not be null.");
113 }
114
115 map = new HashMap<String, String>();
116
117 for (String line : lines)
118 {
119 int colonPosition;
120 String key;
121 String value;
122
123 colonPosition = line.indexOf(':');
124
125
126 if (colonPosition < 0)
127 {
128 continue;
129 }
130
131
132 if (!line.startsWith("agi_") && !line.startsWith("ogi_"))
133 {
134 continue;
135 }
136
137
138 if (line.length() < colonPosition + 2)
139 {
140 continue;
141 }
142
143 key = line.substring(4, colonPosition).toLowerCase(Locale.ENGLISH);
144 value = line.substring(colonPosition + 2);
145
146 if (value.length() != 0)
147 {
148 map.put(key, value);
149 }
150 }
151
152 return map;
153 }
154
155 public Map<String, String> getRequest()
156 {
157 return request;
158 }
159
160
161
162
163
164
165 public synchronized String getScript()
166 {
167 return script;
168 }
169
170
171
172
173
174
175
176
177 public String getRequestURL()
178 {
179 return request.get("request");
180 }
181
182
183
184
185
186
187 public String getChannel()
188 {
189 return request.get("channel");
190 }
191
192
193
194
195
196
197 public String getUniqueId()
198 {
199 return request.get("uniqueid");
200 }
201
202 public String getType()
203 {
204 return request.get("type");
205 }
206
207 public String getLanguage()
208 {
209 return request.get("language");
210 }
211
212 @Deprecated public String getCallerId()
213 {
214 return getCallerIdNumber();
215 }
216
217 public String getCallerIdNumber()
218 {
219 String callerIdName;
220 String callerId;
221
222 callerIdName = request.get("calleridname");
223 callerId = request.get("callerid");
224 if (callerIdName != null)
225 {
226
227 if (callerId == null || "unknown".equals(callerId))
228 {
229 return null;
230 }
231
232 return callerId;
233 }
234 else
235 {
236
237 return getCallerId10();
238 }
239 }
240
241 public String getCallerIdName()
242 {
243 String callerIdName;
244
245 callerIdName = request.get("calleridname");
246 if (callerIdName != null)
247 {
248
249 if ("unknown".equals(callerIdName))
250 {
251 return null;
252 }
253
254 return callerIdName;
255 }
256 else
257 {
258
259 return getCallerIdName10();
260 }
261 }
262
263
264
265
266
267
268 private synchronized String getCallerId10()
269 {
270 final String[] parsedCallerId;
271
272 if (!callerIdCreated)
273 {
274 rawCallerId = request.get("callerid");
275 callerIdCreated = true;
276 }
277
278 parsedCallerId = AstUtil.parseCallerId(rawCallerId);
279 if (parsedCallerId[1] == null)
280 {
281 return parsedCallerId[0];
282 }
283 else
284 {
285 return parsedCallerId[1];
286 }
287 }
288
289
290
291
292
293
294 private synchronized String getCallerIdName10()
295 {
296 if (!callerIdCreated)
297 {
298 rawCallerId = request.get("callerid");
299 callerIdCreated = true;
300 }
301
302 return AstUtil.parseCallerId(rawCallerId)[0];
303 }
304
305 public String getDnid()
306 {
307 String dnid;
308
309 dnid = request.get("dnid");
310
311 if (dnid == null || "unknown".equals(dnid))
312 {
313 return null;
314 }
315
316 return dnid;
317 }
318
319 public String getRdnis()
320 {
321 String rdnis;
322
323 rdnis = request.get("rdnis");
324
325 if (rdnis == null || "unknown".equals(rdnis))
326 {
327 return null;
328 }
329
330 return rdnis;
331 }
332
333 public String getContext()
334 {
335 return request.get("context");
336 }
337
338 public String getExtension()
339 {
340 return request.get("extension");
341 }
342
343 public Integer getPriority()
344 {
345 if (request.get("priority") != null)
346 {
347 return Integer.valueOf(request.get("priority"));
348 }
349 return null;
350 }
351
352 public Boolean getEnhanced()
353 {
354 if (request.get("enhanced") != null)
355 {
356 if ("1.0".equals(request.get("enhanced")))
357 {
358 return Boolean.TRUE;
359 }
360 else
361 {
362 return Boolean.FALSE;
363 }
364 }
365 return null;
366 }
367
368 public String getAccountCode()
369 {
370 return request.get("accountcode");
371 }
372
373 public Integer getCallingAni2()
374 {
375 if (request.get("callingani2") == null)
376 {
377 return null;
378 }
379
380 try
381 {
382 return Integer.valueOf(request.get("callingani2"));
383 }
384 catch (NumberFormatException e)
385 {
386 return null;
387 }
388 }
389
390 public Integer getCallingPres()
391 {
392 if (request.get("callingpres") == null)
393 {
394 return null;
395 }
396
397 try
398 {
399 return Integer.valueOf(request.get("callingpres"));
400 }
401 catch (NumberFormatException e)
402 {
403 return null;
404 }
405 }
406
407 public Integer getCallingTns()
408 {
409 if (request.get("callingtns") == null)
410 {
411 return null;
412 }
413
414 try
415 {
416 return Integer.valueOf(request.get("callingtns"));
417 }
418 catch (NumberFormatException e)
419 {
420 return null;
421 }
422 }
423
424 public Integer getCallingTon()
425 {
426 if (request.get("callington") == null)
427 {
428 return null;
429 }
430
431 try
432 {
433 return Integer.valueOf(request.get("callington"));
434 }
435 catch (NumberFormatException e)
436 {
437 return null;
438 }
439 }
440
441 public String getParameter(String name)
442 {
443 String[] values;
444
445 values = getParameterValues(name);
446
447 if (values == null || values.length == 0)
448 {
449 return null;
450 }
451
452 return values[0];
453 }
454
455 public synchronized String[] getParameterValues(String name)
456 {
457 if (getParameterMap().isEmpty())
458 {
459 return new String[0];
460 }
461
462 final String[] values = parameterMap.get(name);
463 return values == null ? new String[0] : values;
464 }
465
466 public synchronized Map<String, String[]> getParameterMap()
467 {
468 if (parameterMap == null)
469 {
470 parameterMap = parseParameters(parameters);
471 }
472 return parameterMap;
473 }
474
475
476
477
478
479
480
481 private synchronized Map<String, String[]> parseParameters(String s)
482 {
483 Map<String, List<String>> parameterMap;
484 Map<String, String[]> result;
485 StringTokenizer st;
486
487 parameterMap = new HashMap<String, List<String>>();
488 result = new HashMap<String, String[]>();
489
490 if (s == null)
491 {
492 return result;
493 }
494
495 st = new StringTokenizer(s, "&");
496 while (st.hasMoreTokens())
497 {
498 String parameter;
499 Matcher parameterMatcher;
500 String name;
501 String value;
502 List<String> values;
503
504 parameter = st.nextToken();
505 parameterMatcher = PARAMETER_PATTERN.matcher(parameter);
506 if (parameterMatcher.matches())
507 {
508 try
509 {
510 name = URLDecoder.decode(parameterMatcher.group(1), "UTF-8");
511 value = URLDecoder.decode(parameterMatcher.group(2), "UTF-8");
512 }
513 catch (UnsupportedEncodingException e)
514 {
515 logger.error("Unable to decode parameter '" + parameter + "'", e);
516 continue;
517 }
518 }
519 else
520 {
521 try
522 {
523 name = URLDecoder.decode(parameter, "UTF-8");
524 value = "";
525 }
526 catch (UnsupportedEncodingException e)
527 {
528 logger.error("Unable to decode parameter '" + parameter + "'", e);
529 continue;
530 }
531 }
532
533 if (parameterMap.get(name) == null)
534 {
535 values = new ArrayList<String>();
536 values.add(value);
537 parameterMap.put(name, values);
538 }
539 else
540 {
541 values = parameterMap.get(name);
542 values.add(value);
543 }
544 }
545
546 for (Map.Entry<String, List<String>> entry : parameterMap.entrySet())
547 {
548 String[] valueArray;
549
550 valueArray = new String[entry.getValue().size()];
551 result.put(entry.getKey(), entry.getValue().toArray(valueArray));
552 }
553
554 return result;
555 }
556
557 public synchronized String[] getArguments()
558 {
559 if (arguments != null)
560 {
561 return arguments.clone();
562 }
563
564 final Map<Integer, String> map = new HashMap<Integer, String>();
565 int maxIndex = 0;
566 for (Map.Entry<String, String> entry : request.entrySet())
567 {
568 if (! entry.getKey().startsWith("arg_"))
569 {
570 continue;
571 }
572
573 int index = Integer.valueOf(entry.getKey().substring(4));
574 if (index > maxIndex)
575 {
576 maxIndex = index;
577 }
578 map.put(index, entry.getValue());
579 }
580
581 arguments = new String[maxIndex];
582 for (int i = 0; i < maxIndex; i++)
583 {
584 arguments[i] = map.get(i + 1);
585 }
586
587 return arguments.clone();
588 }
589
590 public InetAddress getLocalAddress()
591 {
592 return localAddress;
593 }
594
595 void setLocalAddress(InetAddress localAddress)
596 {
597 this.localAddress = localAddress;
598 }
599
600 public int getLocalPort()
601 {
602 return localPort;
603 }
604
605 void setLocalPort(int localPort)
606 {
607 this.localPort = localPort;
608 }
609
610 public InetAddress getRemoteAddress()
611 {
612 return remoteAddress;
613 }
614
615 void setRemoteAddress(InetAddress remoteAddress)
616 {
617 this.remoteAddress = remoteAddress;
618 }
619
620 public int getRemotePort()
621 {
622 return remotePort;
623 }
624
625 void setRemotePort(int remotePort)
626 {
627 this.remotePort = remotePort;
628 }
629
630 @Override
631 public String toString()
632 {
633 StringBuffer sb;
634
635 sb = new StringBuffer("AgiRequest[");
636 sb.append("script='").append(getScript()).append("',");
637 sb.append("requestURL='").append(getRequestURL()).append("',");
638 sb.append("channel='").append(getChannel()).append("',");
639 sb.append("uniqueId='").append(getUniqueId()).append("',");
640 sb.append("type='").append(getType()).append("',");
641 sb.append("language='").append(getLanguage()).append("',");
642 sb.append("callerIdNumber='").append(getCallerIdNumber()).append("',");
643 sb.append("callerIdName='").append(getCallerIdName()).append("',");
644 sb.append("dnid='").append(getDnid()).append("',");
645 sb.append("rdnis='").append(getRdnis()).append("',");
646 sb.append("context='").append(getContext()).append("',");
647 sb.append("extension='").append(getExtension()).append("',");
648 sb.append("priority='").append(getPriority()).append("',");
649 sb.append("enhanced='").append(getEnhanced()).append("',");
650 sb.append("accountCode='").append(getAccountCode()).append("',");
651 sb.append("systemHashcode=").append(System.identityHashCode(this));
652 sb.append("]");
653
654 return sb.toString();
655 }
656 }