[Asterisk-java-cvs] CVS: asterisk-java/src/java/net/sf/asterisk/manager/impl ResponseBuilderImpl.jav
Brought to you by:
srt
Update of /cvsroot/asterisk-java/asterisk-java/src/java/net/sf/asterisk/manager/impl In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22772/src/java/net/sf/asterisk/manager/impl Added Files: ResponseBuilderImpl.java EventBuilderImpl.java ManagerReaderImpl.java ManagerWriterImpl.java ActionBuilderImpl.java Log Message: Refactored private implementation classes into impl subpackage --- NEW FILE: ResponseBuilderImpl.java --- /* * Copyright 2004-2005 Stefan Reuter * * 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 net.sf.asterisk.manager.impl; import java.util.Map; import net.sf.asterisk.manager.ResponseBuilder; import net.sf.asterisk.manager.response.ChallengeResponse; import net.sf.asterisk.manager.response.ExtensionStateResponse; import net.sf.asterisk.manager.response.MailboxCountResponse; import net.sf.asterisk.manager.response.MailboxStatusResponse; import net.sf.asterisk.manager.response.ManagerError; import net.sf.asterisk.manager.response.ManagerResponse; /** * Default implementation of the ResponseBuilder interface. * * @see net.sf.asterisk.manager.response.ManagerResponse * @author srt * @version $Id: ResponseBuilderImpl.java,v 1.1 2005/03/11 15:27:23 srt Exp $ */ public class ResponseBuilderImpl implements ResponseBuilder { /** * Constructs an instance of ManagerResponse based on a map of attributes. * * @param attributes the attributes and their values. The keys of this map must be all lower * case. * @return the response with the given attributes. */ public ManagerResponse buildResponse(final Map attributes) { ManagerResponse response; String responseType; responseType = (String) attributes.get("response"); // determine type if ("error".equalsIgnoreCase(responseType)) { response = new ManagerError(); } else if (attributes.containsKey("challenge")) { ChallengeResponse challengeResponse = new ChallengeResponse(); challengeResponse.setChallenge((String) attributes.get("challenge")); response = challengeResponse; } else if (attributes.containsKey("mailbox") && attributes.containsKey("waiting")) { MailboxStatusResponse mailboxStatusResponse = new MailboxStatusResponse(); mailboxStatusResponse.setMailbox((String) attributes.get("mailbox")); if ("1".equals((String) attributes.get("waiting"))) { mailboxStatusResponse.setWaiting(Boolean.TRUE); } else { mailboxStatusResponse.setWaiting(Boolean.FALSE); } response = mailboxStatusResponse; } else if (attributes.containsKey("mailbox") && attributes.containsKey("newmessages") && attributes.containsKey("oldmessages")) { MailboxCountResponse mailboxCountResponse = new MailboxCountResponse(); mailboxCountResponse.setMailbox((String) attributes.get("mailbox")); mailboxCountResponse.setNewMessages(new Integer((String) attributes.get("newmessages"))); mailboxCountResponse.setOldMessages(new Integer((String) attributes.get("oldmessages"))); response = mailboxCountResponse; } else if (attributes.containsKey("exten") && attributes.containsKey("context") && attributes.containsKey("hint") && attributes.containsKey("status")) { ExtensionStateResponse extensionStateResponse = new ExtensionStateResponse(); extensionStateResponse.setExten((String) attributes.get("exten")); extensionStateResponse.setContext((String) attributes.get("context")); extensionStateResponse.setHint((String) attributes.get("hint")); extensionStateResponse.setStatus(new Integer((String) attributes.get("status"))); response = extensionStateResponse; } else { response = new ManagerResponse(); } // fill known attributes response.setResponse(responseType); if (attributes.containsKey("actionid")) { response.setActionId((String) attributes.get("actionid")); } if (attributes.containsKey("message")) { response.setMessage((String) attributes.get("message")); } if (attributes.containsKey("uniqueid")) { response.setUniqueId((String) attributes.get("uniqueid")); } return response; } } --- NEW FILE: EventBuilderImpl.java --- /* * Copyright 2004-2005 Stefan Reuter * * 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 net.sf.asterisk.manager.impl; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import net.sf.asterisk.manager.EventBuilder; import net.sf.asterisk.manager.Util; import net.sf.asterisk.manager.event.AgentCallbackLoginEvent; import net.sf.asterisk.manager.event.AgentCallbackLogoffEvent; import net.sf.asterisk.manager.event.AgentCalledEvent; import net.sf.asterisk.manager.event.AgentLoginEvent; import net.sf.asterisk.manager.event.AgentLogoffEvent; import net.sf.asterisk.manager.event.AlarmClearEvent; import net.sf.asterisk.manager.event.AlarmEvent; import net.sf.asterisk.manager.event.CdrEvent; import net.sf.asterisk.manager.event.DialEvent; import net.sf.asterisk.manager.event.ExtensionStatusEvent; import net.sf.asterisk.manager.event.HangupEvent; import net.sf.asterisk.manager.event.HoldedCallEvent; import net.sf.asterisk.manager.event.JoinEvent; import net.sf.asterisk.manager.event.LeaveEvent; import net.sf.asterisk.manager.event.LinkEvent; import net.sf.asterisk.manager.event.ManagerEvent; import net.sf.asterisk.manager.event.MeetMeJoinEvent; import net.sf.asterisk.manager.event.MeetMeLeaveEvent; import net.sf.asterisk.manager.event.MessageWaitingEvent; import net.sf.asterisk.manager.event.NewCallerIdEvent; import net.sf.asterisk.manager.event.NewChannelEvent; import net.sf.asterisk.manager.event.NewExtenEvent; import net.sf.asterisk.manager.event.NewStateEvent; import net.sf.asterisk.manager.event.OriginateFailureEvent; import net.sf.asterisk.manager.event.OriginateSuccessEvent; import net.sf.asterisk.manager.event.ParkedCallEvent; import net.sf.asterisk.manager.event.ParkedCallsCompleteEvent; import net.sf.asterisk.manager.event.PeerStatusEvent; import net.sf.asterisk.manager.event.QueueEntryEvent; import net.sf.asterisk.manager.event.QueueMemberEvent; import net.sf.asterisk.manager.event.QueueMemberStatusEvent; import net.sf.asterisk.manager.event.QueueParamsEvent; import net.sf.asterisk.manager.event.RegistryEvent; import net.sf.asterisk.manager.event.ReloadEvent; import net.sf.asterisk.manager.event.RenameEvent; import net.sf.asterisk.manager.event.ResponseEvent; import net.sf.asterisk.manager.event.ShutdownEvent; import net.sf.asterisk.manager.event.StatusCompleteEvent; import net.sf.asterisk.manager.event.StatusEvent; import net.sf.asterisk.manager.event.UnlinkEvent; import net.sf.asterisk.manager.event.ZapShowChannelsCompleteEvent; import net.sf.asterisk.manager.event.ZapShowChannelsEvent; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Default implementation of the EventBuilder interface. * * @see net.sf.asterisk.manager.event.ManagerEvent * @author srt * @version $Id: EventBuilderImpl.java,v 1.1 2005/03/11 15:27:23 srt Exp $ */ public class EventBuilderImpl implements EventBuilder { private final Log logger = LogFactory.getLog(getClass()); private Map registeredEventClasses; public EventBuilderImpl() { this.registeredEventClasses = new HashMap(); registerBuiltinEventClasses(); } private void registerBuiltinEventClasses() { registerEventClass(AgentCallbackLoginEvent.class); registerEventClass(AgentCallbackLogoffEvent.class); registerEventClass(AgentCalledEvent.class); registerEventClass(AgentLoginEvent.class); registerEventClass(AgentLogoffEvent.class); registerEventClass(AlarmEvent.class); registerEventClass(AlarmClearEvent.class); registerEventClass(CdrEvent.class); registerEventClass(DialEvent.class); registerEventClass(ExtensionStatusEvent.class); registerEventClass(HangupEvent.class); registerEventClass(HoldedCallEvent.class); registerEventClass(JoinEvent.class); registerEventClass(LeaveEvent.class); registerEventClass(LinkEvent.class); registerEventClass(MeetMeJoinEvent.class); registerEventClass(MeetMeLeaveEvent.class); registerEventClass(MessageWaitingEvent.class); registerEventClass(NewCallerIdEvent.class); registerEventClass(NewChannelEvent.class); registerEventClass(NewExtenEvent.class); registerEventClass(NewStateEvent.class); registerEventClass(OriginateFailureEvent.class); registerEventClass(OriginateSuccessEvent.class); registerEventClass(ParkedCallEvent.class); registerEventClass(ParkedCallsCompleteEvent.class); registerEventClass(PeerStatusEvent.class); registerEventClass(QueueEntryEvent.class); registerEventClass(QueueMemberEvent.class); registerEventClass(QueueMemberStatusEvent.class); registerEventClass(QueueParamsEvent.class); registerEventClass(RegistryEvent.class); registerEventClass(ReloadEvent.class); registerEventClass(RenameEvent.class); registerEventClass(ShutdownEvent.class); registerEventClass(StatusEvent.class); registerEventClass(StatusCompleteEvent.class); registerEventClass(UnlinkEvent.class); registerEventClass(ZapShowChannelsEvent.class); registerEventClass(ZapShowChannelsCompleteEvent.class); } public void registerEventClass(Class clazz) { String className; String eventType; className = clazz.getName(); eventType = className.substring(className.lastIndexOf('.') + 1).toLowerCase(); if (eventType.endsWith("event")) { eventType = eventType.substring(0, eventType.length() - "event".length()); } registerEventClass(eventType, clazz); } /** * Registers a new event class for the event given by eventType. * * @param eventType the name of the event to register the class for. For example "Join". * @param clazz the event class to register, must extend net.sf.asterisk.manager.event.Event. */ public void registerEventClass(String eventType, Class clazz) { Constructor defaultConstructor; if (!ManagerEvent.class.isAssignableFrom(clazz)) { throw new IllegalArgumentException(clazz + " is not a ManagerEvent"); } if ((clazz.getModifiers() & Modifier.ABSTRACT) != 0) { throw new IllegalArgumentException(clazz + " is abstract"); } try { defaultConstructor = clazz.getConstructor(new Class[]{Object.class}); } catch (NoSuchMethodException ex) { throw new IllegalArgumentException(clazz + " has no usable constructor"); } if ((defaultConstructor.getModifiers() & Modifier.PUBLIC) == 0) { throw new IllegalArgumentException(clazz + " has no public default constructor"); } registeredEventClasses.put(eventType.toLowerCase(), clazz); logger.debug("Registered event type '" + eventType + "' (" + clazz + ")"); } public ManagerEvent buildEvent(Object source, Map attributes) { ManagerEvent event; String eventType; Class eventClass; Constructor constructor; if (attributes.get("event") == null) { logger.error("No event event type in properties"); return null; } eventType = ((String) attributes.get("event")).toLowerCase(); eventClass = (Class) registeredEventClasses.get(eventType); if (eventClass == null) { logger.warn("No event class registered for event type '" + eventType + "', attributes: " + attributes); return null; } try { constructor = eventClass.getConstructor(new Class[]{Object.class}); } catch (NoSuchMethodException ex) { logger.error("Unable to get constructor of " + eventClass, ex); return null; } try { event = (ManagerEvent) constructor.newInstance(new Object[]{source}); } catch (Exception ex) { logger.error("Unable to create new instance of " + eventClass, ex); return null; } setAttributes(event, attributes); if (event instanceof ResponseEvent) { ResponseEvent responseEvent; String actionId; responseEvent = (ResponseEvent) event; actionId = responseEvent.getActionId(); if (actionId != null) { responseEvent.setActionId(Util.stripInternalActionId(actionId)); } } return event; } private void setAttributes(ManagerEvent event, Map attributes) { Map setters; setters = getSetters(event.getClass()); Iterator i = attributes.keySet().iterator(); while (i.hasNext()) { String name; Object value; Class dataType; Method setter; name = (String) i.next(); if ("event".equals(name)) { continue; } /* * The source property needs special handling as it is already defined in * java.util.EventObject (the base class of ManagerEvent), so we have to translate it. */ if ("source".equals(name)) { setter = (Method) setters.get("src"); } else { setter = (Method) setters.get(name); } if (setter == null) { logger.error("Unable to set property '" + name + "' on " + event.getClass() + ": no setter"); continue; } dataType = setter.getParameterTypes()[0]; if (dataType.isAssignableFrom(String.class)) { value = attributes.get(name); } else { try { Constructor constructor = dataType.getConstructor(new Class[]{String.class}); value = constructor.newInstance(new Object[]{attributes.get(name)}); } catch (Exception e) { logger.error("Unable to convert value '" + attributes.get(name) + "' of property '" + name + "' on " + event.getClass() + " to required type " + dataType, e); continue; } } try { setter.invoke(event, new Object[]{value}); } catch (Exception e) { logger.error("Unable to set property '" + name + "' on " + event.getClass(), e); continue; } } } private Map getSetters(Class clazz) { Map accessors = new HashMap(); Method[] methods = clazz.getMethods(); for (int i = 0; i < methods.length; i++) { String name; String methodName; Method method = methods[i]; methodName = method.getName(); if (!methodName.startsWith("set")) { continue; } // skip methods with != 1 parameters if (method.getParameterTypes().length != 1) { continue; } // ok seems to be an accessor name = methodName.substring("set".length()).toLowerCase(); accessors.put(name, method); } return accessors; } } --- NEW FILE: ManagerReaderImpl.java --- /* * Copyright 2004-2005 Stefan Reuter * * 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 net.sf.asterisk.manager.impl; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import net.sf.asterisk.io.SocketConnectionFacade; import net.sf.asterisk.manager.AsteriskServer; import net.sf.asterisk.manager.DefaultManagerConnection; import net.sf.asterisk.manager.Dispatcher; import net.sf.asterisk.manager.EventBuilder; import net.sf.asterisk.manager.ManagerReader; import net.sf.asterisk.manager.ResponseBuilder; import net.sf.asterisk.manager.event.ConnectEvent; import net.sf.asterisk.manager.event.DisconnectEvent; import net.sf.asterisk.manager.event.ManagerEvent; import net.sf.asterisk.manager.response.CommandResponse; import net.sf.asterisk.manager.response.ManagerResponse; import net.sf.asterisk.manager.util.DateUtil; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Default implementation of the ManagerReader interface. * * @author srt * @version $Id: ManagerReaderImpl.java,v 1.1 2005/03/11 15:27:23 srt Exp $ */ public class ManagerReaderImpl implements ManagerReader { /** * Instance logger. */ private final Log logger = LogFactory.getLog(getClass()); /** * The event builder utility to convert a map of attributes reveived from asterisk to instances * of registered event classes. */ private final EventBuilder eventBuilder; /** * The response builder utility to convert a map of attributes reveived from asterisk to * instances of well known response classes. */ private final ResponseBuilder responseBuilder; /** * The dispatcher to use for dispatching events and responses. */ private final Dispatcher dispatcher; /** * The asterisk server we are reading from. */ private final AsteriskServer asteriskServer; /** * The socket to use for reading from the asterisk server. */ private SocketConnectionFacade socket; /** * If set to <code>true</code>, terminates and closes the reader. */ private boolean die = false; /** * Creates a new ManagerReaderImpl. * * @param dispatcher the dispatcher to use for dispatching events and responses. */ public ManagerReaderImpl(final Dispatcher dispatcher, AsteriskServer asteriskServer) { this.dispatcher = dispatcher; this.asteriskServer = asteriskServer; this.eventBuilder = new EventBuilderImpl(); this.responseBuilder = new ResponseBuilderImpl(); } /** * Sets the socket to use for reading from the asterisk server. * * @param socket the socket to use for reading from the asterisk server. */ public void setSocket(final SocketConnectionFacade socket) { this.socket = socket; } public void registerEventClass(Class eventClass) { eventBuilder.registerEventClass(eventClass); } /** * Reads line by line from the asterisk server, sets the protocol identifier as soon as it is * received and dispatches the received events and responses via the associated dispatcher. * * @see DefaultManagerConnection#dispatchEvent(ManagerEvent) * @see DefaultManagerConnection#dispatchResponse(ManagerResponse) * @see DefaultManagerConnection#setProtocolIdentifier(String) */ public void run() { final Map buffer = new HashMap(); final List commandResult = new ArrayList(); String line; boolean processingCommandResult = false; if (socket == null) { throw new IllegalStateException("Unable to run: socket is null."); } this.die = false; try { while ((line = socket.readLine()) != null && !this.die) { // dirty hack for handling the CommandAction. Needs fix when manager protocol is // enhanced. if (processingCommandResult) { if ("--END COMMAND--".equals(line)) { CommandResponse commandResponse = new CommandResponse(); if (!commandResult.isEmpty() && ((String) commandResult.get(0)).startsWith("ActionID")) { String tmp = (String) commandResult.get(0); int delimiterIndex = tmp.indexOf(":"); if (delimiterIndex > 0 && tmp.length() > delimiterIndex + 2) { commandResult.remove(0); commandResponse.setActionId(tmp.substring(delimiterIndex + 2)); } } commandResponse.setResponse("Follows"); commandResponse.setDateReceived(DateUtil.getDate()); commandResponse.setResult(commandResult); dispatcher.dispatchResponse(commandResponse); processingCommandResult = false; } else { commandResult.add(line); } continue; } // Reponse: Follows indicates that the output starting on the next line until // --END COMMAND-- must be treated as raw output of a command executed by a // CommandAction. if ("Response: Follows".equalsIgnoreCase(line)) { processingCommandResult = true; commandResult.clear(); continue; } // maybe we will find a better way to identify the protocol identifier but for now // this works quite well. if (line.startsWith("Asterisk Call Manager/")) { ConnectEvent connectEvent = new ConnectEvent(asteriskServer); connectEvent.setProtocolIdentifier(line); connectEvent.setDateReceived(DateUtil.getDate()); dispatcher.dispatchEvent(connectEvent); continue; } // an empty line indicates a normal response's or event's end so we build // the corresponding value object and dispatch it through the ManagerConnection. if (line.length() == 0) { if (buffer.containsKey("response")) { ManagerResponse response = buildResponse(buffer); if (response != null) { dispatcher.dispatchResponse(response); } } else if (buffer.containsKey("event")) { ManagerEvent event = buildEvent(asteriskServer, buffer); if (event != null) { dispatcher.dispatchEvent(event); } } buffer.clear(); } else { int delimiterIndex; delimiterIndex = line.indexOf(":"); if (delimiterIndex > 0 && line.length() > delimiterIndex + 2) { String name; String value; name = line.substring(0, delimiterIndex).toLowerCase(); value = line.substring(delimiterIndex + 2); buffer.put(name, value); } } } logger.info("Reached end of stream, terminating reader."); } catch (IOException e) { logger.info("IOException while reading from asterisk server, terminating reader thread: " + e.getMessage()); } finally { // cleans resources and reconnects if needed DisconnectEvent disconnectEvent = new DisconnectEvent(asteriskServer); disconnectEvent.setDateReceived(DateUtil.getDate()); dispatcher.dispatchEvent(disconnectEvent); } } public void die() { this.die = true; } private ManagerResponse buildResponse(Map buffer) { ManagerResponse response; response = responseBuilder.buildResponse(buffer); if (response != null) { response.setDateReceived(DateUtil.getDate()); } return response; } private ManagerEvent buildEvent(Object source, Map buffer) { ManagerEvent event; event = eventBuilder.buildEvent(source, buffer); if (event != null) { event.setDateReceived(DateUtil.getDate()); } return event; } } --- NEW FILE: ManagerWriterImpl.java --- /* * Copyright 2004-2005 Stefan Reuter * * 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 net.sf.asterisk.manager.impl; import java.io.IOException; import net.sf.asterisk.io.SocketConnectionFacade; import net.sf.asterisk.manager.ActionBuilder; import net.sf.asterisk.manager.ManagerWriter; import net.sf.asterisk.manager.action.ManagerAction; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Default implementation of ManagerWriter interface. * * @author srt * @version $Id: ManagerWriterImpl.java,v 1.1 2005/03/11 15:27:23 srt Exp $ */ public class ManagerWriterImpl implements ManagerWriter { /** * Instance logger. */ private final Log logger = LogFactory.getLog(getClass()); /** * The action builder utility to convert ManagerAction to a String suitable to be sent to the * asterisk server. */ private final ActionBuilder actionBuilder; private SocketConnectionFacade socket; /** * Creates a new ManagerWriterImpl. */ public ManagerWriterImpl() { this.actionBuilder = new ActionBuilderImpl(); } public synchronized void setSocket(final SocketConnectionFacade socket) { this.socket = socket; } public synchronized void sendAction(final ManagerAction action) throws IOException { final String actionString; if (socket == null) { throw new IllegalStateException("Unable to send action: socket is null"); } actionString = actionBuilder.buildAction(action); socket.write(actionString); socket.flush(); logger.debug("Sent " + action.getAction() + " action with actionId '" + action.getActionId() + "':\n" + actionString); } } --- NEW FILE: ActionBuilderImpl.java --- /* * Copyright 2004-2005 Stefan Reuter * * 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 net.sf.asterisk.manager.impl; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import net.sf.asterisk.manager.ActionBuilder; import net.sf.asterisk.manager.action.ManagerAction; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Default implementation of the ActionBuilder interface. * * @author srt * @version $Id: ActionBuilderImpl.java,v 1.1 2005/03/11 15:27:23 srt Exp $ */ public class ActionBuilderImpl implements ActionBuilder { /** * Instance logger. */ private final Log logger = LogFactory.getLog(getClass()); public final String buildAction(final ManagerAction action) { StringBuffer sb; Map getters; sb = new StringBuffer(); getters = getGetters(action.getClass()); Iterator i = getters.keySet().iterator(); while (i.hasNext()) { String name; Method getter; Object value; String stringValue; name = (String) i.next(); if ("class".equals(name)) { continue; } getter = (Method) getters.get(name); try { value = getter.invoke(action, new Object[]{}); } catch (IllegalAccessException ex) { logger.error("Unable to retrieve property '" + name + "' of " + action.getClass(), ex); continue; } catch (InvocationTargetException ex) { logger.error("Unable to retrieve property '" + name + "' of " + action.getClass(), ex); continue; } if (value == null) { continue; } if (value instanceof String) { stringValue = (String) value; } else { stringValue = value.toString(); } sb.append(name); sb.append(": "); sb.append(stringValue); sb.append("\r\n"); } sb.append("\r\n"); return sb.toString(); } /** * Returns a Map of getter methods of the given class.<br> * The key of the map contains the name of the attribute that can be accessed by the getter, the * value the getter itself (an instance of java.lang.reflect.Method). A method is considered a * getter if its name starts with "get", it is declared public and takes no arguments. * * @param clazz the class to return the getters for * @return a Map of attributes and their accessor methods (getters) */ private Map getGetters(final Class clazz) { Map accessors = new HashMap(); Method[] methods = clazz.getMethods(); for (int i = 0; i < methods.length; i++) { String name; String methodName; Method method = methods[i]; methodName = method.getName(); if (!methodName.startsWith("get")) { continue; } // skip methods with != 0 parameters if (method.getParameterTypes().length != 0) { continue; } // ok seems to be an accessor name = methodName.substring("get".length()).toLowerCase(); if (name.length() == 0) { continue; } accessors.put(name, method); } return accessors; } } |