You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ColumnFormatter.java 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /*
  2. Copyright (c) 2019 James Ahlborn
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package com.healthmarketscience.jackcess.util;
  14. import java.io.IOException;
  15. import java.util.Map;
  16. import com.healthmarketscience.jackcess.Column;
  17. import com.healthmarketscience.jackcess.PropertyMap;
  18. import com.healthmarketscience.jackcess.expr.EvalConfig;
  19. import com.healthmarketscience.jackcess.expr.EvalException;
  20. import com.healthmarketscience.jackcess.impl.ColEvalContext;
  21. import com.healthmarketscience.jackcess.impl.ColumnImpl;
  22. import com.healthmarketscience.jackcess.impl.expr.FormatUtil;
  23. /**
  24. * Utility for applying Column formatting to column values for display. This
  25. * utility loads the "Format" property from the given column and builds an
  26. * appropriate formatter (essentially leveraging the internals of the
  27. * expression execution engine's support for the "Format()" function). Since
  28. * formats leverage the expression evaluation engine, the underlying
  29. * Database's {@link EvalConfig} can be used to alter how this utility formats
  30. * values. Note, formatted values may be suitable for <i>display only</i>
  31. * (i.e. a formatted value may not be accepted as an input value to a Table
  32. * add/update method).
  33. *
  34. * @author James Ahlborn
  35. * @usage _general_class_
  36. */
  37. public class ColumnFormatter
  38. {
  39. private final ColumnImpl _col;
  40. private final FormatEvalContext _ctx;
  41. private String _fmtStr;
  42. private FormatUtil.StandaloneFormatter _fmt;
  43. public ColumnFormatter(Column col) throws IOException {
  44. _col = (ColumnImpl)col;
  45. _ctx = new FormatEvalContext(_col);
  46. reload();
  47. }
  48. /**
  49. * Returns the currently loaded "Format" property for this formatter, may be
  50. * {@code null}.
  51. */
  52. public String getFormatString() {
  53. return _fmtStr;
  54. }
  55. /**
  56. * Sets the given format string as the "Format" property for the underlying
  57. * Column and reloads this formatter.
  58. *
  59. * @param fmtStr the new format string. may be {@code null}, in which case
  60. * the "Format" property is removed from the underlying Column
  61. */
  62. public void setFormatString(String fmtStr) throws IOException {
  63. PropertyMap props = _col.getProperties();
  64. if(!StringUtil.isEmpty(fmtStr)) {
  65. props.put(PropertyMap.FORMAT_PROP, fmtStr);
  66. } else {
  67. props.remove(PropertyMap.FORMAT_PROP);
  68. }
  69. props.save();
  70. reload();
  71. }
  72. /**
  73. * Formats the given value according to the format currently defined for the
  74. * underlying Column.
  75. *
  76. * @param val a valid input value for the DataType of the underlying Column
  77. * (i.e. a value which could be passed to a Table add/update
  78. * method for this Column). may be {@code null}
  79. *
  80. * @return the formatted result, always non-{@code null}
  81. */
  82. public String format(Object val) {
  83. return _ctx.format(val);
  84. }
  85. /**
  86. * Convenience method for retrieving the appropriate Column value from the
  87. * given row array and formatting it.
  88. *
  89. * @return the formatted result, always non-{@code null}
  90. */
  91. public String getRowValue(Object[] rowArray) {
  92. return format(_col.getRowValue(rowArray));
  93. }
  94. /**
  95. * Convenience method for retrieving the appropriate Column value from the
  96. * given row map and formatting it.
  97. *
  98. * @return the formatted result, always non-{@code null}
  99. */
  100. public String getRowValue(Map<String,?> rowMap) {
  101. return format(_col.getRowValue(rowMap));
  102. }
  103. /**
  104. * If the properties for the underlying Column have been modified directly
  105. * (or the EvalConfig for the underlying Database has been modified), this
  106. * method may be called to reload the format for the underlying Column.
  107. */
  108. public final void reload() throws IOException {
  109. _fmt = null;
  110. _fmtStr = null;
  111. _fmtStr = (String)_col.getProperties().getValue(PropertyMap.FORMAT_PROP);
  112. _fmt = FormatUtil.createStandaloneFormatter(_ctx, _fmtStr, 1, 1);
  113. }
  114. /**
  115. * Utility class to provide an EvalContext for the expression evaluation
  116. * engine format support.
  117. */
  118. private class FormatEvalContext extends ColEvalContext
  119. {
  120. private FormatEvalContext(ColumnImpl col) {
  121. super(col);
  122. }
  123. public String format(Object val) {
  124. try {
  125. return _fmt.format(toValue(val)).getAsString(this);
  126. } catch(EvalException ee) {
  127. // invalid values for a given format result in returning the value as is
  128. return val.toString();
  129. }
  130. }
  131. }
  132. }