View Javadoc

1   /*
2    *  Copyright 2004-2006 Stefan Reuter and others
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   *
16   */
17  package org.asteriskjava.manager.internal;
18  
19  import java.lang.reflect.Method;
20  import java.util.Iterator;
21  import java.util.Locale;
22  import java.util.Map;
23  import java.util.Set;
24  import java.util.HashSet;
25  
26  import org.asteriskjava.AsteriskVersion;
27  import org.asteriskjava.manager.action.ManagerAction;
28  import org.asteriskjava.util.Log;
29  import org.asteriskjava.util.LogFactory;
30  import org.asteriskjava.util.ReflectionUtil;
31  import org.asteriskjava.manager.action.UserEventAction;
32  import org.asteriskjava.manager.event.UserEvent;
33  
34  /***
35   * Default implementation of the ActionBuilder interface.
36   * 
37   * @author srt
38   * @version $Id: ActionBuilderImpl.java 835 2007-07-08 08:39:32Z srt $
39   */
40  class ActionBuilderImpl implements ActionBuilder
41  {
42      private static final String LINE_SEPARATOR = "\r\n";
43  
44      /***
45       * Instance logger.
46       */
47      private final Log logger = LogFactory.getLog(getClass());
48      private AsteriskVersion targetVersion;
49  
50      /***
51       * Creates a new ActionBuilder for Asterisk 1.0.
52       */
53      ActionBuilderImpl()
54      {
55          this.targetVersion = AsteriskVersion.ASTERISK_1_0;
56      }
57  
58      public void setTargetVersion(AsteriskVersion targetVersion)
59      {
60          this.targetVersion = targetVersion;
61      }
62  
63      public String buildAction(final ManagerAction action)
64      {
65          return buildAction(action, null);
66      }
67  
68      @SuppressWarnings("unchecked")
69      public String buildAction(final ManagerAction action, final String internalActionId)
70      {
71          StringBuffer sb = new StringBuffer();
72  
73          sb.append("action: ");
74          sb.append(action.getAction());
75          sb.append(LINE_SEPARATOR);
76          if (internalActionId != null)
77          {
78              sb.append("actionid: ");
79              sb.append(ManagerUtil.addInternalActionId(action.getActionId(), internalActionId));
80              sb.append(LINE_SEPARATOR);
81          }
82          else if (action.getActionId() != null)
83          {
84              sb.append("actionid: ");
85              sb.append(action.getActionId());
86              sb.append(LINE_SEPARATOR);
87          }
88  
89          /*
90           * When using the Reflection API to get all of the getters for building
91           * actions to send, we ignore some of the getters
92           */
93          Set<String> ignore = new HashSet<String>();
94          ignore.add("class");
95          ignore.add("action");
96          ignore.add("actionid");
97  
98          // if this is a user event action, we need to grab the internal event,
99          // otherwise do below as normal
100         if (action instanceof UserEventAction)
101         {
102             UserEvent userEvent = ((UserEventAction) action).getUserEvent();
103             appendUserEvent(sb, userEvent);
104 
105             // eventually we may want to add more Map keys for events to ignore
106             // when appending
107             appendGetters(sb, userEvent, ignore);
108         }
109         else
110         {
111             appendGetters(sb, action, ignore);
112         }
113 
114         sb.append(LINE_SEPARATOR);
115         return sb.toString();
116     }
117 
118     private void appendMap(StringBuffer sb, String key, Map<String, String> values)
119     {
120         String singularKey;
121 
122         // strip plural s (i.e. use "variable: " instead of "variables: "
123         if (key.endsWith("s"))
124         {
125             singularKey = key.substring(0, key.length() - 1);
126         }
127         else
128         {
129             singularKey = key;
130         }
131 
132         if (targetVersion.isAtLeast(AsteriskVersion.ASTERISK_1_2))
133         {
134             appendMap12(sb, singularKey, values);
135         }
136         else
137         {
138             appendMap10(sb, singularKey, values);
139         }
140     }
141 
142     private void appendMap10(StringBuffer sb, String singularKey, Map<String, String> values)
143     {
144         Iterator<Map.Entry<String, String>> entryIterator;
145 
146         sb.append(singularKey);
147         sb.append(": ");
148         entryIterator = values.entrySet().iterator();
149         while (entryIterator.hasNext())
150         {
151             Map.Entry entry;
152 
153             entry = entryIterator.next();
154             sb.append(entry.getKey());
155             sb.append("=");
156             if (entry.getValue() != null)
157             {
158                 sb.append(entry.getValue());
159             }
160 
161             if (entryIterator.hasNext())
162             {
163                 sb.append("|");
164             }
165         }
166         sb.append(LINE_SEPARATOR);
167     }
168 
169     private void appendMap12(StringBuffer sb, String singularKey, Map<String, String> values)
170     {
171         for (Map.Entry entry : values.entrySet())
172         {
173             sb.append(singularKey);
174             sb.append(": ");
175             sb.append(entry.getKey());
176             sb.append("=");
177             if (entry.getValue() != null)
178             {
179                 sb.append(entry.getValue());
180             }
181 
182             sb.append(LINE_SEPARATOR);
183         }
184     }
185 
186     private void appendString(StringBuffer sb, String key, String value)
187     {
188         sb.append(key);
189         sb.append(": ");
190         sb.append(value);
191         sb.append(LINE_SEPARATOR);
192     }
193 
194     private void appendUserEvent(StringBuffer sb, UserEvent event)
195     {
196         Class clazz = event.getClass();
197 
198         String className = clazz.getName();
199         String eventType = className.substring(className.lastIndexOf('.') + 1).toLowerCase(Locale.ENGLISH);
200 
201         if (eventType.endsWith("event"))
202         {
203             eventType = eventType.substring(0, eventType.length() - "event".length());
204         }
205 
206         appendString(sb, "UserEvent", eventType);
207     }
208 
209     private void appendGetters(StringBuffer sb, Object action, Set<String> membersToIgnore)
210     {
211         Map<String, Method> getters = ReflectionUtil.getGetters(action.getClass());
212         for (String name : getters.keySet())
213         {
214             Method getter;
215             Object value;
216 
217             if (membersToIgnore.contains(name))
218                 continue;
219 
220             getter = getters.get(name);
221             try
222             {
223                 value = getter.invoke(action);
224             }
225             catch (Exception ex)
226             {
227                 logger.error("Unable to retrieve property '" + name + "' of " + action.getClass(), ex);
228                 continue;
229             }
230 
231             if (value == null)
232             {
233                 // continue
234             }
235             else if (value instanceof Class)
236             {
237                 // continue
238             }
239             else if (value instanceof Map)
240             {
241                 // is this a place where reflection can make sure we can cast
242                 // the map to <String,String>?
243                 appendMap(sb, name, (Map) value);
244             }
245             else if (value instanceof String)
246             {
247                 appendString(sb, name, (String) value);
248             }
249             else
250             {
251                 appendString(sb, name, value.toString());
252             }
253         }
254 
255     }
256 }