You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

BugtraqConfig.java 7.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. /*
  2. * Copyright (c) 2013 by syntevo GmbH. All Rights Reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions are met:
  6. *
  7. * o Redistributions of source code must retain the above copyright notice,
  8. * this list of conditions and the following disclaimer.
  9. *
  10. * o Redistributions in binary form must reproduce the above copyright notice,
  11. * this list of conditions and the following disclaimer in the documentation
  12. * and/or other materials provided with the distribution.
  13. *
  14. * o Neither the name of syntevo GmbH nor the names of
  15. * its contributors may be used to endorse or promote products derived
  16. * from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  19. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  20. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  21. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  22. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  23. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  24. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  25. * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  26. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  27. * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  28. * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. */
  30. package com.syntevo.bugtraq;
  31. import java.io.*;
  32. import java.util.*;
  33. import org.eclipse.jgit.errors.*;
  34. import org.eclipse.jgit.lib.*;
  35. import org.eclipse.jgit.revwalk.*;
  36. import org.eclipse.jgit.storage.file.*;
  37. import org.eclipse.jgit.treewalk.*;
  38. import org.eclipse.jgit.treewalk.filter.*;
  39. import org.jetbrains.annotations.*;
  40. public final class BugtraqConfig {
  41. // Constants ==============================================================
  42. private static final String DOT_GIT_BUGTRAQ = ".gitbugtraq";
  43. private static final String DOT_TGITCONFIG = ".tgitconfig";
  44. private static final String BUGTRAQ = "bugtraq";
  45. private static final String URL = "url";
  46. private static final String ENABLED = "enabled";
  47. private static final String LOG_REGEX = "logregex";
  48. private static final String LOG_FILTERREGEX = "logfilterregex";
  49. private static final String LOG_LINKREGEX = "loglinkregex";
  50. private static final String LOG_LINKTEXT = "loglinktext";
  51. // Static =================================================================
  52. @Nullable
  53. public static BugtraqConfig read(@NotNull Repository repository) throws IOException, ConfigInvalidException {
  54. Config baseConfig = getBaseConfig(repository, DOT_GIT_BUGTRAQ);
  55. if (baseConfig == null) {
  56. baseConfig = getBaseConfig(repository, DOT_TGITCONFIG);
  57. }
  58. final Set<String> allNames = new HashSet<String>();
  59. final Config config = repository.getConfig();
  60. if (getString(null, URL, config, baseConfig) != null) {
  61. allNames.add(null);
  62. }
  63. else {
  64. allNames.addAll(config.getSubsections(BUGTRAQ));
  65. if (baseConfig != null) {
  66. allNames.addAll(baseConfig.getSubsections(BUGTRAQ));
  67. }
  68. }
  69. final List<BugtraqEntry> entries = new ArrayList<BugtraqEntry>();
  70. for (String name : allNames) {
  71. final String url = getString(name, URL, config, baseConfig);
  72. if (url == null) {
  73. continue;
  74. }
  75. final String enabled = getString(name, ENABLED, config, baseConfig);
  76. if (enabled != null && !"true".equals(enabled)) {
  77. continue;
  78. }
  79. String idRegex = getString(name, LOG_REGEX, config, baseConfig);
  80. if (idRegex == null) {
  81. return null;
  82. }
  83. String filterRegex = getString(name, LOG_FILTERREGEX, config, baseConfig);
  84. final String linkRegex = getString(name, LOG_LINKREGEX, config, baseConfig);
  85. if (filterRegex == null && linkRegex == null) {
  86. final String[] split = idRegex.split("\n", Integer.MAX_VALUE);
  87. if (split.length == 2) {
  88. // Compatibility with TortoiseGit
  89. filterRegex = split[0];
  90. idRegex = split[1];
  91. }
  92. else {
  93. // Backwards compatibility with specification version < 0.3
  94. final List<String> logIdRegexs = new ArrayList<String>();
  95. for (int index = 1; index < Integer.MAX_VALUE; index++) {
  96. final String logIdRegexN = getString(name, LOG_REGEX + index, config, baseConfig);
  97. if (logIdRegexN == null) {
  98. break;
  99. }
  100. logIdRegexs.add(logIdRegexN);
  101. }
  102. if (logIdRegexs.size() > 1) {
  103. throw new ConfigInvalidException("More than three " + LOG_REGEX + " entries found. This is not supported anymore since bugtraq version 0.3, use " + LOG_FILTERREGEX + " and " + LOG_LINKREGEX + " instead.");
  104. }
  105. else if (logIdRegexs.size() == 1) {
  106. filterRegex = idRegex;
  107. idRegex = logIdRegexs.get(0);
  108. }
  109. }
  110. }
  111. final String linkText = getString(name, LOG_LINKTEXT, config, baseConfig);
  112. entries.add(new BugtraqEntry(url, idRegex, linkRegex, filterRegex, linkText));
  113. }
  114. if (entries.isEmpty()) {
  115. return null;
  116. }
  117. return new BugtraqConfig(entries);
  118. }
  119. // Fields =================================================================
  120. @NotNull
  121. private final List<BugtraqEntry> entries;
  122. // Setup ==================================================================
  123. BugtraqConfig(@NotNull List<BugtraqEntry> entries) {
  124. this.entries = entries;
  125. }
  126. // Accessing ==============================================================
  127. @NotNull
  128. public List<BugtraqEntry> getEntries() {
  129. return Collections.unmodifiableList(entries);
  130. }
  131. // Utils ==================================================================
  132. @Nullable
  133. private static Config getBaseConfig(@NotNull Repository repository, @NotNull String configFileName) throws IOException, ConfigInvalidException {
  134. final Config baseConfig;
  135. if (repository.isBare()) {
  136. // read bugtraq config directly from the repository
  137. String content = null;
  138. RevWalk rw = new RevWalk(repository);
  139. TreeWalk tw = new TreeWalk(repository);
  140. tw.setFilter(PathFilterGroup.createFromStrings(configFileName));
  141. try {
  142. ObjectId headId = repository.getRef(Constants.HEAD).getTarget().getObjectId();
  143. RevCommit commit = rw.parseCommit(headId);
  144. RevTree tree = commit.getTree();
  145. tw.reset(tree);
  146. while (tw.next()) {
  147. ObjectId entid = tw.getObjectId(0);
  148. FileMode entmode = tw.getFileMode(0);
  149. if (FileMode.REGULAR_FILE == entmode) {
  150. ObjectLoader ldr = repository.open(entid, Constants.OBJ_BLOB);
  151. content = new String(ldr.getCachedBytes(), commit.getEncoding());
  152. break;
  153. }
  154. }
  155. }
  156. finally {
  157. rw.dispose();
  158. tw.release();
  159. }
  160. if (content == null) {
  161. // config not found
  162. baseConfig = null;
  163. }
  164. else {
  165. // parse the config
  166. Config config = new Config();
  167. config.fromText(content);
  168. baseConfig = config;
  169. }
  170. }
  171. else {
  172. // read bugtraq config from work tree
  173. final File baseFile = new File(repository.getWorkTree(), configFileName);
  174. if (baseFile.isFile()) {
  175. FileBasedConfig fileConfig = new FileBasedConfig(baseFile, repository.getFS());
  176. fileConfig.load();
  177. baseConfig = fileConfig;
  178. }
  179. else {
  180. baseConfig = null;
  181. }
  182. }
  183. return baseConfig;
  184. }
  185. @Nullable
  186. private static String getString(@Nullable String subsection, @NotNull String key, @NotNull Config config, @Nullable Config baseConfig) {
  187. final String value = config.getString(BUGTRAQ, subsection, key);
  188. if (value != null) {
  189. return trimMaybeNull(value);
  190. }
  191. if (baseConfig != null) {
  192. return trimMaybeNull(baseConfig.getString(BUGTRAQ, subsection, key));
  193. }
  194. return value;
  195. }
  196. @Nullable
  197. private static String trimMaybeNull(@Nullable String string) {
  198. if (string == null) {
  199. return null;
  200. }
  201. string = string.trim();
  202. if (string.length() == 0) {
  203. return null;
  204. }
  205. return string;
  206. }
  207. }