/**
* (C) Copyright 2013 Jabylon (http://www.jabylon.org) and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.jabylon.rest.ui.wicket.xliff;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.StatelessForm;
import org.apache.wicket.markup.html.form.upload.FileUpload;
import org.apache.wicket.markup.html.form.upload.FileUploadField;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.StringResourceModel;
import org.jabylon.properties.Resolvable;
import org.jabylon.rest.ui.wicket.xliff.XliffUploadResult.Level;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Represents the UI form used for uploading XLIFF documents.<br>
* Calls {@link XliffUploadHelper} to process subsequent upload/import processing via
* {@link #onSubmit()}.<br>
*
* @author c.samulski (2016-02-08)
*/
public class XliffUploadForm extends StatelessForm<Resolvable<?, ?>> {
private static final long serialVersionUID = 2016_02_08L;
private final IModel<Resolvable<?, ?>> projectVersion;
private static final String LABEL_UPLOAD_XLIFF = "xuf-label-upload";
private static final String INPUT_UPLOAD_XLIFF = "xuf-input-upload";
private FileUploadField fileUpload = new FileUploadField(INPUT_UPLOAD_XLIFF);
private static final Logger LOG = LoggerFactory.getLogger(XliffUploadForm.class);
public XliffUploadForm(String id, IModel<Resolvable<?, ?>> model) {
super(id, model);
add(new Label(LABEL_UPLOAD_XLIFF, new StringResourceModel("label.xliff.upload", this, null)));
add(fileUpload);
this.projectVersion = model;
}
/**
* 1. Triggers import processing via {@link XliffUploadHelper#handleUpload()}.<br>
* 2. Triggers the display of success, warning and error messages based on the result of the
* aforementioned call.<br>
*/
@Override
protected void onSubmit() {
final FileUpload zip = fileUpload.getFileUpload();
if (zip == null) {
getSession().error(getString("xliff.upload.error.nofile"));
return;
}
try {
handleNotifications(new XliffUploadHelper(projectVersion, zip.getInputStream()).handleUpload());
} catch (IOException e) {
getSession().error(getString("xliff.upload.error.unexpected"));
}
}
/**
* Handles UI notifications for errors which may have occurred for specific {@link ZipEntry}s
* during the import process.<br>
*/
private void handleNotifications(Map<Level, List<XliffUploadResult>> results) {
for (Map.Entry<Level, List<XliffUploadResult>> result : results.entrySet()) {
String message = buildMessageForLevel(result.getValue());
if (message.isEmpty()) {
continue;
}
switch (result.getKey()) {
case INFO: // don't spam info UI notifications. create an aggregated message.
getSession().success(createSuccessMessage(result.getValue()));
break;
case WARNING:
getSession().warn(message);
break;
case ERROR:
getSession().error(message);
break;
default:
break;
}
}
}
/**
* Creates one aggregated info message for all files that were uploaded successfully.<br>
*/
private String createSuccessMessage(List<XliffUploadResult> value) {
return MessageFormat.format(getString("xliff.upload.success.aggregated"), value.size());
}
private static final int MAX_NOTIFICATIONS_PER_LEVEL = 2;
/**
* Constructs an aggregated warning/error/info message from the given {@link List} of
* {@link XliffUploadResult}s, consuming at most {@link #MAX_NOTIFICATIONS_PER_LEVEL} results (to not spam the
* screen too much).<br>
*/
private String buildMessageForLevel(List<XliffUploadResult> results) {
StringBuilder message = new StringBuilder("");
int count = 0;
for (XliffUploadResult result : results) {
String singleMessage = MessageFormat.format(getString(result.getKey()), result.getParameters());
if (count < MAX_NOTIFICATIONS_PER_LEVEL) {
message.append(singleMessage);
if (++count < MAX_NOTIFICATIONS_PER_LEVEL) {
message.append('\n');
}
}
/*
* Even though we don't include every result for UI notifications (simply too much), we
* do log them all.<br>
*/
logResult(result.getLevel(), singleMessage);
}
return message.toString();
}
/**
* Log a single (non-aggregated) upload result.<br>
*/
private void logResult(Level level, String message) {
switch (level) {
case INFO:
LOG.info(message);
break;
case WARNING:
LOG.warn(message);
break;
case ERROR:
LOG.error(message);
break;
default:
break;
}
}
}