annotate src/org/tmatesoft/hg/internal/KeywordFilter.java @ 456:909306e412e2

Refactor LogFacility and SessionContext, better API for both
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Mon, 18 Jun 2012 16:54:00 +0200
parents 9c9c442b5f2e
children b3c16d1aede0
rev   line source
112
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
1 /*
418
528b6780a8bd A bit of FIXME cleanup (mostly degraded to TODO post 1.0), comments and javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 367
diff changeset
2 * Copyright (c) 2011-2012 TMate Software Ltd
112
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
3 *
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
4 * This program is free software; you can redistribute it and/or modify
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
5 * it under the terms of the GNU General Public License as published by
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
6 * the Free Software Foundation; version 2 of the License.
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
7 *
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
8 * This program is distributed in the hope that it will be useful,
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
11 * GNU General Public License for more details.
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
12 *
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
13 * For information on how to redistribute this software under
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
14 * the terms of a license other than GNU General Public License
130
7567f4a42fe5 Correct contact address
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 129
diff changeset
15 * contact TMate Software at support@hg4j.com
112
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
16 */
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
17 package org.tmatesoft.hg.internal;
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
18
456
909306e412e2 Refactor LogFacility and SessionContext, better API for both
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 423
diff changeset
19 import static org.tmatesoft.hg.util.LogFacility.Severity.Error;
909306e412e2 Refactor LogFacility and SessionContext, better API for both
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 423
diff changeset
20
112
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
21 import java.nio.ByteBuffer;
114
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
22 import java.util.ArrayList;
354
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 331
diff changeset
23 import java.util.Date;
112
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
24 import java.util.TreeMap;
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
25
354
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 331
diff changeset
26 import org.tmatesoft.hg.core.Nodeid;
154
ba2bf656f00f Changeset => RawChangeset
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
27 import org.tmatesoft.hg.repo.HgChangelog.RawChangeset;
354
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 331
diff changeset
28 import org.tmatesoft.hg.repo.HgInternals;
112
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
29 import org.tmatesoft.hg.repo.HgRepository;
423
9c9c442b5f2e Major refactoring of exception handling. Low-level API uses RuntimeExceptions, while checked are left for higher level
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 418
diff changeset
30 import org.tmatesoft.hg.repo.HgRuntimeException;
331
a37ce7145c3f Access to repository configuration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 154
diff changeset
31 import org.tmatesoft.hg.util.Pair;
133
4a948ec83980 core.Path to util.Path as it's not Hg repo dependant
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 130
diff changeset
32 import org.tmatesoft.hg.util.Path;
112
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
33
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
34 /**
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
35 *
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
36 * @author Artem Tikhomirov
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
37 * @author TMate Software Ltd.
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
38 */
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
39 public class KeywordFilter implements Filter {
113
67ae317408c9 Filter implementation for newline translation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 112
diff changeset
40 // present implementation is stateless, however, filter use pattern shall not assume that. In fact, Factory may us that
114
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
41 private final HgRepository repo;
112
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
42 private final boolean isExpanding;
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
43 private final TreeMap<String,String> keywords;
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
44 private final int minBufferLen;
114
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
45 private final Path path;
154
ba2bf656f00f Changeset => RawChangeset
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
46 private RawChangeset latestFileCset;
112
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
47
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
48 /**
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
49 *
114
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
50 * @param hgRepo
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
51 * @param path
112
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
52 * @param expand <code>true</code> to expand keywords, <code>false</code> to shrink
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
53 */
114
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
54 private KeywordFilter(HgRepository hgRepo, Path p, boolean expand) {
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
55 repo = hgRepo;
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
56 path = p;
112
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
57 isExpanding = expand;
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
58 keywords = new TreeMap<String,String>();
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
59 keywords.put("Id", "Id");
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
60 keywords.put("Revision", "Revision");
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
61 keywords.put("Author", "Author");
113
67ae317408c9 Filter implementation for newline translation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 112
diff changeset
62 keywords.put("Date", "Date");
67ae317408c9 Filter implementation for newline translation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 112
diff changeset
63 keywords.put("LastChangedRevision", "LastChangedRevision");
67ae317408c9 Filter implementation for newline translation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 112
diff changeset
64 keywords.put("LastChangedBy", "LastChangedBy");
67ae317408c9 Filter implementation for newline translation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 112
diff changeset
65 keywords.put("LastChangedDate", "LastChangedDate");
67ae317408c9 Filter implementation for newline translation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 112
diff changeset
66 keywords.put("Source", "Source");
67ae317408c9 Filter implementation for newline translation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 112
diff changeset
67 keywords.put("Header", "Header");
67ae317408c9 Filter implementation for newline translation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 112
diff changeset
68
112
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
69 int l = 0;
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
70 for (String s : keywords.keySet()) {
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
71 if (s.length() > l) {
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
72 l = s.length();
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
73 }
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
74 }
418
528b6780a8bd A bit of FIXME cleanup (mostly degraded to TODO post 1.0), comments and javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 367
diff changeset
75 // TODO post-1.0 later may implement #filter() not to read full kw value (just "$kw:"). However, limit of maxLen + 2 would keep valid.
112
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
76 // for buffers less then minBufferLen, there are chances #filter() implementation would never end
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
77 // (i.e. for input "$LongestKey"$
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
78 minBufferLen = l + 2 + (isExpanding ? 0 : 120 /*any reasonable constant for max possible kw value length*/);
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
79 }
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
80
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
81 /**
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
82 * @param src buffer ready to be read
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
83 * @return buffer ready to be read and original buffer's position modified to reflect consumed bytes. IOW, if source buffer
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
84 * on return has remaining bytes, they are assumed not-read (not processed) and next chunk passed to filter is supposed to
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
85 * start with them
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
86 */
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
87 public ByteBuffer filter(ByteBuffer src) {
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
88 if (src.capacity() < minBufferLen) {
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
89 throw new IllegalStateException(String.format("Need buffer of at least %d bytes to ensure filter won't hang", minBufferLen));
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
90 }
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
91 ByteBuffer rv = null;
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
92 int keywordStart = -1;
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
93 int x = src.position();
119
ed2b4adac51c Index and start of the copy are distinct
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 118
diff changeset
94 int copyFrom = x; // needs to be updated each time we copy a slice, but not each time we modify source index (x)
112
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
95 while (x < src.limit()) {
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
96 if (keywordStart == -1) {
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
97 int i = indexOf(src, '$', x, false);
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
98 if (i == -1) {
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
99 if (rv == null) {
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
100 return src;
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
101 } else {
119
ed2b4adac51c Index and start of the copy are distinct
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 118
diff changeset
102 copySlice(src, copyFrom, src.limit(), rv);
112
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
103 rv.flip();
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
104 src.position(src.limit());
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
105 return rv;
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
106 }
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
107 }
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
108 keywordStart = i;
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
109 // fall-through
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
110 }
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
111 if (keywordStart >= 0) {
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
112 int i = indexOf(src, '$', keywordStart+1, true);
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
113 if (i == -1) {
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
114 // end of buffer reached
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
115 if (rv == null) {
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
116 if (keywordStart == x) {
418
528b6780a8bd A bit of FIXME cleanup (mostly degraded to TODO post 1.0), comments and javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 367
diff changeset
117 // TODO post-1.0 in fact, x might be equal to keywordStart and to src.position() here ('$' is first character in the buffer,
112
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
118 // and there are no other '$' not eols till the end of the buffer). This would lead to deadlock (filter won't consume any
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
119 // bytes). To prevent this, either shall copy bytes [keywordStart..buffer.limit()) to local buffer and use it on the next invocation,
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
120 // or add lookup of the keywords right after first '$' is found (do not wait for closing '$'). For now, large enough src buffer would be sufficient
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
121 // not to run into such situation
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
122 throw new IllegalStateException("Try src buffer of a greater size");
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
123 }
121
b1d6208fb517 Conditionally apply filters to file content
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 119
diff changeset
124 rv = ByteBuffer.allocate(keywordStart - copyFrom);
112
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
125 }
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
126 // copy all from source till latest possible kw start
119
ed2b4adac51c Index and start of the copy are distinct
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 118
diff changeset
127 copySlice(src, copyFrom, keywordStart, rv);
112
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
128 rv.flip();
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
129 // and tell caller we've consumed only to the potential kw start
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
130 src.position(keywordStart);
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
131 return rv;
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
132 } else if (src.get(i) == '$') {
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
133 // end of keyword, or start of a new one.
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
134 String keyword;
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
135 if ((keyword = matchKeyword(src, keywordStart, i)) != null) {
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
136 if (rv == null) {
113
67ae317408c9 Filter implementation for newline translation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 112
diff changeset
137 // src.remaining(), not .capacity because src is not read, and remaining represents
67ae317408c9 Filter implementation for newline translation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 112
diff changeset
138 // actual bytes count, while capacity - potential.
67ae317408c9 Filter implementation for newline translation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 112
diff changeset
139 // Factor of 4 is pure guess and a HACK, need to be fixed with re-expanding buffer on demand
67ae317408c9 Filter implementation for newline translation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 112
diff changeset
140 rv = ByteBuffer.allocate(isExpanding ? src.remaining() * 4 : src.remaining());
112
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
141 }
119
ed2b4adac51c Index and start of the copy are distinct
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 118
diff changeset
142 copySlice(src, copyFrom, keywordStart+1, rv);
112
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
143 rv.put(keyword.getBytes());
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
144 if (isExpanding) {
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
145 rv.put((byte) ':');
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
146 rv.put((byte) ' ');
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
147 expandKeywordValue(keyword, rv);
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
148 rv.put((byte) ' ');
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
149 }
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
150 rv.put((byte) '$');
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
151 keywordStart = -1;
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
152 x = i+1;
119
ed2b4adac51c Index and start of the copy are distinct
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 118
diff changeset
153 copyFrom = x;
112
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
154 continue;
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
155 } else {
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
156 if (rv != null) {
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
157 // we've already did some substitution, thus need to copy bytes we've scanned.
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
158 copySlice(src, x, i, rv);
119
ed2b4adac51c Index and start of the copy are distinct
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 118
diff changeset
159 copyFrom = i;
112
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
160 } // no else in attempt to avoid rv creation if no real kw would be found
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
161 keywordStart = i;
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
162 x = i; // '$' at i wasn't consumed, hence x points to i, not i+1. This is to avoid problems with case: "sdfsd $ asdfs $Id$ sdf"
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
163 continue;
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
164 }
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
165 } else {
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
166 assert src.get(i) == '\n' || src.get(i) == '\r';
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
167 // line break
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
168 if (rv != null) {
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
169 copySlice(src, x, i+1, rv);
119
ed2b4adac51c Index and start of the copy are distinct
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 118
diff changeset
170 copyFrom = i+1;
112
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
171 }
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
172 x = i+1;
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
173 keywordStart = -1; // Wasn't keyword, really
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
174 continue; // try once again
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
175 }
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
176 }
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
177 }
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
178 if (keywordStart != -1) {
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
179 if (rv == null) {
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
180 // no expansion happened yet, and we have potential kw start
113
67ae317408c9 Filter implementation for newline translation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 112
diff changeset
181 rv = ByteBuffer.allocate(keywordStart - src.position());
112
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
182 copySlice(src, src.position(), keywordStart, rv);
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
183 }
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
184 src.position(keywordStart);
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
185 }
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
186 if (rv != null) {
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
187 rv.flip();
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
188 return rv;
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
189 }
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
190 return src;
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
191 }
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
192
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
193 /**
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
194 * @param keyword
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
195 * @param rv
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
196 */
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
197 private void expandKeywordValue(String keyword, ByteBuffer rv) {
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
198 if ("Id".equals(keyword)) {
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
199 rv.put(identityString().getBytes());
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
200 } else if ("Revision".equals(keyword)) {
114
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
201 rv.put(revision().getBytes());
112
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
202 } else if ("Author".equals(keyword)) {
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
203 rv.put(username().getBytes());
114
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
204 } else if ("Date".equals(keyword)) {
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
205 rv.put(date().getBytes());
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
206 } else {
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
207 throw new IllegalStateException(String.format("Keyword %s is not yet supported", keyword));
112
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
208 }
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
209 }
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
210
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
211 private String matchKeyword(ByteBuffer src, int kwStart, int kwEnd) {
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
212 assert kwEnd - kwStart - 1 > 0;
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
213 assert src.get(kwStart) == src.get(kwEnd) && src.get(kwEnd) == '$';
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
214 char[] chars = new char[kwEnd - kwStart - 1];
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
215 int i;
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
216 for (i = 0; i < chars.length; i++) {
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
217 char c = (char) src.get(kwStart + 1 + i);
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
218 if (c == ':') {
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
219 break;
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
220 }
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
221 chars[i] = c;
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
222 }
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
223 String kw = new String(chars, 0, i);
114
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
224 // XXX may use subMap to look up keywords based on few available characters (not waiting till closing $)
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
225 // System.out.println(keywords.subMap("I", "J"));
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
226 // System.out.println(keywords.subMap("A", "B"));
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
227 // System.out.println(keywords.subMap("Au", "B"));
112
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
228 return keywords.get(kw);
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
229 }
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
230
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
231 // copies part of the src buffer, [from..to). doesn't modify src position
113
67ae317408c9 Filter implementation for newline translation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 112
diff changeset
232 static void copySlice(ByteBuffer src, int from, int to, ByteBuffer dst) {
112
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
233 if (to > src.limit()) {
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
234 throw new IllegalArgumentException("Bad right boundary");
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
235 }
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
236 if (dst.remaining() < to - from) {
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
237 throw new IllegalArgumentException("Not enough room in the destination buffer");
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
238 }
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
239 for (int i = from; i < to; i++) {
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
240 dst.put(src.get(i));
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
241 }
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
242 }
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
243
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
244 private static int indexOf(ByteBuffer b, char ch, int from, boolean newlineBreaks) {
113
67ae317408c9 Filter implementation for newline translation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 112
diff changeset
245 for (int i = from; i < b.limit(); i++) {
112
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
246 byte c = b.get(i);
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
247 if (ch == c) {
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
248 return i;
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
249 }
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
250 if (newlineBreaks && (c == '\n' || c == '\r')) {
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
251 return i;
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
252 }
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
253 }
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
254 return -1;
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
255 }
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
256
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
257 private String identityString() {
114
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
258 return String.format("%s,v %s %s %s", path, revision(), date(), username());
112
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
259 }
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
260
114
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
261 private String revision() {
354
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 331
diff changeset
262 try {
418
528b6780a8bd A bit of FIXME cleanup (mostly degraded to TODO post 1.0), comments and javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 367
diff changeset
263 // TODO post-1.0 Either add cset's nodeid into Changeset class or use own inspector
528b6780a8bd A bit of FIXME cleanup (mostly degraded to TODO post 1.0), comments and javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 367
diff changeset
264 // when accessing changelog, see below, #getChangeset
367
2fadf8695f8a Use 'revision index' instead of the vague 'local revision number' concept in the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 354
diff changeset
265 int csetRev = repo.getFileNode(path).getChangesetRevisionIndex(HgRepository.TIP);
354
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 331
diff changeset
266 return repo.getChangelog().getRevision(csetRev).shortNotation();
423
9c9c442b5f2e Major refactoring of exception handling. Low-level API uses RuntimeExceptions, while checked are left for higher level
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 418
diff changeset
267 } catch (HgRuntimeException ex) {
456
909306e412e2 Refactor LogFacility and SessionContext, better API for both
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 423
diff changeset
268 HgInternals.getContext(repo).getLog().dump(getClass(), Error, ex, null);
354
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 331
diff changeset
269 return Nodeid.NULL.shortNotation(); // XXX perhaps, might return anything better? Not sure how hg approaches this.
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 331
diff changeset
270 }
112
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
271 }
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
272
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
273 private String username() {
354
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 331
diff changeset
274 try {
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 331
diff changeset
275 return getChangeset().user();
423
9c9c442b5f2e Major refactoring of exception handling. Low-level API uses RuntimeExceptions, while checked are left for higher level
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 418
diff changeset
276 } catch (HgRuntimeException ex) {
456
909306e412e2 Refactor LogFacility and SessionContext, better API for both
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 423
diff changeset
277 HgInternals.getContext(repo).getLog().dump(getClass(), Error, ex, null);
354
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 331
diff changeset
278 return "";
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 331
diff changeset
279 }
114
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
280 }
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
281
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
282 private String date() {
354
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 331
diff changeset
283 Date d;
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 331
diff changeset
284 try {
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 331
diff changeset
285 d = getChangeset().date();
423
9c9c442b5f2e Major refactoring of exception handling. Low-level API uses RuntimeExceptions, while checked are left for higher level
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 418
diff changeset
286 } catch (HgRuntimeException ex) {
456
909306e412e2 Refactor LogFacility and SessionContext, better API for both
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 423
diff changeset
287 HgInternals.getContext(repo).getLog().dump(getClass(), Error, ex, null);
354
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 331
diff changeset
288 d = new Date(0l);
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 331
diff changeset
289 }
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 331
diff changeset
290 return String.format("%tY/%<tm/%<td %<tH:%<tM:%<tS", d);
114
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
291 }
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
292
423
9c9c442b5f2e Major refactoring of exception handling. Low-level API uses RuntimeExceptions, while checked are left for higher level
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 418
diff changeset
293 private RawChangeset getChangeset() throws HgRuntimeException {
114
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
294 if (latestFileCset == null) {
418
528b6780a8bd A bit of FIXME cleanup (mostly degraded to TODO post 1.0), comments and javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 367
diff changeset
295 // TODO post-1.0 Use of TIP is likely incorrect in cases when working copy is not based
528b6780a8bd A bit of FIXME cleanup (mostly degraded to TODO post 1.0), comments and javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 367
diff changeset
296 // on latest revision. Perhaps, a constant like HgRepository.DIRSTATE_PARENT may come handy
528b6780a8bd A bit of FIXME cleanup (mostly degraded to TODO post 1.0), comments and javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 367
diff changeset
297 // Besides, it's reasonable to pass own inspector instead of implicit use of RawCsetCollector
528b6780a8bd A bit of FIXME cleanup (mostly degraded to TODO post 1.0), comments and javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 367
diff changeset
298 // to get changeset nodeid/index right away. Also check ChangelogHelper if may be of any use
367
2fadf8695f8a Use 'revision index' instead of the vague 'local revision number' concept in the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 354
diff changeset
299 int csetRev = repo.getFileNode(path).getChangesetRevisionIndex(HgRepository.TIP);
114
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
300 latestFileCset = repo.getChangelog().range(csetRev, csetRev).get(0);
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
301 }
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
302 return latestFileCset;
112
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
303 }
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
304
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
305 public static class Factory implements Filter.Factory {
114
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
306
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
307 private HgRepository repo;
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
308 private Path.Matcher matcher;
112
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
309
331
a37ce7145c3f Access to repository configuration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 154
diff changeset
310 public void initialize(HgRepository hgRepo) {
114
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
311 repo = hgRepo;
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
312 ArrayList<String> patterns = new ArrayList<String>();
331
a37ce7145c3f Access to repository configuration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 154
diff changeset
313 for (Pair<String,String> e : hgRepo.getConfiguration().getSection("keyword")) {
a37ce7145c3f Access to repository configuration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 154
diff changeset
314 if (!"ignore".equalsIgnoreCase(e.second())) {
a37ce7145c3f Access to repository configuration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 154
diff changeset
315 patterns.add(e.first());
114
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
316 }
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
317 }
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
318 matcher = new PathGlobMatcher(patterns.toArray(new String[patterns.size()]));
423
9c9c442b5f2e Major refactoring of exception handling. Low-level API uses RuntimeExceptions, while checked are left for higher level
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 418
diff changeset
319 // TODO post-1.0 read and respect keyword patterns from [keywordmaps]
114
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
320 }
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
321
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
322 public Filter create(Path path, Options opts) {
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
323 if (matcher.accept(path)) {
118
68ba22a2133a Defects in the filter initialization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 114
diff changeset
324 return new KeywordFilter(repo, path, opts.getDirection() == Filter.Direction.FromRepo);
114
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
325 }
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
326 return null;
112
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
327 }
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
328 }
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
329
114
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
330 //
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
331 // public static void main(String[] args) throws Exception {
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
332 // FileInputStream fis = new FileInputStream(new File("/temp/kwoutput.txt"));
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
333 // FileOutputStream fos = new FileOutputStream(new File("/temp/kwoutput2.txt"));
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
334 // ByteBuffer b = ByteBuffer.allocate(256);
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
335 // KeywordFilter kwFilter = new KeywordFilter(false);
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
336 // while (fis.getChannel().read(b) != -1) {
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
337 // b.flip(); // get ready to be read
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
338 // ByteBuffer f = kwFilter.filter(b);
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
339 // fos.getChannel().write(f); // XXX in fact, f may not be fully consumed
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
340 // if (b.hasRemaining()) {
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
341 // b.compact();
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
342 // } else {
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
343 // b.clear();
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
344 // }
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
345 // }
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
346 // fis.close();
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
347 // fos.flush();
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
348 // fos.close();
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 113
diff changeset
349 // }
112
d488c7638b87 Prototype Filter support with keyword filter as a playground
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
350 }