View Javadoc
1   /*
2    * dpkg - Debian Package library and the Debian Package Maven plugin
3    * (c) Copyright 2016 Gerrit Hohl
4    *
5    * This program is free software; you can redistribute it and/or
6    * modify it under the terms of the GNU General Public License
7    * as published by the Free Software Foundation; either version 2
8    * of the License, or (at your option) any later version.
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with this program; if not, write to the Free Software
17   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18   */
19  package net.sourceforge.javadpkg.io.impl;
20  
21  import java.io.File;
22  import java.io.FileNotFoundException;
23  import java.io.IOException;
24  import java.io.OutputStream;
25  
26  import net.sourceforge.javadpkg.io.DataTarget;
27  import net.sourceforge.javadpkg.io.Streams;
28  
29  /**
30   * <p>
31   * A {@link DataTarget} implementation based on a file.
32   * </p>
33   *
34   * @author Gerrit Hohl (gerrit-hohl@users.sourceforge.net)
35   * @version <b>1.0</b>, 28.04.2016 by Gerrit Hohl
36   */
37  public class DataFileTarget implements DataTarget {
38  
39  
40  	/** The file. */
41  	private File					file;
42  	/** The stream. */
43  	private OutputStream			out;
44  	/**
45  	 * <p>
46  	 * The public stream which is returned by the {@link #getOutputStream()}
47  	 * method.
48  	 * </p>
49  	 */
50  	private UncloseableOutputStream	publicOut;
51  	/** The name of the source. */
52  	private String					name;
53  	/** The flag if the stream is already open. */
54  	private boolean					opened;
55  									
56  									
57  	/**
58  	 * <p>
59  	 * Creates a source.
60  	 * </p>
61  	 * <p>
62  	 * The stream on the file will be opened the first time the
63  	 * {@link #getOutputStream()} method is called.
64  	 * </p>
65  	 *
66  	 * @param file
67  	 *            The file.
68  	 * @throws IllegalArgumentException
69  	 *             If the file is <code>null</code>.
70  	 */
71  	public DataFileTarget(File file) {
72  		super();
73  		
74  		if (file == null)
75  			throw new IllegalArgumentException("Argument file is null.");
76  			
77  		this.file = file;
78  		this.out = null;
79  		this.publicOut = null;
80  		this.name = file.getAbsolutePath();
81  		this.opened = false;
82  	}
83  	
84  	
85  	@Override
86  	public String getName() {
87  		return this.name;
88  	}
89  
90  
91  	/**
92  	 * <p>
93  	 * Creates the {@link OutputStream} which is returned by the
94  	 * {@link #getOutputStream()} method.
95  	 * </p>
96  	 */
97  	private void createPublicOutputStream() {
98  		this.publicOut = new UncloseableOutputStream(this.out, new DelegateCloseHandler(this));
99  	}
100 
101 
102 	/**
103 	 * <p>
104 	 * Ensures that the stream is opened.
105 	 * </p>
106 	 *
107 	 * @throws IOException
108 	 *             If an error occurs while opening the stream or if the source
109 	 *             is already closed.
110 	 */
111 	private void ensureOutputStream() throws IOException {
112 		if (this.out == null) {
113 			if (!this.opened) {
114 				try {
115 					this.out = Streams.createBufferedFileOutputStream(this.file);
116 				} catch (FileNotFoundException e) {
117 					throw new IOException("Couldn't open stream on target |" + this.name + "|: " + e.getMessage());
118 				}
119 				this.createPublicOutputStream();
120 			} else
121 				throw new IOException("The stream of target |" + this.name + "| is already closed.");
122 		}
123 	}
124 
125 
126 	@Override
127 	public OutputStream getOutputStream() throws IOException {
128 		this.ensureOutputStream();
129 		return this.publicOut;
130 	}
131 	
132 	
133 	@Override
134 	public void close() throws IOException {
135 		try {
136 			if (this.out != null) {
137 				this.out.close();
138 			}
139 		} finally {
140 			this.publicOut = null;
141 			this.out = null;
142 		}
143 	}
144 	
145 }