Java tutorial
/* * Copyright (C) 2017 by Fonoster Inc (http://fonoster.com) * http://github.com/fonoster/astive * * This file is part of Astive * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.fonoster.astive.agi; import java.lang.reflect.Field; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.http.NameValuePair; import org.apache.http.client.utils.URLEncodedUtils; import org.apache.log4j.Logger; import com.fonoster.astive.agi.annotation.RequestField; /** * Contains the data sent by the requesting<code>channel</code> as well as the * queryParameters passed from the dialplan. * * @since 1.0 */ public class AgiRequest { private static final Logger LOG = Logger.getLogger(AgiRequest.class); // Collection of a pair key/value element with information about // the <code>channel</code>. private static Map<String, String> queryParameters; private static String[] arguments; // Use to map Agi field with AgiRequest variables. private HashMap<String, String> fieldsMap; private ArrayList<String> lines; @RequestField("agi_type") private ChannelType channelType; @RequestField("agi_accountcode") private String accountCode; @RequestField("agi_uniqueid") private String callId; @RequestField("agi_callerid") private String callerId; @RequestField("agi_calleridname") private String callerIdName; @RequestField("agi_channel") private String channel; @RequestField("agi_context") private String context; @RequestField("agi_dnid") private String dnId; @RequestField("agi_extension") private String extension; @RequestField("agi_language") private String language; @RequestField("agi_priority") private String priority; @RequestField("agi_rdnis") private String rdNis; @RequestField("agi_request") private String requestURL; @RequestField("agi_network_script") private String script; @RequestField("agi_threadid") private String threadId; @RequestField("agi_version") private String version; @RequestField("agi_enhanced") private boolean enhanced; @RequestField("agi_network") private boolean network; @RequestField("agi_callingani2") private int callingAni2; @RequestField("agi_callingpres") private int callingPres; @RequestField("agi_callingtns") private int callingTns; @RequestField("agi_callington") private int callingTon; /** * Create a new AgiRequest object with the info sent by a new * <code>channel</code>. * * @param lines array of a pairs key/value elements with information about * the <code>channel</code>. */ public AgiRequest(final ArrayList<String> lines) { this.lines = lines; fieldsMap = new HashMap<String, String>(); List<String> args = new ArrayList<String>(); for (String line : lines) { String key = line.split(":")[0].trim(); if (line.split(":").length < 2) { fieldsMap.put(line.split(":")[0].trim(), null); continue; } String value = line.split(":")[1].trim(); if (key.equals("agi_request") && (line.split(":").length == 3)) { value = value + ":" + line.split(":")[2].trim(); } if (key.matches("agi_arg_(.*)")) { args.add(value); } fieldsMap.put(key, value); } arguments = args.toArray(new String[args.size()]); try { fillFields(); } catch (IllegalArgumentException ex) { LOG.warn(ex.getMessage()); } catch (IllegalAccessException ex) { LOG.warn(ex.getMessage()); } queryParameters = new HashMap<String, String>(); List<NameValuePair> params = null; try { params = URLEncodedUtils.parse(new URI(script), "UTF-8"); for (NameValuePair param : params) { queryParameters.put(param.getName(), param.getValue()); } } catch (URISyntaxException ex) { LOG.warn(ex.getMessage()); } } // Set a variables by using reflection. private void fillFields() throws IllegalArgumentException, IllegalAccessException { for (String af : fieldsMap.keySet()) { for (Field f : AgiRequest.class.getDeclaredFields()) { RequestField rf; if (f.isAnnotationPresent(RequestField.class)) { rf = f.getAnnotation(RequestField.class); } else { continue; } if (rf.value().equals(af)) { // There is an exception for the variables: // channelType, enhanced and network if (f.getName().equals("network")) { if (fieldsMap.get(af).equals("yes")) { f.set(this, Boolean.TRUE); } else { f.set(this, Boolean.FALSE); } break; } else if (f.getName().equals("enhanced")) { if (fieldsMap.get(af).equals("1.0")) { f.set(this, Boolean.TRUE); } else { f.set(this, Boolean.FALSE); } break; } else if (f.getType().equals(ChannelType.class)) { f.set(this, ChannelType.get(fieldsMap.get(af))); break; } else if (f.getType().equals(int.class)) { f.set(this, Integer.valueOf(fieldsMap.get(af))); break; } else { f.set(this, fieldsMap.get(af)); break; } } } } } /** * Gets the identifier for the origin * <code>channel</code>. * * @return the account code of the origin channel. */ public String getAccountCode() { return accountCode; } /** * An ID that help identify a particular call in the telephone system and * later in the database(Call Detail Record). * * @return the unique ID for the call. */ public String getCallId() { return callId; } /** * Returns the ID of the origin caller. * * @return the caller ID number (or "unknown"). */ public String getCallerId() { return callerId; } /** * Geet the caller id name only(for example: "John Doe") * * @return the caller Id Name (or "unknown"). */ public String getCallerIdName() { return callerIdName; } /** * ANI2 (Info digits) also called Originating line information or OLI. * <p>Possible codes are listed can be founded at: * http://www.nanpa.com/number_resource_info/ani_ii_assignments.html * * @return a code with information about the line. */ public int getCallingAni2() { return callingAni2; } /** * Caller ID presentation for incoming calls (PRI channels). * * @return a number that can be decode using {@link PresentationType}. */ public int getCallingPres() { return callingPres; } /** * An optional 4 digit number (Transit Network Selector) used in PRI * Channels. * <p> * See http://www.voip-info.org/wiki/view/Asterisk+Detailed+Variable+List * * @return a code with the TNS (transit network selector). */ public int getCallingTns() { return callingTns; } /** * Caller Type of Number (PRI channels). * * @return a number that can be decode using (@link TonType). */ public int getCallingTon() { return callingTon; } /** * The originating channel (your phone). * * @return the calling phone. */ public String getChannel() { return channel; } /** * Helps identify the type of channel(define in {@link ChannelType}). * * @return the channel type (for instance ZAP, SIP, H323, IAX). */ public ChannelType getChannelType() { return channelType; } /** * Returns the * <code>context</code> that was use to place the call. * * @return the current context. */ public String getContext() { return context; } /** * Returns Dialed Number Identifier(DnId). * * @return the dialed number id. */ public String getDnId() { return dnId; } /** * Returns the called number, found in * <code>extension.conf</code>. * * @return the called number. */ public String getExtension() { return extension; } /** * Language for the current * <code>channel</code>. * * @return the language code(for example 'en'). */ public String getLanguage() { return language; } /** * Returns an array with all the queryParameters. * * @return the array with all queryParameters that conform this request. */ public ArrayList<String> getLines() { return lines; } /** * Returns a parameter by parameter name. * * @param parameter parameter name. * @return the value of the parameter. */ public String getQueryParameter(String parameter) { return queryParameters.get(parameter); } /** * Returns the arguments passed to the astivlet. * * @return an array with the arguments of this application */ public String[] getArguments() { return arguments; } /** * The priority it was executed as in the dialplan. * * @return current priority in the dialplan. */ public String getPriority() { return priority; } /** * Returns the Redirected Dial Number ID Service(RDNIS). * * @return the referring DNIS number. */ public String getRdNis() { return rdNis; } /** * Name of the AGI script that is being called. * * @return the script file name. */ public String getRequestURL() { return requestURL; } /** * Returns the name remote AGI script. * * @return the name of the fastagi script. */ public String getScript() { return script; } /** * Thread ID of the AGI script (since Asterisk 1.6) * * @return the thread identifier. */ public String getThreadId() { return threadId; } /** * Returns the version of Asterisk (since Asterisk 1.6). * * @return the asterisk version. */ public String getVersion() { return version; } /** * Whether this AGI is passed audio (EAGI - Enhanced AGI). * * @return true if started as an EAGI script, false otherwise. */ public boolean isEnhanced() { return enhanced; } /** * Whether or not this request was sent through a network. * * @return true only when using fastagi. */ public boolean isNetwork() { return network; } /** * Returns representation of this request in string format. * * @return the request in string format. */ @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("agi_network:"); if (isNetwork()) { sb.append("yes"); } else { sb.append("no"); } sb.append("\n"); sb.append("agi_network_script:"); sb.append(getRequestURL()); sb.append("\n"); sb.append("agi_request:"); sb.append(getScript()); sb.append("\n"); sb.append("agi_channel:"); sb.append(getChannel()); sb.append("\n"); sb.append("agi_language:"); sb.append(getLanguage()); sb.append("\n"); sb.append("agi_type:"); sb.append(getChannelType()); sb.append("\n"); sb.append("agi_uniqueid:"); sb.append(getCallId()); sb.append("\n"); sb.append("agi_version:"); sb.append(getVersion()); sb.append("\n"); sb.append("agi_callerid:"); sb.append(getCallerId()); sb.append("\n"); sb.append("agi_calleridname:"); sb.append(getCallerIdName()); sb.append("\n"); sb.append("agi_callingpres:"); sb.append(getCallingPres()); sb.append("\n"); sb.append("agi_callingani2:"); sb.append(getCallingAni2()); sb.append("\n"); sb.append("agi_callingtns:"); sb.append(getCallingTns()); sb.append("\n"); sb.append("agi_dnid:"); sb.append(getDnId()); sb.append("\n"); sb.append("agi_rdnis:"); sb.append(getRdNis()); sb.append("\n"); sb.append("agi_context:"); sb.append(getContext()); sb.append("\n"); sb.append("agi_extension:"); sb.append(getExtension()); sb.append("\n"); sb.append("agi_priority:"); sb.append(getPriority()); sb.append("\n"); sb.append("agi_enhanced:"); sb.append(isEnhanced()); sb.append("\n"); sb.append("agi_accountcode:"); sb.append(getAccountCode()); sb.append("\n"); sb.append("agi_threadid:"); sb.append(getThreadId()); return sb.toString(); } }