annotate src/org/tmatesoft/hg/internal/SubrepoManager.java @ 338:3cfa4d908fc9

Add options to control DataAccessProvider, allow to turn off use of file memory mapping in particular to solve potential sharing violation (os file handle gets released on MappedByteByffer being GC'd, not on FileChannel.close())
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Tue, 15 Nov 2011 04:47:03 +0100
parents 981f9f50bb6c
children a0864b2892cd
rev   line source
239
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
1 /*
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
2 * Copyright (c) 2011 TMate Software Ltd
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
3 *
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
4 * This program is free software; you can redistribute it and/or modify
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
5 * it under the terms of the GNU General Public License as published by
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
6 * the Free Software Foundation; version 2 of the License.
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
7 *
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
8 * This program is distributed in the hope that it will be useful,
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
11 * GNU General Public License for more details.
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
12 *
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
13 * For information on how to redistribute this software under
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
14 * the terms of a license other than GNU General Public License
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
15 * contact TMate Software at support@hg4j.com
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
16 */
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
17 package org.tmatesoft.hg.internal;
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
18
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
19 import java.io.BufferedReader;
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
20 import java.io.File;
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
21 import java.io.FileReader;
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
22 import java.io.IOException;
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
23 import java.util.Arrays;
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
24 import java.util.Collections;
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
25 import java.util.HashMap;
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
26 import java.util.LinkedList;
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
27 import java.util.List;
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
28 import java.util.Map;
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
29
295
981f9f50bb6c Issue 11: Error log facility. SessionContext to share common facilities
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 239
diff changeset
30 import org.tmatesoft.hg.repo.HgInternals;
239
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
31 import org.tmatesoft.hg.repo.HgRepository;
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
32 import org.tmatesoft.hg.repo.HgSubrepoLocation;
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
33
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
34 /**
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
35 *
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
36 * @author Artem Tikhomirov
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
37 * @author TMate Software Ltd.
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
38 */
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
39 public class SubrepoManager /* XXX RepoChangeNotifier, RepoChangeListener */{
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
40
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
41 private final HgRepository repo;
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
42 private List<HgSubrepoLocation> subRepos;
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
43
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
44 public SubrepoManager(HgRepository hgRepo) {
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
45 assert hgRepo != null;
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
46 repo = hgRepo;
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
47 }
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
48
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
49 private List<HgSubrepoLocation> readActualState() {
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
50 File hgsubFile = new File(repo.getWorkingDir(), ".hgsub");
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
51 if (!hgsubFile.canRead()) {
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
52 return Collections.emptyList();
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
53 }
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
54 try {
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
55 Map<String, String> state; // path -> revision
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
56 File hgstateFile = new File(repo.getWorkingDir(), ".hgsubstate");
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
57 if (hgstateFile.canRead()) {
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
58 state = readState(new BufferedReader(new FileReader(hgstateFile)));
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
59 } else {
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
60 state = Collections.emptyMap();
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
61 }
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
62 BufferedReader br = new BufferedReader(new FileReader(hgsubFile));
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
63 return readConfig(br, state);
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
64 } catch (IOException ex) {
295
981f9f50bb6c Issue 11: Error log facility. SessionContext to share common facilities
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 239
diff changeset
65 HgInternals.getContext(repo).getLog().error(getClass(), ex, "Subrepo state read failed");
239
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
66 }
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
67 return Collections.emptyList();
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
68 }
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
69
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
70 private List<HgSubrepoLocation> readConfig(BufferedReader br, Map<String, String> substate) throws IOException {
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
71 try {
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
72 String line;
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
73 LinkedList<HgSubrepoLocation> res = new LinkedList<HgSubrepoLocation>();
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
74 while ((line = br.readLine()) != null) {
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
75 int sep = line.indexOf('=');
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
76 if (sep == -1) {
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
77 continue;
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
78 }
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
79 // since both key and value are referenced from HgSubrepoLocation, doesn't make sense
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
80 // to have separate String instances (new String(line.substring()))
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
81 String key = line.substring(0, sep).trim();
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
82 String value = line.substring(sep + 1).trim();
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
83 if (value.length() == 0) {
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
84 // XXX log bad line?
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
85 continue;
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
86 }
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
87 HgSubrepoLocation.Kind kind = HgSubrepoLocation.Kind.Hg;
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
88 int kindEnd = value.indexOf(']', 1);
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
89 if (value.charAt(0) == '[' && kindEnd != -1) {
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
90 String kindStr = value.substring(1, kindEnd);
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
91 value = value.substring(kindEnd + 1);
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
92 if ("svn".equals(kindStr)) {
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
93 kind = HgSubrepoLocation.Kind.SVN;
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
94 } else if ("git".equals(kindStr)) {
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
95 kind = HgSubrepoLocation.Kind.Git;
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
96 }
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
97 }
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
98 // TODO respect paths mappings in config file
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
99 HgSubrepoLocation loc = new HgSubrepoLocation(repo, key, value, kind, substate.get(key));
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
100 res.add(loc);
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
101 }
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
102 return Arrays.asList(res.toArray(new HgSubrepoLocation[res.size()]));
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
103 } finally {
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
104 br.close();
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
105 }
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
106 }
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
107
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
108 private Map<String, String> readState(BufferedReader br) throws IOException {
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
109 HashMap<String, String> rv = new HashMap<String, String>();
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
110 try {
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
111 String line;
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
112 while ((line = br.readLine()) != null) {
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
113 int sep = line.trim().indexOf(' ');
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
114 if (sep != -1) {
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
115 rv.put(line.substring(sep+1).trim(), line.substring(0, sep).trim());
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
116 }
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
117 }
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
118 } finally {
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
119 br.close();
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
120 }
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
121 return rv;
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
122 }
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
123
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
124 public List<HgSubrepoLocation> all(/*int revision, or TIP|WC*/) {
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
125 if (subRepos == null) {
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
126 subRepos = readActualState();
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
127 }
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
128 return subRepos;
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
129 }
df9d2854d3d6 Initial access to subrepositories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
130 }