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