/* * Constellation - An open source and standard compliant SDI * http://www.constellation-sdi.org * * Copyright 2014 Geomatys. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.constellation.provider.coveragesql; import org.apache.sis.storage.DataStore; import org.constellation.api.DataType; import org.constellation.provider.AbstractDataProvider; import org.constellation.provider.Data; import org.constellation.provider.configuration.ProviderParameters; import org.geotoolkit.coverage.io.CoverageStoreException; import org.geotoolkit.coverage.sql.CoverageDatabase; import org.geotoolkit.coverage.sql.LayerCoverageReader; import org.geotoolkit.map.ElevationModel; import org.geotoolkit.map.MapBuilder; import org.opengis.parameter.ParameterValueGroup; import java.sql.SQLException; import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.Set; import java.util.concurrent.CancellationException; import java.util.logging.Level; import static org.constellation.provider.configuration.ProviderParameters.LAYER_ELEVATION_MODEL_DESCRIPTOR; import static org.constellation.provider.configuration.ProviderParameters.LAYER_IS_ELEVATION_MODEL_DESCRIPTOR; import static org.constellation.provider.configuration.ProviderParameters.containLayer; import static org.constellation.provider.configuration.ProviderParameters.getLayer; import static org.constellation.provider.configuration.ProviderParameters.isLoadAll; import static org.constellation.provider.coveragesql.CoverageSQLProviderService.COVERAGESQL_DESCRIPTOR; import static org.constellation.provider.coveragesql.CoverageSQLProviderService.NAMESPACE_DESCRIPTOR; import org.geotoolkit.util.NamesExt; import static org.geotoolkit.parameter.Parameters.value; import org.geotoolkit.storage.coverage.CoverageReference; import org.geotoolkit.storage.coverage.DefaultCoverageReference; import org.opengis.util.GenericName; /** * * @author Johann Sorel (Geomatys) */ public class CoverageSQLProvider extends AbstractDataProvider{ private CoverageDatabase database; private final Set<GenericName> index = new HashSet<>(); protected CoverageSQLProvider(String providerId, final CoverageSQLProviderService service, final ParameterValueGroup source) { super(providerId,service,source); visit(); } private ParameterValueGroup getSourceConfiguration(){ return ProviderParameters.getSourceConfiguration(getSource(), COVERAGESQL_DESCRIPTOR); } @Override public DataStore getMainStore() { throw new UnsupportedOperationException("Not supported yet."); } /** * Creates a {@linkplain CoverageDatabase database connection} with the provided * parameters. * * @throws SQLException if the login attempt reaches the timeout (5s here). */ private void loadDataBase() throws Exception{ if(database != null){ return; } final ParameterValueGroup params = getSourceConfiguration(); database = new CoverageDatabase(params); } /** * {@inheritDoc } */ @Override public Set<GenericName> getKeys() { return Collections.unmodifiableSet(index); } /** * {@inheritDoc } */ @Override public Data get(final GenericName key) { return get(key, null); } /** * {@inheritDoc } */ @Override public Data get(final GenericName key, Date version) { // If the key is not present for this provider, it is not necessary to go further. // Without this test, an exception will be logged whose message is a warning about // the non presence of the requested key into the "Layers" table. if (!contains(key)) { return null; } if(database == null){ return null; } LayerCoverageReader reader = null; try { reader = database.createGridCoverageReader(key.tip().toString()); } catch (CoverageStoreException ex) { getLogger().log(Level.WARNING, ex.getMessage(), ex); } if (reader != null) { final String name = key.tip().toString(); final ParameterValueGroup layer = getLayer(getSource(), name); final String elemodel = (layer==null)?null:value(LAYER_ELEVATION_MODEL_DESCRIPTOR, layer); final GenericName em = (layer == null || elemodel == null) ? null : NamesExt.valueOf(elemodel); return new CoverageSQLLayerDetails(reader,null,em,key); } return null; } /** * {@inheritDoc } */ @Override public void reload() { dispose(); synchronized(this){ index.clear(); visit(); } fireUpdateEvent(); } /** * {@inheritDoc } */ @Override public void dispose() { synchronized(this){ index.clear(); if(database != null){ database.dispose(); } database = null; } } /** * Visit all layers detected from the database table {@code Layers}. */ @Override protected void visit() { try { loadDataBase(); } catch (Exception ex) { getLogger().log(Level.WARNING,ex.getLocalizedMessage(),ex); return; } try { final Set<String> layers = database.getLayers().result(); for(String name : layers){ test(name); } } catch (CoverageStoreException | CancellationException ex) { getLogger().log(Level.WARNING, ex.getMessage(), ex); } super.visit(); } /** * Test whether the provided candidate layer can be handled by the provider or not. * * @param candidate Candidate to be a layer. */ private void test(final String candidate){ final String name = candidate; if (isLoadAll(getSource()) || containLayer(getSource(), name)){ String nmsp = value(NAMESPACE_DESCRIPTOR, getSourceConfiguration()); if (nmsp == null) { nmsp = DEFAULT_NAMESPACE; } else if (nmsp.equals(NO_NAMESPACE)){ nmsp = null; } index.add(NamesExt.create(nmsp,name)); } } @Override public ElevationModel getElevationModel(GenericName name) { if(name == null){ return null; } final ParameterValueGroup layer = getLayer(getSource(), name.tip().toString()); if(layer != null){ Boolean isEleModel = value(LAYER_IS_ELEVATION_MODEL_DESCRIPTOR, layer); if(!Boolean.TRUE.equals(isEleModel)){ return null; } final CoverageSQLLayerDetails pgld = (CoverageSQLLayerDetails) getByIdentifier(name); if(pgld != null){ final CoverageReference ref = new DefaultCoverageReference(pgld.getReader(), name); try { return MapBuilder.createElevationModel(ref); } catch (CoverageStoreException ex) { LOGGER.log(Level.WARNING, "error while creating elevation model", ex); } } } return null; } @Override public DataType getDataType() { return DataType.COVERAGE; } }