1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.apache.james.mailrepository;
23
24 import org.apache.avalon.cornerstone.services.store.StreamRepository;
25 import org.apache.james.core.MimeMessageSource;
26 import org.apache.james.util.sql.JDBCUtil;
27
28 import java.io.ByteArrayInputStream;
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.io.SequenceInputStream;
32 import java.sql.Blob;
33 import java.sql.Connection;
34 import java.sql.PreparedStatement;
35 import java.sql.ResultSet;
36 import java.sql.SQLException;
37
38
39
40
41
42 public class MimeMessageJDBCSource extends MimeMessageSource {
43
44
45
46
47 private static final boolean DEEP_DEBUG = false;
48
49
50 JDBCMailRepository repository = null;
51 String key = null;
52 StreamRepository sr = null;
53
54 private long size = -1;
55
56
57
58
59 String retrieveMessageBodySQL = null;
60
61
62
63
64 String retrieveMessageBodySizeSQL = null;
65
66
67
68
69 private static final JDBCUtil theJDBCUtil =
70 new JDBCUtil() {
71 protected void delegatedLog(String logString) {
72
73
74 }
75 };
76
77
78
79
80
81
82
83
84
85
86 public MimeMessageJDBCSource(JDBCMailRepository repository,
87 String key, StreamRepository sr) throws IOException {
88 if (repository == null) {
89 throw new IOException("Repository is null");
90 }
91 if (key == null) {
92 throw new IOException("Message name (key) was not defined");
93 }
94 this.repository = repository;
95 this.key = key;
96 this.sr = sr;
97
98 retrieveMessageBodySQL =
99 repository.sqlQueries.getSqlString("retrieveMessageBodySQL", true);
100
101 retrieveMessageBodySizeSQL =
102 repository.sqlQueries.getSqlString("retrieveMessageBodySizeSQL");
103 }
104
105
106
107
108
109
110
111
112 public String getSourceId() {
113 StringBuffer sourceIdBuffer =
114 new StringBuffer(128)
115 .append(repository.repositoryName)
116 .append("/")
117 .append(key);
118 return sourceIdBuffer.toString();
119 }
120
121
122
123
124
125
126
127
128 public synchronized InputStream getInputStream() throws IOException {
129 Connection conn = null;
130 PreparedStatement retrieveMessageStream = null;
131 ResultSet rsRetrieveMessageStream = null;
132 try {
133 conn = repository.getConnection();
134
135 byte[] headers = null;
136
137 long start = 0;
138 if (DEEP_DEBUG) {
139 start = System.currentTimeMillis();
140 System.out.println("starting");
141 }
142 retrieveMessageStream = conn.prepareStatement(retrieveMessageBodySQL);
143 retrieveMessageStream.setString(1, key);
144 retrieveMessageStream.setString(2, repository.repositoryName);
145 rsRetrieveMessageStream = retrieveMessageStream.executeQuery();
146
147 if (!rsRetrieveMessageStream.next()) {
148 throw new IOException("Could not find message");
149 }
150
151 String getBodyOption = repository.sqlQueries.getDbOption("getBody");
152 if (getBodyOption != null && getBodyOption.equalsIgnoreCase("useBlob")) {
153 Blob b = rsRetrieveMessageStream.getBlob(1);
154 headers = b.getBytes(1, (int)b.length());
155 } else {
156 headers = rsRetrieveMessageStream.getBytes(1);
157 }
158 if (DEEP_DEBUG) {
159 System.err.println("stopping");
160 System.err.println(System.currentTimeMillis() - start);
161 }
162
163 InputStream in = new ByteArrayInputStream(headers);
164 try {
165 if (sr != null) {
166 in = new SequenceInputStream(in, sr.get(key));
167 }
168 } catch (Exception e) {
169
170
171 }
172 return in;
173 } catch (SQLException sqle) {
174 throw new IOException(sqle.toString());
175 } finally {
176 theJDBCUtil.closeJDBCResultSet(rsRetrieveMessageStream);
177 theJDBCUtil.closeJDBCStatement(retrieveMessageStream);
178 theJDBCUtil.closeJDBCConnection(conn);
179 }
180 }
181
182
183
184
185
186
187 public synchronized long getMessageSize() throws IOException {
188 if (size != -1) return size;
189 if (retrieveMessageBodySizeSQL == null) {
190
191 System.err.println("no SQL statement to find size");
192 return size = super.getMessageSize();
193 }
194 Connection conn = null;
195 PreparedStatement retrieveMessageSize = null;
196 ResultSet rsRetrieveMessageSize = null;
197 try {
198 conn = repository.getConnection();
199
200 retrieveMessageSize = conn.prepareStatement(retrieveMessageBodySizeSQL);
201 retrieveMessageSize.setString(1, key);
202 retrieveMessageSize.setString(2, repository.repositoryName);
203 rsRetrieveMessageSize = retrieveMessageSize.executeQuery();
204
205 if (!rsRetrieveMessageSize.next()) {
206 throw new IOException("Could not find message");
207 }
208
209 size = rsRetrieveMessageSize.getLong(1);
210
211 InputStream in = null;
212 try {
213 if (sr != null) {
214 if (sr instanceof org.apache.james.mailrepository.filepair.File_Persistent_Stream_Repository) {
215 size += ((org.apache.james.mailrepository.filepair.File_Persistent_Stream_Repository) sr).getSize(key);
216 } else {
217 in = sr.get(key);
218 int len = 0;
219 byte[] block = new byte[1024];
220 while ((len = in.read(block)) > -1) {
221 size += len;
222 }
223 }
224 }
225 } catch (Exception e) {
226
227
228 } finally {
229 try {
230 if (in != null) {
231 in.close();
232 }
233 } catch (IOException ioe) {
234
235 }
236 }
237
238 return size;
239 } catch (SQLException sqle) {
240 throw new IOException(sqle.toString());
241 } finally {
242 theJDBCUtil.closeJDBCResultSet(rsRetrieveMessageSize);
243 theJDBCUtil.closeJDBCStatement(retrieveMessageSize);
244 theJDBCUtil.closeJDBCConnection(conn);
245 }
246 }
247
248
249
250
251 public boolean equals(Object obj) {
252 if (obj instanceof MimeMessageJDBCSource) {
253
254
255 MimeMessageJDBCSource source = (MimeMessageJDBCSource)obj;
256 return ((source.key == key) || ((source.key != null) && source.key.equals(key))) &&
257 ((source.repository == repository) || ((source.repository != null) && source.repository.equals(repository)));
258 }
259 return false;
260 }
261
262
263
264
265
266
267 public int hashCode() {
268 int result = 17;
269 if (key != null) {
270 result = 37 * key.hashCode();
271 }
272 if (repository != null) {
273 result = 37 * repository.hashCode();
274 }
275 return result;
276 }
277 }