KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectstyle > cayenne > project > ProjectFile


1 /* ====================================================================
2  *
3  * The ObjectStyle Group Software License, version 1.1
4  * ObjectStyle Group - http://objectstyle.org/
5  *
6  * Copyright (c) 2002-2005, Andrei (Andrus) Adamchik and individual authors
7  * of the software. All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution, if any,
22  * must include the following acknowlegement:
23  * "This product includes software developed by independent contributors
24  * and hosted on ObjectStyle Group web site (http://objectstyle.org/)."
25  * Alternately, this acknowlegement may appear in the software itself,
26  * if and wherever such third-party acknowlegements normally appear.
27  *
28  * 4. The names "ObjectStyle Group" and "Cayenne" must not be used to endorse
29  * or promote products derived from this software without prior written
30  * permission. For written permission, email
31  * "andrus at objectstyle dot org".
32  *
33  * 5. Products derived from this software may not be called "ObjectStyle"
34  * or "Cayenne", nor may "ObjectStyle" or "Cayenne" appear in their
35  * names without prior written permission.
36  *
37  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40  * DISCLAIMED. IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
41  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48  * SUCH DAMAGE.
49  * ====================================================================
50  *
51  * This software consists of voluntary contributions made by many
52  * individuals and hosted on ObjectStyle Group web site. For more
53  * information on the ObjectStyle Group, please see
54  * <http://objectstyle.org/>.
55  */

56 package org.objectstyle.cayenne.project;
57
58 import java.io.File JavaDoc;
59 import java.io.FileOutputStream JavaDoc;
60 import java.io.IOException JavaDoc;
61 import java.io.OutputStreamWriter JavaDoc;
62 import java.io.PrintWriter JavaDoc;
63
64 import org.objectstyle.cayenne.util.Util;
65
66 /**
67  * ProjectFile is an adapter from an object in Cayenne project
68  * to its representation in the file system.
69  *
70  * @author Andrei Adamchik
71  */

