/* Copyright (c) 2001 - 2010 TOPP - www.openplans.org. All rights reserved.
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.config;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.geotools.util.logging.Logging;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
/**
* A spring placeholder configurer that loads properties from the data directory.
* <p>
* This class is used by declaring an instance in a spring context:
* <pre>
* <bean id="myPropertyConfigurer" class="org.geoserver.config.GeoServerPropertyConfigurer">
* <constructor-arg ref="dataDirectory"/>
* <property name="location" value="file:myDirectory/myFile.properties"/>
* <property name="properties">
* <props>
* <prop key="prop1">value1</prop>
* <prop key="prop2">value2</prop>
* </props>
* </property>
* </bean>
* </pre>
* The location <tt>myDirectory/myFile.properties</tt> will be resolved relative to the data directory.
* </p>
* <p>
* In the same spring context the configurer is used as follows:
* <pre>
* <bean id="myBean" class="com.xyz.MyClass">
* <property name="someProperty" value="${prop1}"/>
* <property name="someOtherProperty" value="${prop2}"/>
* </bean>
* </pre>
* If the file <tt>myDirectory/myFile.properties</tt> exists then the property values will be loaded
* from it, otherwise the defaults declared on the property configurer will be used. By default when
* the resource is not found it will be copied out into the data directory. However
* {@link #setCopyOutTemplate(boolean)} can be used to control this.
* </p>
*
* @author Justin Deoliveira, OpenGeo
*
*/
public class GeoServerPropertyConfigurer extends PropertyPlaceholderConfigurer {
static Logger LOGGER = Logging.getLogger("org.geoserver.config");
GeoServerDataDirectory data;
Resource location;
boolean copyOutTemplate = true;
String comments;
public GeoServerPropertyConfigurer(GeoServerDataDirectory data) {
this.data = data;
}
public void setCopyOutTemplate(boolean copyOutTemplate) {
this.copyOutTemplate = copyOutTemplate;
}
public void setComments(String comments) {
this.comments = comments;
}
@Override
public void setLocation(Resource location) {
try {
File f = location.getFile();
if (f != null && !f.isAbsolute()) {
//make relative to data directory
f = new File(data.root(), f.getPath());
location = new UrlResource(f.toURI());
this.location = location;
}
}
catch(IOException e) {
LOGGER.log(Level.WARNING, "Error reading resource " + location, e);
}
super.setLocation(location);
}
@Override
public void setLocations(Resource[] locations) {
throw new UnsupportedOperationException("Only a single location is supported");
}
@Override
protected void loadProperties(Properties props) throws IOException {
try {
super.loadProperties(props);
}
catch(FileNotFoundException e) {
//location was not found, create
if (this.location != null && copyOutTemplate) {
File f = location.getFile();
f.getParentFile().mkdirs();
f.createNewFile();
FileOutputStream fout = new FileOutputStream(f);
props.store(fout, comments);
fout.flush();
fout.close();
}
}
}
}