Source code: er/extensions/ERXFixedLengthString.java
1 /*
2 * Copyright (C) NetStruxr, Inc. All rights reserved.
3 *
4 * This software is published under the terms of the NetStruxr
5 * Public Software License version 0.5, a copy of which has been
6 * included with this distribution in the LICENSE.NPL file. */
7 package er.extensions;
8
9 import com.webobjects.foundation.*;
10 import com.webobjects.appserver.*;
11 import java.util.StringTokenizer;
12
13 /**
14 * This stateless component is useful for displaying a
15 * string of a fixed length. For example imagine you have
16 * the string: 'The brown dog jumped' and for a given table
17 * cell you only want to display at most 10 characters of the
18 * string, then using this component you could bind the given
19 * string to the 'value' binding, 10 to the 'length' binding
20 * and the string '...' to the 'suffixWhenTrimmed' binding.
21 * When rendering this would display:<br/>
22 * The brown ...
23 * <br/>
24 * This component can also be used to pad whitespace onto the
25 * end of strings that are shorter than the given length.
26 * <br/>
27 * Synopsis:<br/>
28 * value=<i>aString</i>;length=<i>aNumber</i>;[shouldPadToLength=<i>aBoolean</i>;][suffixWhenTrimmed=<i>aString</i>;][escapeHTML=<i>aBoolean</i>;]
29 *
30 * @binding value string that is passed in to display in a fixed
31 * length setting.
32 * @binding length fixed length that is compared to the length of
33 * the passed in string.
34 * @binding shouldPadToLength boolean binding to indicate if the
35 * string to be displayed is shorter than the fixed
36 * length if it should then be padded with white space.
37 * @binding suffixWhenTrimmed only appended to the end of the string
38 * if characters are trimmed from the end of the string
39 * to be displayed
40 * @binding escapeHTML replace the entities > and & with their
41 * escape codes (like WOString does). When this is set to
42 * true, all HTML text is cleared from the string first to
43 * prevent half-open tags
44 */
45 public class ERXFixedLengthString extends ERXStatelessComponent {
46
47 /**
48 * flag to indicate if characters were trimmed from the end of
49 * the passed in string.
50 */
51 protected boolean valueWasTrimmed = false;
52 /** Holds the local cache for the calculated fixed length string */
53 protected String _fixedLengthString;
54
55 /**
56 * Public constructor
57 * @param context to be used
58 */
59 public ERXFixedLengthString(WOContext context) {
60 super(context);
61 }
62
63 /**
64 * Fixed length of the string to be displayed.
65 * @return int value of the binding: <b>length</b>
66 */
67 public int length() {
68 Integer l=(Integer)valueForBinding("length");
69 return l!=null ? l.intValue() : 0;
70 }
71
72 /**
73 * Resets cached instance variables.
74 */
75 public void reset() {
76 super.reset();
77 valueWasTrimmed = false;
78 _fixedLengthString = null;
79 }
80
81 /**
82 * Calculates the fixed length string from the string
83 * passed in via the binding: <b>value</b>.
84 * If the length of the value string is greater than
85 * the int value of the <b>length</b> binding then
86 * the string is trimmed to the fixed length. If the
87 * string is shorter than the fixed length size and
88 * the binding: <b>shouldPadToLength</b> is set to
89 * true then whitespace is added to the end of the string
90 * buffer.
91 * @return fixed length version of the string passed in
92 * via the <b>value</b> binding.
93 */
94 // ENHANCEME: Should support adding either   or ' '
95 public String value() {
96 if (_fixedLengthString == null) {
97 String result;
98 if(escapeHTML())
99 result =(String)valueForBinding("value");
100 else
101 result = strippedValue();
102 int l=length();
103 if (l!=0 && result!=null) {
104 int sl=result.length();
105 if (sl!=l) {
106 if (sl<l) {
107 StringBuffer sb=new StringBuffer(result);
108 if (valueForBooleanBinding("shouldPadToLength", true)) {
109 for (int i=sl; i<l; i++) sb.append(' ');
110 }
111 result=sb.toString();
112 } else {
113 valueWasTrimmed = true;
114 result=result.substring(0,l-1);
115 }
116 }
117 }
118 _fixedLengthString = result;
119 }
120 return _fixedLengthString;
121 }
122
123 /**
124 * Returns the value stripped from HTML tags if <b>escapeHTML</b> is false.
125 * This makes sense because it is not terribly useful to have half-finished tags in your code.
126 * Note that the "length" of the resulting string is not very exact.
127 * FIXME: we could remove extra whitespace and character entities here
128 * MOVEME: should go to ERXStringUtilities
129 * @return value stripped from tags.
130 */
131
132 public String strippedValue() {
133 String value=(String)valueForBinding("value");
134 if(value == null || value.length() < 1)
135 return null;
136 StringTokenizer tokenizer = new StringTokenizer(value, "<", false);
137 int token = value.charAt(0) == '<' ? 0 : 1;
138 String nextPart = null;
139 StringBuffer result = new StringBuffer();
140 int l=length();
141 int currentLength = result.length();
142 while (tokenizer.hasMoreTokens() && currentLength < l && currentLength < value.length()) {
143 if(token == 0)
144 nextPart = tokenizer.nextToken(">");
145 else {
146 nextPart = tokenizer.nextToken("<");
147 if(nextPart.length() > 0 && nextPart.charAt(0) == '>')
148 nextPart = nextPart.substring(1);
149 }
150 if (nextPart != null && token != 0) {
151 result.append(nextPart);
152 currentLength += nextPart.length();
153 }
154 token = 1 - token;
155 }
156 return result.toString();
157 }
158
159 /**
160 * Returns the value for the binding: <b>suffixWhenTrimmed</b>
161 * only if the string was trimmed.
162 * @return optionally returns the suffix to be added to the end
163 * of the string to be displayed.
164 */
165 public String suffixWhenTrimmed() {
166 value();
167 String result = null;
168 if ((value() != null && valueWasTrimmed))
169 result = (String)valueForObjectBinding("suffixWhenTrimmed");
170 return result;
171 }
172
173 /**
174 * Returns the value for the binding: <b>escapeHTML</b>.
175 * @return optionally returns the boolean value of the binding or TRUE of not given.
176 */
177 public boolean escapeHTML() {
178 return valueForBooleanBinding("escapeHTML", true);
179 }
180 }