KickJava   Java API By Example, From Geeks To Geeks.

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


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.cayenne.project;
21
22 import java.io.File JavaDoc;
23 import java.io.FileOutputStream JavaDoc;
24 import java.io.IOException JavaDoc;
25 import java.io.OutputStreamWriter JavaDoc;
26 import java.io.PrintWriter JavaDoc;
27
28 import org.apache.cayenne.util.Util;
29
30 /**
31  * ProjectFile is an adapter from an object in Cayenne project
32  * to its representation in the file system.
33  *
34  * @author Andrus Adamchik
35  */

36 public abstract class ProjectFile {
37
38     protected String JavaDoc location;
39     protected File JavaDoc tempFile;
40     protected Project projectObj;
41
42     public ProjectFile() {}
43
44     /**
45      * Constructor for ProjectFile.
46      */

47     public ProjectFile(Project project, String JavaDoc location) {
48         this.location = location;
49         this.projectObj = project;
50     }
51
52     /**
53      * Builds a filename from the object name and "file suffix".
54      */

55     public String JavaDoc getLocation() {
56         String JavaDoc oName = getObjectName();
57         if (oName == null) {
58             throw new NullPointerException JavaDoc("Null name.");
59         }
60
61         return oName + getLocationSuffix();
62     }
63
64     /**
65     * Returns saved location of a file.
66     */

67     public String JavaDoc getOldLocation() {
68         return location;
69     }
70
71     /**
72      * Returns suffix to append to object name when
73      * creating a file name. Default implementation
74      * returns empty string.
75      */

76     public String JavaDoc getLocationSuffix() {
77         return "";
78     }
79
80     /**
81      * Returns a project object associated with this file.
82      */

83     public abstract Object JavaDoc getObject();
84
85     /**
86      * Returns a name of associated object, that is also
87      * used as a file name.
88      */

89     public abstract String JavaDoc getObjectName();
90
91     /**
92      * Saves an underlying object to the file.
93      * The procedure is dependent on the type of
94      * object and is implemented by concrete subclasses.
95      */

96     public abstract void save(PrintWriter JavaDoc out) throws Exception JavaDoc;
97
98     /**
99      * Returns true if this file wrapper can handle a
100      * specified object.
101      */

102     public abstract boolean canHandle(Object JavaDoc obj);
103     
104    /**
105      * Returns true if this file wrapper can handle an
106      * internally stored object.
107      */

108     public boolean canHandleObject() {
109         return canHandle(getObject());
110     }
111
112     /**
113      * Replaces internally stored filename with the current object name.
114      */

115     public void synchronizeLocation() {
116         location = getLocation();
117     }
118
119     /**
120      * This method is called by project to let file know that
121      * it will be saved. Default implementation is a noop.
122      */

123     public void willSave() {}
124
125     /**
126      * Saves ProjectFile's underlying object to a temporary
127      * file, returning this file to the caller. If any problems are
128      * encountered during saving, an Exception is thrown.
129      */

130     public void saveTemp() throws Exception JavaDoc {
131         // cleanup any previous temp files
132
if (tempFile != null && tempFile.isFile()) {
133             tempFile.delete();
134             tempFile = null;
135         }
136
137         // check write permissions for the target final file...
138
File JavaDoc finalFile = resolveFile();
139         checkWritePermissions(finalFile);
140
141         // ...but save to temp file first
142
tempFile = tempFileForFile(finalFile);
143         
144         // must encode as UTF-8 - a default used by all Cayenne XML files
145
FileOutputStream JavaDoc fout = new FileOutputStream JavaDoc(tempFile);
146         OutputStreamWriter JavaDoc fw = new OutputStreamWriter JavaDoc(fout, "UTF-8");
147
148         try {
149             PrintWriter JavaDoc pw = new PrintWriter JavaDoc(fw);
150             try {
151                 save(pw);
152             } finally {
153                 pw.close();
154             }
155         } finally {
156             fw.close();
157         }
158     }
159
160     /**
161      * Returns a file which is a canonical representation of the
162      * file to store a wrapped object. If an object was renamed,
163      * the <b>new</b> name is returned.
164      */

165     public File JavaDoc resolveFile() {
166         return getProject().resolveFile(getLocation());
167     }
168
169     /**
170      * Returns a file which is a canonical representation of the
171      * file to store a wrapped object. If an object was renamed,
172      * the <b>old</b> name is returned. Returns null if this file
173      * has never been saved before.
174      */

175     public File JavaDoc resolveOldFile() {
176         String JavaDoc oldLocation = getOldLocation();
177         return (oldLocation != null) ? getProject().resolveFile(oldLocation) : null;
178     }
179
180     /**
181      * Finishes saving the underlying object.
182      */

183     public File JavaDoc saveCommit() throws ProjectException {
184         File JavaDoc finalFile = resolveFile();
185         
186         if (tempFile != null) {
187             if (finalFile.exists()) {
188                 if (!finalFile.delete()) {
189                     throw new ProjectException(
190                         "Unable to remove old master file : " + finalFile);
191                 }
192             }
193
194             if (!tempFile.renameTo(finalFile)) {
195                 throw new ProjectException(
196                     "Unable to move " + tempFile + " to " + finalFile);
197             }
198
199             tempFile = null;
200         }
201         
202         return finalFile;
203     }
204
205     /**
206      * Cleans up after unsuccessful or canceled save attempt.
207      */

208     public void saveUndo() {
209         if (tempFile != null && tempFile.isFile()) {
210             tempFile.delete();
211             tempFile = null;
212         }
213     }
214
215     /**
216       * Returns the project.
217       * @return Project
218       */

219     public Project getProject() {
220         return projectObj;
221     }
222
223     public boolean isRenamed() {
224         return !Util.nullSafeEquals(location, getLocation());
225     }
226
227     /**
228      * Creates a temporary file for the master file.
229      */

230     protected File JavaDoc tempFileForFile(File JavaDoc f) throws IOException JavaDoc {
231         File JavaDoc parent = f.getParentFile();
232         String JavaDoc name = f.getName();
233
234         if (name == null || name.length() < 3) {
235             name = "cayenne-project";
236         }
237  
238         if(!parent.exists()) {
239             if(!parent.mkdirs()) {
240                 throw new IOException JavaDoc("Error creating directory tree: " + parent);
241             }
242         }
243          
244         return File.createTempFile(name, null, parent);
245     }
246
247     protected void checkWritePermissions(File JavaDoc file) throws IOException JavaDoc {
248         if (file.isDirectory()) {
249             throw new IOException JavaDoc("Target file is a directory: " + file);
250         }
251
252         if (file.exists() && !file.canWrite()) {
253             throw new IOException JavaDoc("Can't write to file: " + file);
254         }
255     }
256
257     public String JavaDoc toString() {
258         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
259         buf.append("ProjectFile [").append(getClass().getName()).append("]: name = ");
260         if (getObject() != null) {
261             buf.append("*null*");
262         } else {
263             buf.append(getObjectName());
264         }
265
266         return buf.toString();
267     }
268 }
269
Popular Tags