001 // Copyright 2004, 2005 The Apache Software Foundation
002 //
003 // Licensed under the Apache License, Version 2.0 (the "License");
004 // you may not use this file except in compliance with the License.
005 // You may obtain a copy of the License at
006 //
007 // http://www.apache.org/licenses/LICENSE-2.0
008 //
009 // Unless required by applicable law or agreed to in writing, software
010 // distributed under the License is distributed on an "AS IS" BASIS,
011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012 // See the License for the specific language governing permissions and
013 // limitations under the License.
014
015 package org.apache.hivemind.impl;
016
017 import org.apache.commons.logging.Log;
018 import org.apache.hivemind.ApplicationRuntimeException;
019 import org.apache.hivemind.InterceptorStack;
020 import org.apache.hivemind.internal.Module;
021 import org.apache.hivemind.internal.ServiceInterceptorContribution;
022 import org.apache.hivemind.internal.ServicePoint;
023 import org.apache.hivemind.util.ToStringBuilder;
024
025 /**
026 * Implementation of the {@link org.apache.hivemind.InterceptorStack} interface; localizes
027 * error checking in one place.
028 *
029 * @author Howard Lewis Ship
030 */
031 public final class InterceptorStackImpl implements InterceptorStack
032 {
033 private final Log _log;
034
035 private ServiceInterceptorContribution _contribution;
036 private ServicePoint _sep;
037 private Class _interfaceClass;
038 private Object _top;
039
040 public InterceptorStackImpl(Log log, ServicePoint sep, Object root)
041 {
042 _log = log;
043 _sep = sep;
044 _top = root;
045 _interfaceClass = sep.getServiceInterface();
046 }
047
048 public String toString()
049 {
050 ToStringBuilder builder = new ToStringBuilder(this);
051 builder.append("contribution", _contribution);
052 builder.append("interfaceClass", _interfaceClass);
053 builder.append("top", _top);
054
055 return builder.toString();
056 }
057
058 public String getServiceExtensionPointId()
059 {
060 return _sep.getExtensionPointId();
061 }
062
063 public Module getServiceModule()
064 {
065 return _sep.getModule();
066 }
067
068 public Class getServiceInterface()
069 {
070 return _interfaceClass;
071 }
072
073 public Object peek()
074 {
075 return _top;
076 }
077
078 public void push(Object interceptor)
079 {
080 if (interceptor == null)
081 throw new ApplicationRuntimeException(
082 ImplMessages.nullInterceptor(_contribution, _sep),
083 _contribution.getLocation(),
084 null);
085
086 if (!_interfaceClass.isAssignableFrom(interceptor.getClass()))
087 throw new ApplicationRuntimeException(
088 ImplMessages.interceptorDoesNotImplementInterface(
089 interceptor,
090 _contribution,
091 _sep,
092 _interfaceClass),
093 _contribution.getLocation(),
094 null);
095
096 _top = interceptor;
097 }
098
099 /**
100 * Invoked to process the next interceptor contribution; these should
101 * be processed in ascending order.
102 *
103 */
104
105 public void process(ServiceInterceptorContribution contribution)
106 {
107 if (_log.isDebugEnabled())
108 _log.debug("Applying interceptor factory " + contribution.getFactoryServiceId());
109
110 // And now we can finally do this!
111
112 try
113 {
114 _contribution = contribution;
115
116 contribution.createInterceptor(this);
117 }
118 finally
119 {
120 _contribution = null;
121 }
122 }
123
124 public Log getServiceLog()
125 {
126 return _log;
127 }
128 }