72 public abstract class ProjectFile {
73
74     protected String JavaDoc location;
75     protected File JavaDoc tempFile;
76     protected Project projectObj;
77
78     public ProjectFile() {}
79
80     /**
81      * Constructor for ProjectFile.
82      */

83     public ProjectFile(Project project, String JavaDoc location) {
84         this.location = location;
85         this.projectObj = project;
86     }
87
88     /**
89      * Builds a filename from the object name and "file suffix".
90      */

91     public String JavaDoc getLocation() {
92         String JavaDoc oName = getObjectName();
93         if (oName == null) {
94             throw new NullPointerException JavaDoc("Null name.");
95         }
96
97         return oName + getLocationSuffix();
98     }
99
100     /**
101     * Returns saved location of a file.
102     */

103     public String JavaDoc getOldLocation() {
104         return location;
105     }
106
107     /**
108      * Returns suffix to append to object name when
109      * creating a file name. Default implementation
110      * returns empty string.
111      */

112     public String JavaDoc getLocationSuffix() {
113         return "";
114     }
115
116     /**
117      * Returns a project object associated with this file.
118      */

119     public abstract Object JavaDoc getObject();
120
121     /**
122      * Returns a name of associated object, that is also
123      * used as a file name.
124      */

125     public abstract String JavaDoc getObjectName();
126
127     /**
128      * Saves an underlying object to the file.
129      * The procedure is dependent on the type of
130      * object and is implemented by concrete subclasses.
131      */

132     public abstract void save(PrintWriter JavaDoc out) throws Exception JavaDoc;
133
134     /**
135      * Returns true if this file wrapper can handle a
136      * specified object.
137      */

138     public abstract boolean canHandle(Object JavaDoc obj);
139     
140    /**
141      * Returns true if this file wrapper can handle an
142      * internally stored object.
143      */

144     public boolean canHandleObject() {
145         return canHandle(getObject());
146     }
147
148     /**
149      * Replaces internally stored filename with the current object name.
150      */

151     public void synchronizeLocation() {
152         location = getLocation();
153     }
154
155     /**
156      * This method is called by project to let file know that
157      * it will be saved. Default implementation is a noop.
158      */

159     public void willSave() {}
160
161     /**
162      * Saves ProjectFile's underlying object to a temporary
163      * file, returning this file to the caller. If any problems are
164      * encountered during saving, an Exception is thrown.
165      */

166     public void saveTemp() throws Exception JavaDoc {
167         // cleanup any previous temp files
168
if (tempFile != null && tempFile.isFile()) {
169             tempFile.delete();
170             tempFile = null;
171         }
172
173         // check write permissions for the target final file...
174
File JavaDoc finalFile = resolveFile();
175         checkWritePermissions(finalFile);
176
177         // ...but save to temp file first
178
tempFile = tempFileForFile(finalFile);
179         
180         // must encode as UTF-8 - a default used by all Cayenne XML files
181
FileOutputStream JavaDoc fout = new FileOutputStream JavaDoc(tempFile);
182         OutputStreamWriter JavaDoc fw = new OutputStreamWriter JavaDoc(fout, "UTF-8");
183
184         try {
185             PrintWriter JavaDoc pw = new PrintWriter JavaDoc(fw);
186             try {
187                 save(pw);
188             } finally {
189                 pw.close();
190             }
191         } finally {
192             fw.close();
193         }
194     }
195
196     /**
197      * Returns a file which is a canonical representation of the
198      * file to store a wrapped object. If an object was renamed,
199      * the <b>new</b> name is returned.
200      */

201     public File JavaDoc resolveFile() {
202         return getProject().resolveFile(getLocation());
203     }
204
205     /**
206      * Returns a file which is a canonical representation of the
207      * file to store a wrapped object. If an object was renamed,
208      * the <b>old</b> name is returned. Returns null if this file
209      * has never been saved before.
210      */

211     public File JavaDoc resolveOldFile() {
212         String JavaDoc oldLocation = getOldLocation();
213         return (oldLocation != null) ? getProject().resolveFile(oldLocation) : null;
214     }
215
216     /**
217      * Finishes saving the underlying object.
218      */

219     public File JavaDoc saveCommit() throws ProjectException {
220         File JavaDoc finalFile = resolveFile();
221         
222         if (tempFile != null) {
223             if (finalFile.exists()) {
224                 if (!finalFile.delete()) {
225                     throw new ProjectException(
226                         "Unable to remove old master file : " + finalFile);
227                 }
228             }
229
230             if (!tempFile.renameTo(finalFile)) {
231                 throw new ProjectException(
232                     "Unable to move " + tempFile + " to " + finalFile);
233             }
234
235             tempFile = null;
236         }
237         
238         return finalFile;
239     }
240
241     /**
242      * Cleans up after unsuccessful or canceled save attempt.
243      */

244     public void saveUndo() {
245         if (tempFile != null && tempFile.isFile()) {
246             tempFile.delete();
247             tempFile = null;
248         }
249     }
250
251     /**
252       * Returns the project.
253       * @return Project
254       */

255     public Project getProject() {
256         return projectObj;
257     }
258
259     public boolean isRenamed() {
260         return !Util.nullSafeEquals(location, getLocation());
261     }
262
263     /**
264      * Creates a temporary file for the master file.
265      */

266     protected File JavaDoc tempFileForFile(File JavaDoc f) throws IOException JavaDoc {
267         File JavaDoc parent = f.getParentFile();
268         String JavaDoc name = f.getName();
269
270         if (name == null || name.length() < 3) {
271             name = "cayenne-project";
272         }
273  
274         if(!parent.exists()) {
275             if(!parent.mkdirs()) {
276                 throw new IOException JavaDoc("Error creating directory tree: " + parent);
277             }
278         }
279          
280         return File.createTempFile(name, null, parent);
281     }
282
283     protected void checkWritePermissions(File JavaDoc file) throws IOException JavaDoc {
284         if (file.isDirectory()) {
285             throw new IOException JavaDoc("Target file is a directory: " + file);
286         }
287
288         if (file.exists() && !file.canWrite()) {
289             throw new IOException JavaDoc("Can't write to file: " + file);
290         }
291     }
292
293     public String JavaDoc toString() {
294         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
295         buf.append("ProjectFile [").append(getClass().getName()).append("]: name = ");
296         if (getObject() != null) {
297             buf.append("*null*");
298         } else {
299             buf.append(getObjectName());
300         }
301
302         return buf.toString();
303     }
304 }
305
Popular Tags