Source code: com/RuntimeCollective/webapps/bean/BeanFileFolder.java
1 /* $Header: /home/CVS/rjp/src/com/RuntimeCollective/webapps/bean/BeanFileFolder.java,v 1.9 2003/10/03 14:48:13 criss Exp $
2 * $Revision: 1.9 $
3 * $Date: 2003/10/03 14:48:13 $
4 *
5 * ====================================================================
6 *
7 * Josephine : http://www.runtime-collective.com/josephine/index.html
8 *
9 * Copyright (C) 2003 Runtime Collective
10 *
11 * This product includes software developed by the
12 * Apache Software Foundation (http://www.apache.org/).
13 *
14 * This library is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU Lesser General Public
16 * License as published by the Free Software Foundation; either
17 * version 2.1 of the License, or (at your option) any later version.
18 *
19 * This library is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * Lesser General Public License for more details.
23 *
24 * You should have received a copy of the GNU Lesser General Public
25 * License along with this library; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 *
28 */
29
30 package com.RuntimeCollective.webapps.bean;
31
32 import java.io.File;
33 import java.io.IOException;
34 import java.io.FilenameFilter;
35 import java.io.Serializable;
36 import java.util.Vector;
37 import java.util.Stack;
38
39 import javax.naming.Binding;
40 import javax.naming.Context;
41 import javax.naming.NameClassPair;
42 import javax.naming.NamingException;
43 import javax.naming.NamingEnumeration;
44 import javax.naming.InitialContext;
45 import javax.naming.directory.DirContext;
46
47 import com.RuntimeCollective.webapps.RuntimeParameters;
48 import com.RuntimeCollective.webapps.bean.EntityBean;
49
50 /**
51 * Object that represents a folder containing files associated with an EntityBean.
52 */
53 public class BeanFileFolder implements Serializable {
54
55 // This should be in RuntimeParameters
56 private static final String RESOURCES_ATTR = "org.apache.catalina.resources";
57
58 // This should be in RuntimeParameters
59 /**
60 * JNDI resources name.
61 */
62 private static final String RESOURCES_JNDI_NAME = "java:/comp/Resources";
63
64 /**
65 * The context of this folder.
66 */
67 protected DirContext ivContext;
68
69 /**
70 * The base context for the webapp
71 */
72 protected DirContext ivBaseContext;
73
74
75 /** The base directory for this folder. */
76 protected String ivDirBase;
77
78 /** Get the URL, relative to the doc root, of the directory for this folder. */
79 public String getDirUrl() { return ivDirBase + File.separator + ivBeanId + File.separator; }
80
81
82 /**
83 * The id of the bean that this folder is for
84 */
85 private String ivBeanId;
86
87 // A flag to work out if this Object has been initialised correctly.
88 private boolean ivValid;
89
90
91 /**
92 * Construct a folder for this bean and base directory.
93 * If no such directory exists on
94 * the file system, then one will be created.
95 * @param bean The bean to create a folder for
96 * @param dirBase The base directory for folders for beans of this type
97 *
98 */
99 public BeanFileFolder(EntityBean bean, String dirBase) {
100
101 ivDirBase = dirBase;
102
103 if (ivDirBase == null) RuntimeParameters.logError(this, "The directory base is null");
104
105 // The directory is the id of the bean.
106 ivBeanId = String.valueOf(bean.getId());
107
108 // Okay, here we go
109 RuntimeParameters.log(this, "Trying to setup the DirContext for dir base : " + ivDirBase + " bean id : " + ivBeanId);
110
111 // Get the JNDI binding for the webapp directory...
112 try {
113 ivBaseContext = (DirContext) new InitialContext().lookup(RESOURCES_JNDI_NAME);
114 } catch (NamingException nx) {
115 RuntimeParameters.logWarn(this, "JNDI NamingException trying to get the initial directory context", nx);
116 } catch (ClassCastException cx) {
117 RuntimeParameters.logWarn(this, "JNDI ClassCastException trying to get the initial directory context", cx);
118 }
119
120 // ...and that check we have it. A RuntimeException should be
121 // thrown here!
122 if(ivBaseContext == null) {
123 RuntimeParameters.log(this, "The context is null after lookup of the base directory");
124 } else {
125 RuntimeParameters.log(this, "Got the base directory");
126 }
127
128 // Now get the base directory.
129 try {
130 ivContext = (DirContext) ivBaseContext.lookup(ivDirBase);
131 } catch (IllegalArgumentException ix) {
132 RuntimeParameters.logWarn(this, "The base directory is not configured", ix);
133 // If the bean directory doesn't exist
134 throw new RuntimeException("Directories not configured.");
135 } catch (NamingException nx) {
136 RuntimeParameters.logWarn(this, "NamingException trying to get the base directory", nx);
137 }
138
139 // Debugging code to check that we're getting the base directory.
140 if(ivContext == null) {
141 RuntimeParameters.log(this, "The context is null after base directory lookup");
142 } else {
143 RuntimeParameters.log(this, "Got the context after looking up the base directory");
144 }
145
146 try {
147 ivContext = (DirContext) ivContext.lookup(ivBeanId);
148 RuntimeParameters.logDebug(this,"Found context for bean directory "+ivContext.getNameInNamespace() );
149 } catch (Exception e) {
150 RuntimeParameters.logWarn(this, "The bean directory for bean " + ivBeanId + " has not been construted", e);
151
152 RuntimeParameters.log(this, "Trying to creating the beans directory");
153
154 DirContext baseContext = ivContext;
155
156 // Create the beans directory
157 try {
158 ivContext = (DirContext) ivContext.createSubcontext(ivBeanId);
159 } catch (NamingException nx1) {
160 RuntimeParameters.logWarn(this, "NamingException while trying to create the bean directory", nx1);
161 }
162
163 // Try binding to the new directory to check
164 try {
165 ivContext = (DirContext) baseContext.lookup(ivBeanId);
166 RuntimeParameters.log(this, "The bean directory has been created");
167 } catch (NamingException nx2) {
168 RuntimeParameters.logWarn(this, "Still can't get the beans Folder directory", nx2);
169 ivValid = false;
170 }
171 }
172
173 }
174
175 /**
176 * @return True if the Beans folder is valid.
177 */
178 public boolean isValid() {
179 return ivValid;
180 }
181
182
183 /**
184 * The complete file path of this bean's folder. (Not including trailing "/").
185 */
186 public String getPath() {
187 try {
188 return ivContext.getNameInNamespace();
189 } catch (NamingException nx) {
190 RuntimeParameters.logError(this,"Can't find path of folder",nx);
191 return null;
192 }
193 }
194
195 /** The path to a file within this folder.*/
196 public String getFilePath(String fileName) {
197 try {
198 //return ivContext.getNameInNamespace() + File.separator + fileName;
199 return ivContext.getNameInNamespace() + fileName;
200 } catch (NamingException nx) {
201 RuntimeParameters.logError(this,"Can't find path of folder",nx);
202 return null;
203 }
204 }
205
206 /**
207 * Get the DirContext of the folder
208 */
209 public DirContext getContext() {
210 return ivContext;
211 }
212
213 /** Get the JNDI resource associated with a file in this folder. */
214 public Object getResource(String fileName) throws NamingException {
215 Object object = getContext().lookup(fileName);
216
217 if (object != null) {
218 RuntimeParameters.log(this, "Got a the resource : " + fileName);
219 }
220
221
222 return (Object) object;
223 }
224
225
226 /**
227 * Find all the files in this bean's folder (and its subdirectories).
228 *
229 * @param filter If filter!=null then only return those files that match this filter.
230 * @return A vector of files found (zero-length if no files found, or null if there was a problem accessing the directory.)
231 */
232 public Vector getAllFiles(FilenameFilter filter) {
233 Vector files = new Vector();
234
235 // The stack always contains the object of the current level
236 Stack stack = new Stack();
237 // Start at the top of the folder
238 stack.push("");
239
240 // Stack of the objects one level below
241 Stack stackBelow = new Stack();
242
243 // Retrieve the resources
244 DirContext resources = ivContext;
245 Object object;
246
247 while ( !stack.isEmpty() ) {
248 String currentPath = (String) stack.pop();
249 RuntimeParameters.logDebug(this,"looking up files in path "+currentPath);
250 // Find the resouce, if it's not valid don't include it.
251 try {
252 object = resources.lookup(currentPath);
253 } catch (NamingException ex) {
254 String err = new String("[Folder:getAllFiles] Naming exception on lookup " + currentPath + " : " + ex);
255 RuntimeParameters.logWarn(this, err, ex);
256 RuntimeParameters.logDebug(this, err);
257 continue;
258 }
259
260 if (object instanceof DirContext) {
261 try {
262 NamingEnumeration e = resources.list(currentPath);
263 while (e.hasMoreElements()) {
264 NameClassPair ncPair = (NameClassPair) e.nextElement();
265
266 String file = ncPair.getName();
267 Object resourceFile = null;
268 try {
269 resourceFile = resources.lookup(currentPath + File.separator + file);
270 } catch (NamingException nx) {
271 RuntimeParameters.logDebug(this, "[Folder:getAllFiles] Error looking up " + (currentPath + "/" + file) + " : " + nx);
272 return files;
273 }
274 if(resourceFile instanceof DirContext) {
275 stackBelow.push(currentPath + File.separator +file);
276 } else {
277 files.addElement(currentPath + File.separator +file);
278 }
279 }
280 } catch (NamingException nx) {
281 RuntimeParameters.logWarn(this, "[Folder:getAllFiles] Error getting file list for path " + currentPath + " : ", nx);
282 return files;
283 } catch (ClassCastException cx) {
284 RuntimeParameters.logWarn(this, "[Folder:getAllFiles] Error getting file list for path " + currentPath + " : ", cx);
285 return files;
286 }
287 }
288
289 if (stack.isEmpty()) {
290 stack = stackBelow;
291 stackBelow = new Stack();
292 }
293 }
294 return files;
295 }
296
297 /**
298 * Delete all the files in this bean's folder, but not the
299 * folder itself.
300 */
301 public void deleteAllFiles() throws SecurityException {
302 boolean success = true;
303 try {
304 NamingEnumeration e = ivContext.list("");
305 while (e.hasMoreElements()) {
306 NameClassPair ncPair = (NameClassPair) e.nextElement();
307
308 String file = ncPair.getName();
309 String path = getPath() + File.separator + file;
310 RuntimeParameters.log(this, "[Folder:deleteAllFiles] About to unbind : " + path);
311 ivContext.unbind(file);
312 }
313 } catch (NamingException nx) {
314 RuntimeParameters.logWarn(this, "Naming exception while removing all files", nx);
315 success = false;
316 } catch (ClassCastException cx) {
317 RuntimeParameters.logWarn(this, "Error getting file list", cx);
318 success = false;
319 }
320 }
321
322 /**
323 * Delete this bean's folder, including all files.
324 */
325 public boolean delete() throws SecurityException {
326 RuntimeParameters.log(this, "Deleting folder for path : " + getPath());
327 boolean success = true;
328 try {
329 ivBaseContext.unbind(getPath());
330 } catch(NamingException ex) {
331 success = false;
332 }
333
334 return success;
335 }
336
337 }
338
339
340
341
342