3333import org .geowebcache .util .ApplicationContextProvider ;
3434import org .geowebcache .util .GWCVars ;
3535import org .springframework .context .ApplicationContext ;
36+ import org .springframework .lang .NonNull ;
3637import org .springframework .web .context .WebApplicationContext ;
3738
3839/** Default implementation of ConfigurationResourceProvider that uses the file system. */
@@ -49,9 +50,11 @@ public class XMLFileResourceProvider implements ConfigurationResourceProvider {
4950 private final WebApplicationContext context ;
5051
5152 /** Location of the configuration file */
53+ @ NonNull
5254 private final File configDirectory ;
5355
5456 /** Name of the configuration file */
57+ @ NonNull
5558 private final String configFileName ;
5659
5760 private String templateLocation ;
@@ -135,11 +138,27 @@ public XMLFileResourceProvider(
135138 this (configFileName , appCtx , getConfigDirVar (appCtx ), storageDirFinder );
136139 }
137140
141+ /**
142+ * {@inheritDoc}
143+ *
144+ * <p>If the configuration file doesn't exist and {@link #hasInput() == true}, the file will be first created from
145+ * the {@link #setTemplate(String) template}
146+ *
147+ * @throws IOException if the file can't be created or copied from the template
148+ */
138149 @ Override
139150 public InputStream in () throws IOException {
140151 return new FileInputStream (findOrCreateConfFile ());
141152 }
142153
154+ /**
155+ * {@inheritDoc}
156+ *
157+ * <p>If the configuration file doesn't exist and {@link #hasOutput() == true}, the file will be first created from
158+ * the {@link #setTemplate(String) template}
159+ *
160+ * @throws IOException if the file can't be created or copied from the template
161+ */
143162 @ Override
144163 public OutputStream out () throws IOException {
145164 return new FileOutputStream (findOrCreateConfFile ());
@@ -165,22 +184,13 @@ public void setTemplate(final String templateLocation) {
165184 }
166185
167186 private File findConfigFile () throws IOException {
168- if (null == configDirectory ) {
169- throw new IllegalStateException ();
170- }
171187
172188 if (!configDirectory .exists () && !configDirectory .mkdirs ()) {
173189 throw new IOException ("TileLayerConfiguration directory does not exist and cannot be created: '"
174190 + configDirectory .getAbsolutePath ()
175191 + "'" );
176192 }
177- if (!configDirectory .canWrite ()) {
178- throw new IOException (
179- "TileLayerConfiguration directory is not writable: '" + configDirectory .getAbsolutePath () + "'" );
180- }
181-
182- File xmlFile = new File (configDirectory , configFileName );
183- return xmlFile ;
193+ return new File (configDirectory , configFileName );
184194 }
185195
186196 @ Override
@@ -200,6 +210,11 @@ private File findOrCreateConfFile() throws IOException {
200210 if (xmlFile .exists ()) {
201211 log .config ("Found configuration file in " + configDirectory .getAbsolutePath ());
202212 } else if (templateLocation != null ) {
213+ if (!configDirectory .canWrite ()) {
214+ throw new IOException ("TileLayerConfiguration directory is not writable: '"
215+ + configDirectory .getAbsolutePath () + "'" );
216+ }
217+
203218 log .warning ("Found no configuration file in config directory, will create one at '"
204219 + xmlFile .getAbsolutePath ()
205220 + "' from template "
@@ -249,17 +264,40 @@ private void backUpConfig(final File xmlFile) throws IOException {
249264 log .fine ("Config backup done" );
250265 }
251266
267+ /**
268+ * Determines if the config file exists and is readable, or doesn't exist but can be created.
269+ *
270+ * <p>Calling this method has no side effects. The target file either exists, or can be created throught the
271+ * {@link #setTemplate(String) template}, if a template has been set. In such case, it'll be created by either
272+ * {@link #in()} or {@link #out()}.
273+ */
252274 @ Override
253275 public boolean hasInput () {
254276 try {
255- return findOrCreateConfFile ().exists ();
277+ File file = findConfigFile ();
278+ return file .exists () || (templateLocation != null && configDirectory .canWrite ());
256279 } catch (IOException e ) {
280+ log .log (Level .WARNING , "Error obtaining config file" , e );
257281 return false ;
258282 }
259283 }
260284
285+ /**
286+ * Determines if the configuration can be {@link #out() written} to the {@link #getLocation() output file}.
287+ *
288+ * <p>Calling this method has no side effects. The target file may or may not exist. The target directory must be
289+ * writable, and so must the target file in case it does exist.
290+ *
291+ * @return {@code true} if the {@link #getLocation() configuration file} can be written to.
292+ */
261293 @ Override
262294 public boolean hasOutput () {
263- return true ;
295+ try {
296+ File file = findConfigFile ();
297+ return configDirectory .canWrite () && (!file .exists () || file .canWrite ());
298+ } catch (IOException e ) {
299+ log .log (Level .WARNING , "Error obtaining config file" , e );
300+ return false ;
301+ }
264302 }
265303}
0 commit comments