/** * Copyright 2010 Voxeo Corporation * * 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.voxeo.moho.common.event; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import org.apache.log4j.Logger; import com.voxeo.moho.State; import com.voxeo.moho.event.Event; import com.voxeo.moho.event.EventSource; import com.voxeo.moho.utils.EventListener; public class AutowiredEventTarget { private static final Logger log = Logger.getLogger(AutowiredEventTarget.class); public static final String DEFAULT_FSM = "com.voxeo.moho.event.fsm"; public static final String ANY_STATE = "com.voxeo.moho.event.anystate"; protected final Map<String, String> _definedStates = new HashMap<String, String>(); protected Method _method; protected Object _observer; protected EventListener<Event<? extends EventSource>> _listener; AutowiredEventTarget(final Method method, final Object observer) { final State anno = method.getAnnotation(State.class); if (anno != null) { final String[] states = anno.value(); for (final String state : states) { final String[] values = state.split("="); if (values.length == 1) { if (values[0].trim().length() == 0) { values[0] = ANY_STATE; } _definedStates.put(DEFAULT_FSM, values[0]); } else if (values.length == 2) { if (values[1].trim().length() == 0) { values[1] = ANY_STATE; } _definedStates.put(values[0], values[1]); } else { // log error } } } else { _definedStates.put(DEFAULT_FSM, ANY_STATE); } _method = method; _observer = observer; } AutowiredEventTarget(final String[][] states, final EventListener<Event<? extends EventSource>> listener) { for (final String[] s : states) { _definedStates.put(s[0], s[1]); } _listener = listener; } @Override public boolean equals(final Object o) { if (!(o instanceof AutowiredEventTarget)) { return false; } return this._method.equals(((AutowiredEventTarget) o)._method); } Object getObserver() { return _observer; } EventListener<Event<? extends EventSource>> getListener() { return _listener; } boolean invoke(final Event<? extends EventSource> event) throws Exception { for (final Map.Entry<String, String> entry : _definedStates.entrySet()) { final String defined = entry.getValue(); if (defined != ANY_STATE) { if (!defined.equals(event.getSource().getApplicationState(entry.getKey()))) { return false; } } } if (_observer != null && _method != null) { final boolean accessible = _method.isAccessible(); try { _method.setAccessible(true); _method.invoke(_observer, new Object[] {event}); } catch (final Exception e) { log.error("Got Exception when invoking Application.", e); if (e instanceof InvocationTargetException && ((InvocationTargetException) e).getTargetException() instanceof Exception) { throw (Exception) ((InvocationTargetException) e).getTargetException(); } } finally { _method.setAccessible(accessible); } } if (_listener != null) { try { _listener.onEvent(event); } catch (final Exception e) { log.error("", e); throw e; } } return true; } }