1 /****************************************************************
2 * Licensed to the Apache Software Foundation (ASF) under one *
3 * or more contributor license agreements. See the NOTICE file *
4 * distributed with this work for additional information *
5 * regarding copyright ownership. The ASF licenses this file *
6 * to you under the Apache License, Version 2.0 (the *
7 * "License"); you may not use this file except in compliance *
8 * with the License. You may obtain a copy of the License at *
9 * *
10 * http://www.apache.org/licenses/LICENSE-2.0 *
11 * *
12 * Unless required by applicable law or agreed to in writing, *
13 * software distributed under the License is distributed on an *
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
15 * KIND, either express or implied. See the License for the *
16 * specific language governing permissions and limitations *
17 * under the License. *
18 ****************************************************************/
19
20 package org.apache.james.mailrepository.javamail;
21
22 import javax.mail.Folder;
23 import javax.mail.MessagingException;
24
25
26 /**
27 * offers access to an underlaying Folder and manages open/close operations.<br>
28 * The FolderGateKeeper can be handed over to different threads.
29 *
30 * @see FolderGateKeeper
31 *
32 */
33 public class FolderGateKeeperImpl implements FolderGateKeeper {
34
35 private final FolderInterface folder;
36
37 private int inUse = 0;
38
39 boolean open = false;
40
41 private final StoreGateKeeper storeGateKeeper;
42
43 public FolderGateKeeperImpl(FolderInterface folder,StoreGateKeeper storeGateKeeper) {
44 if (folder.isOpen()) {
45 throw new IllegalStateException(
46 "FolderGateKeeper: initial state must be closed");
47 }
48 this.folder = folder;
49 this.storeGateKeeper=storeGateKeeper;
50 }
51
52 /**
53 * @see org.apache.james.mailrepository.javamail.FolderGateKeeper#use()
54 */
55 public synchronized void use() {
56 inUse++;
57 }
58
59 /**
60 * @see org.apache.james.mailrepository.javamail.FolderGateKeeper#free()
61 */
62 public synchronized void free() throws MessagingException {
63 if (inUse < 1) {
64 throw new IllegalStateException(
65 "called free() but FolderGateKeeper is not in use");
66 } else {
67 inUse--;
68 if (inUse == 0) {
69 if (open != folder.isOpen()) {
70 throw new IllegalStateException(
71 "free(): folder state not equals last known state: open="
72 + open);
73 }
74 if (open) {
75 // TODO expunge should be configurable
76 folder.close(true);
77 open = false;
78 }
79 }
80 }
81
82 }
83
84 /**
85 * @see org.apache.james.mailrepository.javamail.FolderGateKeeper#getOpenFolder()
86 */
87 public synchronized FolderInterface getOpenFolder() throws MessagingException {
88 if ((folder.getType() & Folder.HOLDS_MESSAGES)==0) {
89 throw new RuntimeException("cannot open a Folder that does not hold messages");
90 }
91 if (inUse < 1) {
92 throw new IllegalStateException(
93 "called getFolder() but folder is not in use");
94 }
95 if (open != folder.isOpen()) {
96 throw new IllegalStateException(
97 "getFolder() folder state not equals last known state: open="
98 + open);
99 }
100 if (!open) {
101 folder.open(Folder.READ_WRITE);
102 open = true;
103 }
104 return folder;
105
106 }
107
108 /**
109 * @see org.apache.james.mailrepository.javamail.FolderGateKeeper#getUseCount()
110 */
111 public synchronized int getUseCount() {
112 return inUse;
113 }
114
115 /**
116 * @see org.apache.james.mailrepository.javamail.FolderGateKeeper#getFolder()
117 */
118 public synchronized FolderInterface getFolder() {
119 if (inUse < 1) {
120 throw new IllegalStateException(
121 "called getFolder() but folder is not in use");
122 }
123 if (open != folder.isOpen()) {
124 throw new IllegalStateException(
125 "getFolder() folder state not equals last known state: open="
126 + open);
127 }
128 return folder;
129 }
130
131 /**
132 * @see org.apache.james.mailrepository.javamail.FolderGateKeeper#getFullName()
133 */
134 public String getFullName() throws MessagingException {
135 use();
136 String fn=getFolder().getFullName();
137 free();
138 return fn;
139 }
140
141 /**
142 * @see org.apache.james.mailrepository.javamail.FolderGateKeeper#create(int)
143 */
144 public void create(int holds_folders) throws MessagingException {
145 use();
146 getFolder().create(holds_folders);
147 free();
148 }
149
150 /**
151 * @see org.apache.james.mailrepository.javamail.FolderGateKeeper#exists()
152 */
153 public boolean exists() throws MessagingException {
154 use();
155 boolean e=getFolder().exists();
156 free();
157 return e;
158 }
159
160
161 /**
162 * @see org.apache.james.mailrepository.javamail.FolderGateKeeper#renameTo(javax.mail.Folder)
163 */
164 public synchronized void renameTo(Folder destination) throws MessagingException {
165 if (inUse!=0) {
166 throw new IllegalStateException("cannot operate of folder that is in use");
167 } else {
168 folder.renameTo(destination);
169 }
170
171 }
172
173 /**
174 * @see org.apache.james.mailrepository.javamail.FolderGateKeeper#renameTo(java.lang.String)
175 */
176 public synchronized void renameTo(String newName) throws MessagingException {
177 storeGateKeeper.renameTo(this,newName);
178 }
179
180 }