net.di2e.ecdr.search.transform.atom.AtomTransformerWithPayload.java Source code

Java tutorial

Introduction

Here is the source code for net.di2e.ecdr.search.transform.atom.AtomTransformerWithPayload.java

Source

/**
 * Copyright (C) 2014 Cohesive Integrations, LLC (info@cohesiveintegrations.com)
 *
 * 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 net.di2e.ecdr.search.transform.atom;

import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.io.StringReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.activation.MimeType;

import net.di2e.ecdr.api.security.SecurityConfiguration;
import net.di2e.ecdr.commons.CDRMetacard;
import net.di2e.ecdr.commons.constants.SearchConstants;

import org.apache.abdera.Abdera;
import org.apache.abdera.model.Entry;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ddf.action.ActionProvider;
import ddf.catalog.Constants;
import ddf.catalog.data.BinaryContent;
import ddf.catalog.data.Metacard;
import ddf.catalog.transform.CatalogTransformerException;
import ddf.catalog.transform.MetacardTransformer;

public class AtomTransformerWithPayload extends AtomTransformer {

    private static final String TRANSFORMER_ID = "atom-with-payload";

    private static final Logger LOGGER = LoggerFactory.getLogger(AtomTransformerWithPayload.class);

    private Map<String, MetacardTransformer> metacardTransformerMap = null;

    public AtomTransformerWithPayload(ActionProvider viewMetacardProvider, ActionProvider metadataProvider,
            ActionProvider resourceProvider, ActionProvider thumbnailProvider, MimeType thumbnailMime,
            MimeType viewMime, List<SecurityConfiguration> securityConfig) {
        super(viewMetacardProvider, metadataProvider, resourceProvider, thumbnailProvider, thumbnailMime, viewMime,
                securityConfig);
        metacardTransformerMap = new HashMap<String, MetacardTransformer>();
    }

    @Override
    public void addEntryElements(Entry entry, CDRMetacard metacard, Map<String, Serializable> properties) {
        // Abdera.getParser() spins up a new thread so must do this
        ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
        try {
            Thread.currentThread().setContextClassLoader(AtomTransformerWithPayload.class.getClassLoader());
            String metadata = getMetadataXML(metacard,
                    (String) properties.get(SearchConstants.METACARD_TRANSFORMER_NAME));
            entry.addExtension(Abdera.getNewParser().parse(new StringReader(metadata)).getRoot());
            CDRMetacard newMetacard = new CDRMetacard(metacard);
            newMetacard.setMetadata(metadata);

            setEntrySecurity(entry, newMetacard);
        } finally {
            Thread.currentThread().setContextClassLoader(currentClassLoader);
        }
    }

    /**
     * Method responsible for getting the metadata XML String that is associated
     * with the Metacard. The metadata is retrieved by calling the
     * MetadataTransformer that is registered with the id that matches the
     * format String that is passed into the method. If a MetacardTransformer
     * doesn't exist, or the result of the Transform is not XML, or if there is
     * an error while transforming, the Metacard.METADATA will be returned
     * 
     * @param metacard
     *            the Metacard to get the Metacard from
     * @param format
     *            the format of the MetacardTransformer to use (which is looked
     *            up by MetacardTransformer id)
     * @return the XML String
     */
    protected String getMetadataXML(Metacard metacard, String format) {
        String metadata = null;
        LOGGER.debug(
                "Getting metadata to include in atom response in the format [{}] from metacardTransformerMap {}",
                format, metacardTransformerMap.keySet());
        if (StringUtils.isNotBlank(format)) {
            MetacardTransformer metacardTransformer = metacardTransformerMap.get(format);
            if (metacardTransformer != null) {
                try {
                    LOGGER.debug(
                            "Calling the MetacardTransformer with id [{}] to transform the Metacard into XML Metadata",
                            format);
                    BinaryContent binaryContent = metacardTransformer.transform(metacard, null);
                    String mimeValue = binaryContent.getMimeTypeValue();
                    if (StringUtils.isNotBlank(mimeValue) && mimeValue.contains("xml")) {
                        try (InputStream inputStream = binaryContent.getInputStream()) {
                            metadata = IOUtils.toString(inputStream);
                        } catch (IOException e) {
                            LOGGER.warn("Error while writing transformed Metacard into a String: " + e.getMessage(),
                                    e);
                        }
                    }
                } catch (CatalogTransformerException e) {
                    LOGGER.warn("Error while transforming metacard using the [{}] MetacardTransformer", format);
                    LOGGER.warn(e.getMessage(), e);
                }
            }
        }
        if (metadata == null) {
            LOGGER.debug(
                    "A MetacardTransform didn't exist for format [{}] or ran into problems when transforming Metacard, so falling back to using the Metadata in the Metacard",
                    format);
            metadata = metacard.getMetadata();

        }
        LOGGER.trace("Atom Transformer setting Metacard.METADATA to:{}{}", System.lineSeparator(), metadata);
        return metadata;
    }

    /**
     * Method called by the OSGi container, managed by blueprint whenever a new
     * MetacardTransformer service is exposed to the OSGi Registry
     * 
     * @param transformer
     *            the MetacardTransformer that was added
     * @param map
     *            the service properties for the corresponding
     *            MetacardTransformer
     */
    public void metacardTransformerAdded(MetacardTransformer transformer, Map<String, Object> map) {
        String id = (String) map.get(Constants.SERVICE_ID);
        // We need to filter out this transformer from being included in the
        // Metacard Transformers used to produce metadata records
        if (!StringUtils.equalsIgnoreCase(id, TRANSFORMER_ID)) {
            metacardTransformerMap.put(id, transformer);
            LOGGER.debug("Adding MetacardTransformer with id [{}] to transformer map.", id);
        }
    }

    /**
     * Method is called when a MetacardTransformer is removed from the OSGi
     * registry (called by OSGi container, managed by blueprint)
     * 
     * @param transformer
     *            the MetacardTransformer service that was removed
     * @param map
     *            the service properties for the corresponding
     *            MetacardTransformer
     */
    public void metacardTransformerRemoved(MetacardTransformer transformer, Map<String, Object> map) {
        String id = (String) map.get(Constants.SERVICE_ID);
        metacardTransformerMap.remove(id);
        LOGGER.debug("Removing MetacardTransformer with id [{}] from transformer map.", id);
    }
}