Repository: empire-db Updated Branches: refs/heads/master 1f1259b61 -> 9176b225f
http://git-wip-us.apache.org/repos/asf/empire-db/blob/9176b225/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/SelectInputControl.java ---------------------------------------------------------------------- diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/SelectInputControl.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/SelectInputControl.java index 3912b0b..22378f4 100644 --- a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/SelectInputControl.java +++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/SelectInputControl.java @@ -18,9 +18,11 @@ */ package org.apache.empire.jsf2.controls; +import java.lang.reflect.Field; import java.util.Iterator; import java.util.List; +import javax.el.ValueExpression; import javax.faces.component.UIComponent; import javax.faces.component.UISelectItem; import javax.faces.component.html.HtmlSelectOneMenu; @@ -31,6 +33,7 @@ import org.apache.empire.commons.OptionEntry; import org.apache.empire.commons.Options; import org.apache.empire.data.Column; import org.apache.empire.exceptions.InternalException; +import org.apache.empire.exceptions.ItemNotFoundException; import org.apache.empire.exceptions.UnexpectedReturnValueException; import org.apache.empire.jsf2.app.TextResolver; import org.slf4j.Logger; @@ -38,95 +41,118 @@ import org.slf4j.LoggerFactory; public class SelectInputControl extends InputControl { - private static final Logger log = LoggerFactory.getLogger(SelectInputControl.class); + private static final Logger log = LoggerFactory.getLogger(SelectInputControl.class); - public static final String COLATTR_ABBR_OPTIONS = "ABBR_OPTIONS"; // Option list for abbreviations - - public static final String NAME = "select"; + public static final String COLATTR_ABBR_OPTIONS = "ABBR_OPTIONS"; // Option list for abbreviations + + public static final String VALUE_EXPRESSION_FLAG = "VALUE_EXPRESSION_FLAG"; - private Class<? extends javax.faces.component.html.HtmlSelectOneMenu> inputComponentClass; + public static final String NAME = "select"; + private final Class<? extends HtmlSelectOneMenu> inputComponentClass; + public SelectInputControl(Class<? extends HtmlSelectOneMenu> inputComponentClass) { - super(NAME); + super(SelectInputControl.NAME); this.inputComponentClass = inputComponentClass; } public SelectInputControl() { - this(javax.faces.component.html.HtmlSelectOneMenu.class); + this(HtmlSelectOneMenu.class); } - - /* for SelectTag (when no column is available) */ + + /* for SelectTag (when no column is available) */ public HtmlSelectOneMenu createMenuComponent(UIComponent parent) { - try { - return inputComponentClass.newInstance(); - } catch (InstantiationException e1) { - throw new InternalException(e1); - } catch (IllegalAccessException e2) { - throw new InternalException(e2); - } + return InputControlManager.createComponent(FacesContext.getCurrentInstance(), this.inputComponentClass); } - + @Override protected void createInputComponents(UIComponent parent, InputInfo ii, FacesContext context, List<UIComponent> compList) { HtmlSelectOneMenu input; - if (compList.size()==0) - { try { - input = inputComponentClass.newInstance(); - } catch (InstantiationException e1) { - throw new InternalException(e1); - } catch (IllegalAccessException e2) { - throw new InternalException(e2); - } + if (compList.size() == 0) + { // create component + input = InputControlManager.createComponent(context, this.inputComponentClass); + // setValueExpressionFlag + Object value = ii.getValue(false); + input.getAttributes().put(SelectInputControl.VALUE_EXPRESSION_FLAG, (value instanceof ValueExpression)); // copy Attributes copyAttributes(parent, ii, input); // disabled - boolean disabled = ii.isDisabled(); + boolean disabled = ii.isDisabled(); input.setDisabled(disabled); // Options - Options options = ii.getOptions(); - boolean hasEmpty =(!ii.isRequired() && !(disabled && ii.getColumn().isRequired()) && !options.contains("")); - String nullText = (hasEmpty) ? getNullText(ii) : ""; - initOptions(input, ii.getTextResolver(), options, hasEmpty, nullText); + Options options = getOptions(ii); + boolean addEmpty = getEmptyEntryRequired(ii, disabled) && !options.contains(""); + String nullText = (addEmpty) ? getNullText(ii) : ""; + initOptions(input, ii.getTextResolver(), options, addEmpty, nullText); // add compList.add(input); } else - { // check type + { // check type UIComponent comp = compList.get(0); if (!(comp instanceof HtmlSelectOneMenu)) throw new UnexpectedReturnValueException(comp.getClass().getName(), "compList.get"); // cast - input = (HtmlSelectOneMenu)comp; + input = (HtmlSelectOneMenu) comp; // disabled - boolean disabled = ii.isDisabled(); + boolean disabled = ii.isDisabled(); input.setDisabled(disabled); // Options (sync) - Options options = ii.getOptions(); - boolean hasEmpty =(!ii.isRequired() && !(disabled && ii.getColumn().isRequired()) && !options.contains("")); - String nullText = (hasEmpty) ? getNullText(ii) : ""; - syncOptions(input, ii.getTextResolver(), options, hasEmpty, nullText); + Options options = getOptions(ii); + boolean addEmpty = getEmptyEntryRequired(ii, disabled) && !options.contains(""); + String nullText = (addEmpty) ? getNullText(ii) : ""; + syncOptions(input, ii.getTextResolver(), options, addEmpty, nullText, ii.isInsideUIData()); } // style addRemoveDisabledStyle(input, input.isDisabled()); addRemoveInvalidStyle(input, ii.hasError()); - + // Set Value setInputValue(input, ii); } + + @Override + protected void updateInputState(List<UIComponent> compList, InputInfo ii, FacesContext context) + { + UIComponent comp = compList.get(0); + if (!(comp instanceof HtmlSelectOneMenu)) + { + throw new UnexpectedReturnValueException(comp.getClass().getName(), "parent.getChildren()"); + } + HtmlSelectOneMenu input = (HtmlSelectOneMenu)comp; + // disabled + boolean disabled = ii.isDisabled(); + input.setDisabled(disabled); + // Options (sync) + Options options = ii.getOptions(); + boolean addEmpty = getEmptyEntryRequired(ii, disabled) && !options.contains(""); + String nullText = (addEmpty) ? getNullText(ii) : ""; + syncOptions(input, ii.getTextResolver(), options, addEmpty, nullText, ii.isInsideUIData()); + } + + private boolean getEmptyEntryRequired(InputInfo ii, boolean disabled) + { + if (!ii.isRequired() && !(disabled && ii.getColumn().isRequired())) + { + return true; + } + // Check Value + return (ii.getValue(true) == null); + } public void initOptions(HtmlSelectOneMenu input, TextResolver textResolver, Options options, boolean addEmpty, String nullText) { if (addEmpty) - { // Empty entry - addSelectItem(input, textResolver, new OptionEntry("", nullText)); + { // Empty entry + addSelectItem(input, textResolver, new OptionEntry(null, nullText)); } - if (options!=null && options.size()>0) - { // Add options + if (options != null && options.size() > 0) + { // Add options for (OptionEntry e : options) { // Option entries addSelectItem(input, textResolver, e); @@ -134,110 +160,196 @@ public class SelectInputControl extends InputControl } } - public void syncOptions(HtmlSelectOneMenu input, TextResolver textResolver, Options options, boolean hasEmpty, String nullText) + public void syncOptions(HtmlSelectOneMenu input, TextResolver textResolver, Options options, boolean hasEmpty, String nullText, boolean isInsideUIData) { // Compare child-items with options Iterator<OptionEntry> ioe = options.iterator(); - OptionEntry oe =(ioe.hasNext() ? ioe.next() : null); + OptionEntry oe = (ioe.hasNext() ? ioe.next() : null); List<UIComponent> childList = input.getChildren(); Iterator<UIComponent> ico = childList.iterator(); int lastIndex = 0; + boolean emptyPresent = false; while (ico.hasNext()) { lastIndex++; - UIComponent co = ico.next(); + UIComponent co = ico.next(); if (!(co instanceof UISelectItem)) continue; - UISelectItem si = (UISelectItem)co; + UISelectItem si = (UISelectItem) co; Object ov = si.getItemValue(); if (ObjectUtils.isEmpty(ov) && hasEmpty) + { emptyPresent = true; continue; - if (oe==null) + } + if (oe == null) { // remove obsolete items - lastIndex--; - for (int index = childList.size()-1; index>=lastIndex; index--) + lastIndex--; + for (int index = childList.size() - 1; index >= lastIndex; index--) childList.remove(index); // done return; - } + } if (ObjectUtils.compareEqual(ov, oe.getValue())) { // next - oe =(ioe.hasNext() ? ioe.next() : null); + oe = (ioe.hasNext() ? ioe.next() : null); continue; - } + } // Not equal - do a full reload input.getChildren().clear(); if (hasEmpty) addSelectItem(input, textResolver, new OptionEntry("", nullText)); for (OptionEntry e : options) - { // Option entries + { // Option entries addSelectItem(input, textResolver, e); } // done return; } + // check empty entry + if (hasEmpty && !emptyPresent) + { // add missing empty entry + addSelectItem(input, textResolver, new OptionEntry("", nullText), 0); + } // Are there any items left? - while(oe!=null) - { // add missing item + while (oe != null) + { // add missing item addSelectItem(input, textResolver, oe); - oe =(ioe.hasNext() ? ioe.next() : null); + oe = (ioe.hasNext() ? ioe.next() : null); } } - public void addSelectItem(UIComponent input, TextResolver textResolver, OptionEntry e) + public void addSelectItem(UIComponent input, TextResolver textResolver, OptionEntry e, int pos) { UISelectItem selectItem = new UISelectItem(); // set value - selectItem.setItemValue(e.getValueString()); + Object value; + Object valueExpressionFlag = input.getAttributes().get(SelectInputControl.VALUE_EXPRESSION_FLAG); + if (ObjectUtils.getBoolean(valueExpressionFlag)) + { // Use value as is + value = e.getValue(); + } + else + { // Convert to String + value = e.getValueString(); + } + selectItem.setItemValue(value); // set text String text = e.getText(); text = textResolver.resolveText(text); selectItem.setItemLabel(text); // add item - input.getChildren().add(selectItem); + if (pos>=0) + input.getChildren().add(pos, selectItem); + else + input.getChildren().add(selectItem); + } + + public void addSelectItem(UIComponent input, TextResolver textResolver, OptionEntry e) + { + addSelectItem(input, textResolver, e, -1); } private String getNullText(InputInfo ii) { - String nullText = getFormatString(ii, FORMAT_NULL, FORMAT_NULL_ATTRIBUTE); - return (nullText!=null) ? ii.getText(nullText) : ""; + String nullText = getFormatString(ii, InputControl.FORMAT_NULL, InputControl.FORMAT_NULL_ATTRIBUTE); + return (nullText != null) ? ii.getText(nullText) : ""; } @Override protected String formatValue(Object value, ValueInfo vi) { // Lookup and Print value - if (vi.getOptions()==null) + if (vi.getOptions() == null) { - log.warn("Select field {} has no Option list attached!", vi.getColumn().getName()); + SelectInputControl.log.warn("Select field {} has no Option list attached!", vi.getColumn().getName()); return super.formatValue(value, vi); } // Check for Abbreviation if (hasFormatOption(vi, "short")) { Column column = vi.getColumn(); - if (column!=null) + if (column != null) { // Check for Abbreviation option list - Object attrValue = column.getAttribute(COLATTR_ABBR_OPTIONS); + Object attrValue = column.getAttribute(SelectInputControl.COLATTR_ABBR_OPTIONS); if (attrValue instanceof Options) - { // Check for Options - String text = ((Options)attrValue).get(value); + { // Check for Options + String text = ((Options) attrValue).get(value); if (text != null) return vi.getText(text); // Error - log.error("The element '" + String.valueOf(value) + "' is not part of the supplied option list."); + SelectInputControl.log.error("The element '" + String.valueOf(value) + "' is not part of the supplied option list."); } } } return super.formatValue(value, vi); } + + @Override + protected Object formatInputValue(Object value, InputInfo ii) + { + // the enum Value + if (value != null && value.getClass().isEnum()) + { + return ((Enum<?>) value).name(); + } + // the value + return value; + } + + @Override + protected Object parseInputValue(String value, InputInfo ii) + { + Object enumType = ii.getColumn().getAttribute(Column.COLATTR_ENUMTYPE); + if (enumType != null) + { + try + { // get enum + Class<?> enumClass = (Class<?>) enumType; + Field field = enumClass.getDeclaredField(value); + return field.get(null); + } + catch (NoSuchFieldException e) + { + throw new ItemNotFoundException(value); + } + catch (SecurityException e) + { + throw new InternalException(e); + } + catch (IllegalArgumentException e) + { + throw new InternalException(e); + } + catch (IllegalAccessException e) + { + throw new InternalException(e); + } + } + return value; + } + + /** + * gets the options in a safe way (not null) + * @param ii + * @return the options for this column + */ + protected Options getOptions(InputInfo ii) + { + Options options = ii.getOptions(); + if (options==null) + { + log.warn("No options given for column {}", ii.getColumn().getName()); + options = new Options(); + } + return options; + } /* @Override public void renderInput(ResponseWriter writer, ControlInfo ci) { boolean disabled = ci.getDisabled(); - + HtmlTag input = writer.startTag("select"); input.addAttribute("id", ci.getId()); input.addAttribute("class", ci.getCssClass()); @@ -296,5 +408,5 @@ public class SelectInputControl extends InputControl option.endTag(true); } */ - + } http://git-wip-us.apache.org/repos/asf/empire-db/blob/9176b225/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/TextAreaInputControl.java ---------------------------------------------------------------------- diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/TextAreaInputControl.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/TextAreaInputControl.java index 227f72d..37d6ade 100644 --- a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/TextAreaInputControl.java +++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/TextAreaInputControl.java @@ -26,7 +26,6 @@ import javax.faces.context.FacesContext; import org.apache.empire.commons.ObjectUtils; import org.apache.empire.commons.StringUtils; -import org.apache.empire.exceptions.InternalException; import org.apache.empire.exceptions.UnexpectedReturnValueException; public class TextAreaInputControl extends InputControl @@ -59,13 +58,8 @@ public class TextAreaInputControl extends InputControl { HtmlInputTextarea input; if (compList.size()==0) - { try { - input = inputComponentClass.newInstance(); - } catch (InstantiationException e1) { - throw new InternalException(e1); - } catch (IllegalAccessException e2) { - throw new InternalException(e2); - } + { // create component + input = InputControlManager.createComponent(context, this.inputComponentClass); // once copyAttributes(parent, ii, input); // cols @@ -103,6 +97,24 @@ public class TextAreaInputControl extends InputControl setInputValue(input, ii); } + + @Override + protected void updateInputState(List<UIComponent> compList, InputInfo ii, FacesContext context) + { + UIComponent comp = compList.get(0); + if (!(comp instanceof HtmlInputTextarea)) + { + throw new UnexpectedReturnValueException(comp.getClass().getName(), "compList.get(0)"); + } + HtmlInputTextarea input = (HtmlInputTextarea)comp; + // disabled + Object dis = ii.getAttributeEx("disabled"); + if (dis!=null) + input.setDisabled(ObjectUtils.getBoolean(dis)); + // field-readOnly + if (ObjectUtils.getBoolean(dis)==false) + input.setReadonly(ii.isFieldReadOnly()); + } @Override protected String formatValue(Object value, ValueInfo vi) http://git-wip-us.apache.org/repos/asf/empire-db/blob/9176b225/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/TextInputControl.java ---------------------------------------------------------------------- diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/TextInputControl.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/TextInputControl.java index 7d561b6..6e723c5 100644 --- a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/TextInputControl.java +++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/TextInputControl.java @@ -24,7 +24,6 @@ import java.text.DateFormat; import java.text.NumberFormat; import java.text.ParseException; import java.text.SimpleDateFormat; -import java.util.Currency; import java.util.Date; import java.util.List; import java.util.Locale; @@ -41,8 +40,6 @@ import org.apache.empire.commons.Options; import org.apache.empire.commons.StringUtils; import org.apache.empire.data.Column; import org.apache.empire.data.DataType; -import org.apache.empire.db.DBColumn; -import org.apache.empire.exceptions.InternalException; import org.apache.empire.exceptions.UnexpectedReturnValueException; import org.apache.empire.jsf2.utils.TagEncodingHelper; import org.slf4j.Logger; @@ -50,21 +47,18 @@ import org.slf4j.LoggerFactory; public class TextInputControl extends InputControl { - private static final Logger log = LoggerFactory.getLogger(TextInputControl.class); - - public static final String NAME = "text"; - - public static final String FORMAT_UNIT = "unit:"; - public static final String FORMAT_UNIT_ATTRIBUTE = "format:unit"; - - public static final String DATE_FORMAT = "date-format:"; - public static final String DATE_FORMAT_ATTRIBUTE = "format:date"; - - public static final String GROUP_SEPARATOR = "group-separator:"; - public static final String FRACTION_DIGITS = "fraction-digits:"; - - private Class<? extends javax.faces.component.html.HtmlInputText> inputComponentClass; - + private static final Logger log = LoggerFactory.getLogger(TextInputControl.class); + + public static final String NAME = "text"; + + public static final String FORMAT_UNIT = "unit:"; + public static final String FORMAT_UNIT_ATTRIBUTE = "format:unit"; + + public static final String DATE_FORMAT = "date-format:"; + public static final String DATE_FORMAT_ATTRIBUTE = "format:date"; + + private Class<? extends HtmlInputText> inputComponentClass; + public TextInputControl(String name, Class<? extends HtmlInputText> inputComponentClass) { super(name); @@ -78,118 +72,152 @@ public class TextInputControl extends InputControl public TextInputControl() { - this(NAME, javax.faces.component.html.HtmlInputText.class); + this(TextInputControl.NAME, javax.faces.component.html.HtmlInputText.class); } - + @Override protected void createInputComponents(UIComponent parent, InputInfo ii, FacesContext context, List<UIComponent> compList) { HtmlInputText input; - if (compList.size()==0) - { try { - input = inputComponentClass.newInstance(); - } catch (InstantiationException e1) { - throw new InternalException(e1); - } catch (IllegalAccessException e2) { - throw new InternalException(e2); - } + if (compList.size() == 0) + { // create component + input = InputControlManager.createComponent(context, this.inputComponentClass); // once copyAttributes(parent, ii, input); // language input.setLang(ii.getLocale().getLanguage()); // maxlength - int maxLength = getMaxInputLength(ii.getColumn()); - if (maxLength>0) + int maxLength = getMaxInputLength(ii); + if (maxLength > 0) + { input.setMaxlength(maxLength); + } // add compList.add(input); // add unit String unit = getUnitString(ii); - if (StringUtils.isNotEmpty(unit)) - { // add the unit - compList.add(createUnitLabel("eUnit", ii, unit)); + if (StringUtils.isNotEmpty(unit)) + { // add the unit + compList.add(createUnitLabel("eUnit", ii, unit)); } // add hint String hint = StringUtils.toString(ii.getAttribute("hint")); - if (StringUtils.isNotEmpty(hint) && !ii.isDisabled()) - { // add the hint (if not an empty string!) - compList.add(createUnitLabel("eInputHint", ii, hint)); + if (StringUtils.isNotEmpty(hint) && !ii.isDisabled()) + { // add the hint (if not an empty string!) + compList.add(createUnitLabel("eInputHint", ii, hint)); } - } + } else - { // check type + { // check type UIComponent comp = compList.get(0); if (!(comp instanceof HtmlInputText)) + { throw new UnexpectedReturnValueException(comp.getClass().getName(), "compList.get"); + } // cast - input = (HtmlInputText)comp; + input = (HtmlInputText) comp; } // disabled Object dis = ii.getAttributeEx("disabled"); - if (dis!=null) + if (dis != null) + { input.setDisabled(ObjectUtils.getBoolean(dis)); + } // field-readOnly - if (ObjectUtils.getBoolean(dis)==false) + if (ObjectUtils.getBoolean(dis) == false) + { input.setReadonly(ii.isFieldReadOnly()); + } // style addRemoveDisabledStyle(input, (input.isDisabled() || input.isReadonly())); addRemoveInvalidStyle(input, ii.hasError()); - + // set value setInputValue(input, ii); } - + + @Override + protected void updateInputState(List<UIComponent> compList, InputInfo ii, FacesContext context) + { + UIComponent comp = compList.get(0); + if (!(comp instanceof HtmlInputText)) + { + throw new UnexpectedReturnValueException(comp.getClass().getName(), "compList.get(0)"); + } + HtmlInputText input = (HtmlInputText) comp; + // disabled + Object dis = ii.getAttributeEx("disabled"); + if (dis != null) + { + input.setDisabled(ObjectUtils.getBoolean(dis)); + } + // field-readOnly + if (ObjectUtils.getBoolean(dis) == false) + { + input.setReadonly(ii.isFieldReadOnly()); + } + } + protected UIComponent createUnitLabel(String tagStyle, InputInfo ii, String value) { HtmlOutputText text = new HtmlOutputText(); text.setValue(value); // wrap HtmlPanelGroup span = new HtmlPanelGroup(); - String styleClass = TagEncodingHelper.getTagStyleClass(tagStyle, TagEncodingHelper.getDataTypeClass(ii.getColumn().getDataType()), null, null); + String styleClass = TagEncodingHelper.getTagStyleClass(tagStyle, TagEncodingHelper.getDataTypeClass(ii.getColumn().getDataType()), + null, null); span.getAttributes().put("styleClass", styleClass); span.getChildren().add(text); return span; } - + // ------- parsing ------- @Override protected Object parseInputValue(String value, InputInfo ii) { // Trim - if (hasFormatOption(ii, "notrim")==false) + if (hasFormatOption(ii, "notrim") == false) + { value = value.trim(); + } // Check Data Type Column column = ii.getColumn(); DataType type = column.getDataType(); if (type.isText()) + { return value; + } // Check other types - if (type==DataType.INTEGER) - { NumberFormat nf = NumberFormat.getIntegerInstance(ii.getLocale()); + if (type == DataType.INTEGER) + { + NumberFormat nf = NumberFormat.getIntegerInstance(ii.getLocale()); return parseNumber(value, nf); } - if (type==DataType.DECIMAL || type==DataType.FLOAT) - { NumberFormat nf = NumberFormat.getNumberInstance(ii.getLocale()); + if (type == DataType.DECIMAL || type == DataType.FLOAT) + { + NumberFormat nf = NumberFormat.getNumberInstance(ii.getLocale()); return parseNumber(value, nf); } - if (type==DataType.DATE || type==DataType.DATETIME) - { return parseDate(value, getDateFormat(column.getDataType(), ii, column)); + if (type == DataType.DATE || type == DataType.DATETIME) + { + return parseDate(value, getDateFormat(column.getDataType(), ii, column)); } - if (type==DataType.BOOL) - { return ObjectUtils.getBoolean(value); + if (type == DataType.BOOL) + { + return ObjectUtils.getBoolean(value); } - if (type==DataType.AUTOINC) - { // autoinc + if (type == DataType.AUTOINC) + { // autoinc log.error("Autoinc-value cannot be changed."); return null; } // Default return value; } - + // ------- validation ------- /* @Override @@ -212,12 +240,17 @@ public class TextInputControl extends InputControl return o; } */ - + // ------- formatting ------- @Override protected String formatValue(Object value, ValueInfo vi) { + return formatValue(value, vi, true); + } + + protected String formatValue(Object value, ValueInfo vi, boolean escapeHTML) + { // Lookup and Print value Options options = vi.getOptions(); if (options != null && !options.isEmpty()) @@ -230,9 +263,9 @@ public class TextInputControl extends InputControl } // Check Value if (value == null) - { // Try to use default value - Object nullValue = getFormatOption(vi, FORMAT_NULL, FORMAT_NULL_ATTRIBUTE); - if (nullValue!=null) + { // Try to use default value + Object nullValue = getFormatOption(vi, InputControl.FORMAT_NULL, InputControl.FORMAT_NULL_ATTRIBUTE); + if (nullValue != null) return formatValue(nullValue, vi); // Empty String return ""; @@ -246,7 +279,9 @@ public class TextInputControl extends InputControl if (hasFormatOption(vi, "noencode")) return s; // Encoded text - return escapeHTML(s); + if (escapeHTML) + s = escapeHTML(s); + return s; } if (dataType == DataType.INTEGER || dataType == DataType.AUTOINC) { // Integer @@ -256,12 +291,12 @@ public class TextInputControl extends InputControl } if (dataType == DataType.DECIMAL || dataType == DataType.FLOAT) { // Dezimal oder Double - NumberFormat nf = getNumberFormat(dataType, vi); + NumberFormat nf = getNumberFormat(dataType, vi.getLocale(), column); return nf.format(value); } if (dataType == DataType.DATE || dataType == DataType.DATETIME) { // Date or DateTime - if (dataType== DataType.DATETIME && hasFormatOption(vi, "notime")) + if (dataType == DataType.DATETIME && hasFormatOption(vi, "notime")) dataType = DataType.DATE; // Now format the date according to the user's locale DateFormat df = getDateFormat(dataType, vi, column); @@ -272,7 +307,11 @@ public class TextInputControl extends InputControl * } */ // Convert to String - return escapeHTML(String.valueOf(value)); + if (escapeHTML) + { + return escapeHTML(String.valueOf(value)); + } + return String.valueOf(value); } /* @@ -301,32 +340,32 @@ public class TextInputControl extends InputControl if (options != null && !options.isEmpty()) return value; // Format - return formatValue(value, ii); + return formatValue(value, ii, false); } - + // ------- render ------- - + @Override public void renderValue(ValueInfo vi, ResponseWriter writer) throws IOException { String text = formatValue(vi); if (StringUtils.isEmpty(text)) - { // nothing - writer.append(" "); + { // nothing + writer.append(HTML_EXPR_NBSP); return; - } + } // append text writer.append(text); // unit? String unit = getUnitString(vi); if (StringUtils.isNotEmpty(unit)) - { // append unit + { // append unit writer.append(" "); writer.append(unit); } } - + /* @Override public void renderInput(Response writer, ControlInfo ci) @@ -376,56 +415,65 @@ public class TextInputControl extends InputControl } } */ - + // ------- Input Helpers ------- - protected int getMaxInputLength(Column col) + protected int getMaxInputLength(InputInfo ii) { + // check custom + String maxlen = getFormatOption(ii, "maxlength:"); + if (StringUtils.isNotEmpty(maxlen)) + { + int ml = ObjectUtils.getInteger(maxlen); + if (ml > 0) + return ml; + } + + Column col = ii.getColumn(); // cast to DBTableColumn DataType type = col.getDataType(); - if (type==DataType.CHAR || - type==DataType.TEXT) - return (int)Math.round(col.getSize()); - if (type==DataType.AUTOINC || - type==DataType.INTEGER) - return 10; - if (type==DataType.FLOAT) + if (type == DataType.CHAR || + type == DataType.TEXT) + return (int) Math.round(col.getSize()); + if (type == DataType.AUTOINC || type == DataType.INTEGER) + return 10; + if (type == DataType.FLOAT) return 18; - if (type==DataType.DECIMAL) - { // check precision and scale + if (type == DataType.DECIMAL) + { // check precision and scale double size = col.getSize(); - int prec = (int)Math.round(size); + int prec = (int) Math.round(size); if (prec == 0) return 0; int len = prec; // scale - int scale =((int)(size*10)-(prec*10)); - if (scale>0) + int scale = ((int) (size * 10) - (prec * 10)); + if (scale > 0) len++; // Dezimaltrenner // thousand separator ? - Object groupSep = col.getAttribute(InputControl.NUMBER_GROUPSEP_ATTRIBUTE); - if (groupSep!=null && ObjectUtils.getBoolean(groupSep)) - len += ((prec-scale-1)/3); + Object groupSep = col.getAttribute(Column.COLATTR_NUMBER_GROUPSEP); + if (groupSep != null && ObjectUtils.getBoolean(groupSep)) + len += ((prec - scale - 1) / 3); // sign? - Object minVal = col.getAttribute(DBColumn.DBCOLATTR_MINVALUE); - if (minVal==null || ObjectUtils.getInteger(minVal)<0) + Object minVal = col.getAttribute(Column.COLATTR_MINVALUE); + if (minVal == null || ObjectUtils.getInteger(minVal) < 0) len++; // Vorzeichen // fertig return len; } - if (type==DataType.BOOL) + if (type == DataType.BOOL) return 1; - if (type==DataType.DATE) + if (type == DataType.DATE) return 10; - if (type==DataType.DATETIME) + if (type == DataType.DATETIME) return 16; - if (type==DataType.CLOB) + if (type == DataType.CLOB) return 0; // unlimited (use 0x7FFFFFFF instead?) // undefined! log.info("No max-length available for data type {}.", type); return 0; } - + protected DataType getValueType(Object value, DataType desiredType) { // Detect Data Type from Value @@ -433,8 +481,10 @@ public class TextInputControl extends InputControl return DataType.TEXT; if (value instanceof Number) { // Check desired type - if (desiredType == DataType.AUTOINC || desiredType == DataType.INTEGER || - desiredType == DataType.FLOAT || desiredType == DataType.DECIMAL) + if (desiredType == DataType.AUTOINC || + desiredType == DataType.INTEGER || + desiredType == DataType.FLOAT || + desiredType == DataType.DECIMAL) return desiredType; // Detect type if (value instanceof Integer || value instanceof Long || value instanceof Short) @@ -459,86 +509,93 @@ public class TextInputControl extends InputControl // Default Datatype return DataType.UNKNOWN; } - - protected NumberFormat getNumberFormat(DataType dataType, ValueInfo vi) + + protected NumberFormat getNumberFormat(DataType dataType, Locale locale, Column column) { - Column column = vi.getColumn(); - Locale locale = vi.getLocale(); - if (column==null) - return NumberFormat.getNumberInstance(locale); + if (column == null) + return NumberFormat.getNumberInstance(locale); // Column is supplied - String type = StringUtils.valueOf(column.getAttribute(InputControl.NUMBER_TYPE_ATTRIBUTE)); + String type = StringUtils.valueOf(column.getAttribute(Column.COLATTR_NUMBER_TYPE)); NumberFormat nf = null; if (type.equalsIgnoreCase("Integer")) nf = NumberFormat.getIntegerInstance(locale); else nf = NumberFormat.getNumberInstance(locale); // Groups Separator? - Object groupSep = getFormatOption(vi, GROUP_SEPARATOR, NUMBER_GROUPSEP_ATTRIBUTE); - nf.setGroupingUsed(groupSep!=null && ObjectUtils.getBoolean(groupSep)); + Object groupSep = column.getAttribute(Column.COLATTR_NUMBER_GROUPSEP); + nf.setGroupingUsed(groupSep != null && ObjectUtils.getBoolean(groupSep)); // Fraction Digits? - Object fractDigit = getFormatOption(vi, FRACTION_DIGITS, InputControl.NUMBER_FRACTION_DIGITS); - if (fractDigit!=null) + Object fractDigit = column.getAttribute(Column.COLATTR_FRACTION_DIGITS); + if (fractDigit != null) { int fractionDigits = ObjectUtils.getInteger(fractDigit); nf.setMaximumFractionDigits(fractionDigits); nf.setMinimumFractionDigits(fractionDigits); } // Number format - return nf; + return nf; } - + protected DateFormat getDateFormat(DataType dataType, ValueInfo vi, Column column) { String pattern = null; int type = DateFormat.DEFAULT; // Is unit supplied as a format option - String format = getFormatString(vi, DATE_FORMAT, DATE_FORMAT_ATTRIBUTE); - if (format!=null) - { // format has been provided + String format = getFormatString(vi, TextInputControl.DATE_FORMAT, TextInputControl.DATE_FORMAT_ATTRIBUTE); + if (format != null) + { // format has been provided if (StringUtils.compareEqual(format, "full", true)) - type=DateFormat.FULL; + type = DateFormat.FULL; else if (StringUtils.compareEqual(format, "medium", true)) - type=DateFormat.MEDIUM; + type = DateFormat.MEDIUM; else if (StringUtils.compareEqual(format, "short", true)) - type=DateFormat.SHORT; + type = DateFormat.SHORT; else if (StringUtils.compareEqual(format, "long", true)) - type=DateFormat.LONG; - else - pattern = format; + type = DateFormat.LONG; + else + pattern = format; } // return date formatter DateFormat df; if (StringUtils.isNotEmpty(pattern)) - df = new SimpleDateFormat(pattern, vi.getLocale()); - else if (dataType==DataType.DATE) - df = DateFormat.getDateInstance(type, vi.getLocale()); + df = new SimpleDateFormat(pattern, vi.getLocale()); + else if (dataType == DataType.DATE) + df = DateFormat.getDateInstance(type, vi.getLocale()); else - df = DateFormat.getDateTimeInstance(type, type, vi.getLocale()); + df = DateFormat.getDateTimeInstance(type, type, vi.getLocale()); return df; } - private String getUnitString(ValueInfo vi) + protected String getUnitString(ValueInfo vi) { // Is unit supplied as a format option - String format = getFormatString(vi, FORMAT_UNIT, FORMAT_UNIT_ATTRIBUTE); - if (format!=null) - return format; + String format = getFormatString(vi, TextInputControl.FORMAT_UNIT, TextInputControl.FORMAT_UNIT_ATTRIBUTE); + if (format != null) + { + return vi.getTextResolver().resolveText(format); + } // Is it a currency column Column column = vi.getColumn(); - if (column!=null && column.getDataType()==DataType.DECIMAL) + if (column != null && column.getDataType() == DataType.DECIMAL) { - String numberType = StringUtils.toString(column.getAttribute(InputControl.NUMBER_TYPE_ATTRIBUTE)); - if (numberType!=null) + String numberType = StringUtils.toString(column.getAttribute(Column.COLATTR_NUMBER_TYPE)); + if (numberType != null) { if (numberType.equalsIgnoreCase("Currency")) { - String currencyCode = StringUtils.toString(column.getAttribute(InputControl.CURRENCY_CODE_ATTRIBUTE)); - if (currencyCode!=null) + String currencyCode = StringUtils.toString(column.getAttribute(Column.COLATTR_CURRENCY_CODE)); + if (currencyCode != null) { // nf = NumberFormat.getCurrencyInstance(locale); - Currency currency = Currency.getInstance(currencyCode); - return (currency!=null) ? currency.getSymbol() : null; + // Currency currency = Currency.getInstance(currencyCode); + // return (currency != null) ? currency.getSymbol() : null; + if (currencyCode.equalsIgnoreCase("EUR")) + return "â¬"; + if (currencyCode.equalsIgnoreCase("USD")) + return "$"; + // done + return currencyCode; } - } else if (numberType.equalsIgnoreCase("Percent")) + } + else if (numberType.equalsIgnoreCase("Percent")) { return "%"; } @@ -547,34 +604,38 @@ public class TextInputControl extends InputControl // No Unit supplied return null; } - + // ------- value parsing ------- - + protected Object parseNumber(String s, NumberFormat nf) { // Try to convert - for (int i=0; i<s.length(); i++) - { if (s.charAt(i)>='A') - throw new NumberFormatException("Not a number: "+s); + for (int i = 0; i < s.length(); i++) + { + if (s.charAt(i) >= 'A') + { + throw new NumberFormatException("Not a number: " + s); + } } // Parse String try { return nf.parseObject(s); - } catch(ParseException pe) { - throw new NumberFormatException("Not a number: "+s+" Exception: "+pe.toString()); + } catch (ParseException pe) { + throw new NumberFormatException("Not a number: " + s + " Exception: " + pe.toString()); } } - + protected Object parseDate(String s, DateFormat df) { // Try to convert - try { + try + { // Parse Date df.setLenient(true); return df.parseObject(s); - } catch(ParseException pe) { - throw new RuntimeException("Invalid date format: "+s, pe); + } catch (ParseException pe) { + throw new RuntimeException("Invalid date format: " + s, pe); } } - + } http://git-wip-us.apache.org/repos/asf/empire-db/blob/9176b225/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pageelements/StaticListPageElement.java ---------------------------------------------------------------------- diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pageelements/StaticListPageElement.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pageelements/StaticListPageElement.java index 98a6db9..c67ef65 100644 --- a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pageelements/StaticListPageElement.java +++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pageelements/StaticListPageElement.java @@ -27,7 +27,7 @@ import org.slf4j.LoggerFactory; public class StaticListPageElement<T> extends ListPageElement<T> { - private static final Logger log = LoggerFactory.getLogger(BeanListPageElement.class); + private static final Logger log = LoggerFactory.getLogger(StaticListPageElement.class); private static final long serialVersionUID = 1L; http://git-wip-us.apache.org/repos/asf/empire-db/blob/9176b225/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/Page.java ---------------------------------------------------------------------- diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/Page.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/Page.java index 00e07da..0246ce2 100644 --- a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/Page.java +++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/Page.java @@ -37,9 +37,9 @@ import org.apache.empire.exceptions.EmpireException; import org.apache.empire.exceptions.InternalException; import org.apache.empire.exceptions.ItemNotFoundException; import org.apache.empire.exceptions.MiscellaneousErrorException; -import org.apache.empire.jsf2.app.WebApplication; import org.apache.empire.jsf2.app.FacesUtils; import org.apache.empire.jsf2.app.TextResolver; +import org.apache.empire.jsf2.app.WebApplication; import org.apache.empire.jsf2.utils.ParameterMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -141,7 +141,7 @@ public abstract class Page implements Serializable Page.log.debug("PageBean {} is already initialized. Calling doRefresh().", getPageName()); doRefresh(); } - catch (Throwable e) + catch (Exception e) { logAndHandleActionException("doRefresh", e); } @@ -153,7 +153,7 @@ public abstract class Page implements Serializable { checkPageAccess(); } - catch (Throwable e) + catch (Exception e) { logAndHandleActionException("checkAccess", e); // redirected? @@ -187,7 +187,7 @@ public abstract class Page implements Serializable */ try { - Page.log.debug("Executing action {} on {}.", String.valueOf(action), getPageName()); + log.info("Processing action {} on {}.", String.valueOf(action), getPageName()); Method method = getClass().getMethod(action); Object result = method.invoke(this); if (result != null) @@ -225,13 +225,19 @@ public abstract class Page implements Serializable doInit(); restoreSessionMessage(); } - catch (Throwable e) + catch (Exception e) { logAndHandleActionException("doInit", e); } } } + public boolean isHasMessages() + { + List<FacesMessage> msgl = FacesContext.getCurrentInstance().getMessageList(); + return !msgl.isEmpty(); + } + protected void checkPageAccess() { /* Throw exception if User has no Access */ @@ -263,7 +269,7 @@ public abstract class Page implements Serializable throw new InternalException(e); } } - + protected void setSessionMessage(FacesMessage facesMsg) { // Set Session Message @@ -411,10 +417,6 @@ public abstract class Page implements Serializable public void addJavascriptCall(String function) { - if (!function.endsWith(";")) - { // Add a semicolon (important!) - function += ";"; - } // Add Call FacesContext fc = FacesUtils.getContext(); WebApplication app = FacesUtils.getWebApplication(); @@ -494,6 +496,6 @@ public abstract class Page implements Serializable protected final TextResolver getTextResolver() { FacesContext fc = FacesUtils.getContext(); - return FacesUtils.getWebApplication().getTextResolver(fc); + return FacesUtils.getTextResolver(fc); } } http://git-wip-us.apache.org/repos/asf/empire-db/blob/9176b225/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/PageOutcome.java ---------------------------------------------------------------------- diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/PageOutcome.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/PageOutcome.java index 77b0936..b1f86bd 100644 --- a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/PageOutcome.java +++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/PageOutcome.java @@ -18,11 +18,15 @@ */ package org.apache.empire.jsf2.pages; +import java.io.Serializable; + import org.apache.empire.commons.StringUtils; import org.apache.empire.exceptions.InvalidArgumentException; -public class PageOutcome +public class PageOutcome implements Serializable { + private static final long serialVersionUID = 1L; + private String outcome; public PageOutcome(String outcome) { http://git-wip-us.apache.org/repos/asf/empire-db/blob/9176b225/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/PagesELResolver.java ---------------------------------------------------------------------- diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/PagesELResolver.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/PagesELResolver.java index dbef343..693d703 100644 --- a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/PagesELResolver.java +++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/PagesELResolver.java @@ -96,7 +96,7 @@ public class PagesELResolver extends ELResolver @Override public Object getValue(ELContext context, Object base, Object property) { - // Resolve database, table/view or column + // Resolve PageDefinitions, PageDefinition if (base instanceof PageDefinition) { String action = String.valueOf(property); http://git-wip-us.apache.org/repos/asf/empire-db/blob/9176b225/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/SessionMap.java ---------------------------------------------------------------------- diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/SessionMap.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/SessionMap.java new file mode 100644 index 0000000..44316f5 --- /dev/null +++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/SessionMap.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.empire.jsf2.utils; + +import java.util.Map; + +import javax.faces.context.FacesContext; + +import org.apache.empire.jsf2.pages.Page; + +public class SessionMap +{ + @SuppressWarnings("unchecked") + public static <T> T get(String objectName, Class<T> type) + { + Map<String, Object> map = FacesContext.getCurrentInstance().getExternalContext().getSessionMap(); + return (T) map.get(objectName); + } + + public static <T> T get(Page page, String propertyName, Class<T> type) + { + String objectName = page.getPageName() + "." + propertyName + "." + type.getSimpleName(); + return get(objectName, type); + } + + public static <T> void put(String objectName, Class<T> type, T object) + { + Map<String, Object> map = FacesContext.getCurrentInstance().getExternalContext().getSessionMap(); + if (object != null) + map.put(objectName, object); + else + map.remove(objectName); + } + + public static <T> void remove(Page page, String propertyName, Class<T> type, T object) + { + String objectName = page.getPageName() + "." + propertyName + "." + type.getSimpleName(); + put(objectName, type, object); + } + + public static <T> void remove(String objectName, Class<T> type) + { + put(objectName, type, null); + } + + public static <T> void remove(Page page, String propertyName, Class<T> type) + { + remove(page, propertyName, type, null); + } +} http://git-wip-us.apache.org/repos/asf/empire-db/blob/9176b225/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/TagEncodingHelper.java ---------------------------------------------------------------------- diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/TagEncodingHelper.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/TagEncodingHelper.java index a4ae7af..e5a040b 100644 --- a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/TagEncodingHelper.java +++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/TagEncodingHelper.java @@ -28,6 +28,7 @@ import javax.faces.FacesWrapper; import javax.faces.application.FacesMessage; import javax.faces.component.NamingContainer; import javax.faces.component.UIComponent; +import javax.faces.component.UIData; import javax.faces.component.UIInput; import javax.faces.component.UIOutput; import javax.faces.component.html.HtmlOutputLabel; @@ -54,13 +55,12 @@ import org.apache.empire.db.DBRowSet; import org.apache.empire.db.exceptions.FieldNotNullException; import org.apache.empire.exceptions.BeanPropertyGetException; import org.apache.empire.exceptions.BeanPropertySetException; -import org.apache.empire.exceptions.InternalException; import org.apache.empire.exceptions.InvalidArgumentException; import org.apache.empire.exceptions.NotSupportedException; import org.apache.empire.exceptions.PropertyReadOnlyException; -import org.apache.empire.jsf2.app.WebApplication; import org.apache.empire.jsf2.app.FacesUtils; import org.apache.empire.jsf2.app.TextResolver; +import org.apache.empire.jsf2.app.WebApplication; import org.apache.empire.jsf2.components.ControlTag; import org.apache.empire.jsf2.components.InputTag; import org.apache.empire.jsf2.components.LinkTag; @@ -68,6 +68,7 @@ import org.apache.empire.jsf2.components.RecordTag; import org.apache.empire.jsf2.controls.InputControl; import org.apache.empire.jsf2.controls.InputControlManager; import org.apache.empire.jsf2.controls.SelectInputControl; +import org.apache.empire.jsf2.controls.TextAreaInputControl; import org.apache.empire.jsf2.controls.TextInputControl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -221,6 +222,13 @@ public class TagEncodingHelper implements NamingContainer */ @Override + public String getStyleClass(String addlStyle) + { + String style = getTagStyleClass(addlStyle); + return style; + } + + @Override public String getFormat() { // null value @@ -255,6 +263,12 @@ public class TagEncodingHelper implements NamingContainer { return textResolver; } + + @Override + public boolean isInsideUIData() + { + return TagEncodingHelper.this.isInsideUIData(); + } } private class InputInfoImpl extends ValueInfoImpl implements InputControl.InputInfo @@ -324,13 +338,6 @@ public class TagEncodingHelper implements NamingContainer Column c = getColumn(); return c.getName(); // (c instanceof DBColumn) ? ((DBColumn)c).getFullName() : c.getName(); } - - @Override - public String getStyleClass(String addlStyle) - { - String style = getTagStyleClass(addlStyle); - return style; - } @Override public boolean hasError() @@ -352,8 +359,11 @@ public class TagEncodingHelper implements NamingContainer } // Logger - private static final Logger log = LoggerFactory.getLogger(TagEncodingHelper.class); + private static final Logger log = LoggerFactory.getLogger(TagEncodingHelper.class); + + public static final String ORIGINAL_COMPONENT_ID = "ORIGINAL_COMPONENT_ID"; + public static final String COLATTR_TOOLTIP = "TOOLTIP"; // Column tooltip public static final String COLATTR_ABBR_TITLE = "ABBR_TITLE"; // Column title for abbreviations private final UIOutput tag; @@ -367,7 +377,8 @@ public class TagEncodingHelper implements NamingContainer private TextResolver textResolver = null; private Object mostRecentValue = null; private boolean skipValidation = false; - private boolean hasError = false; + private boolean hasError = false; + private Boolean insideUIData = null; public TagEncodingHelper(UIOutput tag, String tagCssStyle) { @@ -418,27 +429,8 @@ public class TagEncodingHelper implements NamingContainer controlType = SelectInputControl.NAME; } } - // find control type - if (StringUtils.isNotEmpty(controlType)) - control = InputControlManager.getControl(controlType); - if (control == null) - { // Auto-detect - if (getValueOptions()!=null) - controlType = SelectInputControl.NAME; - else - { // get from data type - DataType dataType = column.getDataType(); - controlType = FacesUtils.getWebApplication().getDefaultControlType(dataType); - } - // get default control - control = InputControlManager.getControl(controlType); - // Still not? Use Text Control - if (control == null) - control = InputControlManager.getControl(TextInputControl.NAME); - // debug - if (log.isDebugEnabled() && !controlType.equals(TextInputControl.NAME)) - log.debug("Auto-detected field control for " + column.getName() + " is " + controlType); - } + // detect Control + control = detectInputControl(controlType, column.getDataType(), column.getOptions()!=null); // check record checkRecord(); return control; @@ -590,7 +582,7 @@ public class TagEncodingHelper implements NamingContainer { // a record mostRecentValue = ((RecordData) record).getValue(getColumn()); return mostRecentValue; - } + } else { // a normal bean String prop = getColumn().getBeanPropertyName(); @@ -628,7 +620,7 @@ public class TagEncodingHelper implements NamingContainer return; } */ - if (isDetectFieldChange()) + if (mostRecentValue!=null && isDetectFieldChange()) { // DetectFieldChange by comparing current and most recent value Object currentValue = ((Record) record).getValue(column); if (!ObjectUtils.compareEqual(currentValue, mostRecentValue)) @@ -752,9 +744,6 @@ public class TagEncodingHelper implements NamingContainer Object mandatory = getTagAttributeValue("mandatory"); if (mandatory!=null) return ObjectUtils.getBoolean(mandatory); - // Check Read-Only first - if (isReadOnly()) - return false; // Check Record if ((getRecord() instanceof Record)) { // Ask Record @@ -1031,11 +1020,37 @@ public class TagEncodingHelper implements NamingContainer throw new BeanPropertySetException(bean, property, e); } } - + public String getValueTooltip(Object value) { if (value == null) return null; + // is it a column + if (value instanceof Column) + { // find column value + Column ttc = ((Column)value); + if (getRecord() != null) + { // value + if (record instanceof RecordData) + { // a record + value = ((RecordData) record).getValue(ttc); + } + else + { // a normal bean + String prop = ttc.getBeanPropertyName(); + value = getBeanPropertyValue(record, prop); + } + // translate + // ValueInfoImpl vi = new MiscValueInfoImpl(ttc, textResolver); + // InputControl ctrl = detectInputControl(ttc.getControlType(), ttc.getDataType(), ttc.getOptions()!=null); + return StringUtils.valueOf(value); + } + else + { // Error + log.warn("Unable to resolve Tooltip-value for column {}.", ttc.getName()); + return null; + } + } // is it a template? String templ = StringUtils.valueOf(value); int valIndex = templ.indexOf("{}"); @@ -1060,11 +1075,14 @@ public class TagEncodingHelper implements NamingContainer public String getLabelTooltip(Column column) { String title = getTagAttributeString("title"); + if (title == null) + title = StringUtils.toString(column.getAttribute(Column.COLATTR_TOOLTIP)); if (title != null) return getDisplayText(title); // Check for short form if (hasFormat("short") && !ObjectUtils.isEmpty(column.getAttribute(COLATTR_ABBR_TITLE))) return getDisplayText(column.getTitle()); + // No Title return null; } @@ -1124,9 +1142,9 @@ public class TagEncodingHelper implements NamingContainer public Object getAttributeValueEx(String name) { Object value = getTagAttributeValue(name); - if (value==null) + if (value==null && hasColumn()) { // Check Column - value = getColumn().getAttribute(name); + value = column.getAttribute(name); } // Checks whether it's another column if (value instanceof Column) @@ -1152,13 +1170,24 @@ public class TagEncodingHelper implements NamingContainer } return value; } + + public String getTagAttributeStringEx(String name) + { + Object value = getAttributeValueEx(name); + return (value!=null) ? StringUtils.toString(value) : null; + } public Object getTagAttributeValue(String name) { - Object value = tag.getAttributes().get(name); + return TagEncodingHelper.getTagAttributeValue(tag, name); + } + + public static Object getTagAttributeValue(UIComponent comp, String name) + { + Object value = comp.getAttributes().get(name); if (value==null) { // try value expression - ValueExpression ve = tag.getValueExpression(name); + ValueExpression ve = comp.getValueExpression(name); if (ve!=null) { // It's a value expression FacesContext ctx = FacesContext.getCurrentInstance(); @@ -1240,14 +1269,7 @@ public class TagEncodingHelper implements NamingContainer throw new InvalidArgumentException("column", column); // create label now - HtmlOutputLabel label; - try { - label = InputControlManager.getLabelComponentClass().newInstance(); - } catch (InstantiationException e1) { - throw new InternalException(e1); - } catch (IllegalAccessException e2) { - throw new InternalException(e2); - } + HtmlOutputLabel label = InputControlManager.createComponent(context, InputControlManager.getLabelComponentClass()); // value String labelText = getLabelValue(column, colon); @@ -1288,7 +1310,7 @@ public class TagEncodingHelper implements NamingContainer label.setTitle(title); // required - if (required) + if (required && InputControlManager.isShowLabelRequiredMark()) addRequiredMark(label); return label; @@ -1344,7 +1366,7 @@ public class TagEncodingHelper implements NamingContainer b.append(" "); b.append(addlStyle); } - if (StringUtils.isNotEmpty(userStyle)) + if (StringUtils.isNotEmpty(userStyle) && !StringUtils.compareEqual(userStyle, addlStyle, false)) { b.append(" "); b.append(userStyle); @@ -1393,23 +1415,118 @@ public class TagEncodingHelper implements NamingContainer public final String getTagStyleClass(DataType dataType, String addlStyle) { - String userStyle = getTagAttributeString("styleClass"); + String userStyle = getTagAttributeStringEx("styleClass"); String typeClass = getDataTypeClass(dataType); return getTagStyleClass(tagCssStyle, typeClass, addlStyle, userStyle); } public final String getTagStyleClass(String addlStyle) { - String userStyle = getTagAttributeString("styleClass"); + String userStyle = getTagAttributeStringEx("styleClass"); String typeClass = hasColumn() ? getDataTypeClass(column.getDataType()) : null; return getTagStyleClass(tagCssStyle, typeClass, addlStyle, userStyle); } public final String getTagStyleClass() { - String userStyle = getTagAttributeString("styleClass"); + String userStyle = getTagAttributeStringEx("styleClass"); String typeClass = hasColumn() ? getDataTypeClass(column.getDataType()) : null; return getTagStyleClass(tagCssStyle, typeClass, null, userStyle); } + + public boolean isInsideUIData() + { + if (tag==null) + return false; + if (this.insideUIData!=null) + return this.insideUIData; + // detect + this.insideUIData = false; + for (UIComponent p = tag.getParent(); p!=null; p=p.getParent()) + { // Check whether inside UIData + if (p instanceof UIData) { + this.insideUIData = true; + break; + } + } + return this.insideUIData; + } + + public void saveComponentId(UIComponent comp) + { + if (comp==null || comp.getId()==null) + return; + String compId = comp.getId(); + comp.getAttributes().put(ORIGINAL_COMPONENT_ID, compId); + comp.setId(compId); // reset + } + + public void restoreComponentId(UIComponent comp) + { + if (comp==null) + return; + String compId = StringUtils.toString(comp.getAttributes().get(ORIGINAL_COMPONENT_ID)); + if (compId==null) + return; // not set + if (StringUtils.compareEqual(compId, comp.getId(), false)==false) + { // someone changed the id. Restore original Id + log.warn("Restoring original Component-id from {} to {}", comp.getId(), compId); + comp.setId(compId); + } + } + + public void resetComponentId(UIComponent comp) + { + if (comp==null || comp.getId()==null) + return; + if (isInsideUIData()) + { + String resetId = comp.getId(); + if (log.isInfoEnabled()) + log.info("Resetting Component-id inside UIData to {}", resetId); + comp.setId(resetId); + + /* needed ? + for (UIComponent c : comp.getChildren()) + { + resetComponentId(c); + } + */ + } + } + private static InputControl detectInputControl(String controlType, DataType dataType, boolean hasOptions) + { + // Create + if (dataType==null) + throw new InvalidArgumentException("dataType", dataType); + // find control type + InputControl control = null; + if (StringUtils.isNotEmpty(controlType)) + control = InputControlManager.getControl(controlType); + if (control == null) + { // Auto-detect + if (hasOptions) + controlType = SelectInputControl.NAME; + else + { // get from data type + switch (dataType) + { + case CLOB: + controlType = TextAreaInputControl.NAME; + break; + default: + controlType = TextInputControl.NAME; + } + } + // get default control + control = InputControlManager.getControl(controlType); + // Still not? Use Text Control + if (control == null) + control = InputControlManager.getControl(TextInputControl.NAME); + } + // check record + return control; + } + } http://git-wip-us.apache.org/repos/asf/empire-db/blob/9176b225/empire-db/src/main/java/org/apache/empire/data/Column.java ---------------------------------------------------------------------- diff --git a/empire-db/src/main/java/org/apache/empire/data/Column.java b/empire-db/src/main/java/org/apache/empire/data/Column.java index 96dfe6b..96baa91 100644 --- a/empire-db/src/main/java/org/apache/empire/data/Column.java +++ b/empire-db/src/main/java/org/apache/empire/data/Column.java @@ -26,6 +26,26 @@ package org.apache.empire.data; */ public interface Column extends ColumnExpr { + /** + * Predefined column expression attributes (optional) + * for method + * Object getAttribute(String name) + */ + public static final String COLATTR_TITLE = "title"; + public static final String COLATTR_TOOLTIP = "tooltip"; + public static final String COLATTR_TYPE = "type"; + public static final String COLATTR_ENUMTYPE = "enumType"; + + public static final String COLATTR_MINLENGTH = "minLength"; + public static final String COLATTR_MINVALUE = "minValue"; + public static final String COLATTR_MAXVALUE = "maxValue"; + public static final String COLATTR_REGEXP = "regExp"; + + public static final String COLATTR_NUMBER_TYPE = "numberType"; // "Integer", "Currency", "Percent" + public static final String COLATTR_NUMBER_GROUPSEP = "numberGroupSeparator"; // boolean (true or false) + public static final String COLATTR_FRACTION_DIGITS = "numberFractionDigits"; // integer + public static final String COLATTR_CURRENCY_CODE = "currencyCode"; // "ISO 4217 code of the currency" + public static final String COLATTR_DATETIMEPATTERN = "dateTimePattern"; // default is yyyy-MM-dd HH:mm:ss /** * Returns the maximum size a value for this column is allowed to have. http://git-wip-us.apache.org/repos/asf/empire-db/blob/9176b225/empire-db/src/main/java/org/apache/empire/db/DBColumn.java ---------------------------------------------------------------------- diff --git a/empire-db/src/main/java/org/apache/empire/db/DBColumn.java b/empire-db/src/main/java/org/apache/empire/db/DBColumn.java index e2f2140..0709a42 100644 --- a/empire-db/src/main/java/org/apache/empire/db/DBColumn.java +++ b/empire-db/src/main/java/org/apache/empire/db/DBColumn.java @@ -57,31 +57,29 @@ public abstract class DBColumn extends DBColumnExpr private static final Logger log = LoggerFactory.getLogger(DBColumn.class); // Predefined column attributes - - /** - * Mandatory column (Boolean) - */ - public static final String DBCOLATTR_MANDATORY = "mandatory"; /** - * Read only column (Boolean) + * @deprecated + * Use Column.COLATTR_MINVALUE */ - public static final String DBCOLATTR_READONLY = "readonly"; + public static final String DBCOLATTR_MINVALUE = Column.COLATTR_MINVALUE; /** - * Minimum value (Integer) + * @deprecated + * Use Column.COLATTR_MAXVALUE */ - public static final String DBCOLATTR_MINVALUE = "minValue"; + public static final String DBCOLATTR_MAXVALUE = Column.COLATTR_MAXVALUE; /** - * Maximum value (Integer) + * @deprecated + * Use Column.COLATTR_DATETIMEPATTERN */ - public static final String DBCOLATTR_MAXVALUE = "maxValue"; - + public static final String DBCOLATTR_DATETIMEPATTERN = Column.COLATTR_DATETIMEPATTERN; + /** - * Maximum value (Integer) + * Read only column (Boolean) */ - public static final String DBCOLATTR_DATETIMEPATTERN = "dateTimePattern"; // default is "yyyy-MM-dd HH:mm:ss" + public static final String DBCOLATTR_READONLY = "readonly"; /** * Read only column (Boolean) http://git-wip-us.apache.org/repos/asf/empire-db/blob/9176b225/empire-db/src/main/java/org/apache/empire/db/DBTableColumn.java ---------------------------------------------------------------------- diff --git a/empire-db/src/main/java/org/apache/empire/db/DBTableColumn.java b/empire-db/src/main/java/org/apache/empire/db/DBTableColumn.java index 5b81596..593e790 100644 --- a/empire-db/src/main/java/org/apache/empire/db/DBTableColumn.java +++ b/empire-db/src/main/java/org/apache/empire/db/DBTableColumn.java @@ -26,7 +26,9 @@ import java.util.Date; import org.apache.empire.commons.Attributes; import org.apache.empire.commons.ObjectUtils; +import org.apache.empire.commons.Options; import org.apache.empire.commons.StringUtils; +import org.apache.empire.data.Column; import org.apache.empire.data.DataMode; import org.apache.empire.data.DataType; import org.apache.empire.db.exceptions.FieldIllegalValueException; @@ -332,6 +334,27 @@ public class DBTableColumn extends DBColumn attributes.remove(DBCOLATTR_READONLY); } } + + /** + * sets the options from an enum class + */ + public void setEnumOptions(Class<?> enumType) + { + if (enumType==null || !enumType.isEnum()) + throw new InvalidArgumentException("enumType", enumType); + // Enum special treatment + log.debug("Creating options for enum type {}.", enumType.getName()); + @SuppressWarnings({ "rawtypes", "unchecked" }) + Enum<?>[] items = ((Class<Enum>)enumType).getEnumConstants(); + this.options = new Options(); + for (int i=0; i<items.length; i++) + { + Enum<?> item = items[i]; + options.add(item, item.toString(), true); + } + // set enumType + setAttribute(Column.COLATTR_ENUMTYPE, enumType); + } /** * Checks whether the supplied value is valid for this column. @@ -359,7 +382,7 @@ public class DBTableColumn extends DBColumn if (dateValue.length()==0) return null; // Convert through SimpleDateFormat - String datePattern = StringUtils.coalesce(StringUtils.toString(getAttribute(DBCOLATTR_DATETIMEPATTERN)), "yyyy-MM-dd HH:mm:ss"); + String datePattern = StringUtils.coalesce(StringUtils.toString(getAttribute(Column.COLATTR_DATETIMEPATTERN)), "yyyy-MM-dd HH:mm:ss"); if ((type==DataType.DATE || dateValue.length()<=12) && datePattern.indexOf(' ')>0) datePattern = datePattern.substring(0, datePattern.indexOf(' ')); // Strip off time try @@ -448,8 +471,8 @@ public class DBTableColumn extends DBColumn protected void validateNumber(DataType type, Number n) { // Check Range - Object min = getAttribute(DBColumn.DBCOLATTR_MINVALUE); - Object max = getAttribute(DBColumn.DBCOLATTR_MAXVALUE); + Object min = getAttribute(Column.COLATTR_MINVALUE); + Object max = getAttribute(Column.COLATTR_MAXVALUE); if (min!=null && max!=null) { // Check Range long minVal = ObjectUtils.getLong(min); @@ -529,7 +552,7 @@ public class DBTableColumn extends DBColumn elem.setAttribute("decimals", String.valueOf((int)(size*10)%10)); } if (isRequired()) - elem.setAttribute(DBCOLATTR_MANDATORY, String.valueOf(Boolean.TRUE)); + elem.setAttribute("mandatory", String.valueOf(Boolean.TRUE)); // add All Attributes if (attributes!=null) attributes.addXml(elem, flags);
