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 }