001: /*
002: * Copyright (C) 2005 Jeff Tassin
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2.1 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: */
018:
019: package com.jeta.swingbuilder.app;
020:
021: import java.awt.image.BufferedImage;
022: import java.io.BufferedInputStream;
023: import java.io.BufferedOutputStream;
024: import java.io.BufferedReader;
025: import java.io.BufferedWriter;
026: import java.io.File;
027: import java.io.FileInputStream;
028: import java.io.FileOutputStream;
029: import java.io.FileReader;
030: import java.io.FileWriter;
031: import java.io.FilenameFilter;
032: import java.io.IOException;
033: import java.io.InputStream;
034: import java.io.OutputStream;
035: import java.io.Reader;
036: import java.io.Writer;
037: import java.util.StringTokenizer;
038: import java.util.regex.Matcher;
039: import java.util.regex.Pattern;
040: import java.util.regex.PatternSyntaxException;
041:
042: import javax.swing.ImageIcon;
043:
044: import com.jeta.swingbuilder.interfaces.resources.ResourceLoader;
045:
046: /**
047: * This class is an implementation of a ResourceLoader. It insulates the
048: * application code from having any need to know about the local file system
049: * directory structure. It is also useful for debugging and development so we
050: * can redirect resource request to debug files if needed.
051: *
052: * @author Jeff Tassin
053: */
054: public class AppResourceLoader implements ResourceLoader {
055: /** path to home directory for application */
056: private String m_tshome;
057:
058: /** path to the images directory */
059: private String m_imagespath;
060:
061: private ClassLoader m_classloader;
062:
063: /** an empty icon if a resource cannot be loaded */
064: private static ImageIcon m_empty_icon;
065:
066: public AppResourceLoader(String tshome) {
067: m_tshome = tshome;
068: m_imagespath = "resources/images/";
069: }
070:
071: public AppResourceLoader(String tshome, String imagesPath) {
072: m_tshome = tshome;
073: m_imagespath = imagesPath;
074: }
075:
076: /**
077: * Creates a set of subdirectories under the main resources directory. e.g.
078: * createDirectories( "data/application" ); This will create the directory
079: * structure: TS_HOME/resources/data/application
080: */
081: public void createSubdirectories(String directories)
082: throws IOException {
083: StringBuffer abspath = new StringBuffer(m_tshome);
084: // allow either \ or / path delimiter
085: StringTokenizer tz = new StringTokenizer(directories, "/\\");
086: while (tz.hasMoreElements()) {
087: String subpath = (String) tz.nextToken();
088: abspath.append(File.separatorChar);
089: abspath.append(subpath);
090: File dir = new File(abspath.toString());
091: dir.mkdir();
092: }
093: }
094:
095: /**
096: * Creates a resource(file) relative to the application directory e.g.
097: * createResource( "keybindings/emacs.xml" ); will create the file emacs.xml
098: * in the keybindings directory off of the main subdirectory
099: *
100: * @param resourceName
101: * a path and file name of the file to create.
102: */
103: public void createResource(String resourceName) throws IOException {
104: StringBuffer abspath = new StringBuffer(m_tshome);
105: // allow either \ or / path delimiter
106: StringTokenizer tz = new StringTokenizer(resourceName, "/\\");
107: while (tz.hasMoreElements()) {
108: String subpath = (String) tz.nextToken();
109: abspath.append(File.separatorChar);
110: abspath.append(subpath);
111: if (tz.hasMoreElements()) {
112: File dir = new File(abspath.toString());
113: dir.mkdir();
114: }
115: }
116: }
117:
118: /**
119: * Deletes a named resource from disk or store
120: */
121: public void deleteResource(String resourceName) throws IOException {
122: File f = new File(m_tshome + File.separatorChar + resourceName);
123: f.delete();
124: }
125:
126: /**
127: * @returns true if the given resource exists
128: */
129: public boolean exists(String resourceName) throws IOException {
130: File f = new File(m_tshome + File.separatorChar + resourceName);
131: return f.exists();
132: }
133:
134: /**
135: * @return a custom class loader for the application
136: */
137: public ClassLoader getClassLoader() {
138: if (m_classloader == null)
139: return AppResourceLoader.class.getClassLoader();
140: else
141: return m_classloader;
142: }
143:
144: /**
145: * @return the absolute file name (with the ts home path )
146: */
147: String getAbsoluteFileName(String resourceName) {
148: StringBuffer buff = new StringBuffer();
149: buff.append(m_tshome);
150: buff.append(File.separatorChar);
151: buff.append(resourceName);
152: return buff.toString();
153: }
154:
155: /**
156: * @return the home directory for the application
157: */
158: public String getHomeDirectory() {
159: return m_tshome;
160: }
161:
162: /**
163: * Opens and returns an input stream for the given resourceName. The
164: * resourceName is relative to the application home directory.
165: *
166: * @param resourceName
167: * the relative name of the resource to open
168: * @return an input stream for the given resourceName.
169: */
170: public InputStream getInputStream(String resourceName)
171: throws IOException {
172: File f = new File(getAbsoluteFileName(resourceName));
173: return new BufferedInputStream(new FileInputStream(f));
174: }
175:
176: /**
177: * Opens and returns an output stream for the given resourceName. The
178: * resourceName is relative to the application home directory.
179: *
180: * @param resourceName
181: * the relative name of the resource to open
182: * @return an input stream for the given resourceName.
183: */
184: public OutputStream getOutputStream(String resourceName)
185: throws IOException {
186: String xmlfilename = getAbsoluteFileName(resourceName);
187: return new BufferedOutputStream(new FileOutputStream(
188: xmlfilename));
189: }
190:
191: /**
192: * Opens and returns an input stream for the given resourceName. The
193: * resourceName is relative to the application CLASSPATH (i.e. JAR file).
194: *
195: * @param resourceName
196: * the relative name of the resource to open
197: * @return an input stream for the given resourceName.
198: */
199: public InputStream getPackagedInputStream(String resourceName)
200: throws IOException {
201: ClassLoader classloader = getClassLoader();
202: return classloader.getResourceAsStream(resourceName);
203: }
204:
205: public Reader getReader(String resourceName) throws IOException {
206: String filename = getAbsoluteFileName(resourceName);
207: return new BufferedReader(new FileReader(filename));
208: }
209:
210: public Writer getWriter(String resourceName) throws IOException {
211: String filename = getAbsoluteFileName(resourceName);
212: return new BufferedWriter(new FileWriter(filename));
213: }
214:
215: /**
216: * Lists all files that are found in the given subdirectory. The
217: * subdirectory is relative to the main application directory.
218: *
219: * @param subdirectory
220: * the subdirectory whose file names we are going to return. Only
221: * the name of the file is returned (no path information)
222: * @param regexFilter
223: * this is a regular expression filter that you can use to locate
224: * the files
225: */
226: public String[] listFiles(String subdirectory, String regexFilter)
227: throws IOException {
228: String fname = getAbsoluteFileName(subdirectory);
229: File dir = new File(fname);
230:
231: Pattern pat = null;
232: try {
233: pat = Pattern.compile(regexFilter);
234: } catch (PatternSyntaxException e) {
235: throw new IllegalArgumentException(regexFilter);
236: }
237:
238: final Pattern pattern = pat;
239: String[] filenames = dir.list(new FilenameFilter() {
240: public boolean accept(File dir, String name) {
241: Matcher matcher = pattern.matcher(name);
242: if (matcher.find())
243: return true;
244: else
245: return false;
246: }
247: });
248:
249: if (filenames == null)
250: return new String[0];
251: else
252: return filenames;
253: }
254:
255: /**
256: * Helper utility to load an image file from the application images
257: * directory
258: *
259: * @param the
260: * name (and optional sub directory ) of the file to load
261: */
262: public ImageIcon loadImage(String imageName) {
263: try {
264: ClassLoader classloader = getClassLoader();
265: java.net.URL url = classloader.getResource(m_imagespath
266: + imageName);
267: ImageIcon icon = new ImageIcon(url);
268: return icon;
269: } catch (Exception e) {
270: System.out.println("invalid url: " + m_imagespath
271: + imageName);
272: e.printStackTrace();
273: }
274:
275: synchronized (AppResourceLoader.class) {
276:
277: if (m_empty_icon == null) {
278: BufferedImage img = new BufferedImage(16, 16,
279: BufferedImage.TYPE_INT_RGB);
280: m_empty_icon = new ImageIcon(img);
281: }
282: }
283: return m_empty_icon;
284: }
285:
286: public void setClassLoader(ClassLoader loader) {
287: m_classloader = loader;
288: }
289:
290: }
|