package org.aplikator.client.local.widgets; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; import org.aplikator.client.local.Aplikator; import org.aplikator.client.shared.data.ContainerNodeDTO; import org.aplikator.client.shared.data.Operation; import org.aplikator.client.shared.data.PrimaryKey; import org.aplikator.client.shared.data.RecordContainerDTO; import org.aplikator.client.shared.data.RecordDTO; import org.aplikator.client.shared.descriptor.FormDTO; import org.aplikator.client.shared.descriptor.PropertyDTO; import org.aplikator.client.shared.descriptor.ViewDTO; import org.aplikator.client.shared.descriptor.WidgetDTO; import org.aplikator.client.shared.rpc.AfterErrorExecutor; import org.aplikator.client.shared.rpc.AplikatorErrorCallback; import org.aplikator.client.shared.rpc.AplikatorService; import org.jboss.errai.common.client.api.RemoteCallback; import org.jboss.errai.enterprise.client.jaxrs.api.RestClient; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.user.client.ui.DeckPanel; import com.google.gwt.user.client.ui.Widget; @SuppressWarnings("rawtypes") public class FormWidget extends AbstractFormContainerWidget implements HasFields { private static Logger LOG = Logger.getLogger(FormWidget.class.getName()); RecordContainerDTO recordContainerDTO; private List<DataField<?>> fields = new ArrayList<DataField<?>>(); private List<NestedCollectionWidget> collections = new ArrayList<NestedCollectionWidget>(); private List<BinaryFieldWidget> binaryFields = new ArrayList<BinaryFieldWidget>(); private List<FunctionButtonWidget> functionButtons = new ArrayList<FunctionButtonWidget>(); private ViewDTO view; private RecordDTO original; //private Record edited; private boolean dirty = false; private TableListerWidget table; private HasFields ownerForm; private DeckPanel formHolder; private LoadingLabel loadingLabel; private Widget formWidget; public FormWidget(ViewDTO view, TableListerWidget table, HasFields ownerForm) { this.view = view; this.table = table; this.ownerForm = ownerForm; formHolder = new DeckPanel(); loadingLabel = new LoadingLabel(Aplikator.application.getConfigString("aplikator.form.loading")); FormDTO descriptor = view.getFormDescriptor(); WidgetDTO layout = descriptor.getLayout(); formWidget = layout.getWidget(this); formHolder.add(loadingLabel); formHolder.add(formWidget); initWidget(formHolder); hideLoadingLabel(); } private void showLoadingLabel() { formHolder.showWidget(0); } private void hideLoadingLabel() { formHolder.showWidget(1); } @Override @SuppressWarnings("unchecked") public void registerDataField(DataField<? extends Object> field) { fields.add(field); field.addValueChangeHandler(this); } @Override public void registerNestedCollection(NestedCollectionWidget collection) { collections.add(collection); } @Override @SuppressWarnings("unchecked") public void registerBinaryField(BinaryFieldWidget binaryField) { binaryFields.add(binaryField); binaryField.addValueChangeHandler(this); } @Override public void registerFunctionButton(FunctionButtonWidget functionButton) { functionButtons.add(functionButton); } public void setEnabled(boolean enabled) { if (enabled) return; //we want only to disable nested fields, not to re-enable for (DataField field : fields) { field.setEnabled(enabled); } for (NestedCollectionWidget collection : collections) { collection.setEnabled(enabled); } for (BinaryFieldWidget binaryField : binaryFields) { binaryField.setEnabled(enabled); } } @SuppressWarnings({"unchecked"}) public void onValueChange(ValueChangeEvent event) { setDirty(true); if (ownerForm != null) { ownerForm.onValueChange(event); } if (event.getSource().getClass().equals(ReferenceFieldWidget.class)) { ReferenceFieldWidget source = (ReferenceFieldWidget) event.getSource(); RecordDTO reference = source.getSelectedRecord(); if (reference != null) { for (DataField field : fields) { PropertyDTO prop = field.getProperty(); if (prop.getRefferedThrough() != null) {// TODO kontrolovat // pres co je // referovano... PropertyDTO unreferencedProperty = prop.cloneUnreferenced(); Serializable val = (Serializable) unreferencedProperty.getValue(reference); if (val != null) { field.setValue(val); } } } } else { for (DataField field : fields) { PropertyDTO prop = field.getProperty(); if (prop.getRefferedThrough() != null) { field.setValue(null); } } } } } public void displayRecord(final PrimaryKey primaryKey, final RecordContainerDTO recordContainerDTO, final String ownerPropertyId, final PrimaryKey ownerPrimaryKey, final RecordContainerDTO initializingRecords) { this.recordContainerDTO = recordContainerDTO; if (primaryKey != null && primaryKey.getId() != -1) { showLoadingLabel(); RestClient.create(AplikatorService.class, new RemoteCallback<RecordDTO>() { @Override public void callback(RecordDTO recordDTO) { hideLoadingLabel(); original = recordDTO; original.setOwnerPropertyId(ownerPropertyId); original.setOwnerPrimaryKey(ownerPrimaryKey); populateFormWithData(null); } }, new AplikatorErrorCallback("aplikator.table.loaderror") ).getRecord(primaryKey.getSerializationString(), view.getId()); } else { RecordDTO lastUpdated = recordContainerDTO.findLastUpdated(primaryKey); if (lastUpdated != null) { original = lastUpdated; original.setOwnerPropertyId(ownerPropertyId); original.setOwnerPrimaryKey(ownerPrimaryKey); } if (original != null) { populateFormWithData(initializingRecords); } } } public void refreshRecord() { if (original != null && original.getPrimaryKey() != null && original.getPrimaryKey().getId() != -1) { showLoadingLabel(); RestClient.create(AplikatorService.class, new RemoteCallback<RecordDTO>() { @Override public void callback(RecordDTO recordDTO) { hideLoadingLabel(); original = recordDTO; original.setOwnerPropertyId(original.getOwnerPropertyId()); original.setOwnerPrimaryKey(original.getPrimaryKey()); populateFormWithData(null); } }, new AplikatorErrorCallback("aplikator.table.loaderror") ).getRecord(original.getPrimaryKey().getSerializationString(), view.getId()); } } public void addRecord(final RecordContainerDTO recordContainerDTO, final String ownerPropertyId, final PrimaryKey ownerPrimaryKey, final RecordDTO toCopy, final AddRecordCallback addRecordCallback) { showLoadingLabel(); LOG.fine("ADD RECORD"); this.recordContainerDTO = recordContainerDTO; RestClient.create(AplikatorService.class, new RemoteCallback<RecordContainerDTO>() { public void callback(RecordContainerDTO preparedRecords) { hideLoadingLabel(); LOG.fine("ADDRECORD CALLBACK:" + preparedRecords.getRecords().get(0).getEdited().getPrimaryKey()); original = preparedRecords.getRecords().get(0).getEdited(); recordContainerDTO.addRecord(view.getId(), original, original, Operation.CREATE); populateFormWithData(preparedRecords); if (addRecordCallback != null) { addRecordCallback.recordAdded(original); } } }, new AplikatorErrorCallback("aplikator.table.loaderror") ).prepareRecord(toCopy != null ? toCopy.getPrimaryKey().getSerializationString() : null, view.getId(), ownerPropertyId, ownerPrimaryKey != null ? ownerPrimaryKey.getSerializationString() : null); } @SuppressWarnings({"unchecked"}) public void populateFormWithData(RecordContainerDTO initializingRecords) { boolean setDirty = false; if (initializingRecords != null) { setDirty = true; } //LOG.fine("POPULATE FORM WITH DATA " + setDirty + " " + original.getPrimaryKey()); setDirty(setDirty); this.populateFormWithSimpleData(setDirty); for (NestedCollectionWidget collection : collections) { collection.setRecordContainerDTO(recordContainerDTO); collection.setOwnerPrimaryKey(original.getPrimaryKey()); if (!setDirty) { collection.reload(); } else { collection.initFromContainer(initializingRecords); } collection.setDirty(setDirty); } for (BinaryFieldWidget binaryField : binaryFields) { binaryField.setPrimaryKey(original.getPrimaryKey()); binaryField.setDirty(setDirty); } } public void cancel() { if (table != null && table.getOwnerPrimaryKey() == null) { recordContainerDTO.clear(); } LOG.fine("ONCLOSE:" + (original != null ? original.getPrimaryKey() : null)); if (dirty) { populateFormWithData(null); } } @Override public RecordDTO getPopulateRecord() { return getOriginal(); } @SuppressWarnings({"unchecked"}) public void save(boolean toBackend) { LOG.fine("SAVE:" + original.getPrimaryKey()); for (NestedCollectionWidget collection : collections) { collection.save(); } RecordDTO edited = new RecordDTO(original.getPrimaryKey()); edited.setOwnerPrimaryKey(original.getOwnerPrimaryKey()); edited.setOwnerPropertyId(original.getOwnerPropertyId()); StringBuilder emptyRequiredFields = new StringBuilder(); for (DataField field : fields) { if (field.getProperty().isRequired()) { if (field.getValue() == null) { //if (emptyRequiredFields.length()>0){ emptyRequiredFields.append("<br>"); //} emptyRequiredFields.append(field.getProperty().getLocalizedName()); } } } if (emptyRequiredFields.length() > 0) { Messages.error(Aplikator.application.getConfigString("aplikator.table.requiredfields") + " " + emptyRequiredFields.toString()); return; } for (DataField field : fields) { if (field.isDirty()) { PropertyDTO prop = field.getProperty(); Serializable val = field.getValue(); prop.setValue(edited, val); } } for (BinaryFieldWidget binaryField : binaryFields) { if (binaryField.isDirty()) {//load temporary file IDs from binary fields PropertyDTO prop = binaryField.getProperty(); String val = binaryField.getValue(); prop.setValue(edited, val); } } recordContainerDTO.addRecord(view.getId(), original, edited, Operation.UPDATE); if (toBackend) { showLoadingLabel(); RestClient.create(AplikatorService.class, new RemoteCallback<RecordContainerDTO>() { public void callback(RecordContainerDTO records) { hideLoadingLabel(); for (ContainerNodeDTO node : records.getRecords()) { if (Operation.DELETE.equals(node.getOperation())) { continue; } if (node.getOriginal().getPrimaryKey().equals(original.getPrimaryKey())) { original = node.getOriginal(); populateFormWithData(null); if (table != null) { table.updateEditedRecord(original); } } } setDirty(false); recordContainerDTO.clear(); Messages.success(Aplikator.application.getConfigString("aplikator.table.saveok")); } }, new AplikatorErrorCallback("aplikator.table.saveerror", new AfterErrorExecutor() { @Override public void execute() { if (table != null) { table.buttonCancel.setEnabled(true); table.buttonSave.setEnabled(true); } } }) ).processRecords(recordContainerDTO); } } @Override public RecordDTO getOriginal() { return original; } public boolean isDirty() { return dirty; } @Override public void setDirty(boolean dirty) { this.dirty = dirty; for (FunctionButtonWidget button : functionButtons) { button.setEnabled(!dirty); } if (table != null) { table.setListAccess(!dirty); if (dirty) { table.enableEditingControls(); } else { table.enableNavigationControls(); } } if (ownerForm != null) { ownerForm.setDirty(dirty); } } public void setNestedDirty(boolean dirty) { setDirty(dirty); for (DataField field : fields) { field.setDirty(dirty); } } @Override public List<DataField<?>> getDataFields() { return this.fields; } public ViewDTO getView() { return view; } }