/* * 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.admin; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.inject.Inject; import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; import javax.xml.namespace.QName; import org.apache.lucene.queryparser.classic.ParseException; import org.apache.sis.metadata.iso.DefaultMetadata; import org.apache.sis.storage.DataStoreException; import org.apache.sis.xml.MarshallerPool; import org.constellation.ServiceDef; import org.constellation.admin.exception.ConstellationException; import org.constellation.admin.index.IndexEngine; import org.constellation.admin.listener.DefaultDataBusinessListener; import org.constellation.admin.listener.IDataBusinessListener; import org.constellation.admin.util.ImageStatisticDeserializer; import org.constellation.api.DataType; import org.constellation.business.IDataBusiness; import org.constellation.business.IDataCoverageJob; import org.constellation.configuration.*; import org.constellation.dto.CoverageMetadataBean; import org.constellation.dto.FileBean; import org.constellation.dto.ParameterValues; import org.constellation.database.api.jooq.tables.pojos.CstlUser; import org.constellation.database.api.jooq.tables.pojos.Data; import org.constellation.database.api.jooq.tables.pojos.Dataset; import org.constellation.database.api.jooq.tables.pojos.Layer; import org.constellation.database.api.jooq.tables.pojos.Provider; import org.constellation.database.api.jooq.tables.pojos.Service; import org.constellation.database.api.jooq.tables.pojos.Style; import org.constellation.database.api.repository.DataRepository; import org.constellation.database.api.repository.DatasetRepository; import org.constellation.database.api.repository.LayerRepository; import org.constellation.database.api.repository.ProviderRepository; import org.constellation.database.api.repository.SensorRepository; import org.constellation.database.api.repository.StyleRepository; import org.constellation.database.api.repository.UserRepository; import org.constellation.provider.DataProvider; import org.constellation.provider.DataProviders; import org.constellation.token.TokenUtils; import org.constellation.utils.GeotoolkitFileExtensionAvailable; import org.geotoolkit.data.FeatureStore; import org.geotoolkit.metadata.ImageStatistics; import org.geotoolkit.util.FileUtilities; import org.opengis.feature.PropertyType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.DependsOn; import org.springframework.context.annotation.Primary; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.support.TransactionCallbackWithoutResult; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; import com.google.common.base.Optional; import java.util.Collection; import org.constellation.business.IMetadataBusiness; import org.constellation.database.api.pojo.DataItem; import org.constellation.database.api.repository.ServiceRepository; /** * Business facade for data. * * @author Mehdi Sidhoum (Geomatys). * @version 0.9 * @since 0.9 */ @Component("cstlDataBusiness") @DependsOn({"database-initer", "providerBusiness"}) @Primary public class DataBusiness implements IDataBusiness { /** * Used for debugging purposes. */ protected static final Logger LOGGER = LoggerFactory.getLogger(DataBusiness.class); /** * Injected user repository. */ @Inject private UserRepository userRepository; /** * Injected data repository. */ @Inject protected DataRepository dataRepository; /** * Injected layer repository. */ @Inject private LayerRepository layerRepository; /** * Injected security manager. */ @Inject private org.constellation.security.SecurityManager securityManager; /** * Injected style repository. */ @Inject private StyleRepository styleRepository; /** * Injected provider repository. */ @Inject private ProviderRepository providerRepository; /** * Injected dataset repository. */ @Inject protected DatasetRepository datasetRepository; /** * Injected sensor repository. */ @Inject private SensorRepository sensorRepository; /** * Injected metadata repository. */ @Inject protected IMetadataBusiness metadataBusiness; /** * Injected lucene index engine. */ @Inject protected IndexEngine indexEngine; /** * Injected data coverage job */ @Inject private IDataCoverageJob dataCoverageJob; @Autowired(required = false) private IDataBusinessListener dataBusinessListener = new DefaultDataBusinessListener(); /** * Injected service repository. */ @Inject private ServiceRepository serviceRepository; /** * {@inheritDoc} */ @Override public Provider getProvider(int dataId) { final Data d = dataRepository.findById(dataId); return providerRepository.findOne(d.getProvider()); } /** * {@inheritDoc} */ @Override public DefaultMetadata loadIsoDataMetadata(final String providerId, final QName name) throws ConfigurationException { final Data data = dataRepository.findDataFromProvider(name.getNamespaceURI(), name.getLocalPart(), providerId); return metadataBusiness.getIsoMetadataForData(data.getId()); } @Override public Dataset getDatasetForData(final String providerId, final QName name) throws ConstellationException{ final Data data = dataRepository.findDataFromProvider(name.getNamespaceURI(), name.getLocalPart(), providerId); if (data != null && data.getDatasetId() != null) { return datasetRepository.findById(data.getDatasetId()); } return null; } @Override public Dataset getDatasetForData(final int dataId) throws ConstellationException{ final Data data = dataRepository.findById(dataId); if (data != null && data.getDatasetId() != null) { return datasetRepository.findById(data.getDatasetId()); } return null; } /** * {@inheritDoc} */ @Override public List<Data> searchOnMetadata(final String query) throws IOException, ConstellationException { final List<Data> result = new ArrayList<>(); final Set<Integer> ids; try { ids = indexEngine.searchOnMetadata(query, "dataId"); } catch( ParseException ex) { throw new ConstellationException(ex); } for (final Integer dataId : ids){ final Data d = dataRepository.findById(dataId); if(d!=null){ result.add(d); } } return result; } /** * {@inheritDoc} */ @Override public CoverageMetadataBean loadDataMetadata(final String providerId, final QName name, final MarshallerPool pool) throws ConstellationException { try { final Data data = dataRepository.findDataFromProvider(name.getNamespaceURI(), name.getLocalPart(), providerId); if (data != null && data.getMetadata() != null) { final InputStream sr = new ByteArrayInputStream(data.getMetadata().getBytes()); final Unmarshaller m = pool.acquireUnmarshaller(); final CoverageMetadataBean metadata = (CoverageMetadataBean) m.unmarshal(sr); pool.recycle(m); return metadata; } } catch (JAXBException ex) { LOGGER.warn("An error occurred while updating service database", ex); throw new ConstellationException(ex); } return null; } /** * {@inheritDoc} */ @Override public DataBrief getDataBrief(QName dataName,Integer providerId) throws ConstellationException { final Data data = dataRepository.findByNameAndNamespaceAndProviderId(dataName.getLocalPart(), dataName.getNamespaceURI(), providerId); final List<Data> datas = new ArrayList<>(); datas.add(data); final List<DataBrief> dataBriefs = getDataBriefFrom(datas); if (dataBriefs != null && dataBriefs.size() == 1) { return dataBriefs.get(0); } throw new ConstellationException(new Exception("Problem : DataBrief Construction is null or multiple")); } /** * {@inheritDoc} */ @Override public DataBrief getDataBrief(final QName fullName, final String providerIdentifier) throws ConstellationException { final Data data = dataRepository.findDataFromProvider(fullName.getNamespaceURI(), fullName.getLocalPart(), providerIdentifier); final List<Data> datas = new ArrayList<>(); if (data != null) { datas.add(data); final List<DataBrief> dataBriefs = getDataBriefFrom(datas); if (dataBriefs != null && dataBriefs.size() == 1) { return dataBriefs.get(0); } } throw new ConstellationException(new Exception("Problem : DataBrief Construction is null or multiple")); } /** * {@inheritDoc} */ @Override public List<DataBrief> getDataBriefsFromMetadataId(final String metadataId) { final List<Data> datas = findByMetadataId(metadataId); return getDataBriefFrom(datas); } /** * {@inheritDoc} */ @Override public DataBrief getDataLayer(final String layerAlias, final String providerId) throws ConstellationException { final Data data = layerRepository.findDatasFromLayerAlias(layerAlias, providerId); final List<Data> datas = new ArrayList<>(); datas.add(data); final List<DataBrief> dataBriefs = getDataBriefFrom(datas); if (dataBriefs != null && !dataBriefs.isEmpty()){ return dataBriefs.get(0); } throw new ConstellationException(new Exception("Problem : DataBrief Construction is null or multiple")); } /** * {@inheritDoc} */ @Override public List<Data> findByDatasetId(final Integer datasetId) { return dataRepository.findByDatasetId(datasetId); } /** * {@inheritDoc} */ @Override public List<DataBrief> getDataBriefsFromDatasetId(final Integer datasetId) { final List<Data> dataList = findByDatasetId(datasetId); return getDataBriefFrom(dataList); } /** * {@inheritDoc} */ @Override public List<Data> findByStyleId(final Integer styleId) { return dataRepository.getFullDataByLinkedStyle(styleId); } /** * {@inheritDoc} */ @Override public List<DataBrief> getDataBriefsFromStyleId(final Integer styleId) { final List<Data> dataList = dataRepository.getRefDataByLinkedStyle(styleId); if (dataList != null) { return getDataBriefFrom(dataList); } return new ArrayList<>(); } /** * {@inheritDoc} */ @Override public List<DataBrief> getDataRefsFromStyleId(final Integer styleId) { final List<Data> dataList = dataRepository.getRefDataByLinkedStyle(styleId); if (dataList != null) { return toDataRef(dataList); } return new ArrayList<>(); } /** * Returns a list of {@link Data} for given metadata identifier. * @param metadataId given metadata identifier. * @return list of {@link Data}. */ private List<Data> findByMetadataId(final String metadataId) { List<Data> dataResult = new ArrayList<>(); final Dataset dataset = datasetRepository.findByMetadataId(metadataId); final Data data = dataRepository.findByMetadataId(metadataId); final Service service = serviceRepository.findByMetadataId(metadataId); if (dataset != null){ dataResult = dataRepository.findByDatasetId(dataset.getId()); } else if (service!= null) { dataResult = serviceRepository.findDataByServiceId(service.getId()); } else if (data != null) { dataResult.add(data); } return dataResult; } /** * Convert a Data to DataBrief using only fields : * <ul> * <li>id</li> * <li>name</li> * <li>namespace</li> * <li>provider</li> * <li>type</li> * <li>subtype</li> * </ul> * @param dataList data to convert * @return */ protected List<DataBrief> toDataRef(List<Data> dataList) { final List<DataBrief> dataBriefs = new ArrayList<>(); for (final Data data : dataList) { final String providerId = getProviderIdentifier(data.getProvider()); final DataBrief db = new DataBrief(); db.setId(data.getId()); db.setName(data.getName()); db.setNamespace(data.getNamespace()); db.setProvider(providerId); db.setType(data.getType()); db.setSubtype(data.getSubtype()); dataBriefs.add(db); } return dataBriefs; } /** * Convert a list of {@link Data} to list of {@link DataBrief}. * @param datas given list of {@link Data}. * @return the list of {@link DataBrief}. */ protected List<DataBrief> getDataBriefFrom(final List<Data> datas) { final List<DataBrief> dataBriefs = new ArrayList<>(); for (final Data data : datas) { final List<Style> styles = styleRepository.findByData(data); final DataBrief db = new DataBrief(); db.setId(data.getId()); final Optional<CstlUser> user = userRepository.findById(data.getOwner()); if (user != null && user.isPresent()) { final CstlUser cstlUser = user.get(); if(cstlUser!=null){ db.setOwner(cstlUser.getLogin()); } } final String providerId = getProviderIdentifier(data.getProvider()); db.setName(data.getName()); db.setNamespace(data.getNamespace()); db.setDate(new Date(data.getDate())); db.setProvider(providerId); db.setDatasetId(data.getDatasetId()); db.setType(data.getType()); db.setSubtype(data.getSubtype()); db.setSensorable(data.getSensorable()); db.setTargetSensor(sensorRepository.getLinkedSensors(data)); db.setStatsResult(data.getStatsResult()); db.setStatsState(data.getStatsState()); db.setRendered(data.getRendered()); db.setMdCompletion(metadataBusiness.getCompletionForData(data.getId())); final List<Data> linkedDataList = getDataLinkedData(data.getId()); for(final Data d : linkedDataList){ if("pyramid".equalsIgnoreCase(d.getSubtype()) && !d.getRendered()){ final String pyramidProvId = getProviderIdentifier(d.getProvider()); db.setPyramidConformProviderId(pyramidProvId); break; } } //if the data is a pyramid itself. we need to fill the property to enable the picto of pyramided data. if("pyramid".equalsIgnoreCase(data.getSubtype()) && !data.getRendered()){ db.setPyramidConformProviderId(providerId); } final List<StyleBrief> styleBriefs = new ArrayList<>(0); for (final Style style : styles) { final StyleBrief sb = new StyleBrief(); sb.setId(style.getId()); sb.setType(style.getType()); sb.setProvider(getProviderIdentifier(style.getProvider())); sb.setDate(new Date(style.getDate())); sb.setName(style.getName()); final Optional<CstlUser> userStyle = userRepository.findById(style.getOwner()); if (userStyle!=null && userStyle.isPresent()) { final CstlUser cstlUser = userStyle.get(); if(cstlUser!=null){ sb.setOwner(cstlUser.getLogin()); } } styleBriefs.add(sb); } db.setTargetStyle(styleBriefs); final List<Service> services = serviceRepository.findByDataId(data.getId()); for(final Data d : linkedDataList){ final List<Service> servicesLinked = serviceRepository.findByDataId(d.getId()); services.addAll(servicesLinked); } // add csw link //use HashSet to avoid duplicated objects. final Set<ServiceProtocol> serviceProtocols = new HashSet<>(); for (final Service service : services) { final List<String> protocol = new ArrayList<>(); final ServiceDef.Specification spec = ServiceDef.Specification.valueOf(service.getType().toUpperCase()); protocol.add(spec.name()); protocol.add(spec.fullName); final ServiceProtocol sp = new ServiceProtocol(service.getIdentifier(), protocol); serviceProtocols.add(sp); } db.setTargetService(new ArrayList<>(serviceProtocols)); dataBriefs.add(db); } return dataBriefs; } /** * Returns provider identifier for given provider id. * @param providerId given provider id. * @return provider identifier as string. */ private String getProviderIdentifier(final int providerId) { return providerRepository.findOne(providerId).getIdentifier(); } /** * {@inheritDoc} */ @Override @Transactional public void missingData(final QName name, final String providerIdentifier) throws ConfigurationException { final Provider provider = providerRepository.findByIdentifier(providerIdentifier); if (provider != null) { final Data data = dataRepository.findByNameAndNamespaceAndProviderId(name.getLocalPart(), name.getNamespaceURI(), provider.getId()); if (data != null) { // remove data metadata from index indexEngine.removeDataMetadataFromIndex(data.getId()); // delete data entry metadataBusiness.deleteDataMetadata(data.getId()); dataBusinessListener.preDataDelete(data); dataRepository.delete(data.getId()); dataBusinessListener.postDataDelete(data); // Relevant erase dataset when the is no more data in it. fr now we remove it deleteDatasetIfEmpty(data.getDatasetId()); } } } protected void deleteDatasetIfEmpty(Integer datasetID) throws ConfigurationException { if (datasetID != null) { List<Data> datas = dataRepository.findAllByDatasetId(datasetID); if (datas.isEmpty()) { indexEngine.removeDatasetMetadataFromIndex(datasetID); metadataBusiness.deleteDatasetMetadata(datasetID); datasetRepository.remove(datasetID); } } } /** * {@inheritDoc} */ @Override @Transactional public void removeData(Integer dataId) throws ConfigurationException { final List<Data> linkedDataList = getDataLinkedData(dataId); for(final Data d : linkedDataList){ updateDataIncluded(d.getId(), false); } updateDataIncluded(dataId, false); } /** * {@inheritDoc} */ @Override @Transactional public void deleteAll() throws ConfigurationException { final List<Data> datas = dataRepository.findAll(); for (final Data data : datas) { indexEngine.removeDataMetadataFromIndex(data.getId()); metadataBusiness.deleteDataMetadata(data.getId()); dataBusinessListener.preDataDelete(data); dataRepository.delete(data.getId()); dataBusinessListener.postDataDelete(data); // Relevant erase dataset when the is no more data in it. fr now we remove it deleteDatasetIfEmpty(data.getDatasetId()); } } /** * {@inheritDoc} */ @Override @Transactional public Data create(final QName name, final String providerIdentifier, final String type, final boolean sensorable, final boolean included, final String subType, final String metadataXml) { return create(name, providerIdentifier, type, sensorable, included, null, subType, metadataXml); } /** * {@inheritDoc} */ @Override @Transactional public Data create(QName name, String providerIdentifier, String type, boolean sensorable, boolean included, Boolean rendered, String subType, String metadataXml) { final Provider provider = providerRepository.findByIdentifier(providerIdentifier); if (provider != null) { Data data = new Data(); data.setDate(new Date().getTime()); data.setName(name.getLocalPart()); data.setNamespace(name.getNamespaceURI()); final Optional<CstlUser> user = userRepository.findOne(securityManager.getCurrentUserLogin()); if (user.isPresent()) { data.setOwner(user.get().getId()); } data.setProvider(provider.getId()); data.setSensorable(sensorable); data.setType(type); data.setSubtype(subType); data.setIncluded(included); data.setMetadata(metadataXml); data.setRendered(rendered); data = dataRepository.create(data); dataBusinessListener.postDataCreate(data); return data; } return null; } /** * {@inheritDoc} */ @Override @Transactional public void updateDataIncluded(final int dataId, boolean included) throws ConfigurationException { final Data data = dataRepository.findById(dataId); data.setIncluded(included); dataRepository.update(data); final int providerID = data.getProvider(); final int dataID = data.getId(); if (!included) { // 1. remove layer involving the data for (Layer layer : layerRepository.findByDataId(dataID)) { layerRepository.delete(layer.getId()); } // 2. unlink from csw dataRepository.removeDataFromAllCSW(dataID); // 3. cleanup provider if empty boolean remove = true; List<Data> providerData = dataRepository.findByProviderId(providerID); for (Data pdata : providerData) { if (pdata.getIncluded()) { remove = false; break; } } if (remove) { //notify pre delete for (Data pdata : providerData) { dataBusinessListener.preDataDelete(pdata); // remove metadata metadataBusiness.deleteDataMetadata(pdata.getId()); } final Provider p = providerRepository.findOne(providerID); final DataProvider dp = DataProviders.getInstance().getProvider(p.getIdentifier()); DataProviders.getInstance().removeProvider(dp); providerRepository.delete(providerID); //notify post delete for (Data pdata : providerData) { dataBusinessListener.postDataDelete(pdata); } // delete associated files in integrated folder. the file name (p.getIdentifier()) is a folder. final File provDir = ConfigDirectory.getDataIntegratedDirectory(p.getIdentifier()); FileUtilities.deleteDirectory(provDir); } // Relevant erase dataset when there is no more data in it. for now we remove it deleteDatasetIfEmpty(data.getDatasetId()); } } /** * {@inheritDoc} */ @Override @Transactional public synchronized void removeDataFromProvider(final String providerId) throws ConfigurationException { final Provider p = providerRepository.findByIdentifier(providerId); if (p != null) { final List<Data> datas = dataRepository.findByProviderId(p.getId()); for (final Data data : datas) { indexEngine.removeDataMetadataFromIndex(data.getId()); dataBusinessListener.preDataDelete(data); metadataBusiness.deleteDataMetadata(data.getId()); dataRepository.delete(data.getId()); dataBusinessListener.postDataDelete(data); // Relevant erase dataset when the is no more data in it. fr now we remove it deleteDatasetIfEmpty( data.getDatasetId()); } } } @Override public ParameterValues getVectorDataColumns(int id) throws DataStoreException { final Provider provider = getProvider(id); final DataProvider dataProvider = DataProviders.getInstance().getProvider(provider.getIdentifier()); if (!(dataProvider.getMainStore() instanceof FeatureStore)) { throw new DataStoreException("Not a vector data requested"); } final List<String> colNames = new ArrayList<>(); final String dataName = dataRepository.findById(id).getName(); final FeatureStore store = (FeatureStore) dataProvider.getMainStore(); final org.opengis.feature.FeatureType ft = store.getFeatureType(dataName); for (final PropertyType prop : ft.getProperties(true)) { colNames.add(prop.getName().toString()); } final ParameterValues values = new ParameterValues(); final HashMap<String, String> mapVals = new HashMap<>(); for (final String colName : colNames) { mapVals.put(colName, colName); } values.setValues(mapVals); return values; } @Override @Transactional public void updateMetadata(String providerId, QName dataName, DefaultMetadata metadata) throws ConfigurationException { final Data data = dataRepository.findDataFromProvider(dataName.getNamespaceURI(), dataName.getLocalPart(), providerId); if (data != null) { metadataBusiness.updateMetadata(metadata.getFileIdentifier(), metadata, data.getId(), null, null); indexEngine.addMetadataToIndexForData(metadata, data.getId()); } else { throw new TargetNotFoundException("Data :" + dataName + " in provider:" + providerId + " not found"); } } /** * {@inheritDoc} */ @Override public ImageStatistics getDataStatistics(final int dataId) throws ConfigurationException { final Data data = dataRepository.findById(dataId); if (data != null && DataType.COVERAGE.name().equals(data.getType()) && (data.getRendered() == null || !data.getRendered())) { try { final String state = data.getStatsState(); final String result = data.getStatsResult(); if (state != null) { switch (state) { case "PARTIAL" : //fall through case "COMPLETED" : return deserializeImageStatistics(result); case "PENDING" : return null; case "ERROR" : //can have partial statistics even if an error occurs. if (result != null && result.startsWith("{")) { return deserializeImageStatistics(result); } else { return null; } } } } catch (IOException e) { throw new ConfigurationException("Invalid statistic JSON format for data : "+dataId, e); } } return null; } private ImageStatistics deserializeImageStatistics(String state) throws IOException { final ObjectMapper mapper = new ObjectMapper(); final SimpleModule module = new SimpleModule(); module.addDeserializer(ImageStatistics.class, new ImageStatisticDeserializer()); //custom deserializer mapper.registerModule(module); return mapper.readValue(state, ImageStatistics.class); } /** * {@inheritDoc} */ @Override public Data findById(final Integer id) throws ConfigurationException { return dataRepository.findById(id); } /** * {@inheritDoc} */ public Integer getCountAll(boolean includeInvisibleData) { return dataRepository.countAll(includeInvisibleData); } /** * {@inheritDoc} */ @Override @Scheduled(cron = "1 * * * * *") public void updateDataStatistics() { String propertyValue = Application.getProperty(AppProperty.DATA_AUTO_ANALYSE); boolean doAnalysis = propertyValue == null ? false : Boolean.valueOf(propertyValue); if (doAnalysis) { computeEmptyDataStatistics(false); } } /** * {@inheritDoc} */ @Override public void computeEmptyDataStatistics(boolean isInit) { final List<Data> dataList = dataRepository.findStatisticLess(); List<Integer> dataWithoutStats = new ArrayList<>(); for (final Data data : dataList) { //compute statistics only on coverage data not rendered and without previous statistic computed. if (DataType.COVERAGE.name().equals(data.getType()) && !"pyramid".equalsIgnoreCase(data.getSubtype()) && (data.getRendered() == null || !data.getRendered())) { String state = data.getStatsState(); if (isInit) { //rerun statistic for error and pending states if ("PENDING".equalsIgnoreCase(state) || "ERROR".equalsIgnoreCase(state)) { data.setStatsState(null); data.setStatsResult(null); SpringHelper.executeInTransaction(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) { dataRepository.update(data); } }); dataWithoutStats.add(data.getId()); } } if (state == null || state.isEmpty()) { dataWithoutStats.add(data.getId()); } } } for (Integer dataId : dataWithoutStats) { dataCoverageJob.asyncUpdateDataStatistics(dataId); } } /** * {@inheritDoc } */ @Override @Transactional public void updateDataRendered(final QName fullName, final String providerIdentifier, boolean isRendered) { final Data data = dataRepository.findDataFromProvider(fullName.getNamespaceURI(), fullName.getLocalPart(), providerIdentifier); data.setRendered(isRendered); dataRepository.update(data); } /** * {@inheritDoc } */ @Override @Transactional public void updateDataDataSetId(final QName fullName, final String providerIdentifier, final Integer datasetId) { final Data data = dataRepository.findDataFromProvider(fullName.getNamespaceURI(), fullName.getLocalPart(), providerIdentifier); data.setDatasetId(datasetId); dataRepository.update(data); } /** * {@inheritDoc } */ @Override @Transactional public void updateHidden(final int dataId, boolean value) { final Data data = dataRepository.findById(dataId); data.setHidden(value); dataRepository.update(data); } @Override //FIXME RESTORE cleaning mechanism @Scheduled(fixedDelay=5*60*1000) public void uploadCleaner() { LOGGER.debug("Cleaner"); java.nio.file.Path uploadDirectory = ConfigDirectory.getUploadDirectory(); File[] listFiles = uploadDirectory.toFile().listFiles(); if (listFiles != null) { for (File file : listFiles) { if (TokenUtils.isExpired(file.getName())) { LOGGER.info(file.getName() + " expired"); FileUtilities.deleteDirectory(file); } } } } /** * {@inheritDoc } */ @Override public List<FileBean> getFilesFromPath(final String path, final boolean filtered, final boolean onlyXML) throws ConstellationException { final List<FileBean> listBean = new ArrayList<>(); final Set<String> extensions = GeotoolkitFileExtensionAvailable.getAvailableFileExtension().keySet(); final File[] children; if (Paths.get(path).toFile().exists()) { final File nextRoot = new File(path); children = nextRoot.listFiles(); }else{ throw new ConstellationException("path does not exists!"); } //loop on subfiles/folders to create bean if (children != null) { for (final File child : children) { final FileBean bean = new FileBean(child.getName(), child.isDirectory(), child.getAbsolutePath(), child.getParentFile().getAbsolutePath()); if (!child.isDirectory() || !filtered) { final int lastIndexPoint = child.getName().lastIndexOf('.'); final String extension = child.getName().substring(lastIndexPoint + 1); if(onlyXML) { if ("xml".equalsIgnoreCase(extension)) { listBean.add(bean); } }else { if (extensions.contains(extension.toLowerCase())) { listBean.add(bean); } } } else { listBean.add(bean); } } } Collections.sort(listBean); return listBean; } @Transactional @Override public void linkDataToData(final int dataId, final int childId) { dataRepository.linkDataToData(dataId, childId); } @Transactional @Override public List<Data> getDataLinkedData(final int dataId){ return dataRepository.getDataLinkedData(dataId); } @Override public List<DataItem> fetchByDatasetId(int datasetId) { return dataRepository.fetchByDatasetId(datasetId); } @Override public List<DataItem> fetchByDatasetIds(Collection<Integer> datasetIds) { return dataRepository.fetchByDatasetIds(datasetIds); } @Override public boolean existsById(int dataId) { return dataRepository.existsById(dataId); } }