MediaFormatValidateServlet.java
/*
* #%L
* wcm.io
* %%
* Copyright (C) 2019 wcm.io
* %%
* 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.
* #L%
*/
package io.wcm.handler.media.impl;
import java.io.IOException;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.HttpConstants;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.apache.sling.servlets.annotations.SlingServletResourceTypes;
import org.jetbrains.annotations.NotNull;
import org.osgi.service.component.annotations.Component;
import com.day.cq.i18n.I18n;
import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.PageManager;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.wcm.handler.media.Media;
import io.wcm.handler.media.MediaArgs.MediaFormatOption;
import io.wcm.handler.media.MediaHandler;
import io.wcm.handler.media.MediaInvalidReason;
import io.wcm.sling.commons.adapter.AdaptTo;
import io.wcm.sling.commons.request.RequestParam;
import io.wcm.wcm.commons.contenttype.ContentType;
import io.wcm.wcm.commons.contenttype.FileExtension;
/**
* Validates if the given asset references matches with the given
* set of media formats. This is used for the File Upload Granite UI component.
*/
@Component(service = Servlet.class)
@SlingServletResourceTypes(
extensions = FileExtension.JSON,
selectors = MediaFormatValidateServlet.SELECTOR,
resourceTypes = "sling/servlet/default",
methods = HttpConstants.METHOD_GET)
public final class MediaFormatValidateServlet extends SlingSafeMethodsServlet {
private static final long serialVersionUID = 1L;
static final String SELECTOR = "wcm-io-handler-media-mediaformat-validate";
static final String RP_MEDIA_FORMATS = "mediaFormats";
static final String RP_MEDIA_FORMATS_MANDATORY = "mediaFormatsMandatory";
static final String RP_MEDIA_CROPAUTO = "mediaCropAuto";
static final String RP_MEDIA_REF = "mediaRef";
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
/**
* Prefix for i18n keys to generated messages for media invalid reasons.
*/
public static final String MEDIA_INVALID_REASON_I18N_PREFIX = "io.wcm.handler.media.invalidReason.";
private static final String ASSET_INVALID_I18N_KEY = "io.wcm.handler.media.assetInvalid";
@Override
protected void doGet(@NotNull SlingHttpServletRequest request, @NotNull SlingHttpServletResponse response) throws ServletException, IOException {
// read and validated request parameters
String[] mediaFormats = StringUtils.split(RequestParam.get(request, RP_MEDIA_FORMATS), ",");
String[] mediaFormatsMandatory = StringUtils.split(RequestParam.get(request, RP_MEDIA_FORMATS_MANDATORY), ",");
boolean mediaCropAuto = RequestParam.getBoolean(request, RP_MEDIA_CROPAUTO);
String mediaRef = RequestParam.get(request, RP_MEDIA_REF);
if (mediaFormats == null || mediaFormats.length == 0
|| StringUtils.isEmpty(mediaRef)) {
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
MediaFormatOption[] mediaFormatOptions = new MediaFormatOption[mediaFormats.length];
for (int i = 0; i < mediaFormats.length; i++) {
boolean mandatory = false;
if (mediaFormatsMandatory != null) {
mandatory = ArrayUtils.contains(mediaFormatsMandatory, mediaFormats[i]);
}
mediaFormatOptions[i] = new MediaFormatOption(mediaFormats[i], mandatory);
}
// try to resolve media
MediaHandler mediaHandler = AdaptTo.notNull(request, MediaHandler.class);
Media media = mediaHandler.get(mediaRef)
.mediaFormatOptions(mediaFormatOptions)
.autoCrop(mediaCropAuto)
.build();
// response
ResultResponse result = new ResultResponse();
result.valid = media.isValid();
if (!media.isValid()) {
I18n i18n = getI18n(request);
result.reason = getI18nText(i18n, getMediaInvalidReasonI18nKeyOrMessage(media));
result.reasonTitle = getI18nText(i18n, ASSET_INVALID_I18N_KEY);
}
response.setContentType(ContentType.JSON);
response.getWriter().write(OBJECT_MAPPER.writeValueAsString(result));
}
private String getMediaInvalidReasonI18nKeyOrMessage(@NotNull Media media) {
MediaInvalidReason reason = media.getMediaInvalidReason();
if (reason == MediaInvalidReason.CUSTOM) {
return media.getMediaInvalidReasonCustomMessage();
}
else if (reason != null) {
return MEDIA_INVALID_REASON_I18N_PREFIX + reason.name();
}
else {
return "";
}
}
private String getI18nText(I18n i18n, String key) {
try {
return i18n.get(key);
}
catch (MissingResourceException ex) {
return key;
}
}
private I18n getI18n(SlingHttpServletRequest request) {
PageManager pageManager = AdaptTo.notNull(request.getResourceResolver(), PageManager.class);
Page currentPage = pageManager.getContainingPage(request.getResource());
if (currentPage != null) {
Locale locale = currentPage.getLanguage(false);
ResourceBundle resourceBundle = request.getResourceBundle(locale);
return new I18n(resourceBundle);
}
return new I18n(request);
}
@JsonInclude(Include.NON_NULL)
static class ResultResponse {
private boolean valid;
private String reason;
private String reasonTitle;
public boolean isValid() {
return this.valid;
}
public String getReason() {
return this.reason;
}
public String getReasonTitle() {
return this.reasonTitle;
}
}
}