Mercurial > jhg
comparison src/org/tmatesoft/hg/internal/ConfigFile.java @ 378:9fb990c8a724
Investigate approaches to alter Mercurial configuration files
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Thu, 09 Feb 2012 04:15:17 +0100 |
parents | a37ce7145c3f |
children | e31e85cf4d4c |
comparison
equal
deleted
inserted
replaced
377:86f049e6bcae | 378:9fb990c8a724 |
---|---|
15 * contact TMate Software at support@hg4j.com | 15 * contact TMate Software at support@hg4j.com |
16 */ | 16 */ |
17 package org.tmatesoft.hg.internal; | 17 package org.tmatesoft.hg.internal; |
18 | 18 |
19 import java.io.BufferedReader; | 19 import java.io.BufferedReader; |
20 import java.io.ByteArrayOutputStream; | |
20 import java.io.File; | 21 import java.io.File; |
22 import java.io.FileOutputStream; | |
21 import java.io.FileReader; | 23 import java.io.FileReader; |
22 import java.io.IOException; | 24 import java.io.IOException; |
25 import java.io.PrintStream; | |
26 import java.nio.ByteBuffer; | |
27 import java.nio.channels.FileChannel; | |
28 import java.nio.channels.FileLock; | |
23 import java.util.ArrayList; | 29 import java.util.ArrayList; |
24 import java.util.Collections; | 30 import java.util.Collections; |
31 import java.util.Iterator; | |
25 import java.util.LinkedHashMap; | 32 import java.util.LinkedHashMap; |
26 import java.util.List; | 33 import java.util.List; |
27 import java.util.Map; | 34 import java.util.Map; |
28 | 35 |
29 /** | 36 /** |
50 public List<String> getSectionNames() { | 57 public List<String> getSectionNames() { |
51 return sections == null ? Collections.<String>emptyList() : Collections.unmodifiableList(sections); | 58 return sections == null ? Collections.<String>emptyList() : Collections.unmodifiableList(sections); |
52 } | 59 } |
53 | 60 |
54 public Map<String,String> getSection(String sectionName) { | 61 public Map<String,String> getSection(String sectionName) { |
55 if (sections == null) { | 62 if (sections == null) { |
56 return Collections.emptyMap(); | 63 return Collections.emptyMap(); |
57 } | 64 } |
58 int x = sections.indexOf(sectionName); | 65 int x = sections.indexOf(sectionName); |
59 if (x == -1) { | 66 if (x == -1) { |
60 return Collections.emptyMap(); | 67 return Collections.emptyMap(); |
77 | 84 |
78 public String getString(String sectionName, String key, String defaultValue) { | 85 public String getString(String sectionName, String key, String defaultValue) { |
79 String value = getSection(sectionName).get(key); | 86 String value = getSection(sectionName).get(key); |
80 return value == null ? defaultValue : value; | 87 return value == null ? defaultValue : value; |
81 } | 88 } |
82 | 89 |
90 public void putString(String sectionName, String key, String newValue) { | |
91 Map<String, String> section = null; | |
92 if (sections == null) { | |
93 // init, in case we didn't read any file with prev config | |
94 sections = new ArrayList<String>(); | |
95 content = new ArrayList<Map<String,String>>(); | |
96 } | |
97 int x = sections.indexOf(sectionName); | |
98 if (x == -1) { | |
99 if (newValue == null) { | |
100 return; | |
101 } | |
102 sections.add(sectionName); | |
103 content.add(section = new LinkedHashMap<String, String>()); | |
104 } else { | |
105 section = content.get(x); | |
106 } | |
107 if (newValue == null) { | |
108 section.remove(key); | |
109 } else { | |
110 section.put(key, newValue); | |
111 } | |
112 } | |
113 | |
83 // TODO handle %include and %unset directives | 114 // TODO handle %include and %unset directives |
84 // TODO "" and lists | 115 // TODO "" and lists |
85 // XXX perhaps, single string to keep whole section with substrings for keys/values to minimize number of arrays (String.value) | 116 // XXX perhaps, single string to keep whole section with substrings for keys/values to minimize number of arrays (String.value) |
86 private void read(File f) throws IOException { | 117 private void read(File f) throws IOException { |
87 if (f == null || !f.canRead()) { | 118 if (f == null || !f.canRead()) { |
139 br.close(); | 170 br.close(); |
140 } | 171 } |
141 } | 172 } |
142 assert sections.size() == content.size(); | 173 assert sections.size() == content.size(); |
143 } | 174 } |
175 | |
176 public void writeTo(File f) throws IOException { | |
177 byte[] data = compose(); | |
178 if (!f.exists()) { | |
179 f.createNewFile(); | |
180 } | |
181 FileChannel fc = new FileOutputStream(f).getChannel(); | |
182 FileLock fl = fc.lock(); | |
183 try { | |
184 fc.write(ByteBuffer.wrap(data)); | |
185 } finally { | |
186 fl.release(); | |
187 fc.close(); | |
188 } | |
189 } | |
190 | |
191 private byte[] compose() { | |
192 ByteArrayOutputStream bos = new ByteArrayOutputStream(1024); | |
193 PrintStream ps = new PrintStream(bos); | |
194 Iterator<String> sectionNames = sections.iterator(); | |
195 for (Map<String,String> s : content) { | |
196 final String name = sectionNames.next(); // iterate through names despite section may be empty | |
197 if (s.isEmpty()) { | |
198 continue; // do not write an empty section | |
199 } | |
200 ps.print('['); | |
201 ps.print(name); | |
202 ps.println(']'); | |
203 for (Map.Entry<String, String> e : s.entrySet()) { | |
204 ps.print(e.getKey()); | |
205 ps.print('='); | |
206 ps.println(e.getValue()); | |
207 } | |
208 ps.println(); | |
209 } | |
210 ps.flush(); | |
211 return bos.toByteArray(); | |
212 } | |
144 } | 213 } |