/*
* 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.metadata.io.internal;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Map;
import javax.inject.Inject;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.stream.XMLInputFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.constellation.admin.SpringHelper;
import org.constellation.business.IMetadataBusiness;
import org.constellation.configuration.ConfigurationException;
import org.constellation.database.api.jooq.tables.pojos.Metadata;
import org.constellation.generic.database.Automatic;
import org.constellation.metadata.io.AbstractMetadataWriter;
import org.constellation.metadata.io.MetadataIoException;
import org.constellation.metadata.utils.Utils;
import org.geotoolkit.lucene.index.AbstractIndexer;
import static org.geotoolkit.ows.xml.OWSExceptionCode.NO_APPLICABLE_CODE;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
*
* @author Guilhem Legal (Geomatys)
*/
public class InternalMetadataWriter extends AbstractMetadataWriter {
private final boolean displayServiceMetadata = false;
@Inject
protected IMetadataBusiness metadataBusiness;
/**
* An indexer lucene to add object into the index.
*/
protected final AbstractIndexer indexer;
protected boolean partial = false;
private boolean onlyPublished = false;
protected final String id;
protected final DocumentBuilderFactory dbf;
protected final XMLInputFactory xif = XMLInputFactory.newFactory();
public InternalMetadataWriter(final Automatic configuration, final AbstractIndexer indexer, final String serviceID) throws MetadataIoException {
SpringHelper.injectDependencies(this);
this.indexer = indexer;
if (configuration.getCustomparameters().containsKey("partial")) {
this.partial = Boolean.parseBoolean(configuration.getParameter("partial"));
}
if (configuration.getCustomparameters().containsKey("onlyPublished")) {
this.onlyPublished = Boolean.parseBoolean(configuration.getParameter("onlyPublished"));
}
this.id = serviceID;
dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
}
@Override
public boolean storeMetadata(Node original) throws MetadataIoException {
final String identifier = Utils.findIdentifier(original);
try {
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
StringWriter sw = new StringWriter();
StreamResult sr = new StreamResult(sw);
transformer.transform(new DOMSource(original),sr);
if (indexer != null) {
indexer.removeDocument(identifier);
indexer.indexDocument(original);
}
metadataBusiness.updateMetadata(identifier, sw.toString());
metadataBusiness.linkMetadataIDToCSW(identifier, id);
return true;
} catch (TransformerException | ConfigurationException ex) {
throw new MetadataIoException("Unable to write the file.", ex, NO_APPLICABLE_CODE);
}
}
@Override
public boolean deleteMetadata(String metadataID) throws MetadataIoException {
if (partial) {
metadataBusiness.unlinkMetadataIDToCSW(metadataID, id);
return true;
} else {
throw new MetadataIoException("The delete is not supported in internal metadata.");
}
}
@Override
public boolean isAlreadyUsedIdentifier(String metadataID) throws MetadataIoException {
return metadataBusiness.existInternalMetadata(metadataID, true, false);
}
@Override
public boolean replaceMetadata(String metadataID, Node any) throws MetadataIoException {
return storeMetadata(any);
}
@Override
public boolean deleteSupported() {
return false;
}
@Override
public boolean updateSupported() {
return true;
}
@Override
public void destroy() {
if (indexer != null) {
indexer.destroy();
}
}
@Override
public boolean updateMetadata(String metadataID, Map<String, Object> properties) throws MetadataIoException {
throw new MetadataIoException("The update by properties is not supported in internal metadata.");
}
@Override
public boolean canImportInternalData() {
return partial;
}
@Override
public void linkInternalMetadata(final String metadataID) throws MetadataIoException {
final Metadata metadata = metadataBusiness.searchFullMetadata(metadataID, true, false);
if (metadata != null) {
if (displayServiceMetadata ||
(!displayServiceMetadata && metadata.getServiceId() == null) ||
!onlyPublished ||
(onlyPublished && metadata.getIsPublished())) {
try {
final InputSource source = new InputSource(new StringReader(metadata.getMetadataIso()));
final DocumentBuilder docBuilder = dbf.newDocumentBuilder();
final Document document = docBuilder.parse(source);
final Node n = document.getDocumentElement();
if (indexer != null) {
indexer.removeDocument(metadataID);
indexer.indexDocument(n);
}
} catch (SAXException | IOException | ParserConfigurationException ex) {
throw new MetadataIoException(ex);
}
}
try {
metadataBusiness.linkMetadataIDToCSW(metadataID, id);
} catch (ConfigurationException ex) {
throw new MetadataIoException(ex);
}
}
}
}