/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2012, Geomatys * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library 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 * Lesser General Public License for more details. */ package org.geotoolkit.coverage.xmlstore; import java.io.File; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.logging.Level; import javax.xml.bind.JAXBException; import org.geotoolkit.storage.coverage.AbstractCoverageStore; import org.geotoolkit.storage.coverage.CoverageReference; import org.geotoolkit.storage.coverage.CoverageStoreFactory; import org.geotoolkit.storage.coverage.CoverageType; import org.geotoolkit.coverage.grid.ViewType; import org.geotoolkit.util.NamesExt; import org.apache.sis.storage.DataStoreException; import org.geotoolkit.parameter.Parameters; import org.geotoolkit.storage.DataNode; import org.geotoolkit.storage.DataStores; import org.geotoolkit.storage.DefaultDataNode; import org.opengis.util.GenericName; import org.opengis.parameter.ParameterValueGroup; /** * Coverage store relying on an xml file. * * @author Johann Sorel (Geomatys) * @module */ public class XMLCoverageStore extends AbstractCoverageStore { private final Path root; private final DataNode rootNode = new DefaultDataNode(); final boolean cacheTileState; @Deprecated public XMLCoverageStore(File root) throws URISyntaxException, IOException { this(root.toPath(),true); } public XMLCoverageStore(Path root) throws URISyntaxException, IOException { this(root,true); } public XMLCoverageStore(URL rootPath) throws URISyntaxException, IOException { this(rootPath, true); } @Deprecated public XMLCoverageStore(File root, boolean cacheTileStateInMemory) throws URISyntaxException, IOException { this(toParameters(root.toURI(),cacheTileStateInMemory)); } public XMLCoverageStore(Path root, boolean cacheTileStateInMemory) throws URISyntaxException, IOException { this(toParameters(root.toUri(),cacheTileStateInMemory)); } public XMLCoverageStore(URL rootPath, boolean cacheTileStateInMemory) throws URISyntaxException, IOException { this(toParameters(rootPath.toURI(), cacheTileStateInMemory)); } public XMLCoverageStore(ParameterValueGroup params) throws URISyntaxException, IOException { super(params); final URI rootPath = Parameters.value(XMLCoverageStoreFactory.PATH, params); root = Paths.get(rootPath); Boolean tmpCacheState = Parameters.value(XMLCoverageStoreFactory.CACHE_TILE_STATE, params); cacheTileState = (tmpCacheState == null)? true : tmpCacheState; explore(); } private static ParameterValueGroup toParameters(URI rootPath, boolean cacheState) { final ParameterValueGroup params = XMLCoverageStoreFactory.PARAMETERS_DESCRIPTOR.createValue(); Parameters.getOrCreate(XMLCoverageStoreFactory.PATH, params).setValue(rootPath); Parameters.getOrCreate(XMLCoverageStoreFactory.CACHE_TILE_STATE, params).setValue(cacheState); return params; } @Override public CoverageStoreFactory getFactory() { return (CoverageStoreFactory) DataStores.getFactoryById(XMLCoverageStoreFactory.NAME); } @Override public DataNode getRootNode() { return rootNode; } /** * Search all xml files in the folder which define a pyramid model. */ private void explore() throws IOException { if (!Files.exists(root)) { Files.createDirectories(root); } if (Files.isRegularFile(root)) { createReference(root); } else { List<Path> paths = new ArrayList<>(); try (DirectoryStream<Path> stream = Files.newDirectoryStream(root)) { for (Path path : stream) { if (Files.isRegularFile(path) && path.getFileName().toString().toLowerCase().endsWith(".xml")) { paths.add(path); } } } if (!paths.isEmpty()) { for (Path candidate : paths) { //try to parse the file createReference(candidate); } } } } private void createReference(Path refDescriptor) { try { //TODO useless copy here final XMLCoverageReference set = XMLCoverageReference.read(refDescriptor); final GenericName name = NamesExt.create(getDefaultNamespace(), set.getId()); final XMLCoverageReference ref = new XMLCoverageReference(this,name,set.getPyramidSet()); ref.copy(set); rootNode.getChildren().add(ref); } catch (JAXBException ex) { getLogger().log(Level.INFO, "file is not a pyramid : {0}", refDescriptor.toString()); } catch (DataStoreException ex) { getLogger().log(Level.WARNING, "Pyramid descriptor contains an invalid CRS : "+refDescriptor.toAbsolutePath().toString(), ex); } catch (IOException e) { getLogger().log(Level.WARNING, "Unable to read pyramid file description : {0}", refDescriptor.toString()); } } @Override public void close() { } @Override public CoverageReference create(GenericName name) throws DataStoreException { return create(name, null, null); } /** * Create a CoverageReference with a specific data type and preferred image tile format. * Default is ViewType.RENDERED and PNG tile format. * * @param name name of the new CoverageReference. * @param packMode data type (Geophysic or Rendered). Can be null. * @param preferredFormat pyramid tile format. Can be null. * @return new CoverageReference. * @throws DataStoreException */ public CoverageReference create(GenericName name, ViewType packMode, String preferredFormat) throws DataStoreException { if (Files.isRegularFile(root)) { throw new DataStoreException("Store root is a file, not a directory, no reference creation allowed."); } name = NamesExt.create(getDefaultNamespace(), name.tip().toString()); final Set<GenericName> names = getNames(); if(names.contains(name)){ throw new DataStoreException("Name already used in store : " + name.tip().toString()); } final XMLPyramidSet set = new XMLPyramidSet(); final XMLCoverageReference ref = new XMLCoverageReference(this,name,set); ref.initialize(root.resolve(name.tip().toString()+".xml")); if (packMode != null) { ref.setPackMode(packMode); } if (preferredFormat != null) { ref.setPreferredFormat(preferredFormat); } rootNode.getChildren().add(ref); ref.save(); return ref; } @Override public CoverageType getType() { return CoverageType.PYRAMID; } }