/** * Copyright (c) Codice Foundation * <p/> * This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser * General Public License as published by the Free Software Foundation, either version 3 of the * License, or any later version. * <p/> * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. A copy of the GNU Lesser General Public License * is distributed along with this program and can be found at * <http://www.gnu.org/licenses/lgpl.html>. */ package org.codice.ddf.catalog.content.resource.reader; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; import org.apache.commons.lang.StringUtils; import org.apache.http.NameValuePair; import org.apache.http.client.utils.URIBuilder; import org.apache.http.client.utils.URLEncodedUtils; import org.apache.http.message.BasicNameValuePair; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ddf.action.Action; import ddf.action.ActionProvider; import ddf.action.MultiActionProvider; import ddf.action.impl.ActionImpl; import ddf.catalog.content.data.ContentItem; import ddf.catalog.data.Metacard; public class DerivedContentActionProvider implements MultiActionProvider { private static final String ID = "catalog.data.metacard.derived-content"; private static final Logger LOGGER = LoggerFactory.getLogger(DerivedContentActionProvider.class); private final ActionProvider resourceActionProvider; private static final String DESCRIPTION_PREFIX = "Retrieves derived resource: "; public DerivedContentActionProvider(ActionProvider actionProvider) { this.resourceActionProvider = actionProvider; } @Override public <T> List<Action> getActions(T input) { if (!canHandle(input)) { return Collections.emptyList(); } Action resourceAction = resourceActionProvider.getAction(input); if (resourceAction == null) { return Collections.emptyList(); } return ((Metacard) input).getAttribute(Metacard.DERIVED_RESOURCE_URI) .getValues() .stream() .map(value -> { try { URI uri = new URI(value.toString()); URIBuilder builder = new URIBuilder(resourceAction .getUrl() .toURI()); if (StringUtils.equals(uri.getScheme(), ContentItem.CONTENT_SCHEME)) { String qualifier = uri.getFragment(); builder.addParameters(Collections.singletonList(new BasicNameValuePair( ContentItem.QUALIFIER, qualifier))); return Optional.of(new ActionImpl(ID, "View " + qualifier, DESCRIPTION_PREFIX + qualifier, builder.build() .toURL())); } else { String uriString = uri.toString(); String qualifier = getQualifierForRemoteResource(uriString); if (StringUtils.isNotBlank(qualifier)) { // remote source return Optional.of(new ActionImpl(ID, "View " + qualifier, DESCRIPTION_PREFIX + uriString, uri.toURL())); } else { // fail case return Optional.of(new ActionImpl(ID, "View " + uriString, DESCRIPTION_PREFIX + uriString, uri.toURL())); } } } catch (URISyntaxException | MalformedURLException e) { LOGGER.debug("Unable to create action URL.", e); return Optional.<Action>empty(); } }) .filter(Optional::isPresent) .map(Optional::get) .collect(Collectors.toList()); } @Override public String getId() { return ID; } @Override public <T> boolean canHandle(T subject) { if (subject instanceof Metacard) { Metacard metacard = (Metacard) subject; if (metacard.getAttribute(Metacard.DERIVED_RESOURCE_URI) != null && !metacard.getAttribute(Metacard.DERIVED_RESOURCE_URI) .getValues() .isEmpty()) { return true; } } return false; } private String getQualifierForRemoteResource(String uriString) throws URISyntaxException { final String QUALIFIER_KEY = "qualifier"; return URLEncodedUtils.parse(new URI(uriString), StandardCharsets.UTF_8.name()) .stream() .filter(pair -> QUALIFIER_KEY.equals(pair.getName())) .map(NameValuePair::getValue) .findFirst() .orElse(""); // default } }