/**
* (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.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import org.apache.wicket.Component;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.StatelessForm;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.model.StringResourceModel;
import org.apache.wicket.request.IRequestCycle;
import org.apache.wicket.request.IRequestHandler;
import org.apache.wicket.request.resource.IResource;
import org.jabylon.common.review.ReviewParticipant;
import org.jabylon.properties.Resolvable;
import org.jabylon.rest.ui.wicket.panels.PropertyListMode;
import org.jabylon.rest.ui.wicket.panels.PropertyListModeFactory;
import org.jabylon.rest.ui.wicket.panels.XliffLanguageTupleSelectionPanel;
/**
* @author c.samulski (2016-01-28)
*/
public class XliffDownloadForm extends StatelessForm<Void> {
private static final long serialVersionUID = -7727556253068015509L;
private static final String FORM_ID = "mdf-languageselect";
private static final String COMPONENT_LIST_ID = "mdf-components";
private static final String LABEL_TARGETLANG_ID = "mdf-label-targetlang";
private static final String LABEL_SOURCELANG_ID = "mdf-label-sourcelang";
private static final String SELECT_FILTER_ID = "mdf-select-filter";
private final IModel<Resolvable<?, ?>> projectVersion;
private PropertyListMode filter = PropertyListModeFactory.ALL;
@Inject
List<ReviewParticipant> reviewParticipants;
public XliffDownloadForm(List<Language> languages, IModel<Resolvable<?, ?>> model) {
super(FORM_ID);
this.projectVersion = model;
buildForm(languages);
}
/**
* Constructs *this* form. <br>
*
* @param languages
* Languages to serve as basis for {@link Component} data.<br>
*/
private void buildForm(List<Language> languages) {
/* Retrieve language selection panel form elements. */
List<XliffLanguageTupleSelectionPanel> languageSelectionTupels = getLanguageSelectionPanels(languages);
/* Add form components */
add(new Label(LABEL_TARGETLANG_ID, new StringResourceModel("label.target.language", this, null)));
add(new Label(LABEL_SOURCELANG_ID, new StringResourceModel("label.source.language", this, null)));
add(new DropDownChoice<PropertyListMode>(SELECT_FILTER_ID, //
new PropertyModel<PropertyListMode>(this, "filter"), //
PropertyListModeFactory.all(reviewParticipants)) {
private static final long serialVersionUID = 1L;
/* We want to localize the values via property files */
@Override
protected boolean localizeDisplayValues() {
return true;
}
});
add(new ListView<XliffLanguageTupleSelectionPanel>(COMPONENT_LIST_ID, languageSelectionTupels) {
private static final long serialVersionUID = 1L;
@Override
protected void populateItem(ListItem<XliffLanguageTupleSelectionPanel> item) {
item.add(item.getModelObject());
}
});
}
/**
* Construct a {@link XliffLanguageTupleSelectionPanel} for each language, filter out the template as
* we don't want to offer this as a selection choice in our form.<br>
*
* @return {@link List} of populated {@link XliffLanguageTupleSelectionPanel}s, for each language
* passed.<br>
*/
private static List<XliffLanguageTupleSelectionPanel> getLanguageSelectionPanels(List<Language> languages) {
List<XliffLanguageTupleSelectionPanel> languageSelectionTupels = new ArrayList<XliffLanguageTupleSelectionPanel>();
for (Iterator<Language> languageIterator = languages.iterator(); languageIterator.hasNext();) {
Language language = languageIterator.next();
/* Don't offer template as target. */
if (language.isTemplate()) {
continue;
}
languageSelectionTupels.add(new XliffLanguageTupleSelectionPanel(languages, language));
}
return languageSelectionTupels;
}
/**
* Called by WICKET on form submit. Triggers subsequent processing, i.e. the conversion/download
* of XLIFF files.
* <p>
* 1. Retrieve form result as {@link XliffLanguageTupleSelectionPanel} objects.<br>
* 2. Convert to Map holding Language tuples.<br>
* 3. Call XLIFF conversion/export processing.<br>
*/
@Override
protected void onSubmit() {
List<XliffLanguageTupleSelectionPanel> result = getSelection();
final Map<Language, Language> resultAsMap = processSelection(result);
getRequestCycle().scheduleRequestHandlerAfterCurrent(new IRequestHandler() {
@Override
public void respond(IRequestCycle requestCycle) {
XliffDownloadResource downloadResource = new XliffDownloadResource(resultAsMap, projectVersion, filter);
downloadResource.respond(new IResource.Attributes(requestCycle.getRequest(), requestCycle.getResponse()));
}
@Override
public void detach(IRequestCycle requestCycle) {
// nothing to do.
}
});
}
/**
* Presumably *not* the "WICKET way" of doing things, as we're abusing a {@link Panel} object as
* a storage POJO, but it works fine for now, is clear enough and hassle-free. ;-)<br>
*
* Iterates *this* forms children, retrieving selected child {@link Panel}s.<br>
*
* @return a {@link List} of {@link XliffLanguageTupleSelectionPanel}s, which represent
* {@link Language} tuples (source and target).<br>
*/
private List<XliffLanguageTupleSelectionPanel> getSelection() {
final List<XliffLanguageTupleSelectionPanel> result = new ArrayList<XliffLanguageTupleSelectionPanel>();
for (Component languageTupel : this.visitChildren(XliffLanguageTupleSelectionPanel.class)) {
XliffLanguageTupleSelectionPanel asLanguageTupel = (XliffLanguageTupleSelectionPanel) languageTupel;
if (asLanguageTupel.isSelected()) {
result.add(asLanguageTupel);
}
}
return result;
}
/**
* Convert the retrieved {@link XliffLanguageTupleSelectionPanel} objects to a {@link Map}.
* K=TargetLanguage, V=SourceLanguage.<br>
*/
private static Map<Language, Language> processSelection(List<XliffLanguageTupleSelectionPanel> selectedItems) {
Map<Language, Language> languageTupels = new HashMap<Language, Language>();
for (XliffLanguageTupleSelectionPanel languageTupel : selectedItems) {
languageTupels.put(languageTupel.getTargetLanguage(), languageTupel.getSourceLanguage());
}
return languageTupels;
}
}