org.roda.wui.client.browse.CreateDescriptiveMetadata.java Source code

Java tutorial

Introduction

Here is the source code for org.roda.wui.client.browse.CreateDescriptiveMetadata.java

Source

/**
 * The contents of this file are subject to the license and copyright
 * detailed in the LICENSE file at the root of the source
 * tree and available online at
 *
 * https://github.com/keeps/roda
 */
/**
 * 
 */
package org.roda.wui.client.browse;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

import org.roda.core.data.common.RodaConstants;
import org.roda.core.data.exceptions.AlreadyExistsException;
import org.roda.core.data.v2.index.select.SelectedItemsList;
import org.roda.core.data.v2.ip.IndexedAIP;
import org.roda.core.data.v2.validation.ValidationException;
import org.roda.core.data.v2.validation.ValidationIssue;
import org.roda.wui.client.browse.bundle.DescriptiveMetadataEditBundle;
import org.roda.wui.client.browse.bundle.SupportedMetadataTypeBundle;
import org.roda.wui.client.common.LastSelectedItemsSingleton;
import org.roda.wui.client.common.UserLogin;
import org.roda.wui.client.common.dialogs.Dialogs;
import org.roda.wui.client.common.utils.AsyncCallbackUtils;
import org.roda.wui.client.common.utils.FormUtilities;
import org.roda.wui.client.common.utils.JavascriptUtils;
import org.roda.wui.client.common.utils.StringUtils;
import org.roda.wui.common.client.HistoryResolver;
import org.roda.wui.common.client.tools.HistoryUtils;
import org.roda.wui.common.client.tools.ListUtils;
import org.roda.wui.common.client.widgets.Toast;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.i18n.client.LocaleInfo;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.FocusPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;

import config.i18n.client.ClientMessages;

/**
 * @author Luis Faria
 * 
 */
public class CreateDescriptiveMetadata extends Composite {
    public static final String NEW = "new";

    public static final HistoryResolver RESOLVER = new HistoryResolver() {

        @Override
        public void resolve(List<String> historyTokens, final AsyncCallback<Widget> callback) {
            boolean isAIP = historyTokens.get(0).equals(RodaConstants.RODA_OBJECT_AIP);

            if ((isAIP && (historyTokens.size() == 2 || historyTokens.size() == 3))
                    || (historyTokens.get(0).equals(RodaConstants.RODA_OBJECT_REPRESENTATION)
                            && (historyTokens.size() == 3 || historyTokens.size() == 4))) {
                final String aipId = historyTokens.get(1);
                boolean newAIP;
                CreateDescriptiveMetadata create;

                if (isAIP) {
                    newAIP = historyTokens.size() == 3 && historyTokens.get(2).equals(NEW);
                    create = new CreateDescriptiveMetadata(aipId, null, newAIP);
                } else {
                    final String representationId = historyTokens.get(2);
                    newAIP = historyTokens.size() == 4 && historyTokens.get(3).equals(NEW);
                    create = new CreateDescriptiveMetadata(aipId, representationId, newAIP);
                }

                callback.onSuccess(create);
            } else {
                HistoryUtils.newHistory(BrowseAIP.RESOLVER);
                callback.onSuccess(null);
            }
        }

        @Override
        public void isCurrentUserPermitted(AsyncCallback<Boolean> callback) {
            // TODO check for edit metadata permission
            UserLogin.getInstance().checkRoles(new HistoryResolver[] { BrowseAIP.RESOLVER }, false, callback);
        }

        @Override
        public List<String> getHistoryPath() {
            return ListUtils.concat(BrowseAIP.RESOLVER.getHistoryPath(), getHistoryToken());
        }

        @Override
        public String getHistoryToken() {
            return "create_metadata";
        }
    };

    interface MyUiBinder extends UiBinder<Widget, CreateDescriptiveMetadata> {
    }

