package folioxml.core; import java.io.*; import java.util.ArrayList; /** * An implementation of IIncludeResolutionService for testing. You 'pre-fill' the class with avaialble includes by calling the add() method. * The collection of available includes is shared with each Resolver that .add() is called on. That way .getChild() doesn't affect the possibilities. * * @author nathanael */ public class StringIncludeResolver implements IIncludeResolutionService { public StringIncludeResolver() { this("test.fff", ""); } /** * Creates a StringIncludeResolver. */ public StringIncludeResolver(String filename, String data) { //Parse base document string this.baseDocument = new File(filename).getAbsoluteFile(); assert (this.baseDocument.isAbsolute()); this.data = data; //Calculate base dir this.baseDirectory = this.baseDocument.getParentFile(); } private File baseDocument; private File baseDirectory; private String data; /** * Returns a reader * * @param fileReference * @return * @throws java.io.FileNotFoundException */ public Reader getReader() throws FileNotFoundException { return new StringReader(data); } private ArrayList<StringIncludeResolver> files = new ArrayList<StringIncludeResolver>(); public StringIncludeResolver add(StringIncludeResolver sir) { files.add(sir); sir.files = files; return this; } /** * This returns the hash for the base document, so it can be excluded from circular references. * This is a hashing function that the circular reference tracking uses. * Creats and absolute string that should be a function of the referenced file, not just the string. * * @return */ public String getHash() throws IOException { return baseDocument.getCanonicalPath().toLowerCase(); } public String getDescription() { return baseDocument.toString(); } /** * Takes an absolute or relative path and returns an absolute File instance. * * @param path * @return */ private File resolve(String path) { File f = new File(path); if (f.isAbsolute()) return f; //nothing needed. else { //relative return new File(baseDirectory, path); } } /** * Gets a child for the specified sub-reference. In this implementation, the only available childern are those added by the .add() method. * The collection is shared among all children, so recursive includes are possibile as long as the filenames are added once at the root level. * * @param fileReference * @return * @throws java.io.IOException */ public IIncludeResolutionService getChild(String fileReference) throws IOException { String hash = resolve(fileReference).getCanonicalPath().toLowerCase(); for (int i = 0; i < files.size(); i++) { if (files.get(i).getHash().equals(hash)) return files.get(i); } throw new IOException("The specified include \"" + fileReference + "\" was not found - please add it using .add() before tryingt to include it."); } }