001 /*
002 * Copyright 2010 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package com.hs.mail.sieve;
017
018 import java.lang.reflect.InvocationTargetException;
019 import java.lang.reflect.Method;
020 import java.util.HashMap;
021 import java.util.Map;
022
023 import javax.mail.MessagingException;
024
025 import org.apache.jsieve.mail.Action;
026 import org.apache.jsieve.mail.ActionFileInto;
027 import org.apache.jsieve.mail.ActionKeep;
028 import org.apache.jsieve.mail.ActionRedirect;
029 import org.apache.jsieve.mail.ActionReject;
030 import org.apache.jsieve.mail.MailAdapter;
031
032 import com.hs.mail.mailet.MailetContext;
033
034 public class ActionDispatcher {
035 /**
036 * The sole instance of the receiver.
037 */
038 static private ActionDispatcher fieldInstance;
039
040 /**
041 * A Map keyed by the type of Action. The values are the methods to invoke
042 * to handle the Action.
043 */
044 private Map fieldMethodMap;
045
046 /**
047 * Constructor for ActionDispatcher.
048 */
049 private ActionDispatcher() {
050 super();
051 }
052
053 /**
054 * Returns the sole instance of the receiver, lazily initialised.
055 *
056 * @return ActionDispatcher
057 */
058 public static synchronized ActionDispatcher getInstance() {
059 ActionDispatcher instance = null;
060 if (null == (instance = getInstanceBasic())) {
061 updateInstance();
062 return getInstance();
063 }
064 return instance;
065 }
066
067 /**
068 * Returns the sole instance of the receiver.
069 *
070 * @return ActionDispatcher
071 */
072 private static ActionDispatcher getInstanceBasic() {
073 return fieldInstance;
074 }
075
076 /**
077 * Returns a new instance of the receiver.
078 *
079 * @return ActionDispatcher
080 */
081 protected static ActionDispatcher computeInstance() {
082 return new ActionDispatcher();
083 }
084
085 /**
086 * Sets the instance.
087 *
088 * @param instance
089 * The instance to set
090 */
091 protected static void setInstance(ActionDispatcher instance) {
092 fieldInstance = instance;
093 }
094
095 /**
096 * Resets the instance.
097 */
098 public static void resetInstance() {
099 setInstance(null);
100 }
101
102 /**
103 * Updates the instance.
104 */
105 protected static void updateInstance() {
106 setInstance(computeInstance());
107 }
108
109 /**
110 * Method execute executes the passed Action by invoking the method mapped by the
111 * receiver with a parameter of the EXACT type of Action.
112 * @param anAction
113 * @param aMail
114 * @param aMailetContext
115 * @throws NoSuchMethodException
116 * @throws IllegalAccessException
117 * @throws InvocationTargetException
118 * @throws MessagingException
119 */
120 public void execute(Action anAction, MailAdapter aMail,
121 MailetContext aMailetContext) throws NoSuchMethodException,
122 IllegalArgumentException, IllegalAccessException,
123 InvocationTargetException {
124 Method actionMethod = (Method) getMethodMap().get(anAction.getClass());
125 if (null == actionMethod)
126 throw new NoSuchMethodException("Method accepting parameters ("
127 + anAction.getClass().getName() + ", "
128 + aMail.getClass().getName() + ", "
129 + aMailetContext.getClass().getName() + ") not mapped.");
130 actionMethod.invoke(null, new Object[] { anAction, aMail,
131 aMailetContext });
132 }
133
134 /**
135 * Returns the methodMap, lazily initialised.
136 *
137 * @return Map
138 * @throws NoSuchMethodException
139 */
140 protected synchronized Map getMethodMap() throws NoSuchMethodException {
141 Map methodMap = null;
142 if (null == (methodMap = getMethodMapBasic())) {
143 updateMethodMap();
144 return getMethodMap();
145 }
146 return methodMap;
147 }
148
149 /**
150 * Returns the methodMap.
151 *
152 * @return Map
153 */
154 private Map getMethodMapBasic() {
155 return fieldMethodMap;
156 }
157
158 /**
159 * Returns a new methodMap.
160 * @return Map
161 */
162 protected Map computeMethodMap() throws NoSuchMethodException {
163 Map methodNameMap = new HashMap();
164 methodNameMap.put(
165 ActionFileInto.class,
166 Actions.class.getMethod(
167 "execute",
168 new Class[] {
169 ActionFileInto.class,
170 SieveMailAdapter.class,
171 MailetContext.class }));
172 methodNameMap.put(
173 ActionKeep.class,
174 Actions.class.getMethod(
175 "execute",
176 new Class[] {
177 ActionKeep.class,
178 SieveMailAdapter.class,
179 MailetContext.class }));
180 methodNameMap.put(
181 ActionRedirect.class,
182 Actions.class.getMethod(
183 "execute",
184 new Class[] {
185 ActionRedirect.class,
186 SieveMailAdapter.class,
187 MailetContext.class }));
188 methodNameMap.put(
189 ActionReject.class,
190 Actions.class.getMethod(
191 "execute",
192 new Class[] {
193 ActionReject.class,
194 SieveMailAdapter.class,
195 MailetContext.class }));
196 return methodNameMap;
197 }
198
199 /**
200 * Sets the methodMap.
201 *
202 * @param methodMap
203 * The methodMap to set
204 */
205 protected void setMethodMap(Map methodMap) {
206 fieldMethodMap = methodMap;
207 }
208
209 /**
210 * Updates the methodMap.
211 *
212 * @throws NoSuchMethodException
213 */
214 protected void updateMethodMap() throws NoSuchMethodException {
215 setMethodMap(computeMethodMap());
216 }
217
218 }