Search in sources :

Example 26 with BinaryContentImpl

use of ddf.catalog.data.impl.BinaryContentImpl in project ddf by codice.

the class AtomTransformer method transform.

@Override
public BinaryContent transform(SourceResponse sourceResponse, Map<String, Serializable> arguments) throws CatalogTransformerException {
    if (sourceResponse == null) {
        throw new CatalogTransformerException("Cannot transform null " + SourceResponse.class.getName());
    }
    Date currentDate = new Date();
    ClassLoader tccl = Thread.currentThread().getContextClassLoader();
    Feed feed = null;
    try {
        Thread.currentThread().setContextClassLoader(AtomTransformer.class.getClassLoader());
        feed = ABDERA.newFeed();
    } finally {
        Thread.currentThread().setContextClassLoader(tccl);
    }
    /*
         * Atom spec text (rfc4287) Sect 4.2.14: "The "atom:title" element is a Text construct that
         * conveys a human- readable title for an entry or feed."
         */
    feed.setTitle(DEFAULT_FEED_TITLE);
    feed.setUpdated(currentDate);
    // TODO Use the same id for the same query
    // one challenge is a query in one site should not have the same feed id
    // as a query in another site probably could factor in ddf.host and port
    // into the algorithm
    feed.setId(URN_UUID + UUID.randomUUID().toString());
    // TODO SELF LINK For the Feed, possible design --> serialize Query into
    // a URL
    /*
         * Atom spec text (rfc4287): "atom:feed elements SHOULD contain one atom:link element with a
         * rel attribute value of self. This is the preferred URI for retrieving Atom Feed Documents
         * representing this Atom feed. "
         */
    feed.addLink("#", Link.REL_SELF);
    if (!StringUtils.isEmpty(SystemInfo.getOrganization())) {
        feed.addAuthor(SystemInfo.getOrganization());
    } else {
        feed.addAuthor(DEFAULT_AUTHOR);
    }
    /*
         * Atom spec text (rfc4287 sect. 4.2.4): "The "atom:generator" element's content identifies
         * the agent used to generate a feed, for debugging and other purposes." Generator is not
         * required in the atom:feed element.
         */
    if (!StringUtils.isEmpty(SystemInfo.getSiteName())) {
        // text is required.
        feed.setGenerator(null, SystemInfo.getVersion(), SystemInfo.getSiteName());
    }
    /*
         * According to http://www.opensearch.org/Specifications/OpenSearch/1.1 specification,
         * totalResults must be a non-negative integer. Requirements: This attribute is optional.
         */
    if (sourceResponse.getHits() > -1) {
        Element hits = feed.addExtension(OpenSearchConstants.TOTAL_RESULTS);
        hits.setText(Long.toString(sourceResponse.getHits()));
    }
    if (sourceResponse.getRequest() != null && sourceResponse.getRequest().getQuery() != null) {
        Element itemsPerPage = feed.addExtension(OpenSearchConstants.ITEMS_PER_PAGE);
        Element startIndex = feed.addExtension(OpenSearchConstants.START_INDEX);
        /*
             * According to http://www.opensearch.org/Specifications/OpenSearch/1.1 specification,
             * itemsPerPage must be a non-negative integer. It is possible that Catalog pageSize is
             * set to a non-negative integer though. When non-negative we will instead we will
             * change it to the number of search results on current page.
             */
        if (sourceResponse.getRequest().getQuery().getPageSize() > -1) {
            itemsPerPage.setText(Integer.toString(sourceResponse.getRequest().getQuery().getPageSize()));
        } else {
            if (sourceResponse.getResults() != null) {
                itemsPerPage.setText(Integer.toString(sourceResponse.getResults().size()));
            }
        }
        startIndex.setText(Integer.toString(sourceResponse.getRequest().getQuery().getStartIndex()));
    }
    for (Result result : sourceResponse.getResults()) {
        Metacard metacard = result.getMetacard();
        if (metacard == null) {
            continue;
        }
        Entry entry = feed.addEntry();
        String sourceName = DEFAULT_SOURCE_ID;
        if (result.getMetacard().getSourceId() != null) {
            sourceName = result.getMetacard().getSourceId();
        }
        Element source = entry.addExtension(new QName(FEDERATION_EXTENSION_NAMESPACE, "resultSource", "fs"));
        /*
             * According to the os-federation.xsd, the resultSource element text has a max length of
             * 16 and is the shortname of the source id. Previously, we were duplicating the names
             * in both positions, but since we truly do not have a shortname for our source ids, I
             * am purposely omitting the shortname text and leaving it as the empty string. The real
             * source id can still be found in the attribute instead.
             */
        source.setAttributeValue(new QName(FEDERATION_EXTENSION_NAMESPACE, "sourceId"), sourceName);
        if (result.getRelevanceScore() != null) {
            Element relevance = entry.addExtension(new QName("http://a9.com/-/opensearch/extensions/relevance/1.0/", "score", "relevance"));
            relevance.setText(result.getRelevanceScore().toString());
        }
        entry.setId(URN_CATALOG_ID + metacard.getId());
        /*
             * Atom spec text (rfc4287): "The "atom:title" element is a Text construct that conveys
             * a human- readable title for an entry or feed."
             */
        entry.setTitle(metacard.getTitle());
        /*
             * Atom spec text (rfc4287): "The "atom:updated" element is a Date construct indicating
             * the most recent instant in time when an entry or feed was modified in a way the
             * publisher considers significant." Therefore, a new Date is used because we are making
             * the entry for the first time.
             */
        if (metacard.getModifiedDate() != null) {
            entry.setUpdated(metacard.getModifiedDate());
        } else {
            entry.setUpdated(currentDate);
        }
        /*
             * Atom spec text (rfc4287): "Typically, atom:published will be associated with the
             * initial creation or first availability of the resource."
             */
        if (metacard.getCreatedDate() != null) {
            entry.setPublished(metacard.getCreatedDate());
        }
        /*
             * For atom:link elements, Atom spec text (rfc4287): "The value "related" signifies that
             * the IRI in the value of the href attribute identifies a resource related to the
             * resource described by the containing element."
             */
        addLink(resourceActionProvider, metacard, entry, Link.REL_RELATED);
        addLink(viewMetacardActionProvider, metacard, entry, Link.REL_ALTERNATE);
        addLink(thumbnailActionProvider, metacard, entry, REL_PREVIEW);
        /*
             * Atom spec text (rfc4287) Sect. 4.2.2.: "The "atom:category" element conveys
             * information about a category associated with an entry or feed. This specification
             * assigns no meaning to the content (if any) of this element."
             */
        if (metacard.getContentTypeName() != null) {
            entry.addCategory(metacard.getContentTypeName());
        }
        for (Position position : getGeoRssPositions(metacard)) {
            GeoHelper.addPosition(entry, position, Encoding.GML);
        }
        BinaryContent binaryContent = null;
        String contentOutput = metacard.getId();
        Type atomContentType = Type.TEXT;
        if (metacardTransformer != null) {
            try {
                binaryContent = metacardTransformer.transform(metacard, new HashMap<>());
            } catch (CatalogTransformerException | RuntimeException e) {
                LOGGER.debug(COULD_NOT_CREATE_XML_CONTENT_MESSAGE, e);
            }
            if (binaryContent != null) {
                try {
                    byte[] xmlBytes = binaryContent.getByteArray();
                    if (xmlBytes != null && xmlBytes.length > 0) {
                        contentOutput = new String(xmlBytes, StandardCharsets.UTF_8);
                        atomContentType = Type.XML;
                    }
                } catch (IOException e) {
                    LOGGER.debug(COULD_NOT_CREATE_XML_CONTENT_MESSAGE, e);
                }
            }
        }
        tccl = Thread.currentThread().getContextClassLoader();
        try {
            Thread.currentThread().setContextClassLoader(AtomTransformer.class.getClassLoader());
            entry.setContent(contentOutput, atomContentType);
        } finally {
            Thread.currentThread().setContextClassLoader(tccl);
        }
    }
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    try {
        tccl = Thread.currentThread().getContextClassLoader();
        try {
            Thread.currentThread().setContextClassLoader(AtomTransformer.class.getClassLoader());
            feed.writeTo(baos);
        } finally {
            Thread.currentThread().setContextClassLoader(tccl);
        }
    } catch (IOException e) {
        LOGGER.info("Could not write to output stream.", e);
        throw new CatalogTransformerException("Could not transform into Atom.", e);
    }
    return new BinaryContentImpl(new ByteArrayInputStream(baos.toByteArray()), MIME_TYPE);
}
Also used : Position(org.apache.abdera.ext.geo.Position) HashMap(java.util.HashMap) QName(javax.xml.namespace.QName) Element(org.apache.abdera.model.Element) CatalogTransformerException(ddf.catalog.transform.CatalogTransformerException) IOException(java.io.IOException) ByteArrayOutputStream(org.apache.commons.io.output.ByteArrayOutputStream) BinaryContentImpl(ddf.catalog.data.impl.BinaryContentImpl) BinaryContent(ddf.catalog.data.BinaryContent) Date(java.util.Date) Result(ddf.catalog.data.Result) Metacard(ddf.catalog.data.Metacard) Entry(org.apache.abdera.model.Entry) MimeType(javax.activation.MimeType) Type(org.apache.abdera.model.Content.Type) ByteArrayInputStream(java.io.ByteArrayInputStream) Feed(org.apache.abdera.model.Feed)

