Refresh data on "Back", allow configuration of View + border
[jvcard.git] / src / be / nikiroo / jvcard / resources / StringUtils.java
CommitLineData
7da41ecd 1package be.nikiroo.jvcard.resources;
a3b510ab 2
cf77cb35
NR
3import java.security.MessageDigest;
4import java.security.NoSuchAlgorithmException;
296a0b75
NR
5import java.text.Normalizer;
6import java.text.Normalizer.Form;
b9f192ed
NR
7import java.text.ParseException;
8import java.text.SimpleDateFormat;
9import java.util.Date;
296a0b75
NR
10import java.util.regex.Pattern;
11
a3b510ab
NR
12import com.googlecode.lanterna.gui2.LinearLayout.Alignment;
13
14public class StringUtils {
296a0b75
NR
15 static private Pattern marks = Pattern
16 .compile("[\\p{InCombiningDiacriticalMarks}\\p{IsLm}\\p{IsSk}]+");
a3b510ab 17
296a0b75
NR
18 /**
19 * Fix the size of the given {@link String} either with space-padding or by
20 * shortening it.
21 *
22 * @param text
23 * the {@link String} to fix
24 * @param width
3634193b 25 * the size of the resulting {@link String} or -1 for a noop
296a0b75
NR
26 *
27 * @return the resulting {@link String} of size <i>size</i>
28 */
a3b510ab
NR
29 static public String padString(String text, int width) {
30 return padString(text, width, true, Alignment.Beginning);
31 }
32
296a0b75
NR
33 /**
34 * Fix the size of the given {@link String} either with space-padding or by
35 * optionally shortening it.
36 *
37 * @param text
38 * the {@link String} to fix
39 * @param width
40 * the size of the resulting {@link String} if the text fits or
3634193b 41 * if cut is TRUE or -1 for a noop
296a0b75
NR
42 * @param cut
43 * cut the {@link String} shorter if needed
44 * @param align
45 * align the {@link String} in this position if we have enough
46 * space
47 *
48 * @return the resulting {@link String} of size <i>size</i> minimum
49 */
a3b510ab
NR
50 static public String padString(String text, int width, boolean cut,
51 Alignment align) {
3634193b 52
a3b510ab
NR
53 if (width >= 0) {
54 if (text == null)
55 text = "";
56
57 int diff = width - text.length();
58
59 if (diff < 0) {
60 if (cut)
61 text = text.substring(0, width);
62 } else if (diff > 0) {
63 if (diff < 2 && align != Alignment.End)
64 align = Alignment.Beginning;
65
66 switch (align) {
67 case Beginning:
68 text = text + new String(new char[diff]).replace('\0', ' ');
69 break;
70 case End:
71 text = new String(new char[diff]).replace('\0', ' ') + text;
72 break;
73 case Center:
74 case Fill:
75 default:
76 int pad1 = (diff) / 2;
77 int pad2 = (diff + 1) / 2;
78 text = new String(new char[pad1]).replace('\0', ' ') + text
79 + new String(new char[pad2]).replace('\0', ' ');
80 break;
81 }
82 }
83 }
84
85 return text;
86 }
87
296a0b75
NR
88 /**
89 * Sanitise the given input to make it more Terminal-friendly by removing
90 * combining characters.
91 *
92 * @param input
93 * the input to sanitise
94 * @param allowUnicode
95 * allow Unicode or only allow ASCII Latin characters
96 *
97 * @return the sanitised {@link String}
98 */
99 static public String sanitize(String input, boolean allowUnicode) {
100 return sanitize(input, allowUnicode, !allowUnicode);
101 }
102
103 /**
104 * Sanitise the given input to make it more Terminal-friendly by removing
105 * combining characters.
106 *
107 * @param input
108 * the input to sanitise
109 * @param allowUnicode
110 * allow Unicode or only allow ASCII Latin characters
111 * @param removeAllAccents
112 * TRUE to replace all accentuated characters by their non
113 * accentuated counter-parts
114 *
115 * @return the sanitised {@link String}
116 */
117 static public String sanitize(String input, boolean allowUnicode,
118 boolean removeAllAccents) {
119
120 if (removeAllAccents) {
121 input = Normalizer.normalize(input, Form.NFKD);
122 input = marks.matcher(input).replaceAll("");
123 }
124
125 input = Normalizer.normalize(input, Form.NFKC);
126
127 if (!allowUnicode) {
adf9c449
NR
128 StringBuilder builder = new StringBuilder();
129 for (int index = 0; index < input.length(); index++) {
130 char car = input.charAt(index);
131 // displayable chars in ASCII are in the range 32<->255,
132 // except DEL (127)
133 if (car >= 32 && car <= 255 && car != 127) {
134 builder.append(car);
135 }
136 }
137 input = builder.toString();
296a0b75
NR
138 }
139
140 return input;
141 }
b9f192ed
NR
142
143 /**
144 * Convert between time in milliseconds to {@link String} in a "static" way
145 * (to exchange data over the wire, for instance).
146 *
147 * @param time
148 * the time in milliseconds
149 *
150 * @return the time as a {@link String}
151 */
152 static public String fromTime(long time) {
153 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
154 return sdf.format(new Date(time));
155 }
156
157 /**
158 * Convert between time as a {@link String} to milliseconds in a "static"
159 * way (to exchange data over the wire, for instance).
160 *
161 * @param time
162 * the time as a {@link String}
163 *
164 * @return the time in milliseconds
165 */
166 static public long toTime(String display) {
167 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
168 try {
169 return sdf.parse(display).getTime();
170 } catch (ParseException e) {
171 return -1;
172 }
173 }
cf77cb35
NR
174
175 /**
176 * Return a hash of the given {@link String}.
177 *
178 * @param input
179 * the input data
180 *
181 * @return the hash
182 */
183 static public String getHash(String input) {
184 try {
185 MessageDigest md = MessageDigest.getInstance("MD5");
186 md.update(input.getBytes());
187 byte byteData[] = md.digest();
188
189 StringBuffer hexString = new StringBuffer();
190 for (int i = 0; i < byteData.length; i++) {
191 String hex = Integer.toHexString(0xff & byteData[i]);
192 if (hex.length() == 1)
193 hexString.append('0');
194 hexString.append(hex);
195 }
196
197 return hexString.toString();
198 } catch (NoSuchAlgorithmException e) {
199 // all JVM most probably have an MD5 implementation, but even if
200 // not, returning the input is "correct", if inefficient and
201 // unsecure
202 return input;
203 }
204 }
a3b510ab 205}