1 17 18 package org.apache.james.core; 19 20 import org.apache.avalon.framework.activity.Initializable; 21 import org.apache.avalon.framework.component.Component; 22 import org.apache.avalon.framework.component.ComponentException; 23 import org.apache.avalon.framework.component.ComponentManager; 24 import org.apache.avalon.framework.component.Composable; 25 import org.apache.avalon.framework.configuration.Configurable; 26 import org.apache.avalon.framework.configuration.Configuration; 27 import org.apache.avalon.framework.configuration.ConfigurationException; 28 import org.apache.avalon.framework.configuration.DefaultConfiguration; 29 import org.apache.avalon.framework.context.Context; 30 import org.apache.avalon.framework.context.ContextException; 31 import org.apache.avalon.framework.context.Contextualizable; 32 import org.apache.avalon.framework.logger.AbstractLogEnabled; 33 import org.apache.avalon.framework.logger.LogEnabled; 34 import org.apache.james.services.MailRepository; 35 import org.apache.james.services.MailStore; 36 import org.apache.james.services.SpoolRepository; 37 38 import java.util.HashMap ; 39 40 45 public class AvalonMailStore 46 extends AbstractLogEnabled 47 implements Contextualizable, Composable, Configurable, Initializable, MailStore { 48 49 private static final String REPOSITORY_NAME = "Repository"; 51 52 private static long id; 55 56 private HashMap repositories; 58 59 private HashMap classes; 61 62 private HashMap defaultConfigs; 64 65 68 protected Context context; 69 70 73 protected Configuration configuration; 74 75 78 protected ComponentManager componentManager; 79 80 private SpoolRepository inboundSpool; 81 82 85 public void contextualize(final Context context) 86 throws ContextException { 87 this.context = context; 88 } 89 90 93 public void compose( final ComponentManager componentManager ) 94 throws ComponentException 95 { 96 this.componentManager = componentManager; 97 } 98 99 102 public void configure( final Configuration configuration ) 103 throws ConfigurationException 104 { 105 this.configuration = configuration; 106 } 107 108 111 public void initialize() 112 throws Exception { 113 114 getLogger().info("JamesMailStore init..."); 115 repositories = new HashMap (); 116 classes = new HashMap (); 117 defaultConfigs = new HashMap (); 118 Configuration[] registeredClasses 119 = configuration.getChild("repositories").getChildren("repository"); 120 for ( int i = 0; i < registeredClasses.length; i++ ) 121 { 122 registerRepository((Configuration) registeredClasses[i]); 123 } 124 125 126 Configuration spoolRepConf 127 = configuration.getChild("spoolRepository").getChild("repository"); 128 try { 129 inboundSpool = (SpoolRepository) select(spoolRepConf); 130 } catch (Exception e) { 131 getLogger().error("Cannot open private SpoolRepository"); 132 throw e; 133 } 134 if (getLogger().isInfoEnabled()) { 135 getLogger().info("SpoolRepository inboundSpool opened: " 136 + inboundSpool.hashCode()); 137 getLogger().info("James MailStore ...init"); 138 } 139 } 140 141 154 public synchronized void registerRepository(Configuration repConf) 155 throws ConfigurationException { 156 String className = repConf.getAttribute("class"); 157 boolean infoEnabled = getLogger().isInfoEnabled(); 158 Configuration[] protocols 159 = repConf.getChild("protocols").getChildren("protocol"); 160 Configuration[] types = repConf.getChild("types").getChildren("type"); 161 for ( int i = 0; i < protocols.length; i++ ) 162 { 163 String protocol = protocols[i].getValue(); 164 165 Configuration defConf = repConf.getChild("config"); 167 168 for ( int j = 0; j < types.length; j++ ) 169 { 170 String type = types[j].getValue(); 171 String key = protocol + type ; 172 if (infoEnabled) { 173 StringBuffer infoBuffer = 174 new StringBuffer (128) 175 .append("Registering Repository instance of class ") 176 .append(className) 177 .append(" to handle ") 178 .append(protocol) 179 .append(" protocol requests for repositories of type ") 180 .append(type); 181 getLogger().info(infoBuffer.toString()); 182 } 183 if (classes.get(key) != null) { 184 throw new ConfigurationException("The combination of protocol and type comprise a unique key for repositories. This constraint has been violated. Please check your repository configuration."); 185 } 186 classes.put(key, className); 187 if (defConf != null) { 188 defaultConfigs.put(key, defConf); 189 } 190 } 191 } 192 193 } 194 195 213 public synchronized Component select(Object hint) throws ComponentException { 214 Configuration repConf = null; 215 try { 216 repConf = (Configuration) hint; 217 } catch (ClassCastException cce) { 218 throw new ComponentException( 219 "hint is of the wrong type. Must be a Configuration", cce); 220 } 221 String destination = null; 222 String protocol = null; 223 try { 224 destination = repConf.getAttribute("destinationURL"); 225 int idx = destination.indexOf(':'); 226 if ( idx == -1 ) 227 throw new ComponentException( 228 "destination is malformed. Must be a valid URL: " 229 + destination); 230 protocol = destination.substring(0,idx); 231 } catch (ConfigurationException ce) { 232 throw new ComponentException( 233 "Malformed configuration has no destinationURL attribute", ce); 234 } 235 236 try 237 { 238 String type = repConf.getAttribute("type"); 239 String repID = destination + type; 240 MailRepository reply = (MailRepository) repositories.get(repID); 241 StringBuffer logBuffer = null; 242 if (reply != null) { 243 if (getLogger().isDebugEnabled()) { 244 logBuffer = 245 new StringBuffer (128) 246 .append("obtained repository: ") 247 .append(repID) 248 .append(",") 249 .append(reply.getClass()); 250 getLogger().debug(logBuffer.toString()); 251 } 252 return (Component)reply; 253 } else { 254 String key = protocol + type; 255 String repClass = (String ) classes.get( key ); 256 257 if (getLogger().isDebugEnabled()) { 258 logBuffer = 259 new StringBuffer (128) 260 .append("obtained repository: ") 261 .append(repClass) 262 .append(" to handle: ") 263 .append(protocol) 264 .append(",") 265 .append(type); 266 getLogger().debug( logBuffer.toString() ); 267 } 268 269 Configuration config; 274 Configuration defConf = (Configuration)defaultConfigs.get(key); 275 if ( defConf == null) { 276 config = repConf; 277 } 278 else { 279 config = new DefaultConfiguration(repConf.getName(), 280 repConf.getLocation()); 281 copyConfig(defConf, (DefaultConfiguration)config); 282 copyConfig(repConf, (DefaultConfiguration)config); 283 } 284 285 try { 286 reply = (MailRepository) this.getClass().getClassLoader().loadClass(repClass).newInstance(); 287 if (reply instanceof LogEnabled) { 288 setupLogger(reply); 289 } 290 if (reply instanceof Contextualizable) { 291 ((Contextualizable) reply).contextualize(context); 292 } 293 if (reply instanceof Composable) { 294 ((Composable) reply).compose( componentManager ); 295 } 296 if (reply instanceof Configurable) { 297 ((Configurable) reply).configure(config); 298 } 299 if (reply instanceof Initializable) { 300 ((Initializable) reply).initialize(); 301 } 302 repositories.put(repID, reply); 303 if (getLogger().isInfoEnabled()) { 304 logBuffer = 305 new StringBuffer (128) 306 .append("added repository: ") 307 .append(repID) 308 .append("->") 309 .append(repClass); 310 getLogger().info(logBuffer.toString()); 311 } 312 return (Component)reply; 313 } catch (Exception e) { 314 if (getLogger().isWarnEnabled()) { 315 getLogger().warn( "Exception while creating repository:" + 316 e.getMessage(), e ); 317 } 318 throw new 319 ComponentException("Cannot find or init repository", 320 e); 321 } 322 } 323 } catch( final ConfigurationException ce ) { 324 throw new ComponentException( "Malformed configuration", ce ); 325 } 326 } 327 328 336 public static final String getName() { 337 synchronized (AvalonMailStore.class) { 338 return REPOSITORY_NAME + id++; 339 } 340 } 341 342 350 public SpoolRepository getInboundSpool() { 351 if (inboundSpool != null) { 352 return inboundSpool; 353 } else { 354 throw new IllegalStateException ("Inbound spool not defined"); 355 } 356 } 357 358 366 public boolean hasComponent( Object hint ) { 367 Component comp = null; 368 try { 369 comp = select(hint); 370 } catch(ComponentException ex) { 371 if (getLogger().isErrorEnabled()) { 372 getLogger().error("Exception AvalonMailStore.hasComponent-" + ex.toString()); 373 } 374 } 375 return (comp != null); 376 } 377 378 385 private void copyConfig(Configuration fromConfig, DefaultConfiguration toConfig) 386 { 387 String [] attrs = fromConfig.getAttributeNames(); 389 for ( int i = 0; i < attrs.length; i++ ) { 390 String attrName = attrs[i]; 391 String attrValue = fromConfig.getAttribute(attrName, null); 392 toConfig.setAttribute(attrName, attrValue); 393 } 394 395 Configuration[] children = fromConfig.getChildren(); 397 for ( int i = 0; i < children.length; i++ ) { 398 Configuration child = children[i]; 399 String childName = child.getName(); 400 Configuration existingChild = toConfig.getChild(childName, false); 401 if ( existingChild == null ) { 402 toConfig.addChild(child); 403 } 404 else { 405 copyConfig(child, (DefaultConfiguration)existingChild); 406 } 407 } 408 409 String val = fromConfig.getValue(null); 411 if ( val != null ) { 412 toConfig.setValue(val); 413 } 414 } 415 416 422 public void release(Component component) {} 423 } 424 | Popular Tags |