Rev 2630 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* Copyright (C) 2007 Steve Ratcliffe
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* Author: Steve Ratcliffe
* Create date: Feb 17, 2008
*/
package uk.me.parabola.mkgmap.osmstyle;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.Reader;
import java.net.URL;
import uk.me.parabola.log.Logger;
/**
* Open a style which can be on the classpath (mainly for the built-in styles)
* or in a specified file or directory.
*
* @author Steve Ratcliffe
*/
public abstract class StyleFileLoader
{
private static final Logger log =
Logger.
getLogger(StyleFileLoader.
class);
/**
* Open a style that is contained in a file. This is expected to be a
* directory or zip file containing the files that make up the style.
*
* @param loc The file or directory containing the style(s). If this is null then the location "classpath:styles"
* is used.
* @param name If the name is given then we look for a directory with the
* given name. If there is no name, then the style is assumed to be at
* the top level and/or the only file.
*
* @return A style loader.
*/
public static StyleFileLoader createStyleLoader
(String loc,
String name
)
throws FileNotFoundException
{
if (loc ==
null)
return createStyleLoader
("classpath:styles", name
);
StyleFileLoader loader
;
File file =
new File(loc
);
if (file.
isDirectory()) {
File dir = file
;
if (name
!=
null) {
dir =
new File(file, name
);
if (dir.
exists() ==
false)
throw new FileNotFoundException("style " + name +
" not found in " + dir
);
if (!dir.
isDirectory())
dir = file
;
}
log.
debug("style directory", dir
);
loader =
new DirectoryFileLoader
(dir
);
} else if (file.
isFile()) {
String loclc = loc.
toLowerCase();
if (loclc.
endsWith(".style")) {
if (name
!=
null)
throw new FileNotFoundException("no sub styles in a simple style file");
log.
debug("a single file style");
loader =
new CombinedStyleFileLoader
(loc
);
} else {
log.
debug("jar file", file
);
loader =
new JarFileLoader
(file.
toURI().
toString(), name
);
}
} else {
log.
debug("style url location", loc
);
String s = loc.
toLowerCase();
if (s.
startsWith("classpath:")) {
log.
debug("load style off classpath");
loader = classpathLoader
(loc.
substring(10), name
);
return loader
;
} else if (s.
startsWith("jar:")) {
loader =
new JarFileLoader
(loc, name
);
} else if (s.
indexOf(':') > 0) {
loader =
new JarFileLoader
(s, name
);
} else {
throw new FileNotFoundException("no such file or path: " + loc
);
}
}
return loader
;
}
/**
* Open the specified file in the style definition.
* @param filename The name of the file in the style.
* @return An open file reader for the file.
* @throws FileNotFoundException When the file can't be opened.
*/
public abstract Reader open
(String filename
) throws FileNotFoundException;
/**
* Close the FileLoader. This is different from closing individual files
* that were opened via {@link #open}. After this call then you shouldn't
* open any more files.
*/
public abstract void close
();
/**
* List the names of the styles that are contained in this loader.
* @return An array of style names.
*/
public abstract String[] list
();
/**
* Find a style on the class path. First we find out if the style is in
* a jar or a directory and then use the appropriate Loader.
*
* @param loc The file or directory location.
* @param name The style name.
* @return A loader for the style.
* @throws FileNotFoundException If it can't be found.
*/
private static StyleFileLoader classpathLoader
(String loc,
String name
) throws FileNotFoundException
{
String path = loc
;
if (name
!=
null)
path = loc +
'/' + name +
'/';
ClassLoader classLoader =
Thread.
currentThread().
getContextClassLoader();
if (classLoader ==
null)
throw new FileNotFoundException("no classloader to find style");
// all style files must be in the same directory or zip
URL url = classLoader.
getResource(path
);
if (url ==
null) {
classLoader = StyleFileLoader.
class.
getClassLoader();
url = classLoader.
getResource(path
);
if (url ==
null)
throw new FileNotFoundException("Could not find style " + path
);
}
String proto = url.
getProtocol().
toLowerCase();
if (proto.
equals("jar")) {
log.
debug("classpath loading from jar with url", url
);
return new JarFileLoader
(url
);
} else if (proto.
equals("file")) {
log.
debug("classpath loading from directory", url.
getPath());
return new DirectoryFileLoader
(new File(url.
getPath()));
}
throw new FileNotFoundException("Could not load style from classpath");
}
}