001package org.jszip.sass; 002 003import org.codehaus.plexus.util.IOUtil; 004import org.jszip.pseudo.io.PseudoFile; 005import org.jszip.pseudo.io.PseudoFileInputStream; 006import org.jszip.pseudo.io.PseudoFileSystem; 007import org.mozilla.javascript.Context; 008 009import java.io.IOException; 010import java.io.InputStream; 011import java.util.Date; 012 013/** 014 * @author stephenc 015 * @since 31/01/2013 12:01 016 */ 017public class PseudoFileSystemImporter { 018 019 private final PseudoFileSystem fs; 020 private final String encoding; 021 022 public PseudoFileSystemImporter(PseudoFileSystem fs, String encoding) { 023 this.fs = fs; 024 this.encoding = encoding; 025 } 026 027 /** 028 * Find a Sass file, if it exists. 029 * <p/> 030 * This is the primary entry point of the Importer. 031 * It corresponds directly to an `@import` statement in Sass. 032 * It should do three basic things: 033 * <p/> 034 * * Determine if the URI is in this importer's format. 035 * If not, return nil. 036 * * Determine if the file indicated by the URI actually exists and is readable. 037 * If not, return nil. 038 * * Read the file and place the contents in a {Sass::Engine}. 039 * Return that engine. 040 * <p/> 041 * If this importer's format allows for file extensions, 042 * it should treat them the same way as the default {Filesystem} importer. 043 * If the URI explicitly has a `.sass` or `.scss` filename, 044 * the importer should look for that exact file 045 * and import it as the syntax indicated. 046 * If it doesn't exist, the importer should return nil. 047 * <p/> 048 * If the URI doesn't have either of these extensions, 049 * the importer should look for files with the extensions. 050 * If no such files exist, it should return nil. 051 * <p/> 052 * The {Sass::Engine} to be returned should be passed `options`, 053 * with a few modifications. `:syntax` should be set appropriately, 054 * `:filename` should be set to `uri`, 055 * and `:importer` should be set to this importer. 056 * 057 * @param uri [String] The URI to import. 058 * @return the contents of the uri. 059 */ 060 public String find(String uri) throws IOException { 061 Context.enter(); 062 try { 063 fs.installInContext(); 064 final PseudoFile file = fs.getPseudoFile(uri); 065 if (file.isFile()) { 066 InputStream is = null; 067 try { 068 is = new PseudoFileInputStream(file); 069 return IOUtil.toString(is, encoding); 070 } finally { 071 IOUtil.close(is); 072 } 073 } 074 return null; 075 } finally { 076 fs.removeFromContext(); 077 Context.exit(); 078 } 079 } 080 081 /** 082 * Returns the time the given Sass file was last modified. 083 * <p/> 084 * If the given file has been deleted or the time can't be accessed 085 * for some other reason, this should return nil. 086 * 087 * @param uri [String] The URI of the file to check. 088 * Comes from a `:filename` option set on an engine returned by this importer. 089 * @return [Time, nil] 090 */ 091 public Date mtime(String uri) { 092 Context.enter(); 093 try { 094 fs.installInContext(); 095 final PseudoFile file = fs.getPseudoFile(uri); 096 if (file.isFile()) { 097 return new Date(file.lastModified()); 098 } 099 return null; 100 } finally { 101 fs.removeFromContext(); 102 Context.exit(); 103 } 104 } 105 106}