metadata-profile-form-build.../src/main/java/org/gcube/portlets/widgets/mpformbuilder/client/form/generic/CreateMetadataForm.java

819 lines
24 KiB
Java

package org.gcube.portlets.widgets.mpformbuilder.client.form.generic;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.gcube.portlets.widgets.mpformbuilder.client.MetadataProfileFormBuilderService;
import org.gcube.portlets.widgets.mpformbuilder.client.MetadataProfileFormBuilderServiceAsync;
import org.gcube.portlets.widgets.mpformbuilder.client.events.CloseCreationFormEvent;
import org.gcube.portlets.widgets.mpformbuilder.client.events.CloseCreationFormEventHandler;
import org.gcube.portlets.widgets.mpformbuilder.client.events.DeleteCustomFieldEvent;
import org.gcube.portlets.widgets.mpformbuilder.client.events.DeleteCustomFieldEventHandler;
import org.gcube.portlets.widgets.mpformbuilder.client.form.MetaDataField;
import org.gcube.portlets.widgets.mpformbuilder.client.ui.metadata.CategoryPanel;
import org.gcube.portlets.widgets.mpformbuilder.client.ui.metadata.CustomFieldEntry;
import org.gcube.portlets.widgets.mpformbuilder.client.ui.metadata.MetaDataFieldSkeleton;
import org.gcube.portlets.widgets.mpformbuilder.client.ui.resources.AddResourceToDataset;
import org.gcube.portlets.widgets.mpformbuilder.client.ui.twincolumnselection.TwinColumnSelectionMainPanel;
import org.gcube.portlets.widgets.mpformbuilder.client.ui.utils.InfoIconsLabels;
import org.gcube.portlets.widgets.mpformbuilder.client.ui.utils.LoaderIcon;
import org.gcube.portlets.widgets.mpformbuilder.shared.catalogue.OrganizationBean;
import org.gcube.portlets.widgets.mpformbuilder.shared.license.LicenseBean;
import org.gcube.portlets.widgets.mpformbuilder.shared.metadata.CategoryWrapper;
import org.gcube.portlets.widgets.mpformbuilder.shared.metadata.MetaDataProfileBean;
import org.gcube.portlets.widgets.mpformbuilder.shared.metadata.MetadataFieldWrapper;
import com.github.gwtbootstrap.client.ui.AlertBlock;
import com.github.gwtbootstrap.client.ui.Button;
import com.github.gwtbootstrap.client.ui.ControlGroup;
import com.github.gwtbootstrap.client.ui.Form;
import com.github.gwtbootstrap.client.ui.Icon;
import com.github.gwtbootstrap.client.ui.ListBox;
import com.github.gwtbootstrap.client.ui.Paragraph;
import com.github.gwtbootstrap.client.ui.Popover;
import com.github.gwtbootstrap.client.ui.TabPanel;
import com.github.gwtbootstrap.client.ui.constants.AlertType;
import com.google.gwt.core.client.GWT;
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.event.shared.HandlerManager;
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.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FocusPanel;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
/**
* Create metadata form for ckan product.
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
*/
public class CreateMetadataForm extends Composite{
private static EditMetadataFormUiBinder uiBinder = GWT
.create(EditMetadataFormUiBinder.class);
/**
* The Interface EditMetadataFormUiBinder.
*
* @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it)
*
* Oct 1, 2020
*/
interface EditMetadataFormUiBinder extends
UiBinder<Widget, CreateMetadataForm> {
}
@UiField HTMLPanel createDatasetMainPanel;
@UiField ControlGroup customFields;
@UiField Button addCustomFieldButton;
@UiField Button createButton;
// @UiField Button resetButton;
@UiField AlertBlock infoBlock;
@UiField AlertBlock onContinueAlertBlock;
@UiField AlertBlock onCreateAlertBlock;
@UiField VerticalPanel metadataFieldsPanel;
@UiField ListBox metadataTypeListbox;
@UiField Form formFirstStep;
@UiField Form formThirdStep;
// @UiField Button continueButton;
@UiField Paragraph selectedProfile;
@UiField LoaderIcon loaderProfiles;
@UiField LoaderIcon loaderProfileInformation;
//@UiField TagsPanel tagsPanel;
// info panels
@UiField Icon infoIconTypes;
@UiField FocusPanel focusPanelTypes;
@UiField Popover popoverTypes;
@UiField Icon infoIconCustomFields;
@UiField FocusPanel focusPanelCustomFields;
@UiField Popover popoverCustomFields;
@UiField ControlGroup metadataTypesControlGroup;
private final MetadataProfileFormBuilderServiceAsync formBuilderService = GWT.create(MetadataProfileFormBuilderService.class);
private static final String REGEX_TITLE_PRODUCT_SUBWORD = "[^a-zA-Z0-9_.-]";
private static final String REGEX_MAIL = "\\b[\\w.%-]+@[-.\\w]+\\.[A-Za-z]{2,4}\\b";
private static final String NONE_PROFILE = "none";
// error/info messages
protected static final String ERROR_PRODUCT_CREATION = "There was an error while trying to publish your item.";
protected static final String PRODUCT_CREATED_OK = "Item correctly published!";
private static final String TRYING_TO_CREATE_PRODUCT = "Trying to publish the item, please wait...";
protected static final String MISSING_PUBLISH_RIGHTS = "It seems you are not authorized to publish on catalogue. Request it to the VRE manager or the portal administrator.";
// tab panel
private TabPanel tabPanel;
// add resource form
private AddResourceToDataset resourceForm;
// the licenses
private List<LicenseBean> licenseBean;
// event bus
private HandlerManager eventBus;
// added custom field entries (by the user)
private List<CustomFieldEntry> customFieldEntriesList = new ArrayList<CustomFieldEntry>();
// the list of MetaDataField added
private List<MetaDataField> listOfMetadataFields = new ArrayList<MetaDataField>();
// dataset metadata bean
//private DatasetBean receivedBean;
// the owner
private String owner;
// resource table
private TwinColumnSelectionMainPanel resourcesTwinPanel;
// List of opened popup'ids
private List<String> popupOpenedIds = new ArrayList<String>();
// map of organization name title
private Map<String, String> nameTitleOrganizationMap = new HashMap<String, String>();
private String scope;
private String genericResourceSecondaryType;
/**
* Invoked in the most general case.
*
* @param scope the scope
* @param genericResourceSecondaryType the generic resource secondary type
* @param eventBus the event bus
*/
public CreateMetadataForm(String scope, String genericResourceSecondaryType, HandlerManager eventBus) {
this(eventBus);
this.scope = scope;
this.genericResourceSecondaryType = genericResourceSecondaryType;
showLoadingProfiles(true);
MetadataProfileFormBuilderServiceAsync.Util.getInstance().getProfilesInTheScope(scope, genericResourceSecondaryType, new AsyncCallback<List<MetaDataProfileBean>>() {
@Override
public void onFailure(Throwable caught) {
}
@Override
public void onSuccess(List<MetaDataProfileBean> profiles) {
createDatasetFormBody(profiles);
showLoadingProfiles(false);
}
});
}
/**
* Instantiates a new creates the dataset form.
*
* @param profiles the profiles
* @param eventBus the event bus
*/
public CreateMetadataForm(List<MetaDataProfileBean> profiles, HandlerManager eventBus) {
this(eventBus);
showLoadingProfiles(true);
createDatasetFormBody(profiles);
showLoadingProfiles(false);
}
/**
* Instantiates a new creates the dataset form.
*
* @param eventBus the event bus
*/
private CreateMetadataForm(HandlerManager eventBus) {
initWidget(uiBinder.createAndBindUi(this));
this.eventBus = eventBus;
bind();
prepareInfoIcons();
}
private void showLoadingProfiles(boolean bool) {
loaderProfiles.setText("Loading Profiles...");
loaderProfiles.setVisible(bool);
}
private void showLoadingProfileInformation(boolean bool) {
loaderProfileInformation.setText("Loading Profile Information...");
loaderProfileInformation.setVisible(bool);
}
/**
* Bind on events.
*/
private void bind() {
// when a custom field is removed, remove it from the list
eventBus.addHandler(DeleteCustomFieldEvent.TYPE, new DeleteCustomFieldEventHandler() {
@Override
public void onRemoveEntry(DeleteCustomFieldEvent event) {
customFieldEntriesList.remove(event.getRemovedEntry());
customFields.remove(event.getRemovedEntry());
}
});
// on close form
eventBus.addHandler(CloseCreationFormEvent.TYPE, new CloseCreationFormEventHandler() {
@Override
public void onClose(CloseCreationFormEvent event) {
InfoIconsLabels.closeDialogBox(popupOpenedIds);
}
});
}
/**
* Creates the dataset form body.
*
* @param profiles the profiles
*/
private void createDatasetFormBody(final List<MetaDataProfileBean> profiles){
if(profiles == null){
setAlertBlock("An unknow error occurred while retrieving types, sorry", AlertType.ERROR, true);
}
else{
prepareMetadataList(profiles);
metadataTypeListbox.setEnabled(true);
}
}
/**
* Add the items to the listbox and put data into the metadataPanel.
*
* @param profiles the profiles
*/
private void prepareMetadataList(final List<MetaDataProfileBean> profiles) {
if(profiles != null && !profiles.isEmpty()){
for(MetaDataProfileBean metadataBean: profiles){
metadataTypeListbox.addItem(metadataBean.getType());
}
// add handler on select
metadataTypeListbox.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
String selectedItemText = metadataTypeListbox.getSelectedItemText();
metadataFieldsPanel.clear();
if(selectedItemText.equals(NONE_PROFILE)){
metadataFieldsPanel.setVisible(false);
//receivedBean.setChosenType(null);
}else{
//receivedBean.setChosenType(selectedItemText);
showLoadingProfileInformation(true);
formThirdStep.setVisible(true);
selectedProfile.setText("Selected Profile is " + metadataTypeListbox.getSelectedItemText());
addFields(selectedItemText, profiles);
showLoadingProfileInformation(false);
}
}
});
// // hide elements or show them if needed (groups in profiles cannot be present again in groups listbox)
// if(groupsControlGroup.isVisible()){
// List<String> groupsToHide = new ArrayList<String>();
// for(MetaDataProfileBean profile: profiles)
// groupsToHide.add(profile.getType().toString());
//
// SelectElement se = groupsListbox.getElement().cast();
//
// for (int i = 0; i < groupsListbox.getItemCount(); i++) {
// if(groupsToHide.contains(groupsListbox.getItemText(i))){
// se.getOptions().getItem(i).getStyle().setProperty("display", "none");
// }else
// se.getOptions().getItem(i).getStyle().setProperty("display", "");
// }
// }
//
// metadataTypesControlGroup.setVisible(true);
}else{
// just hide this listbox
metadataTypesControlGroup.setVisible(false);
metadataFieldsPanel.clear();
listOfMetadataFields.clear();
//receivedBean.setChosenType(null);
}
}
/**
* Add fields of the selected metadata profile to the widget.
*
* @param selectedItem the selected item
* @param listProfiles the list profiles
*/
protected void addFields(String selectedItem, List<MetaDataProfileBean> listProfiles) {
for(MetaDataProfileBean bean: listProfiles){
if(bean.getType().equals(selectedItem)){
// clear old data
listOfMetadataFields.clear();
// prepare the data
List<MetadataFieldWrapper> fields = bean.getMetadataFields();
List<CategoryWrapper> categories = bean.getCategories();
GWT.log("There are " + categories.size() + " categories for profile " + bean.getTitle());
if(categories == null || categories.isEmpty()){
for (MetadataFieldWrapper field : fields) {
/*MetaDataFieldSkeleton fieldWidget;
try {
fieldWidget = new MetaDataFieldSkeleton(field, eventBus);
metadataFieldsPanel.add(fieldWidget);
listOfMetadataFields.add(fieldWidget);
} catch (Exception e) {
GWT.log("Unable to build such widget", e);
}*/
MetaDataField fieldWidget;
try {
fieldWidget = new MetaDataField(field, eventBus);
metadataFieldsPanel.add(fieldWidget);
listOfMetadataFields.add(fieldWidget);
} catch (Exception e) {
GWT.log("Unable to build such widget", e);
}
}
}else{
// create the categories, then parse the fields. Fields do not belonging to a category are put at the end
for (CategoryWrapper categoryWrapper : categories) {
if(categoryWrapper.getFieldsForThisCategory() != null && categoryWrapper.getFieldsForThisCategory().size() > 0){
CategoryPanel cp = new CategoryPanel(categoryWrapper.getTitle(), categoryWrapper.getDescription());
List<MetadataFieldWrapper> fieldsForThisCategory = categoryWrapper.getFieldsForThisCategory();
fields.removeAll(fieldsForThisCategory);
for (MetadataFieldWrapper metadataFieldWrapper : fieldsForThisCategory) {
/*MetaDataFieldSkeleton fieldWidget;
try {
fieldWidget = new MetaDataFieldSkeleton(metadataFieldWrapper, eventBus);
cp.addField(fieldWidget);
listOfMetadataFields.add(fieldWidget);
} catch (Exception e) {
GWT.log("Unable to build such widget", e);
}*/
MetaDataField fieldWidget;
try {
fieldWidget = new MetaDataField(metadataFieldWrapper, eventBus);
cp.addField(fieldWidget);
listOfMetadataFields.add(fieldWidget);
} catch (Exception e) {
GWT.log("Unable to build such widget", e);
}
}
metadataFieldsPanel.add(cp);
}
}
// add the remaining one at the end of the categories
CategoryPanel extrasCategory = new CategoryPanel("Other", null);
for (MetadataFieldWrapper field : fields) {
/*MetaDataFieldSkeleton fieldWidget;
try {
fieldWidget = new MetaDataFieldSkeleton(field, eventBus);
extrasCategory.addField(fieldWidget);
listOfMetadataFields.add(fieldWidget);
} catch (Exception e) {
GWT.log("Unable to build such widget", e);
}*/
MetaDataField fieldWidget;
try {
fieldWidget = new MetaDataField(field, eventBus);
extrasCategory.addField(fieldWidget);
listOfMetadataFields.add(fieldWidget);
} catch (Exception e) {
GWT.log("Unable to build such widget", e);
}
}
metadataFieldsPanel.add(extrasCategory);
}
metadataFieldsPanel.setVisible(true);
}
}
}
/**
* Adds the custom field event.
*
* @param e the e
*/
@UiHandler("addCustomFieldButton")
void addCustomFieldEvent(ClickEvent e){
CustomFieldEntry toAdd = new CustomFieldEntry(eventBus, "", "", true);
customFieldEntriesList.add(toAdd);
customFields.add(toAdd);
}
/**
* On continue button.
*
* @param e the e
*/
/*@UiHandler("continueButton")
void onContinueButton(ClickEvent e){
// validate data
final String errorMsg = validateDataOnContinue();
if(errorMsg != null){
alertOnContinue("Please check inserted data [" + errorMsg + "]", AlertType.ERROR);
return;
}else{
formThirdStep.setVisible(true);
if(metadataTypeListbox.getSelectedItemText().equals(NONE_PROFILE))
selectedProfile.setText("");
else
selectedProfile.setText("Selected Type is " + metadataTypeListbox.getSelectedItemText());
}
}*/
/**
* After onContinue ...
*/
private void actionsAfterOnContinue(){
Window.alert("Called actionsAfterOnContinue");
if(metadataTypeListbox.getSelectedItemText().equals(NONE_PROFILE))
selectedProfile.setText("");
else
selectedProfile.setText("Selected Type is " + metadataTypeListbox.getSelectedItemText());
}
// /**
// * On go back button first step.
// *
// * @param e the e
// */
// @UiHandler("goBackButtonFirstStep")
// void onGoBackButtonFirstStep(ClickEvent e){
//
// Window.alert("Called onGoBackButtonFirstStep");
//
//// // swap forms
//// formFirstStep.setVisible(true);
//// formSecondStep.setVisible(false);
//// formThirdStep.setVisible(false);
//
// }
/**
* On go back button.
*
* @param e the e
*/
// @UiHandler("goBackButtonSecondStep")
// void onGoBackButton(ClickEvent e){
//
// Window.alert("Called onGoBackButton");
//
//// // swap forms
//// if(isWorkspaceRequest){
//// formFirstStep.setVisible(hideManageResources());
//// formSecondStep.setVisible(!hideManageResources());
//// }else{
//// formFirstStep.setVisible(true);
//// formSecondStep.setVisible(false);
//// }
//// formThirdStep.setVisible(false);
//
// }
// /**
// * On continue third step.
// *
// * @param e the e
// */
// @UiHandler("continueThirdStep")
// void onContinueThirdStep(ClickEvent e){
//
// Window.alert("Called onGoBackButton");
//
// // swap forms
//// formSecondStep.setVisible(false);
//// formThirdStep.setVisible(true);
//
// }
/**
* Creates the dataset event.
*
* @param e the e
*/
@UiHandler("createButton")
void createDatasetEvent(ClickEvent e){
String errorMessage = areProfileDataValid();
if(errorMessage != null){
alertOnCreate("Please check the inserted values and the mandatory fields [" + errorMessage +"]", AlertType.ERROR, true);
}
else{
//Set<String> tags = new HashSet<String>(tagsPanel.getTags());
List<OrganizationBean> groups = new ArrayList<OrganizationBean>();
List<OrganizationBean> groupsToForceCreation = new ArrayList<OrganizationBean>();
Map<String, List<String>> customFieldsMap = new HashMap<String, List<String>>();
// prepare custom fields
for (MetaDataField metaField : listOfMetadataFields) {
for (MetaDataFieldSkeleton field : metaField.getListOfMetadataFields()) {
List<String> valuesForField = field.getFieldCurrentValue();
if(!valuesForField.isEmpty()){
String key = field.getFieldNameQualified();
List<String> valuesForThisField = null;
if(customFieldsMap.containsKey(key))
valuesForThisField = customFieldsMap.get(key);
else
valuesForThisField = new ArrayList<String>();
valuesForThisField.addAll(valuesForField);
customFieldsMap.put(key, valuesForThisField);
// get also tag/group if it is the case for this field
// List<String> tagsField = field.getTagFromThisField();
// if(tagsField != null)
// tags.addAll(tagsField);
List<String> groupsTitle = field.getGroupTitleFromThisGroup();
if(groupsTitle != null){
for (String groupTitle : groupsTitle) {
if(field.isGroupToForce())
groupsToForceCreation.add(new OrganizationBean(groupTitle, groupTitle, false, field.isPropagateUp()));
else
groups.add(new OrganizationBean(groupTitle, groupTitle, false, field.isPropagateUp()));
}
}
}
}
}
for(CustomFieldEntry customEntry : customFieldEntriesList){
String key = customEntry.getKey();
String value = customEntry.getValue();
if(value != null && !value.isEmpty()){
List<String> valuesForThisField = null;
if(customFieldsMap.containsKey(key))
valuesForThisField = customFieldsMap.get(key);
else
valuesForThisField = new ArrayList<String>();
valuesForThisField.add(value);
customFieldsMap.put(key, valuesForThisField);
}
}
// alert
alertOnCreate(TRYING_TO_CREATE_PRODUCT, AlertType.INFO, false);
// invoke the create method
createButton.setEnabled(false);
}
}
/**
* Prepare the info icons of all core metadata info.
*/
private void prepareInfoIcons() {
// tags
//tagsPanel.prepareIcon(popupOpenedIds);
// profiles (or types)
InfoIconsLabels.preparePopupPanelAndPopover(
InfoIconsLabels.PROFILES_INFO_ID_POPUP,
InfoIconsLabels.PROFILES_INFO_TEXT,
InfoIconsLabels.PROFILES_INFO_CAPTION,
infoIconTypes,
popoverTypes,
focusPanelTypes,
popupOpenedIds
);
// custom fields
InfoIconsLabels.preparePopupPanelAndPopover(
InfoIconsLabels.CUSTOM_FIELDS_INFO_ID_POPUP,
InfoIconsLabels.CUSTOM_FIELDS_INFO_TEXT,
InfoIconsLabels.CUSTOM_FIELDS_INFO_CAPTION,
infoIconCustomFields,
popoverCustomFields,
focusPanelCustomFields,
popupOpenedIds
);
}
/**
* Test if profile data are valid.
*
* @return the string
*/
private String areProfileDataValid() {
for (MetaDataField metaField : listOfMetadataFields) {
for (MetaDataFieldSkeleton field : metaField.getListOfMetadataFields()) {
field.removeError();
String error = field.isFieldValueValid();
if(error != null){
field.showError();
return field.getFieldNameOriginal() + " is not valid. Suggestion: " + error;
}
}
}
return null;
}
/**
* On continue show alert box and enable buttons.
*
* @param text the text
* @param type the type
*/
private void alertOnContinue(String text, AlertType type){
onContinueAlertBlock.setText(text);
onContinueAlertBlock.setType(type);
onContinueAlertBlock.setVisible(true);
// continueButton.setEnabled(true);
// resetButton.setEnabled(true);
// hide after some seconds
Timer t = new Timer() {
@Override
public void run() {
onContinueAlertBlock.setVisible(false);
}
};
t.schedule(4000);
}
/**
* On continue show alert box and enable buttons.
*
* @param text the text
* @param type the type
* @param hideAfterAWhile the hide after A while
*/
private void alertOnCreate(String text, AlertType type, boolean hideAfterAWhile){
Window.alert("Called alertOnCreate");
// onCreateAlertBlock.setText(text);
// onCreateAlertBlock.setType(type);
// onCreateAlertBlock.setVisible(true);
// createButton.setEnabled(true);
// goBackButtonSecondStep.setEnabled(true);
//
// if(hideAfterAWhile){
// // hide after some seconds
// Timer t = new Timer() {
//
// @Override
// public void run() {
//
// onCreateAlertBlock.setVisible(false);
//
// }
// };
// t.schedule(10000);
// }
}
/**
* Validate data.
*
* @return true on success, false otherwise
*/
private String validateDataOnContinue() {
return null;
}
/**
* Checks if a metadata profile has been chosen and its fields have been fulfilled.
*
* @return true, if successful
*/
private boolean checkSelectedMetaDataProfile() {
return metadataTypeListbox.getSelectedItemText().equals(NONE_PROFILE) && metadataTypeListbox.getItemCount() != 1;
}
/**
* Reset form event.
*
* @param e the e
*/
/*@UiHandler("resetButton")
void resetFormEvent(ClickEvent e){
// delete custom fields
for (CustomFieldEntry customField : customFieldEntriesList) {
customField.removeFromParent();
}
customFieldEntriesList.clear();
}*/
/**
* Disable dataset editable fields once the dataset has been successfully created.
*/
protected void disableDatasetFields() {
//tagsPanel.freeze();
addCustomFieldButton.setEnabled(false);
metadataTypeListbox.setEnabled(false);
for(CustomFieldEntry ce: customFieldEntriesList)
ce.freeze();
// disable profile fields
for (MetaDataField metaField : listOfMetadataFields) {
for (MetaDataFieldSkeleton field : metaField.getListOfMetadataFields()) {
field.freeze();
}
}
// freeze table of resources
if(resourcesTwinPanel != null)
resourcesTwinPanel.freeze();
}
/**
* change alert block behavior.
*
* @param textToShow the text to show
* @param type the type
* @param visible the visible
*/
private void setAlertBlock(String textToShow, AlertType type, boolean visible){
infoBlock.setText(textToShow);
infoBlock.setType(type);
infoBlock.setVisible(visible);
}
// /**
// * On selected license change.
// *
// * @param c the c
// */
// @UiHandler("licenseListbox")
// void onSelectedLicenseChange(ChangeEvent c){
//
// showLicenseUrl();
//
// }
/**
* The body of the onSelectedLicenseChange.
*/
private void showLicenseUrl(){
Window.alert("Called showLicenseUrl");
}
}