annotate src/org/tmatesoft/hg/internal/ConfigFileParser.java @ 709:497e697636fc

Report merged lines as changed block if possible, not as a sequence of added/deleted blocks. To facilitate access to merge parent lines AddBlock got mergeLineAt() method that reports index of the line in the second parent (if any), while insertedAt() has been changed to report index in the first parent always
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Wed, 21 Aug 2013 16:23:27 +0200
parents 0205a5c4566b
children
rev   line source
497
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
1 /*
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
2 * Copyright (c) 2012 TMate Software Ltd
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
3 *
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
4 * This program is free software; you can redistribute it and/or modify
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
5 * it under the terms of the GNU General Public License as published by
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
6 * the Free Software Foundation; version 2 of the License.
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
7 *
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
8 * This program is distributed in the hope that it will be useful,
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
11 * GNU General Public License for more details.
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
12 *
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
13 * For information on how to redistribute this software under
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
14 * the terms of a license other than GNU General Public License
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
15 * contact TMate Software at support@hg4j.com
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
16 */
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
17 package org.tmatesoft.hg.internal;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
18
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
19 import java.io.ByteArrayOutputStream;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
20 import java.io.IOException;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
21 import java.io.InputStream;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
22 import java.io.OutputStream;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
23 import java.util.ArrayList;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
24 import java.util.Collections;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
25 import java.util.HashSet;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
26 import java.util.Iterator;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
27 import java.util.LinkedHashMap;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
28 import java.util.LinkedHashSet;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
29 import java.util.List;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
30
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
31 /**
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
32 * Simplistic parser to allow altering configuration files without touching user modifications/formatting/comments
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
33 *
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
34 * @author Artem Tikhomirov
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
35 * @author TMate Software Ltd.
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
36 */
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
37 public class ConfigFileParser {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
38 private enum ParseState {Initial, Section, Entry};
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
39 private ParseState state = ParseState.Initial;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
40 private int lastNonEmptyLineEndOffset = -1;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
41 private String sectionName;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
42 private int sectionStart = -1;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
43 private String entryKey;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
44 private int entryStart = -1;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
45 private int valueStart = -1, valueEnd = -1;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
46 private ArrayList<Entry> entries;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
47 private ArrayList<Section> sections = new ArrayList<Section>();
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
48 private byte[] contents;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
49
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
50 private List<String> deletions = new ArrayList<String>(5);
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
51 private List<String> additions = new ArrayList<String>(5), changes = new ArrayList<String>(5);
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
52
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
53
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
54 public boolean exists(String section, String key) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
55 assert contents != null;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
56 for (Section s : sections) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
57 if (s.name.equals(section)) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
58 for (Entry e : s.entries) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
59 if (e.name.equals(key)) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
60 return true;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
61 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
62 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
63 return false;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
64 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
65 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
66 return false;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
67 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
68
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
69 public void add(String section, String key, String newValue) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
70 additions.add(section);
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
71 additions.add(key);
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
72 additions.add(newValue);
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
73 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
74
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
75 public void change(String section, String key, String newValue) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
76 changes.add(section);
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
77 changes.add(key);
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
78 changes.add(newValue);
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
79 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
80
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
81 public void delete(String section, String key) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
82 deletions.add(section);
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
83 deletions.add(key);
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
84 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
85
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
86 public void parse(InputStream is) throws IOException {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
87 state = ParseState.Initial;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
88 sections.clear();
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
89 contents = null;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
90 ByteArrayOutputStream bos = new ByteArrayOutputStream(1024);
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
91 ByteArrayOutputStream line = new ByteArrayOutputStream(80);
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
92 int offset = 0;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
93 int lineOffset = -1;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
94 int lineNumber = 1;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
95 boolean crDetected = false; // true when previous char was \r
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
96 int b;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
97 while ( (b = is.read()) != -1) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
98 bos.write(b);
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
99 if (b == '\n' || b == '\r') {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
100 if (line.size() > 0) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
101 processLine(lineNumber, lineOffset, line.toByteArray());
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
102 line.reset();
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
103 lineOffset = -1;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
104 lastNonEmptyLineEndOffset = bos.size() - 1; // offset points to EOL char
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
105 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
106 // else: XXX does empty line closes entry???
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
107 // when \n follows \r, increment line count only once
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
108 if (!(b == '\n' && crDetected)) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
109 lineNumber++;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
110 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
111 crDetected = b == '\r';
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
112 } else {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
113 crDetected = false;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
114 if (line.size() == 0) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
115 lineOffset = offset;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
116 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
117 line.write(b);
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
118 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
119 offset++;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
120 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
121 // handle last line in case it's not EOL-terminated
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
122 if (line.size() > 0) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
123 processLine(lineNumber, lineOffset, line.toByteArray());
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
124 // might need it for #closeSection() below
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
125 lastNonEmptyLineEndOffset = bos.size();
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
126 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
127 if (state == ParseState.Entry) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
128 closeEntry();
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
129 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
130 if (state == ParseState.Section) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
131 closeSection();
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
132 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
133 contents = bos.toByteArray();
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
134 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
135
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
136 public void update(OutputStream out) throws IOException {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
137 if (contents == null) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
138 throw new IOException("Shall parse first");
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
139 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
140 HashSet<String> processedSections = new HashSet<String>();
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
141 int contentsOffset = 0;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
142 for (Section section : sections) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
143 LinkedHashMap<String,String> additionsInSection = new LinkedHashMap<String,String>();
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
144 LinkedHashMap<String,String> changesInSection = new LinkedHashMap<String,String>();
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
145 LinkedHashSet<String> deletionsInSection = new LinkedHashSet<String>();
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
146 if (!processedSections.contains(section.name)) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
147 for (Iterator<String> it = additions.iterator(); it.hasNext();) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
148 String s = it.next(), k = it.next(), v = it.next();
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
149 if (section.name.equals(s)) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
150 additionsInSection.put(k, v);
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
151 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
152 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
153 for (Iterator<String> it = changes.iterator(); it.hasNext();) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
154 String s = it.next(), k = it.next(), v = it.next();
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
155 if (section.name.equals(s)) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
156 changesInSection.put(k, v);
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
157 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
158 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
159 for (Iterator<String> it = deletions.iterator(); it.hasNext();) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
160 String s = it.next(), k = it.next();
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
161 if (section.name.equals(s)) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
162 deletionsInSection.add(k);
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
163 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
164 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
165 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
166 for (Entry e : section.entries) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
167 if (deletionsInSection.contains(e.name)) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
168 // write up to key start only
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
169 out.write(contents, contentsOffset, e.start - contentsOffset);
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
170 contentsOffset = e.valueEnd + 1;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
171 } else if (changesInSection.containsKey(e.name)) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
172 if (e.valueStart == -1) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
173 // e.valueEnd determines insertion point
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
174 out.write(contents, contentsOffset, e.valueEnd + 1 - contentsOffset);
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
175 } else {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
176 // e.valueEnd points to last character of the value
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
177 out.write(contents, contentsOffset, e.valueStart - contentsOffset);
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
178 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
179 String value = changesInSection.get(e.name);
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
180 out.write(value == null ? new byte[0] : value.getBytes());
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
181 contentsOffset = e.valueEnd + 1;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
182 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
183 // else: keep contentsOffset to point to first uncopied character
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
184 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
185 if (section.entries.length == 0) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
186 // no entries, empty or only comments, perhaps.
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
187 // use end of last meaningful line (whether [section] or comment string),
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
188 // which points to newline character
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
189 out.write(contents, contentsOffset, section.end - contentsOffset);
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
190 contentsOffset = section.end;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
191 // since it's tricky to track \n or \r\n with lastNonEmptyLineEndOffset,
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
192 // we copy up to the line delimiter and insert new lines, if any, with \n prepended,
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
193 // so that original EOL will be moved to the very end of the section.
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
194 // Indeed, would be better to insert *after* lastNonEmptyLineEndOffset,
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
195 // but I don't want to complicate #parse (if line.size() > 0 part) method.
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
196 // Hope, this won't make too much trouble (if any, at all -
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
197 // if String.format translates \n to system EOL, then nobody would notice)
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
198 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
199 if (!additionsInSection.isEmpty()) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
200 // make sure additions are written once everything else is there
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
201 out.write(contents, contentsOffset, section.end - contentsOffset);
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
202 contentsOffset = section.end;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
203 for (String k : additionsInSection.keySet()) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
204 String v = additionsInSection.get(k);
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
205 out.write(String.format("\n%s = %s", k, v == null ? "" : v).getBytes());
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
206 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
207 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
208 // if section comes more than once, update only first one.
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
209 processedSections.add(section.name);
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
210 }
498
0205a5c4566b Issue 38: preserve user formatting and comments when updating configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 497
diff changeset
211 // push rest of the contents
497
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
212 out.write(contents, contentsOffset, contents.length - contentsOffset);
498
0205a5c4566b Issue 38: preserve user formatting and comments when updating configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 497
diff changeset
213 //
0205a5c4566b Issue 38: preserve user formatting and comments when updating configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 497
diff changeset
214 // add entries in new sections
0205a5c4566b Issue 38: preserve user formatting and comments when updating configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 497
diff changeset
215 LinkedHashSet<String> newSections = new LinkedHashSet<String>();
0205a5c4566b Issue 38: preserve user formatting and comments when updating configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 497
diff changeset
216 for (Iterator<String> it = additions.iterator(); it.hasNext();) {
0205a5c4566b Issue 38: preserve user formatting and comments when updating configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 497
diff changeset
217 String s = it.next(); it.next(); it.next();
0205a5c4566b Issue 38: preserve user formatting and comments when updating configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 497
diff changeset
218 if (!processedSections.contains(s)) {
0205a5c4566b Issue 38: preserve user formatting and comments when updating configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 497
diff changeset
219 newSections.add(s);
0205a5c4566b Issue 38: preserve user formatting and comments when updating configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 497
diff changeset
220 }
0205a5c4566b Issue 38: preserve user formatting and comments when updating configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 497
diff changeset
221 }
0205a5c4566b Issue 38: preserve user formatting and comments when updating configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 497
diff changeset
222 for (String newSectionName : newSections) {
0205a5c4566b Issue 38: preserve user formatting and comments when updating configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 497
diff changeset
223 out.write(String.format("\n[%s]", newSectionName).getBytes());
0205a5c4566b Issue 38: preserve user formatting and comments when updating configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 497
diff changeset
224 for (Iterator<String> it = additions.iterator(); it.hasNext();) {
0205a5c4566b Issue 38: preserve user formatting and comments when updating configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 497
diff changeset
225 String s = it.next(), k = it.next(), v = it.next();
0205a5c4566b Issue 38: preserve user formatting and comments when updating configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 497
diff changeset
226 if (newSectionName.equals(s)) {
0205a5c4566b Issue 38: preserve user formatting and comments when updating configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 497
diff changeset
227 out.write(String.format("\n%s = %s", k, v).getBytes());
0205a5c4566b Issue 38: preserve user formatting and comments when updating configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 497
diff changeset
228 }
0205a5c4566b Issue 38: preserve user formatting and comments when updating configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 497
diff changeset
229 }
0205a5c4566b Issue 38: preserve user formatting and comments when updating configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 497
diff changeset
230 out.write("\n".getBytes());
0205a5c4566b Issue 38: preserve user formatting and comments when updating configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 497
diff changeset
231 }
497
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
232 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
233
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
234 private void processLine(int lineNumber, int offset, byte[] line) throws IOException {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
235 int localOffset = 0, i = 0;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
236 while (i < line.length && Character.isWhitespace(line[i])) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
237 i++;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
238 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
239 if (i == line.length) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
240 return;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
241 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
242 localOffset = i;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
243 if (line[i] == '[') {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
244 if (state == ParseState.Entry) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
245 closeEntry();
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
246 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
247 if (state == ParseState.Section) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
248 closeSection();
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
249 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
250
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
251 while (i < line.length && line[i] != ']') {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
252 i++;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
253 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
254 if (i == line.length) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
255 throw new IOException(String.format("Can't find closing ']' for section name in line %d", lineNumber));
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
256 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
257 sectionName = new String(line, localOffset+1, i-localOffset-1);
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
258 sectionStart = offset + localOffset;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
259 state = ParseState.Section;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
260 } else if (line[i] == '#' || line[i] == ';') {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
261 // comment line, nothing to process
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
262 return;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
263 } else {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
264 // entry
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
265 if (state == ParseState.Initial) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
266 throw new IOException(String.format("Line %d doesn't belong to any section", lineNumber));
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
267 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
268 if (localOffset > 0) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
269 if (state == ParseState.Section) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
270 throw new IOException(String.format("Non-indented key is expected in line %d", lineNumber));
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
271 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
272 assert state == ParseState.Entry;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
273 // whitespace-indented continuation of the previous entry
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
274 if (valueStart == -1) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
275 // value didn't start at the same line the key was found at
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
276 valueStart = offset + localOffset;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
277 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
278 // value ends with eol (assumption is trailing comments are not allowed)
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
279 valueEnd = offset + line.length - 1;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
280 } else {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
281 if (state == ParseState.Entry) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
282 closeEntry();
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
283 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
284 assert state == ParseState.Section;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
285 // it's a new entry
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
286 state = ParseState.Entry;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
287 // get name of the entry
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
288 while (i < line.length && !Character.isWhitespace(line[i]) && line[i] != '=') {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
289 i++;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
290 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
291 if (i == line.length) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
292 throw new IOException(String.format("Can't process entry in line %d", lineNumber));
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
293 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
294 entryKey = new String(line, localOffset, i - localOffset);
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
295 entryStart = offset + localOffset;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
296 // look for '=' after key name
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
297 while (i < line.length && line[i] != '=') {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
298 i++;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
299 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
300 if (i == line.length) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
301 throw new IOException(String.format("Can't find '=' after key %s in line %d", entryKey, lineNumber));
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
302 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
303 // skip whitespaces after '='
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
304 i++; // line[i] == '='
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
305 while (i < line.length && Character.isWhitespace(line[i])) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
306 i++;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
307 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
308 // valueStart might be -1 in case no value is specified in the same line as key
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
309 // but valueEnd is always initialized just in case there's no next, value continuation line
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
310 if (i == line.length) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
311 valueStart = -1;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
312 } else {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
313 valueStart = offset + i;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
314 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
315
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
316 // if trailing comments are allowed, shall
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
317 // look up comment char and set valueEnd to its position-1
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
318 valueEnd = offset + line.length - 1;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
319 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
320 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
321 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
322
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
323 private void closeSection() {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
324 assert state == ParseState.Section;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
325 assert sectionName != null;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
326 assert lastNonEmptyLineEndOffset != -1;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
327 Section s = new Section(sectionName, sectionStart, lastNonEmptyLineEndOffset, entries == null ? Collections.<Entry>emptyList() : entries);
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
328 sections.add(s);
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
329 sectionName = null;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
330 sectionStart = -1;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
331 state = ParseState.Initial;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
332 entries = null;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
333 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
334
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
335 private void closeEntry() {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
336 assert state == ParseState.Entry;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
337 assert entryKey != null;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
338 state = ParseState.Section;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
339 Entry e = new Entry(entryKey, entryStart, valueStart, valueEnd);
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
340 if (entries == null) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
341 entries = new ArrayList<Entry>();
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
342 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
343 entries.add(e);
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
344 entryKey = null;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
345 entryStart = valueStart = valueEnd -1;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
346 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
347
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
348
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
349 private static class Block {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
350 public final int start;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
351 Block(int s) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
352 start = s;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
353 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
354 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
355
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
356 private static class Entry extends Block {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
357 public final int valueStart, valueEnd;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
358 public final String name;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
359
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
360 Entry(String n, int s, int vs, int ve) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
361 super(s);
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
362 name = n;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
363 valueStart = vs;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
364 valueEnd = ve;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
365 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
366 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
367
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
368 private static class Section extends Block {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
369 public final String name;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
370 public final Entry[] entries;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
371 public final int end;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
372
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
373 Section(String n, int s, int endOffset, List<Entry> e) {
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
374 super(s);
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
375 name = n;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
376 end = endOffset;
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
377 entries = new Entry[e.size()];
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
378 e.toArray(entries);
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
379 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
380 }
02140be396d5 Issue 38. Towards gentle handling of config files - parse them and keep every possible user change
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
381 }