Example 27 with BinaryContentImpl

use of ddf.catalog.data.impl.BinaryContentImpl in project ddf by codice.

the class TestCswQueryResponseTransformer method testMarshalAcknowledgementWithFailedTransforms.

@Test
public void testMarshalAcknowledgementWithFailedTransforms() throws WebApplicationException, IOException, JAXBException, CatalogTransformerException {
    GetRecordsType query = new GetRecordsType();
    query.setResultType(ResultType.RESULTS);
    query.setMaxRecords(BigInteger.valueOf(6));
    query.setStartPosition(BigInteger.valueOf(0));
    SourceResponse sourceResponse = createSourceResponse(query, 6);
    Map<String, Serializable> args = new HashMap<>();
    args.put(CswConstants.RESULT_TYPE_PARAMETER, ResultType.RESULTS);
    args.put(CswConstants.GET_RECORDS, query);
    PrintWriter printWriter = getSimplePrintWriter();
    MetacardTransformer mockMetacardTransformer = mock(MetacardTransformer.class);
    final AtomicLong atomicLong = new AtomicLong(0);
    when(mockMetacardTransformer.transform(any(Metacard.class), anyMap())).then(invocationOnMock -> {
        if (atomicLong.incrementAndGet() == 2) {
            throw new CatalogTransformerException("");
        }
        Metacard metacard = (Metacard) invocationOnMock.getArguments()[0];
        BinaryContentImpl bci = new BinaryContentImpl(IOUtils.toInputStream(metacard.getId() + ","), new MimeType("application/xml"));
        return bci;
    });
    when(mockPrintWriterProvider.build((Class<Metacard>) notNull())).thenReturn(printWriter);
    when(mockTransformerManager.getTransformerBySchema(anyString())).thenReturn(mockMetacardTransformer);
    CswQueryResponseTransformer cswQueryResponseTransformer = new CswQueryResponseTransformer(mockTransformerManager, mockPrintWriterProvider);
    cswQueryResponseTransformer.init();
    BinaryContent content = cswQueryResponseTransformer.transform(sourceResponse, args);
    cswQueryResponseTransformer.destroy();
    String xml = new String(content.getByteArray());
    assertThat(xml, containsString(CswQueryResponseTransformer.NUMBER_OF_RECORDS_MATCHED_ATTRIBUTE + " 6"));
    assertThat(xml, containsString(CswQueryResponseTransformer.NUMBER_OF_RECORDS_RETURNED_ATTRIBUTE + " 5"));
    assertThat(xml, containsString(CswQueryResponseTransformer.NEXT_RECORD_ATTRIBUTE + " 0"));
}
Also used : Serializable(java.io.Serializable) MetacardTransformer(ddf.catalog.transform.MetacardTransformer) SourceResponse(ddf.catalog.operation.SourceResponse) HashMap(java.util.HashMap) GetRecordsType(net.opengis.cat.csw.v_2_0_2.GetRecordsType) CatalogTransformerException(ddf.catalog.transform.CatalogTransformerException) Matchers.containsString(org.hamcrest.Matchers.containsString) Matchers.anyString(org.mockito.Matchers.anyString) BinaryContentImpl(ddf.catalog.data.impl.BinaryContentImpl) BinaryContent(ddf.catalog.data.BinaryContent) MimeType(javax.activation.MimeType) AtomicLong(java.util.concurrent.atomic.AtomicLong) Metacard(ddf.catalog.data.Metacard) PrintWriter(ddf.catalog.transformer.api.PrintWriter) Test(org.junit.Test)

