📄 avalonmailrepository.java
字号:
/**************************************************************** * Licensed to the Apache Software Foundation (ASF) under one * * or more contributor license agreements. See the NOTICE file * * distributed with this work for additional information * * regarding copyright ownership. The ASF licenses this file * * to you under the Apache License, Version 2.0 (the * * "License"); you may not use this file except in compliance * * with the License. You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, * * software distributed under the License is distributed on an * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * * KIND, either express or implied. See the License for the * * specific language governing permissions and limitations * * under the License. * ****************************************************************/package org.apache.james.mailrepository;import org.apache.avalon.cornerstone.services.store.ObjectRepository;import org.apache.avalon.cornerstone.services.store.Store;import org.apache.avalon.cornerstone.services.store.StreamRepository;import org.apache.avalon.framework.activity.Initializable;import org.apache.avalon.framework.configuration.Configurable;import org.apache.avalon.framework.configuration.Configuration;import org.apache.avalon.framework.configuration.ConfigurationException;import org.apache.avalon.framework.configuration.DefaultConfiguration;import org.apache.avalon.framework.logger.AbstractLogEnabled;import org.apache.avalon.framework.service.ServiceException;import org.apache.avalon.framework.service.ServiceManager;import org.apache.avalon.framework.service.Serviceable;import org.apache.james.core.MimeMessageCopyOnWriteProxy;import org.apache.james.core.MimeMessageWrapper;import org.apache.james.services.MailRepository;import org.apache.james.util.Lock;import org.apache.mailet.Mail;import javax.mail.MessagingException;import javax.mail.internet.MimeMessage;import java.io.OutputStream;import java.util.ArrayList;import java.util.Collection;import java.util.Collections;import java.util.HashSet;import java.util.Iterator;import java.util.Set;/** * Implementation of a MailRepository on a FileSystem. * * Requires a configuration element in the .conf.xml file of the form: * <repository destinationURL="file://path-to-root-dir-for-repository" * type="MAIL" * model="SYNCHRONOUS"/> * Requires a logger called MailRepository. * * @version 1.0.0, 24/04/1999 */public class AvalonMailRepository extends AbstractLogEnabled implements MailRepository, Configurable, Serviceable, Initializable { /** * Whether 'deep debugging' is turned on. */ protected final static boolean DEEP_DEBUG = false; private Lock lock; private Store store; private StreamRepository sr; private ObjectRepository or; private String destination; private Set keys; private boolean fifo; private boolean cacheKeys; // experimental: for use with write mostly repositories such as spam and error /** * @see org.apache.avalon.framework.service.Serviceable#compose(ServiceManager ) */ public void service( final ServiceManager componentManager ) throws ServiceException { store = (Store)componentManager.lookup( Store.ROLE ); } /** * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration) */ public void configure(Configuration conf) throws ConfigurationException { destination = conf.getAttribute("destinationURL"); if (getLogger().isDebugEnabled()) { getLogger().debug("AvalonMailRepository.destinationURL: " + destination); } String checkType = conf.getAttribute("type"); if (! (checkType.equals("MAIL") || checkType.equals("SPOOL")) ) { String exceptionString = "Attempt to configure AvalonMailRepository as " + checkType; if (getLogger().isWarnEnabled()) { getLogger().warn(exceptionString); } throw new ConfigurationException(exceptionString); } fifo = conf.getAttributeAsBoolean("FIFO", false); cacheKeys = conf.getAttributeAsBoolean("CACHEKEYS", true); // ignore model } /** * @see org.apache.avalon.framework.activity.Initializable#initialize() */ public void initialize() throws Exception { try { //prepare Configurations for object and stream repositories DefaultConfiguration objectConfiguration = new DefaultConfiguration( "repository", "generated:AvalonFileRepository.compose()" ); objectConfiguration.setAttribute("destinationURL", destination); objectConfiguration.setAttribute("type", "OBJECT"); objectConfiguration.setAttribute("model", "SYNCHRONOUS"); DefaultConfiguration streamConfiguration = new DefaultConfiguration( "repository", "generated:AvalonFileRepository.compose()" ); streamConfiguration.setAttribute( "destinationURL", destination ); streamConfiguration.setAttribute( "type", "STREAM" ); streamConfiguration.setAttribute( "model", "SYNCHRONOUS" ); sr = (StreamRepository) store.select(streamConfiguration); or = (ObjectRepository) store.select(objectConfiguration); lock = new Lock(); if (cacheKeys) keys = Collections.synchronizedSet(new HashSet()); //Finds non-matching pairs and deletes the extra files HashSet streamKeys = new HashSet(); for (Iterator i = sr.list(); i.hasNext(); ) { streamKeys.add(i.next()); } HashSet objectKeys = new HashSet(); for (Iterator i = or.list(); i.hasNext(); ) { objectKeys.add(i.next()); } Collection strandedStreams = (Collection)streamKeys.clone(); strandedStreams.removeAll(objectKeys); for (Iterator i = strandedStreams.iterator(); i.hasNext(); ) { String key = (String)i.next(); remove(key); } Collection strandedObjects = (Collection)objectKeys.clone(); strandedObjects.removeAll(streamKeys); for (Iterator i = strandedObjects.iterator(); i.hasNext(); ) { String key = (String)i.next(); remove(key); } if (keys != null) { // Next get a list from the object repository // and use that for the list of keys keys.clear(); for (Iterator i = or.list(); i.hasNext(); ) { keys.add(i.next()); } } if (getLogger().isDebugEnabled()) { StringBuffer logBuffer = new StringBuffer(128) .append(this.getClass().getName()) .append(" created in ") .append(destination); getLogger().debug(logBuffer.toString()); } } catch (Exception e) { final String message = "Failed to retrieve Store component:" + e.getMessage(); getLogger().error( message, e ); throw e; } } /** * Releases a lock on a message identified by a key * * @param key the key of the message to be unlocked * * @return true if successfully released the lock, false otherwise */ public boolean unlock(String key) { if (lock.unlock(key)) { if ((DEEP_DEBUG) && (getLogger().isDebugEnabled())) { StringBuffer debugBuffer = new StringBuffer(256) .append("Unlocked ") .append(key) .append(" for ") .append(Thread.currentThread().getName()) .append(" @ ") .append(new java.util.Date(System.currentTimeMillis())); getLogger().debug(debugBuffer.toString()); } return true; } else { return false; } } /** * Obtains a lock on a message identified by a key * * @param key the key of the message to be locked * * @return true if successfully obtained the lock, false otherwise */ public boolean lock(String key) { if (lock.lock(key)) { if ((DEEP_DEBUG) && (getLogger().isDebugEnabled())) { StringBuffer debugBuffer =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -