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;
}
}