Mercurial > jhg
comparison src/org/tmatesoft/hg/internal/ChangelogEntryBuilder.java @ 618:7c0d2ce340b8
Refactor approach how content finds it way down to a commit revision
| author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
|---|---|
| date | Thu, 16 May 2013 19:46:13 +0200 |
| parents | dd4f6311af52 |
| children | 4e6179bde4fc |
comparison
equal
deleted
inserted
replaced
| 617:65c01508f002 | 618:7c0d2ce340b8 |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 TMate Software Ltd | 2 * Copyright (c) 2012-2013 TMate Software Ltd |
| 3 * | 3 * |
| 4 * This program is free software; you can redistribute it and/or modify | 4 * This program is free software; you can redistribute it and/or modify |
| 5 * it under the terms of the GNU General Public License as published by | 5 * it under the terms of the GNU General Public License as published by |
| 6 * the Free Software Foundation; version 2 of the License. | 6 * the Free Software Foundation; version 2 of the License. |
| 7 * | 7 * |
| 14 * the terms of a license other than GNU General Public License | 14 * the terms of a license other than GNU General Public License |
| 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.ByteArrayOutputStream; | |
| 19 import java.util.ArrayList; | 20 import java.util.ArrayList; |
| 20 import java.util.Collection; | 21 import java.util.Collection; |
| 21 import java.util.Collections; | 22 import java.util.Collections; |
| 22 import java.util.Iterator; | 23 import java.util.Iterator; |
| 23 import java.util.LinkedHashMap; | 24 import java.util.LinkedHashMap; |
| 24 import java.util.List; | 25 import java.util.List; |
| 25 import java.util.Map; | 26 import java.util.Map; |
| 27 import java.util.Map.Entry; | |
| 26 import java.util.TimeZone; | 28 import java.util.TimeZone; |
| 27 import java.util.Map.Entry; | |
| 28 | 29 |
| 30 import org.tmatesoft.hg.core.HgIOException; | |
| 29 import org.tmatesoft.hg.core.Nodeid; | 31 import org.tmatesoft.hg.core.Nodeid; |
| 32 import org.tmatesoft.hg.internal.DataSerializer.DataSource; | |
| 30 import org.tmatesoft.hg.util.Path; | 33 import org.tmatesoft.hg.util.Path; |
| 31 | 34 |
| 32 /** | 35 /** |
| 33 * | 36 * Builds changelog entry |
| 34 * @author Artem Tikhomirov | 37 * @author Artem Tikhomirov |
| 35 * @author TMate Software Ltd. | 38 * @author TMate Software Ltd. |
| 36 */ | 39 */ |
| 37 public class ChangelogEntryBuilder { | 40 public class ChangelogEntryBuilder implements DataSource { |
| 38 | 41 |
| 39 private String user; | 42 private String user; |
| 40 private List<Path> modifiedFiles; | 43 private List<Path> modifiedFiles; |
| 41 private final Map<String, String> extrasMap = new LinkedHashMap<String, String>(); | 44 private final Map<String, String> extrasMap = new LinkedHashMap<String, String>(); |
| 42 private Integer tzOffset; | 45 private Integer tzOffset; |
| 43 private Long csetTime; | 46 private Long csetTime; |
| 47 private Nodeid manifestRev; | |
| 48 private CharSequence comment; | |
| 44 | 49 |
| 45 public ChangelogEntryBuilder user(String username) { | 50 public ChangelogEntryBuilder user(String username) { |
| 46 user = username; | 51 user = username; |
| 47 return this; | 52 return this; |
| 48 } | 53 } |
| 87 csetTime = seconds; | 92 csetTime = seconds; |
| 88 tzOffset = timezoneOffset; | 93 tzOffset = timezoneOffset; |
| 89 return this; | 94 return this; |
| 90 } | 95 } |
| 91 | 96 |
| 97 public ChangelogEntryBuilder manifest(Nodeid manifestRevision) { | |
| 98 manifestRev = manifestRevision; | |
| 99 return this; | |
| 100 } | |
| 101 | |
| 102 public ChangelogEntryBuilder comment(CharSequence commentString) { | |
| 103 comment = commentString; | |
| 104 return this; | |
| 105 } | |
| 106 | |
| 107 public void serialize(DataSerializer out) throws HgIOException { | |
| 108 byte[] b = build(); | |
| 109 out.write(b, 0, b.length); | |
| 110 } | |
| 111 | |
| 112 public int serializeLength() { | |
| 113 return -1; | |
| 114 } | |
| 115 | |
| 116 public byte[] build() { | |
| 117 ByteArrayOutputStream out = new ByteArrayOutputStream(); | |
| 118 final int LF = '\n'; | |
| 119 CharSequence extras = buildExtras(); | |
| 120 CharSequence files = buildFiles(); | |
| 121 byte[] manifestRevision = manifestRev.toString().getBytes(); | |
| 122 byte[] username = user().getBytes(EncodingHelper.getUTF8()); | |
| 123 out.write(manifestRevision, 0, manifestRevision.length); | |
| 124 out.write(LF); | |
| 125 out.write(username, 0, username.length); | |
| 126 out.write(LF); | |
| 127 final long csetDate = csetTime(); | |
| 128 byte[] date = String.format("%d %d", csetDate, csetTimezone(csetDate)).getBytes(); | |
| 129 out.write(date, 0, date.length); | |
| 130 if (extras.length() > 0) { | |
| 131 out.write(' '); | |
| 132 byte[] b = extras.toString().getBytes(); | |
| 133 out.write(b, 0, b.length); | |
| 134 } | |
| 135 out.write(LF); | |
| 136 byte[] b = files.toString().getBytes(); | |
| 137 out.write(b, 0, b.length); | |
| 138 out.write(LF); | |
| 139 out.write(LF); | |
| 140 byte[] cmt = comment.toString().getBytes(EncodingHelper.getUTF8()); | |
| 141 out.write(cmt, 0, cmt.length); | |
| 142 return out.toByteArray(); | |
| 143 } | |
| 144 | |
| 145 private CharSequence buildExtras() { | |
| 146 StringBuilder extras = new StringBuilder(); | |
| 147 for (Iterator<Entry<String, String>> it = extrasMap.entrySet().iterator(); it.hasNext();) { | |
| 148 final Entry<String, String> next = it.next(); | |
| 149 extras.append(encodeExtrasPair(next.getKey())); | |
| 150 extras.append(':'); | |
| 151 extras.append(encodeExtrasPair(next.getValue())); | |
| 152 if (it.hasNext()) { | |
| 153 extras.append('\00'); | |
| 154 } | |
| 155 } | |
| 156 return extras; | |
| 157 } | |
| 158 | |
| 159 private CharSequence buildFiles() { | |
| 160 StringBuilder files = new StringBuilder(); | |
| 161 if (modifiedFiles != null) { | |
| 162 Collections.sort(modifiedFiles); | |
| 163 for (Iterator<Path> it = modifiedFiles.iterator(); it.hasNext(); ) { | |
| 164 files.append(it.next()); | |
| 165 if (it.hasNext()) { | |
| 166 files.append('\n'); | |
| 167 } | |
| 168 } | |
| 169 } | |
| 170 return files; | |
| 171 } | |
| 172 | |
| 173 private final static CharSequence encodeExtrasPair(String s) { | |
| 174 if (s != null) { | |
| 175 return s.replace("\\", "\\\\").replace("\n", "\\n").replace("\r", "\\r").replace("\00", "\\0"); | |
| 176 } | |
| 177 return s; | |
| 178 } | |
| 179 | |
| 92 private long csetTime() { | 180 private long csetTime() { |
| 93 if (csetTime != null) { | 181 if (csetTime != null) { |
| 94 return csetTime; | 182 return csetTime; |
| 95 } | 183 } |
| 96 return System.currentTimeMillis() / 1000; | 184 return System.currentTimeMillis() / 1000; |
| 100 if (tzOffset != null) { | 188 if (tzOffset != null) { |
| 101 return tzOffset; | 189 return tzOffset; |
| 102 } | 190 } |
| 103 return -(TimeZone.getDefault().getOffset(time) / 1000); | 191 return -(TimeZone.getDefault().getOffset(time) / 1000); |
| 104 } | 192 } |
| 105 | |
| 106 public byte[] build(Nodeid manifestRevision, String comment) { | |
| 107 String f = "%s\n%s\n%d %d %s\n%s\n\n%s"; | |
| 108 StringBuilder extras = new StringBuilder(); | |
| 109 for (Iterator<Entry<String, String>> it = extrasMap.entrySet().iterator(); it.hasNext();) { | |
| 110 final Entry<String, String> next = it.next(); | |
| 111 extras.append(encodeExtrasPair(next.getKey())); | |
| 112 extras.append(':'); | |
| 113 extras.append(encodeExtrasPair(next.getValue())); | |
| 114 if (it.hasNext()) { | |
| 115 extras.append('\00'); | |
| 116 } | |
| 117 } | |
| 118 StringBuilder files = new StringBuilder(); | |
| 119 if (modifiedFiles != null) { | |
| 120 for (Iterator<Path> it = modifiedFiles.iterator(); it.hasNext(); ) { | |
| 121 files.append(it.next()); | |
| 122 if (it.hasNext()) { | |
| 123 files.append('\n'); | |
| 124 } | |
| 125 } | |
| 126 } | |
| 127 final long date = csetTime(); | |
| 128 final int tz = csetTimezone(date); | |
| 129 return String.format(f, manifestRevision.toString(), user(), date, tz, extras, files, comment).getBytes(); | |
| 130 } | |
| 131 | |
| 132 private final static CharSequence encodeExtrasPair(String s) { | |
| 133 if (s != null) { | |
| 134 return s.replace("\\", "\\\\").replace("\n", "\\n").replace("\r", "\\r").replace("\00", "\\0"); | |
| 135 } | |
| 136 return s; | |
| 137 } | |
| 138 } | 193 } |
