]> git.argeo.org Git - gpl/argeo-slc.git/blob - ext/javax.mail.mbox/src/com/sun/mail/mbox/TempFile.java
Make logging synchronous during native image build
[gpl/argeo-slc.git] / ext / javax.mail.mbox / src / com / sun / mail / mbox / TempFile.java
1 /*
2 * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v. 2.0, which is available at
6 * http://www.eclipse.org/legal/epl-2.0.
7 *
8 * This Source Code may also be made available under the following Secondary
9 * Licenses when the conditions for such availability set forth in the
10 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11 * version 2 with the GNU Classpath Exception, which is available at
12 * https://www.gnu.org/software/classpath/license.html.
13 *
14 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15 */
16
17 package com.sun.mail.mbox;
18
19 import java.util.*;
20 import java.net.*;
21 import java.io.*;
22 import java.security.*;
23
24 import com.sun.mail.util.PropUtil;
25 import javax.mail.util.SharedFileInputStream;
26
27 /**
28 * A temporary file used to cache messages.
29 */
30 class TempFile {
31
32 private File file; // the temp file name
33 private WritableSharedFile sf;
34
35 /**
36 * Create a temp file in the specified directory (if not null).
37 * The file will be deleted when the JVM exits.
38 */
39 public TempFile(File dir) throws IOException {
40 file = File.createTempFile("mbox.", ".mbox", dir);
41 // XXX - need JDK 6 to set permissions on the file to owner-only
42 file.deleteOnExit();
43 sf = new WritableSharedFile(file);
44 }
45
46 /**
47 * Return a stream for appending to the temp file.
48 */
49 public AppendStream getAppendStream() throws IOException {
50 return sf.getAppendStream();
51 }
52
53 /**
54 * Return a stream for reading from part of the file.
55 */
56 public InputStream newStream(long start, long end) {
57 return sf.newStream(start, end);
58 }
59
60 public long length() {
61 return file.length();
62 }
63
64 /**
65 * Close and remove this temp file.
66 */
67 public void close() {
68 try {
69 sf.close();
70 } catch (IOException ex) {
71 // ignore it
72 }
73 file.delete();
74 }
75
76 protected void finalize() throws Throwable {
77 try {
78 close();
79 } finally {
80 super.finalize();
81 }
82 }
83 }
84
85 /**
86 * A subclass of SharedFileInputStream that also allows writing.
87 */
88 class WritableSharedFile extends SharedFileInputStream {
89 private RandomAccessFile raf;
90 private AppendStream af;
91
92 public WritableSharedFile(File file) throws IOException {
93 super(file);
94 try {
95 raf = new RandomAccessFile(file, "rw");
96 } catch (IOException ex) {
97 // if anything goes wrong opening the writable file,
98 // close the readable file too
99 super.close();
100 }
101 }
102
103 /**
104 * Return the writable version of this file.
105 */
106 public RandomAccessFile getWritableFile() {
107 return raf;
108 }
109
110 /**
111 * Close the readable and writable files.
112 */
113 public void close() throws IOException {
114 try {
115 super.close();
116 } finally {
117 raf.close();
118 }
119 }
120
121 /**
122 * Update the size of the readable file after writing
123 * to the file. Updates the length to be the current
124 * size of the file.
125 */
126 synchronized long updateLength() throws IOException {
127 datalen = in.length();
128 af = null;
129 return datalen;
130 }
131
132 /**
133 * Return a new AppendStream, but only if one isn't in active use.
134 */
135 public synchronized AppendStream getAppendStream() throws IOException {
136 if (af != null)
137 throw new IOException(
138 "file cache only supports single threaded access");
139 af = new AppendStream(this);
140 return af;
141 }
142 }
143
144 /**
145 * A stream for writing to the temp file, and when done
146 * can return a stream for reading the data just written.
147 * NOTE: We assume that only one thread is writing to the
148 * file at a time.
149 */
150 class AppendStream extends OutputStream {
151 private final WritableSharedFile tf;
152 private RandomAccessFile raf;
153 private final long start;
154 private long end;
155
156 public AppendStream(WritableSharedFile tf) throws IOException {
157 this.tf = tf;
158 raf = tf.getWritableFile();
159 start = raf.length();
160 raf.seek(start);
161 }
162
163 public void write(int b) throws IOException {
164 raf.write(b);
165 }
166
167 public void write(byte[] b) throws IOException {
168 raf.write(b);
169 }
170
171 public void write(byte[] b, int off, int len) throws IOException {
172 raf.write(b, off, len);
173 }
174
175 public synchronized void close() throws IOException {
176 end = tf.updateLength();
177 raf = null; // no more writing allowed
178 }
179
180 public synchronized InputStream getInputStream() throws IOException {
181 return tf.newStream(start, end);
182 }
183 }