001/**************************************************************** 002 * Licensed to the Apache Software Foundation (ASF) under one * 003 * or more contributor license agreements. See the NOTICE file * 004 * distributed with this work for additional information * 005 * regarding copyright ownership. The ASF licenses this file * 006 * to you under the Apache License, Version 2.0 (the * 007 * "License"); you may not use this file except in compliance * 008 * with the License. You may obtain a copy of the License at * 009 * * 010 * http://www.apache.org/licenses/LICENSE-2.0 * 011 * * 012 * Unless required by applicable law or agreed to in writing, * 013 * software distributed under the License is distributed on an * 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * 015 * KIND, either express or implied. See the License for the * 016 * specific language governing permissions and limitations * 017 * under the License. * 018 ****************************************************************/ 019 020package org.apache.james.mailrepository.lib; 021 022import java.io.IOException; 023import java.util.Collection; 024 025import javax.mail.MessagingException; 026 027import org.apache.commons.configuration.ConfigurationException; 028import org.apache.commons.configuration.HierarchicalConfiguration; 029import org.apache.james.lifecycle.api.Configurable; 030import org.apache.james.lifecycle.api.LogEnabled; 031import org.apache.james.mailrepository.api.MailRepository; 032import org.apache.james.repository.api.Initializable; 033import org.apache.mailet.Mail; 034import org.slf4j.Logger; 035 036/** 037 * This class represent an AbstractMailRepository. All MailRepositories should 038 * extend this class. 039 */ 040public abstract class AbstractMailRepository implements MailRepository, LogEnabled, Configurable, Initializable { 041 042 /** 043 * Whether 'deep debugging' is turned on. 044 */ 045 protected static final boolean DEEP_DEBUG = false; 046 047 /** 048 * A lock used to control access to repository elements, locking access 049 * based on the key 050 */ 051 private final Lock lock = new Lock(); 052 053 private Logger logger; 054 055 public void setLog(Logger logger) { 056 this.logger = logger; 057 } 058 059 protected Logger getLogger() { 060 return logger; 061 } 062 063 public void configure(HierarchicalConfiguration configuration) throws ConfigurationException { 064 doConfigure(configuration); 065 } 066 067 protected void doConfigure(HierarchicalConfiguration config) throws ConfigurationException { 068 069 } 070 071 /** 072 * @see org.apache.james.mailrepository.api.MailRepository#unlock(String) 073 */ 074 public boolean unlock(String key) { 075 return lock.unlock(key); 076 } 077 078 /** 079 * @see org.apache.james.mailrepository.api.MailRepository#lock(String) 080 */ 081 public boolean lock(String key) { 082 return lock.lock(key); 083 } 084 085 /** 086 * @see org.apache.james.mailrepository.api.MailRepository#store(Mail) 087 */ 088 public void store(Mail mc) throws MessagingException { 089 boolean wasLocked = true; 090 String key = mc.getName(); 091 try { 092 synchronized (this) { 093 wasLocked = lock.isLocked(key); 094 if (!wasLocked) { 095 // If it wasn't locked, we want a lock during the store 096 lock(key); 097 } 098 } 099 internalStore(mc); 100 } catch (MessagingException e) { 101 getLogger().error("Exception caught while storing mail " + key, e); 102 throw e; 103 } catch (Exception e) { 104 getLogger().error("Exception caught while storing mail " + key, e); 105 throw new MessagingException("Exception caught while storing mail " + key, e); 106 } finally { 107 if (!wasLocked) { 108 // If it wasn't locked, we need to unlock now 109 unlock(key); 110 synchronized (this) { 111 notify(); 112 } 113 } 114 } 115 } 116 117 /** 118 * @see #store(Mail) 119 */ 120 protected abstract void internalStore(Mail mc) throws MessagingException, IOException; 121 122 /** 123 * @see org.apache.james.mailrepository.api.MailRepository#remove(Mail) 124 */ 125 public void remove(Mail mail) throws MessagingException { 126 remove(mail.getName()); 127 } 128 129 /** 130 * @see org.apache.james.mailrepository.api.MailRepository#remove(Collection) 131 */ 132 public void remove(Collection<Mail> mails) throws MessagingException { 133 for (Mail mail : mails) { 134 remove(mail); 135 } 136 } 137 138 /** 139 * @see org.apache.james.mailrepository.api.MailRepository#remove(String) 140 */ 141 public void remove(String key) throws MessagingException { 142 if (lock(key)) { 143 try { 144 internalRemove(key); 145 } finally { 146 unlock(key); 147 } 148 } else { 149 String exceptionBuffer = "Cannot lock " + key + " to remove it"; 150 throw new MessagingException(exceptionBuffer.toString()); 151 } 152 } 153 154 /** 155 * @see #remove(String) 156 */ 157 protected abstract void internalRemove(String key) throws MessagingException; 158 159}