DCAE-D be initial commit
[sdc/dcae-d/dt-be-main.git] / dcaedt_validator / kwalify / src / main / java / kwalify / Util.java
1 /*
2  * copyright(c) 2005 kuwata-lab all rights reserved.
3  */
4
5 package kwalify;
6
7 import java.util.Collections;
8 import java.util.List;
9 import java.util.ArrayList;
10 import java.util.Map;
11 import java.util.HashMap;
12 import java.util.IdentityHashMap;
13 import java.util.Iterator;
14 import java.util.regex.Pattern;
15 import java.util.regex.Matcher;
16 import java.util.Date;
17 import java.io.Reader;
18 import java.io.InputStreamReader;
19 import java.io.InputStream;
20 import java.io.FileInputStream;
21 import java.io.IOException;
22
23 public class Util {
24     private static final int VALUE_INTEGER =  1;
25     private static final int VALUE_DOUBLE  =  2;
26     private static final int VALUE_STRING  =  4;
27     private static final int VALUE_BOOLEAN =  8;
28     private static final int VALUE_DATE    = 16;
29     private static final int VALUE_OBJECT  = 32;
30     private static HashMap<String,Pattern> __patterns = new HashMap<>();
31
32     private Util(){
33         // You shouldn't instantiate this class
34     }
35
36     /**
37      *  inspect List or Map
38      */
39     public static String inspect(Object obj) {
40         StringBuilder sb = new StringBuilder();
41         inspect(obj, sb, null);
42         return sb.toString();
43     }
44
45     private static void inspect(Object obj, StringBuilder sb, IdentityHashMap done) {
46         if (obj == null) {
47             sb.append("nil");   // null?
48         } else if (obj instanceof String) {
49             inspect((String)obj, sb);
50         } else if (obj instanceof IdentityHashMap) {
51             if (done == null) {
52                 done = new IdentityHashMap();
53             }
54             if (done.containsKey(obj)) {
55                 sb.append("{...}");
56             } else {
57                 done.put(obj, Boolean.TRUE);
58                 inspect((Map)obj, sb, done);
59             }
60         } else if (obj instanceof List) {
61             if (done == null) {
62                 done = new IdentityHashMap();
63             }
64             if (done.containsKey(obj)) {
65                 sb.append("[...]");
66             } else {
67                 done.put(obj, Boolean.TRUE);
68                 inspect((List)obj, sb);
69             }
70         } else {
71             sb.append(obj.toString());
72         }
73     }
74
75     private static void inspect(Map map, StringBuilder sb, IdentityHashMap done) {
76         sb.append('{');
77         List list = new ArrayList(map.keySet());
78         Collections.sort(list);
79         int i = 0;
80         for (Iterator it = list.iterator(); it.hasNext(); i++) {
81             Object key   = it.next();
82             Object value = map.get(key);
83             if (i > 0) {
84                 sb.append(", ");
85             }
86             inspect(key, sb, done);
87             sb.append("=>");
88             inspect(value, sb, done);
89         }
90         sb.append('}');
91     }
92
93     private static void inspect(List list, StringBuilder sb) {
94         sb.append('[');
95         int i = 0;
96         for (Iterator it = list.iterator(); it.hasNext(); i++) {
97             if (i > 0) {
98                 sb.append(", ");
99             }
100             Object item = it.next();
101             inspect(item, sb, null);
102         }
103         sb.append(']');
104     }
105
106     private static void inspect(String str, StringBuilder sb) {
107         sb.append('"');
108         for (int i = 0; i < str.length(); i++) {
109             char ch = str.charAt(i);
110             switch (ch) {
111               case '"':
112                   sb.append("\\\"");
113                   break;
114               case '\n':
115                   sb.append("\\n");
116                   break;
117               case '\r':
118                   sb.append("\\r");
119                   break;
120               case '\t':
121                   sb.append("\\t");
122                   break;
123               default:
124                   sb.append(ch);
125                   break;
126             }
127         }
128         sb.append('"');
129     }
130
131     /**
132      *  match pattern and return Mather object.
133      *
134      *  ex.
135      *  <pre>
136      *   String target = " name = foo\n mail = foo@mail.com\m";
137      *   Matcher m = Util.matcher(target, "^\\s*(\\w+)\\s*=\\s*(.*)$");
138      *   while (m.find()) {
139      *     String key   = m.group(1);
140      *     String value = m.gropu(2);
141      *   }
142      *  </pre>
143      */
144     public static Matcher matcher(String target, String regexp) {
145         Pattern pat = __patterns.get(regexp);
146         if (pat == null) {
147             pat = Pattern.compile(regexp);
148             __patterns.put(regexp, pat);
149         }
150         return pat.matcher(target);
151     }
152
153     /**
154      *  return if pattern matched or not.
155      *
156      *  ex.
157      *  <pre>
158      *   String target = " name = foo\n";
159      *   if (Util.matches(target, "^\\s*(\\w+)\\s*=\\s*(.*)$")) {
160      *     System.out.println("matched.");
161      *   }
162      *  </pre>
163      */
164     public static boolean matches(String target, String regexp) {
165         Matcher m = matcher(target, regexp);
166         return m.find();
167     }
168
169
170     public static boolean matches(String target, Pattern regexp) {
171         Matcher m = regexp.matcher(target);
172         return m.find();
173     }
174
175    /**
176      *  split string into list of line
177      */
178     public static List toListOfLines(String str) {
179         List<String> list = new ArrayList<>();
180         int len = str.length();
181         int head = 0;
182         for (int i = 0; i < len; i++) {
183             char ch = str.charAt(i);
184             if (ch == '\n') {
185                 int tail = i + 1;
186                 String line = str.substring(head, tail);
187                 list.add(line);
188                 head = tail;
189             }
190         }
191         if (head != len) {
192             String line = str.substring(head, len);
193             list.add(line);
194         }
195         return list;
196     }
197
198     /**
199      *  return true if 'instance' is an instance of 'klass'
200      */
201     public static boolean isInstanceOf(Object instance, Class klass) {
202         if (instance == null || klass == null) {
203             return false;
204         }
205         Class c = instance.getClass();
206         if (klass.isInterface()) {
207             while (c != null) {
208                 Class[] interfaces = c.getInterfaces();
209                 for (Class anInterface : interfaces) {
210                     if (anInterface == klass) {
211                         return true;
212                     }
213                 }
214                 c = c.getSuperclass();
215             }
216         } else {
217             while (c != null) {
218                 if (c == klass) {
219                     return true;
220                 }
221                 c = c.getSuperclass();
222             }
223         }
224         return false;
225     }
226
227
228     /**
229      *  read file content with default encoding of system
230      */
231     public static String readFile(String filename) throws IOException {
232         String charset = System.getProperty("file.encoding");
233         return readFile(filename, charset);
234     }
235
236
237     /**
238      *  read file content with specified encoding
239      */
240     private static String readFile(String filename, String encoding) throws IOException {
241         String content;
242         try (InputStream stream = new FileInputStream(filename)){
243             content = readInputStream(stream, encoding);
244         }
245         return content;
246     }
247
248     public static String readInputStream(InputStream stream) throws IOException {
249         String encoding = System.getProperty("file.encoding");
250         return readInputStream(stream, encoding);
251     }
252
253     private static String readInputStream(InputStream stream, String encoding) throws IOException {
254         String content;
255         try (Reader reader = new InputStreamReader(stream, encoding)){
256             StringBuilder sb = new StringBuilder();
257             int ch;
258             while ((ch = reader.read()) >= 0) {
259                 sb.append((char)ch);
260             }
261             content = sb.toString();
262         }
263         return content;
264     }
265
266     public static String untabify(CharSequence str) {
267         int tabWidth = 8;
268         StringBuilder sb = new StringBuilder();
269         int len = str.length();
270         int col = -1;
271         for (int i = 0; i < len; i++) {
272             col = ++col % tabWidth;
273             char ch = str.charAt(i);
274
275             switch (ch) {
276             case '\t':
277                 appendTabAsSpaces(tabWidth, sb, col);
278                 col = -1;
279                 break;
280             case '\n':
281                 sb.append(ch);
282                 col = -1;
283                 break;
284             default:
285                 sb.append(ch);
286             }
287         }
288         return sb.toString();
289     }
290
291     private static void appendTabAsSpaces(int tabWidth, StringBuilder sb, int col) {
292         int n = tabWidth - col;
293         while (--n >= 0) {
294             sb.append(' ');
295         }
296     }
297
298     public static int compareValues(Object value1, Object value2) {
299         int vtype = (valueType(value1) << 8) | valueType(value2);
300         switch (vtype) {
301         case (VALUE_INTEGER << 8) | VALUE_INTEGER :
302             return ((Integer)value1).compareTo((Integer)value2);
303         case (VALUE_DOUBLE  << 8) | VALUE_DOUBLE :
304             return ((Double)value1).compareTo((Double)value2);
305         case (VALUE_STRING  << 8) | VALUE_STRING :
306             return ((String)value1).compareTo((String)value2);
307         case (VALUE_BOOLEAN << 8) | VALUE_BOOLEAN :
308             boolean b1 = (Boolean) value1;
309             boolean b2 = (Boolean) value2;
310             int ret = b1 ? 1 : -1;
311             return (b1 == b2) ? 0 : ret;
312         case (VALUE_DATE    << 8) | VALUE_DATE :
313             return ((Date)value1).compareTo((Date)value2);
314         case (VALUE_DOUBLE  << 8) | VALUE_INTEGER :
315         case (VALUE_INTEGER << 8) | VALUE_DOUBLE  :
316             double d1 = ((Number)value1).doubleValue();
317             double d2 = ((Number)value2).doubleValue();
318             return Double.compare(d1, d2);
319             default:
320                 throw new InvalidTypeException("cannot compare '" + value1.getClass().getName() + "' with '" + value2.getClass().getName());
321         }
322     }
323
324     private static int valueType(Object value) {
325         if (value instanceof Integer) {
326             return VALUE_INTEGER;
327         }
328
329         if (value instanceof Double) {
330             return VALUE_DOUBLE;
331         }
332
333         if (value instanceof String) {
334             return VALUE_STRING;
335         }
336
337         if (value instanceof Boolean) {
338             return VALUE_BOOLEAN;
339         }
340
341         if (value instanceof Date) {
342             return VALUE_DATE;
343         }
344
345         return VALUE_OBJECT;
346     }
347
348     public static String repeatString(String str, int times) {
349         StringBuilder sb = new StringBuilder();
350         for (int i = 0; i < times; i++) {
351             sb.append(str);
352         }
353         return sb.toString();
354     }
355
356     /**
357      * parse command-line options.
358      *
359      * ex.
360      * <pre>
361      *   public static void main(String[] arg) {
362      *      String singles = "hv";    // options which takes no argument.
363      *      String requireds = "fI";  // options which requires an argument.
364      *      String optionals = "i";   // options which can take optional argument.
365      *      try {
366      *         Object[] ret = parseCommandOptions(args, singles, requireds, optionals);
367      *         Map options        = (Map)ret[0];
368      *         Map properties     = (Map)ret[1];
369      *         String[] filenames = (String[])ret[2];
370      *         //...
371      *      } catch (CommandOptionException ex) {
372      *         char option = ex.getOption();
373      *         String error_symbol = ex.getErrorSymbol();
374      *         Systen.err.println("*** error: " + ex.getMessage());
375      *      }
376      *   }
377      * </pre>
378      *
379      * @param args      command-line strings
380      * @param singles   options which takes no argument
381      * @param requireds options which requires an argument.
382      * @param optionals otpions which can take optional argument.
383      * @return array of options(Map), properties(Map), and filenames(String[])
384      */
385     public static Object[] parseCommandOptions(String[] args, String singles, String requireds, String optionals) throws CommandOptionException {
386         Map<String, Object> options = new HashMap<>();
387         Map<String, Object> properties = new HashMap<>();
388         String[] filenames;
389
390         int i;
391         for (i = 0; i < args.length; i++) {
392             if (args[i].length() == 0 || args[i].charAt(0) != '-') {
393                 break;
394             }
395             String opt = args[i];
396             int len = opt.length();
397             if (len == 1) {   // option '-' means "don't parse arguments!"
398                 i++;
399                 break;
400             }
401             assert len > 1;
402             if (opt.charAt(1) == '-') {  // properties (--pname=pvalue)
403                 String pname;
404                 Object pvalue;
405                 int idx = opt.indexOf('=');
406                 if (idx >= 0) {
407                     pname  = opt.substring(2, idx);
408                     pvalue = idx + 1 < opt.length() ? opt.substring(idx + 1) : "";
409                 } else {
410                     pname  = opt.substring(2);
411                     pvalue = Boolean.TRUE;
412                 }
413                 properties.put(pname, pvalue);
414             } else {              // command-line options
415                 for (int j = 1; j < len; j++) {
416                     char ch = opt.charAt(j);
417                     String chstr = Character.toString(ch);
418                     if (singles != null && singles.indexOf(ch) >= 0) {
419                         options.put(chstr, Boolean.TRUE);
420                     } else if (requireds != null && requireds.indexOf(ch) >= 0) {
421                         String arg = null;
422                         if (++j < len) {
423                             arg = opt.substring(j);
424                         } else if (++i < args.length) {
425                             arg = args[i];
426                         } else {
427                             throw new CommandOptionException("-" + ch + ": filename required.", ch, "command.option.noarg");
428                         }
429                         options.put(chstr, arg);
430                         break;
431                     } else if (optionals != null && optionals.indexOf(ch) >= 0) {
432                         Object arg;
433                         if (++j < len) {
434                             arg = opt.substring(j);
435                         } else {
436                             arg = Boolean.TRUE;
437                         }
438                         options.put(chstr, arg);
439                         break;
440                     } else {
441                         throw new CommandOptionException("-" + ch + "invalid option.", ch, "command.option.invalid");
442                     }
443                 }
444             }
445         }
446
447         assert i <= args.length;
448         int n = args.length - i;
449         filenames = new String[n];
450         for (int j = 0; i < args.length; i++, j++) {
451             filenames[j] = args[i];
452         }
453
454         return new Object[] { options, properties, filenames };
455     }
456 }