01: // Copyright 2006, 2007 The Apache Software Foundation
02: //
03: // Licensed under the Apache License, Version 2.0 (the "License");
04: // you may not use this file except in compliance with the License.
05: // You may obtain a copy of the License at
06: //
07: // http://www.apache.org/licenses/LICENSE-2.0
08: //
09: // Unless required by applicable law or agreed to in writing, software
10: // distributed under the License is distributed on an "AS IS" BASIS,
11: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12: // See the License for the specific language governing permissions and
13: // limitations under the License.
14:
15: package org.apache.tapestry.internal.services;
16:
17: import static org.apache.tapestry.ioc.internal.util.Defense.notBlank;
18: import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
19:
20: import org.apache.tapestry.ComponentEventHandler;
21: import org.apache.tapestry.ioc.services.TypeCoercer;
22: import org.apache.tapestry.runtime.ComponentEvent;
23:
24: public class ComponentEventImpl extends EventImpl implements
25: ComponentEvent {
26: private final String _eventType;
27:
28: private final String _originatingComponentId;
29:
30: private final Object[] _context;
31:
32: private final TypeCoercer _typeCoercer;
33:
34: /**
35: * @param eventType
36: * non blank string used to identify the type of event that was triggered
37: * @param originatingComponentId
38: * the id of the component that triggered the event (this will likely need to change
39: * somewhat)
40: * @param context
41: * an array of values that can be made available to handler methods via method
42: * parameters
43: * @param handler
44: * invoked when a non-null return value is obtained from an event handler method
45: * @param typeCoercer
46: * used when coercing context values to parameter types
47: */
48: public ComponentEventImpl(String eventType,
49: String originatingComponentId, Object[] context,
50: ComponentEventHandler handler, TypeCoercer typeCoercer) {
51: super (handler);
52:
53: _eventType = notBlank(eventType, "eventType");
54: _originatingComponentId = originatingComponentId;
55: _context = context != null ? context : new Object[0];
56: _typeCoercer = notNull(typeCoercer, "typeCoercer");
57: }
58:
59: /**
60: * TODO: This implementation is broken, but will get the job done for simple cases. It just
61: * doesn't do quite the right think when an event bubbles up past its originating component's
62: * container (can lead to false matches).
63: */
64: public boolean matchesByComponentId(String componentId) {
65: return _originatingComponentId.equalsIgnoreCase(componentId);
66: }
67:
68: public boolean matchesByEventType(String eventType) {
69: return _eventType.equalsIgnoreCase(eventType);
70: }
71:
72: public boolean matchesByParameterCount(int parameterCount) {
73: return _context.length >= parameterCount;
74: }
75:
76: @SuppressWarnings("unchecked")
77: public Object coerceContext(int index, String desiredTypeName) {
78: if (index >= _context.length)
79: throw new IllegalArgumentException(ServicesMessages
80: .contextIndexOutOfRange(getMethodDescription()));
81:
82: try {
83: Class desiredType = Class.forName(desiredTypeName);
84:
85: return _typeCoercer.coerce(_context[index], desiredType);
86: } catch (Exception ex) {
87: throw new IllegalArgumentException(ServicesMessages
88: .exceptionInMethodParameter(getMethodDescription(),
89: index, ex), ex);
90: }
91: }
92:
93: public Object[] getContext() {
94: return _context;
95: }
96: }
|