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 } |
