/* (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.data.store.panel;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.wicket.model.IModel;
import org.geoserver.platform.GeoServerExtensions;
import org.geoserver.platform.GeoServerResourceLoader;
import org.geoserver.platform.resource.Files;
import org.geotools.util.logging.Logging;
/**
* Makes sure the file path for files do start with file:// otherwise
* stuff like /home/user/file.shp won't be recognized as valid. Also, if a
* path is inside the data directory it will be turned into a relative path
* @author Andrea Aime - GeoSolutions
*
*/
public class FileModel implements IModel<String> {
private static final long serialVersionUID = 3911203737278340528L;
static final Logger LOGGER = Logging.getLogger(FileModel.class);
IModel<String> delegate;
File rootDir;
public FileModel(IModel<String> delegate) {
this(delegate, GeoServerExtensions.bean(GeoServerResourceLoader.class).getBaseDirectory());
}
public FileModel(IModel<String> delegate, File rootDir) {
this.delegate = delegate;
this.rootDir = rootDir;
}
private boolean isSubfile(File root, File selection) {
if(selection == null || "".equals(selection.getPath()))
return false;
if(selection.equals(root))
return true;
return isSubfile(root, selection.getParentFile());
}
@Override
public String getObject() {
Object obj = delegate.getObject();
if (obj instanceof URL) {
URL url = (URL)obj;
return url.toExternalForm();
}
return (String)obj;
}
public void detach() {
// TODO Auto-generated method stub
}
public void setObject(String location) {
if(location != null) {
File dataDirectory = canonicalize(rootDir);
File file = canonicalize(new File(location));
if(isSubfile(dataDirectory, file)) {
File curr = file;
String path = null;
// paranoid check to avoid infinite loops
while(curr != null && !curr.equals(dataDirectory)){
if(path == null) {
path = curr.getName();
} else {
path = curr.getName() + "/" + path;
}
curr = curr.getParentFile();
}
location = "file:" + path;
}
else {
File dataFile = Files.url( rootDir, location );
if( dataFile != null && !dataFile.equals(file)) {
// relative to the data directory, does not need fixing
} else {
location = "file://" + file.getAbsolutePath();
}
}
}
delegate.setObject(location);
}
/**
* Turns a file in canonical form if possible
* @param file
*
*/
File canonicalize(File file) {
try {
return file.getCanonicalFile();
} catch(IOException e) {
LOGGER.log(Level.INFO, "Could not convert " + file + " into canonical form", e);
return file;
}
}
}