Example 28 with BinaryContentImpl

use of ddf.catalog.data.impl.BinaryContentImpl in project ddf by codice.

the class KMLTransformerImpl method transform.

@Override
public BinaryContent transform(Metacard metacard, Map<String, Serializable> arguments) throws CatalogTransformerException {
    try {
        Placemark placemark = transformEntry(null, metacard, arguments);
        if (placemark.getStyleSelector().isEmpty() && StringUtils.isBlank(placemark.getStyleUrl())) {
            placemark.getStyleSelector().addAll(defaultStyle);
        }
        Kml kml = KmlFactory.createKml().withFeature(placemark);
        String transformedKmlString = marshalKml(kml);
        InputStream kmlInputStream = new ByteArrayInputStream(transformedKmlString.getBytes(StandardCharsets.UTF_8));
        return new BinaryContentImpl(kmlInputStream, KML_MIMETYPE);
    } catch (Exception e) {
        LOGGER.debug("Error transforming metacard ({}) to KML: {}", metacard.getId(), e.getMessage());
        throw new CatalogTransformerException("Error transforming metacard to KML.", e);
    }
}
Also used : Placemark(de.micromata.opengis.kml.v_2_2_0.Placemark) ByteArrayInputStream(java.io.ByteArrayInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) CatalogTransformerException(ddf.catalog.transform.CatalogTransformerException) Kml(de.micromata.opengis.kml.v_2_2_0.Kml) LineString(com.vividsolutions.jts.geom.LineString) BinaryContentImpl(ddf.catalog.data.impl.BinaryContentImpl) URISyntaxException(java.net.URISyntaxException) XMLStreamException(javax.xml.stream.XMLStreamException) ParseException(com.vividsolutions.jts.io.ParseException) JAXBException(javax.xml.bind.JAXBException) CatalogTransformerException(ddf.catalog.transform.CatalogTransformerException) MimeTypeParseException(javax.activation.MimeTypeParseException) IOException(java.io.IOException)

