/* (c) 2014 - 2016 Open Source Geospatial Foundation - all rights reserved * (c) 2001 - 2013 OpenPlans * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.web.util; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.net.URI; import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.wicket.IConverterLocator; import org.apache.wicket.util.convert.IConverter; import org.geoserver.platform.GeoServerResourceLoader; import org.geotools.util.logging.Logging; /** * Special converter locator which can resolve relative urls relative to the * GeoServer data directory. * <p> * This converter locator will turn URL's of the form "file:data/..." into full * path URL's such as "file://var/lib/geoserver/data/...". *</p> * @author Justin Deoliveira, The Open Planning Project * */ @SuppressWarnings("serial") public class DataDirectoryConverterLocator implements IConverterLocator { static final Logger LOGGER = Logging.getLogger(DataDirectoryConverterLocator.class); GeoServerResourceLoader resourceLoader; public DataDirectoryConverterLocator( GeoServerResourceLoader resourceLoader ) { this.resourceLoader = resourceLoader; } @SuppressWarnings("unchecked") public <C> IConverter<C> getConverter(Class<C> type) { if ( File.class.isAssignableFrom( type ) ) { return (IConverter<C>) new FileLocator(); } if ( URL.class.isAssignableFrom( type ) ) { return (IConverter<C>) new URLLocator(); } if ( URI.class.isAssignableFrom( type ) ) { return (IConverter<C>) new URILocator(); } return null; } File toFile( String value ) { if ( value == null || "".equals( value ) ) { return null; } try { //first try as a url to strip off url protocol prefix try { URL url = new URL( value ); if ( "file".equals( url.getProtocol() ) ) { value = url.getFile(); } } catch( MalformedURLException e ) {} File file = new File( value ); if ( file.isAbsolute() ) { return file; } return resourceLoader.find( value ); } catch (IOException e) { LOGGER.log(Level.WARNING, "Error converting \""+value+"\" to File", e); } return null; } String fromFile( File file ) { File data = resourceLoader.getBaseDirectory(); //figure out if the file is a child of the base data directory List<String> path = new ArrayList<String>(); boolean isChild = false; while( file != null ) { if ( file.equals( data ) ) { isChild = true; break; } path.add( file.getName() ); file = file.getParentFile(); } if ( isChild ) { StringBuffer b = new StringBuffer( "file:" ); for ( int i = path.size()-1; i > -1; i--) { b.append( path.get( i ) ).append( File.separatorChar ); } b.setLength( b.length()-1 ); return b.toString(); } return null; } class FileLocator implements IConverter<File> { public File convertToObject(String value, Locale locale) { return toFile( value ); } public String convertToString(File value, Locale locale) { return fromFile( (File) value ); } } class URLLocator implements IConverter<URL> { public URL convertToObject(String value, Locale locale) { File file = toFile( value ); if ( file != null ) { try { return file.toURI().toURL(); } catch (MalformedURLException e) { LOGGER.log(Level.WARNING, "Error converting \""+value+"\" to URL", e); } } return null; } public String convertToString(URL value, Locale locale) { String file = value.getFile(); if ( file != null && !"".equals( file ) ) { return fromFile( new File( value.getFile() ) ); } return null; } } class URILocator implements IConverter<URI> { public URI convertToObject(String value, Locale locale) { File file = toFile( value ); if ( file != null ) { return file.toURI(); } return null; } public String convertToString(URI value, Locale locale) { try { return new URLLocator().convertToString( value.toURL() , locale ); } catch (Exception e) { LOGGER.log(Level.WARNING, "Error converting \""+value+"\" to URI", e); return null; } } } }