001: /* *****************************************************************************
002: * FileResolver.java
003: * ****************************************************************************/
004:
005: /* J_LZ_COPYRIGHT_BEGIN *******************************************************
006: * Copyright 2001-2007 Laszlo Systems, Inc. All Rights Reserved. *
007: * Use is subject to license terms. *
008: * J_LZ_COPYRIGHT_END *********************************************************/
009:
010: package org.openlaszlo.compiler;
011:
012: import java.io.File;
013: import java.io.FilenameFilter;
014: import java.util.*;
015: import org.openlaszlo.server.*;
016: import org.apache.log4j.*;
017:
018: import org.openlaszlo.utils.FileUtils;
019:
020: /**
021: * Provides an interface for resolving a pathname to a File. The
022: * Compiler class uses this to resolve includes (hrefs).
023: *
024: * @author Oliver Steele
025: */
026: public interface FileResolver {
027: /** An instance of the DefaultFileResolver */
028: FileResolver DEFAULT_FILE_RESOLVER = new DefaultFileResolver();
029:
030: /** Given a pathname, return the File that it names.
031: * @param pathname a path to resolve
032: * @param base a relative URI against which to resolve it
033: * @param asLibrary whether this URI is to a library or not
034: * @return see doc
035: * @exception java.io.FileNotFoundException if an error occurs
036: */
037: File resolve(String pathname, String base, boolean asLibrary)
038: throws java.io.FileNotFoundException;
039:
040: File resolve(CompilationEnvironment env, String pathname,
041: String base, boolean asLibrary)
042: throws java.io.FileNotFoundException;
043:
044: /**
045: * The Set of Files that represents the includes that have been
046: * implicitly included by binary libraries. This is updated by
047: * the library compiler and used to resolve paths that may not
048: * exist in the binary distribution.
049: */
050: Set getBinaryIncludes();
051: }
052:
053: /** DefaultFileResolver maps each pathname onto the File that
054: * it names, without doing any directory resolution or other
055: * magic. (The operating system's notion of a working directory
056: * supplies the context for partial pathnames.)
057: */
058: class DefaultFileResolver implements FileResolver {
059:
060: public Set binaryIncludes = new HashSet();
061:
062: public Set getBinaryIncludes() {
063: return binaryIncludes;
064: }
065:
066: public DefaultFileResolver() {
067: }
068:
069: public File resolve(String pathname, String base, boolean asLibrary)
070: throws java.io.FileNotFoundException {
071: return resolve(null, pathname, base, asLibrary);
072: }
073:
074: /** @see FileResolver */
075: public File resolve(CompilationEnvironment env, String pathname,
076: String base, boolean asLibrary)
077: throws java.io.FileNotFoundException {
078: if (asLibrary) {
079: // If it is a library, search for .lzo's, consider the
080: // path may be just to the directory of the library
081: File library = null;
082: if (pathname.endsWith(".lzx")) {
083: library = resolveInternal(env, pathname.substring(0,
084: pathname.length() - 4)
085: + ".lzo", base);
086: if (library != null) {
087: return library;
088: }
089: } else {
090: // Try pathname as a directory
091: library = resolveInternal(env, (new File(pathname,
092: "library.lzo").getPath()), base);
093: if (library != null) {
094: return library;
095: }
096: library = resolveInternal(env, (new File(pathname,
097: "library.lzx").getPath()), base);
098: if (library != null) {
099: return library;
100: }
101: }
102: }
103: // Last resort for a library, normal case for plain files
104: File resolved = resolveInternal(env, pathname, base);
105: if (resolved != null) {
106: return resolved;
107: }
108: throw new java.io.FileNotFoundException(pathname);
109: }
110:
111: protected File resolveInternal(CompilationEnvironment env,
112: String pathname, String base) {
113: Logger mLogger = Logger.getLogger(FileResolver.class);
114:
115: final String FILE_PROTOCOL = "file";
116: String protocol = FILE_PROTOCOL;
117:
118: // The >1 test allows file pathnames to start with DOS
119: // drive letters.
120: int pos = pathname.indexOf(':');
121: if (pos > 1) {
122: protocol = pathname.substring(0, pos);
123: pathname = pathname.substring(pos + 1);
124: }
125: mLogger.debug(
126: /* (non-Javadoc)
127: * @i18n.test
128: * @org-mes="Resolving pathname: " + p[0] + " and base: " + p[1]
129: */
130: org.openlaszlo.i18n.LaszloMessages.getMessage(
131: FileResolver.class.getName(), "051018-68",
132: new Object[] { pathname, base }));
133: if (!FILE_PROTOCOL.equals(protocol)) {
134: throw new CompilationError(
135: /* (non-Javadoc)
136: * @i18n.test
137: * @org-mes="unknown protocol: " + p[0]
138: */
139: org.openlaszlo.i18n.LaszloMessages.getMessage(
140: FileResolver.class.getName(), "051018-77",
141: new Object[] { protocol }));
142: }
143:
144: // Determine whether to substitue resource files initially just swf to png
145: String pnext = FileUtils.getExtension(pathname);
146: boolean dhtmlResourceFlag = false;
147: if (env != null) {
148: dhtmlResourceFlag = env.isDHTML();
149: }
150: boolean SWFtoPNG = dhtmlResourceFlag
151: && pnext.equalsIgnoreCase("swf");
152: if (SWFtoPNG) {
153: String pnbase = FileUtils.getBase(pathname);
154: pathname = pnbase + ".png";
155: }
156:
157: // FIXME: [ebloch] this vector should be in a properties file
158: Vector v = new Vector();
159: if (pathname.startsWith("/")) {
160: // Try absolute
161: v.add("");
162: v.add(LPS.getComponentsDirectory());
163: }
164: v.add(base);
165: if (SWFtoPNG) {
166: String toAdd = FileUtils
167: .insertSubdir(base + "/", "autoPng");
168: mLogger.debug("Default File Resolver Adding " + toAdd
169: + '\n');
170: v.add(toAdd);
171: }
172: if (!pathname.startsWith("./") && !pathname.startsWith("../")) {
173: v.add(LPS.getComponentsDirectory());
174: v.add(LPS.getFontDirectory());
175: v.add(LPS.getLFCDirectory());
176: }
177:
178: Enumeration e = v.elements();
179: while (e.hasMoreElements()) {
180: String dir = (String) e.nextElement();
181: try {
182: File f = (new File(dir, pathname)).getCanonicalFile();
183: if (f.exists()
184: || ((binaryIncludes != null) && binaryIncludes
185: .contains(f))) {
186: mLogger.debug("Resolved " + pathname + " to "
187: + f.getAbsolutePath());
188: return f;
189: } else if (SWFtoPNG) {
190: String autoPngPath = FileUtils.insertSubdir(f
191: .getPath(), "autoPng");
192: mLogger.debug("Default File Resolver Looking for "
193: + autoPngPath + '\n');
194: File autoPngFile = new File(autoPngPath);
195: if (autoPngFile.exists()) {
196: mLogger.debug("Default File Resolver "
197: + pathname + " to "
198: + autoPngFile.getAbsolutePath() + '\n');
199: return autoPngFile;
200: } else {
201: File[] pathArray = FileUtils
202: .matchPlusSuffix(autoPngFile);
203: if (pathArray != null && pathArray.length != 0) {
204: return autoPngFile;
205: }
206: }
207: }
208: } catch (java.io.IOException ex) {
209: // Not a valid file?
210: }
211: }
212: return null;
213: }
214: }
|