Example 29 with BinaryContentImpl

use of ddf.catalog.data.impl.BinaryContentImpl in project ddf by codice.

the class KMLTransformerImpl method transform.

@Override
public BinaryContent transform(SourceResponse upstreamResponse, Map<String, Serializable> arguments) throws CatalogTransformerException {
    LOGGER.trace("ENTERING: ResponseQueue transform");
    if (arguments == null) {
        LOGGER.debug("Null arguments, unable to complete transform");
        throw new CatalogTransformerException("Unable to complete transform without arguments");
    }
    String docId = UUID.randomUUID().toString();
    String restUriAbsolutePath = (String) arguments.get("url");
    LOGGER.debug("rest string url arg: {}", restUriAbsolutePath);
    // Transform Metacards to KML
    Document kmlDoc = KmlFactory.createDocument();
    boolean needDefaultStyle = false;
    for (Result result : upstreamResponse.getResults()) {
        try {
            Placemark placemark = transformEntry(null, result.getMetacard(), arguments);
            if (placemark.getStyleSelector().isEmpty() && StringUtils.isEmpty(placemark.getStyleUrl())) {
                placemark.setStyleUrl("#default");
                needDefaultStyle = true;
            }
            kmlDoc.getFeature().add(placemark);
        } catch (CatalogTransformerException e) {
            LOGGER.debug("Error transforming current metacard ({}) to KML and will continue with remaining query responses.", result.getMetacard().getId(), e);
        }
    }
    if (needDefaultStyle) {
        kmlDoc.getStyleSelector().addAll(defaultStyle);
    }
    Kml kmlResult = encloseKml(kmlDoc, docId, KML_RESPONSE_QUEUE_PREFIX + kmlDoc.getFeature().size() + CLOSE_PARENTHESIS);
    String transformedKml = marshalKml(kmlResult);
    InputStream kmlInputStream = new ByteArrayInputStream(transformedKml.getBytes(StandardCharsets.UTF_8));
    LOGGER.trace("EXITING: ResponseQueue transform");
    return new BinaryContentImpl(kmlInputStream, KML_MIMETYPE);
}
Also used : Placemark(de.micromata.opengis.kml.v_2_2_0.Placemark) ByteArrayInputStream(java.io.ByteArrayInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) CatalogTransformerException(ddf.catalog.transform.CatalogTransformerException) LineString(com.vividsolutions.jts.geom.LineString) Kml(de.micromata.opengis.kml.v_2_2_0.Kml) BinaryContentImpl(ddf.catalog.data.impl.BinaryContentImpl) Document(de.micromata.opengis.kml.v_2_2_0.Document) Result(ddf.catalog.data.Result)

