/*
* Copyright 2014-2015 CyberVision, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.kaaproject.avro.ui.shared;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public abstract class FormField implements Serializable, Cloneable, Iterable<FormField> {
private static final long serialVersionUID = 6978997793895098628L;
public static enum FieldAccess {
EDITABLE,
READ_ONLY,
HIDDEN
}
protected int id;
private String fieldName;
private String displayName;
private String displayPrompt;
private String schema;
private boolean optional;
private FieldAccess fieldAccess = FieldAccess.EDITABLE;
private float weight = 1f;
private int keyIndex = -1;
private int rowIndex = -1;
private boolean isOverride = false;
private boolean isOverrideDisabled = false;
private boolean changed = false;
protected FormContext context;
private transient List<ChangeListener> changeListeners = new ArrayList<>();
private transient List<ValueChangeListener> transientValueChangeListeners = new ArrayList<>();
private List<ValueChangeListener> valueChangeListeners = new ArrayList<>();
private FormField parentField;
public FormField() {
}
public FormField(FormContext context,
String fieldName,
String displayName,
String schema,
boolean optional) {
this.id = context.nextFieldId();
this.context = context;
this.fieldName = fieldName;
this.displayName = displayName;
this.schema = schema;
this.optional = optional;
}
public FormContext getContext() {
return context;
}
public int getId() {
return id;
}
public FormField getParentField() {
return parentField;
}
public void setParentField(FormField parentField) {
this.parentField = parentField;
}
public String getFieldName() {
return fieldName;
}
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public String getDisplayPrompt() {
return displayPrompt;
}
public void setDisplayPrompt(String displayPrompt) {
this.displayPrompt = displayPrompt;
}
public String getSchema() {
return schema;
}
public void setSchema(String schema) {
this.schema = schema;
}
public boolean isOptional() {
return optional;
}
public void setOptional(boolean optional) {
this.optional = optional;
}
public void setWeight(float weight) {
this.weight = weight;
}
public float getWeight() {
return weight;
}
public int getKeyIndex() {
return keyIndex;
}
public void setKeyIndex(int keyIndex) {
this.keyIndex = keyIndex;
}
public int getRowIndex() {
return rowIndex;
}
public void setRowIndex(int rowIndex) {
this.rowIndex = rowIndex;
}
public FieldAccess getFieldAccess() {
return fieldAccess;
}
public void setFieldAccess(FieldAccess fieldAccess) {
this.fieldAccess = fieldAccess;
}
public boolean isReadOnly() {
return this.fieldAccess == FieldAccess.READ_ONLY;
}
public boolean isOverride() {
return isOverride;
}
public void setOverride(boolean isOverride) {
this.isOverride = isOverride;
}
public boolean isOverrideDisabled() {
return isOverrideDisabled;
}
public boolean isChanged() {
return changed;
}
public boolean isRootChild() {
if (parentField != null && context != null
&& context.getRootRecord() != null) {
return context.getRootRecord().getId() == parentField.getId();
} else {
return false;
}
}
protected void fireChanged() {
setChanged(true, true);
}
public void setChanged(boolean changed) {
setChanged(changed, false);
}
public void setChanged(boolean changed, boolean fireChanged) {
if (this.changed != changed) {
this.changed = changed;
if (fireChanged) {
for (ChangeListener listener : changeListeners) {
listener.onChanged(changed);
}
}
}
}
protected void fireValueChanged(Object value) {
for (ValueChangeListener listener : transientValueChangeListeners) {
listener.onValueChanged(value);
}
for (ValueChangeListener listener : valueChangeListeners) {
listener.onValueChanged(value);
}
}
public void addChangeListener(ChangeListener listener) {
changeListeners.add(listener);
}
public void addTransientValueChangeListener(ValueChangeListener listener) {
transientValueChangeListeners.add(listener);
}
public void removeTransientValueChangeListener(ValueChangeListener listener) {
transientValueChangeListeners.remove(listener);
}
public void addValueChangeListener(ValueChangeListener listener) {
valueChangeListeners.add(listener);
}
public void removeValueChangeListener(ValueChangeListener listener) {
valueChangeListeners.remove(listener);
}
public String getTypeFullname() {
return getFieldType().getName();
}
public String getDisplayString() {
String str = "\"" + getDisplayName();
if (isOverride) {
str += " (" + (changed ? "changed" : "unchanged") + ")";
}
str += "\"";
return str;
}
public abstract FieldType getFieldType();
public abstract boolean isNull();
public boolean isSameType(FormField otherRecord) {
return getTypeFullname().equals(otherRecord.getTypeFullname());
}
public boolean isValid() {
if (optional || (isOverride && !changed)) {
return true;
} else {
return valid();
}
}
protected abstract boolean valid();
public void finalizeMetadata() {}
public void disableOverride() {
isOverride = false;
isOverrideDisabled = true;
}
public FormField clone() {
return clone(false);
}
public FormField clone(boolean deepCopy) {
FormField cloned = createInstance();
cloned.id = context.nextFieldId();
copyFields(cloned, deepCopy);
return cloned;
}
protected abstract FormField createInstance();
protected void copyFields (FormField cloned, boolean deepCopy) {
cloned.context = context;
cloned.fieldName = fieldName;
cloned.displayName = displayName;
cloned.displayPrompt = displayPrompt;
cloned.schema = schema;
cloned.optional = optional;
cloned.fieldAccess = fieldAccess;
cloned.weight = weight;
cloned.keyIndex = keyIndex;
cloned.rowIndex = rowIndex;
cloned.isOverride = isOverride;
cloned.isOverrideDisabled = isOverrideDisabled;
cloned.changed = changed;
}
protected void dispose() {
context = null;
parentField = null;
changeListeners.clear();
transientValueChangeListeners.clear();
valueChangeListeners.clear();
}
@Override
public Iterator<FormField> iterator() {
return FormFieldIterator.singletonIterator(this);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (changed ? 1231 : 1237);
result = prime * result
+ ((displayName == null) ? 0 : displayName.hashCode());
result = prime * result
+ ((displayPrompt == null) ? 0 : displayPrompt.hashCode());
result = prime * result
+ ((fieldAccess == null) ? 0 : fieldAccess.hashCode());
result = prime * result
+ ((fieldName == null) ? 0 : fieldName.hashCode());
result = prime * result + keyIndex;
result = prime * result + (optional ? 1231 : 1237);
result = prime * result + rowIndex;
result = prime * result + Float.floatToIntBits(weight);
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
FormField other = (FormField) obj;
if (changed != other.changed)
return false;
if (displayName == null) {
if (other.displayName != null)
return false;
} else if (!displayName.equals(other.displayName))
return false;
if (displayPrompt == null) {
if (other.displayPrompt != null)
return false;
} else if (!displayPrompt.equals(other.displayPrompt))
return false;
if (fieldAccess != other.fieldAccess)
return false;
if (fieldName == null) {
if (other.fieldName != null)
return false;
} else if (!fieldName.equals(other.fieldName))
return false;
if (keyIndex != other.keyIndex)
return false;
if (optional != other.optional)
return false;
if (rowIndex != other.rowIndex)
return false;
if (Float.floatToIntBits(weight) != Float.floatToIntBits(other.weight))
return false;
return true;
}
protected static boolean strIsEmpty(String str) {
return str == null || str.length() == 0;
}
protected static String valueToDisplayString(Object value) {
String str = "";
if (value == null) {
str = "null";
} else {
if (value instanceof FormField) {
str = ((FormField)value).getDisplayString();
} else {
str = value.toString();
}
if (value instanceof CharSequence || value instanceof FormEnum) {
str = "\"" + str + "\"";
}
}
return str;
}
public static interface ChangeListener {
public void onChanged (boolean changed);
}
public static abstract class ValueChangeListener implements Serializable {
private static final long serialVersionUID = -3772014837874641680L;
public ValueChangeListener() {}
public abstract void onValueChanged (Object value);
}
}