    private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);

    private static final ClientMessages messages = GWT.create(ClientMessages.class);

    private final String aipId;
    private final String representationId;
    private final boolean isNew;

    private boolean inXML = false;

    private List<SupportedMetadataTypeBundle> metadataTypes = new ArrayList<>();
    private SupportedMetadataTypeBundle selectedBundle = null;
    private TextArea metadataXML;
    private String metadataTextFromForm = null;

    @UiField
    TextBox id;

    @UiField
    ListBox type;

    @UiField
    FocusPanel showXml;

    @UiField
    HTML showXmlIconXML;

    @UiField
    HTML showXmlIconForm;

    @UiField
    FlowPanel formOrXML;

    @UiField
    Button buttonApply;

    @UiField
    Button buttonCancel;

    @UiField
    HTML errors;

    @UiField
    HTML idError;

    /**
     * Create a new panel to edit a user
     * 
     * @param user
     *          the user to edit
     */
    public CreateDescriptiveMetadata(String aipId, String representationId, boolean isNew) {
        this.aipId = aipId;
        this.representationId = representationId;
        this.isNew = isNew;

        initWidget(uiBinder.createAndBindUi(this));
        metadataXML = new TextArea();
        metadataXML.addStyleName("form-textbox metadata-edit-area metadata-form-textbox");

        type.addChangeHandler(new ChangeHandler() {

            @Override
            public void onChange(ChangeEvent event) {
                String value = type.getSelectedValue();

                selectedBundle = null;
                if (StringUtils.isNotBlank(value)) {
                    for (SupportedMetadataTypeBundle bundle : metadataTypes) {
                        if (bundle.getId().equals(value)) {
                            selectedBundle = bundle;
                            break;
                        }
                    }

                    id.setText(value + RodaConstants.PREMIS_SUFFIX);
                } else {
                    id.setText("");
                }
                updateFormOrXML();
            }
        });

        BrowserService.Util.getInstance().retrieveSupportedMetadata(aipId, representationId,
                LocaleInfo.getCurrentLocale().getLocaleName(),
                new AsyncCallback<List<SupportedMetadataTypeBundle>>() {

                    @Override
                    public void onFailure(Throwable caught) {
                        AsyncCallbackUtils.defaultFailureTreatment(caught);
                    }

                    @Override
                    public void onSuccess(List<SupportedMetadataTypeBundle> metadataTypes) {
                        CreateDescriptiveMetadata.this.metadataTypes = metadataTypes;

                        for (SupportedMetadataTypeBundle b : metadataTypes) {
                            if (b.getVersion() != null) {
                                type.addItem(b.getLabel(),
                                        b.getType() + RodaConstants.METADATA_VERSION_SEPARATOR + b.getVersion());
                            } else {
                                type.addItem(b.getLabel(), b.getType());
                            }
                        }

                        type.addItem(messages.otherItem(), "");
                        type.setSelectedIndex(0);
                        selectedBundle = metadataTypes.get(0);
                        if (selectedBundle.getVersion() != null) {
                            id.setText(selectedBundle.getType() + RodaConstants.METADATA_VERSION_SEPARATOR
                                    + selectedBundle.getVersion() + RodaConstants.PREMIS_SUFFIX);
                        } else {
                            id.setText(selectedBundle.getType() + RodaConstants.PREMIS_SUFFIX);
                        }
                        updateFormOrXML();
                    }
                });

        Element firstElement = showXml.getElement().getFirstChildElement();
        if ("input".equalsIgnoreCase(firstElement.getTagName())) {
            firstElement.setAttribute("title", "browse input");
        }
    }

    @Override
    protected void onLoad() {
        super.onLoad();
        JavascriptUtils.stickSidebar();
    }

    private void createForm(SupportedMetadataTypeBundle bundle) {
        formOrXML.clear();
        FormUtilities.create(formOrXML, bundle.getValues(), true);
    }

    public void setInXML(boolean inXML) {
        this.inXML = inXML;
        if (inXML) {
            showXmlIconXML.setVisible(false);
            showXmlIconForm.setVisible(true);
        } else {
            showXmlIconXML.setVisible(true);
            showXmlIconForm.setVisible(false);
        }
    }

    @UiHandler("showXml")
    void buttonShowXmlHandler(ClickEvent e) {
        setInXML(!inXML);
        updateFormOrXML();
    }

    private void updateFormOrXML() {
        if (selectedBundle != null && selectedBundle.getValues() != null) {
            showXml.setVisible(true);
            if (inXML) {
                updateMetadataXML();
            } else {
                // if the user changed the metadata text
                if (metadataTextFromForm != null && !metadataXML.getText().equals(metadataTextFromForm)) {
                    Dialogs.showConfirmDialog(messages.confirmChangeToFormTitle(),
                            messages.confirmChangeToFormMessage(), messages.dialogCancel(), messages.dialogYes(),
                            new AsyncCallback<Boolean>() {
                                @Override
                                public void onFailure(Throwable caught) {
                                    AsyncCallbackUtils.defaultFailureTreatment(caught);
                                }

                                @Override
                                public void onSuccess(Boolean aBoolean) {
                                    if (aBoolean) {
                                        formOrXML.clear();
                                        createForm(selectedBundle);
                                    } else {
                                        setInXML(!inXML);
                                    }
                                }
                            });
                } else {
                    formOrXML.clear();
                    createForm(selectedBundle);
                }
            }
        } else {
            formOrXML.clear();
            if (selectedBundle != null)
                metadataXML.setText(selectedBundle.getTemplate());
            else
                metadataXML.setText("");
            formOrXML.add(metadataXML);
            showXml.setVisible(false);
        }
    }

    private void updateMetadataXML() {
        BrowserService.Util.getInstance().retrieveDescriptiveMetadataPreview(selectedBundle,
                new AsyncCallback<String>() {
                    @Override
                    public void onFailure(Throwable caught) {
                        AsyncCallbackUtils.defaultFailureTreatment(caught);
                    }

                    @Override
                    public void onSuccess(String preview) {
                        formOrXML.clear();
                        metadataXML.setText(preview);
                        formOrXML.add(metadataXML);
                        metadataTextFromForm = preview;
                    }
                });
    }

    @UiHandler("buttonApply")
    void buttonApplyHandler(ClickEvent e) {
        buttonApply.setEnabled(false);
        String idText = id.getText();
        String typeText = selectedBundle != null ? selectedBundle.getType() : messages.otherItem(); // Other
        String typeVersion = selectedBundle != null ? selectedBundle.getVersion() : null;
        String template = selectedBundle != null ? selectedBundle.getTemplate() : null;
        String xmlText = metadataXML.getText();
        boolean hasOverridenTheForm = inXML && !xmlText.equals(metadataTextFromForm);

        if (idText.length() > 0) {
            Set<MetadataValue> values = null;
            // we only send the values map if the user hasn't overriden the form by
            // modifying the XML directly
            if (!hasOverridenTheForm && selectedBundle != null) {
                values = selectedBundle.getValues();
            }
            DescriptiveMetadataEditBundle newBundle = new DescriptiveMetadataEditBundle(idText, typeText,
                    typeVersion, xmlText, template, values, true);

            BrowserService.Util.getInstance().createDescriptiveMetadataFile(aipId, representationId, newBundle,
                    new AsyncCallback<Void>() {

                        @Override
                        public void onFailure(Throwable caught) {
                            if (caught instanceof ValidationException) {
                                ValidationException e = (ValidationException) caught;
                                updateErrors(e);
                                idError.setVisible(false);
                            } else if (caught instanceof AlreadyExistsException) {
                                idError.setVisible(true);
                                idError.setHTML(SafeHtmlUtils.fromSafeConstant(messages.fileAlreadyExists()));
                                errors.setVisible(false);
                            } else {
                                idError.setVisible(false);
                                AsyncCallbackUtils.defaultFailureTreatment(caught);
                            }
                            buttonApply.setEnabled(true);
                        }

                        @Override
                        public void onSuccess(Void result) {
                            errors.setText("");
                            errors.setVisible(false);
                            Toast.showInfo(messages.dialogSuccess(), messages.metadataFileCreated());
                            if (representationId == null) {
                                HistoryUtils.newHistory(BrowseAIP.RESOLVER, aipId);
                            } else {
                                HistoryUtils.newHistory(BrowseRepresentation.RESOLVER, aipId, representationId);
                            }
                        }
                    });
        } else {
            Toast.showError("Please fill the mandatory fields");
            buttonApply.setEnabled(true);
        }

    }

    protected void updateErrors(ValidationException e) {
        SafeHtmlBuilder b = new SafeHtmlBuilder();
        for (ValidationIssue issue : e.getReport().getIssues()) {
            b.append(SafeHtmlUtils.fromSafeConstant("<span class='error'>"));
            b.append(messages.metadataParseError(issue.getLineNumber(), issue.getColumnNumber(),
                    issue.getMessage()));
            b.append(SafeHtmlUtils.fromSafeConstant("</span>"));

        }

        errors.setHTML(b.toSafeHtml());
        errors.setVisible(true);
    }

    @UiHandler("buttonCancel")
    void buttonCancelHandler(ClickEvent e) {
        cancel();
    }

    private void cancel() {
        if (isNew) {
            if (representationId == null) {
                SelectedItemsList<IndexedAIP> selected = new SelectedItemsList<>(Arrays.asList(aipId),
                        IndexedAIP.class.getName());
                BrowserService.Util.getInstance().deleteAIP(selected, null, new AsyncCallback<Void>() {

                    @Override
                    public void onFailure(Throwable caught) {
                        AsyncCallbackUtils.defaultFailureTreatment(caught);
                    }

                    @Override
                    public void onSuccess(Void result) {
                        HistoryUtils.newHistory(LastSelectedItemsSingleton.getInstance().getLastHistory());
                    }
                });
            } else {
                HistoryUtils.newHistory(BrowseRepresentation.RESOLVER, aipId, representationId);
            }
        } else {
            if (representationId == null) {
                HistoryUtils.newHistory(BrowseAIP.RESOLVER, aipId);
            } else {
                HistoryUtils.newHistory(BrowseRepresentation.RESOLVER, aipId, representationId);
            }
        }
    }

}