Example 30 with BinaryContentImpl

use of ddf.catalog.data.impl.BinaryContentImpl in project ddf by codice.

the class GeoJsonQueryResponseTransformer method transform.

@Override
public BinaryContent transform(SourceResponse upstreamResponse, Map<String, Serializable> arguments) throws CatalogTransformerException {
    if (upstreamResponse == null) {
        throw new CatalogTransformerException("Cannot transform null " + SourceResponse.class.getName());
    }
    JSONObject rootObject = new JSONObject();
    addNonNullObject(rootObject, "hits", upstreamResponse.getHits());
    JSONArray resultsList = new JSONArray();
    if (upstreamResponse.getResults() != null) {
        for (Result result : upstreamResponse.getResults()) {
            if (result == null) {
                throw new CatalogTransformerException("Cannot transform null " + Result.class.getName());
            }
            JSONObject jsonObj = convertToJSON(result);
            if (jsonObj != null) {
                resultsList.add(jsonObj);
            }
        }
    }
    addNonNullObject(rootObject, "results", resultsList);
    String jsonText = JSONValue.toJSONString(rootObject);
    return new BinaryContentImpl(new ByteArrayInputStream(jsonText.getBytes(StandardCharsets.UTF_8)), DEFAULT_MIME_TYPE);
}
Also used : JSONObject(net.minidev.json.JSONObject) ByteArrayInputStream(java.io.ByteArrayInputStream) JSONArray(net.minidev.json.JSONArray) CatalogTransformerException(ddf.catalog.transform.CatalogTransformerException) BinaryContentImpl(ddf.catalog.data.impl.BinaryContentImpl) Result(ddf.catalog.data.Result)

Aggregations

BinaryContentImpl (ddf.catalog.data.impl.BinaryContentImpl)33 ByteArrayInputStream (java.io.ByteArrayInputStream)19 InputStream (java.io.InputStream)12 Test (org.junit.Test)12 CatalogTransformerException (ddf.catalog.transform.CatalogTransformerException)11 IOException (java.io.IOException)11 BinaryContent (ddf.catalog.data.BinaryContent)10 HashMap (java.util.HashMap)10 FileInputStream (java.io.FileInputStream)9 Metacard (ddf.catalog.data.Metacard)8 MimeType (javax.activation.MimeType)8 Map (java.util.Map)7 Matchers.anyString (org.mockito.Matchers.anyString)6 Result (ddf.catalog.data.Result)5 MarshallingContext (com.thoughtworks.xstream.converters.MarshallingContext)4 TreeMarshaller (com.thoughtworks.xstream.core.TreeMarshaller)4 StringWriter (java.io.StringWriter)4 MimeTypeParseException (javax.activation.MimeTypeParseException)4 Failure (org.junit.runner.notification.Failure)4 CatalogFramework (ddf.catalog.CatalogFramework)3