1 package net.sf.statsvn.util;
2
3 import java.io.IOException;
4 import java.io.InputStream;
5 import java.io.InputStreamReader;
6 import java.util.regex.Matcher;
7 import java.util.regex.Pattern;
8
9 import net.sf.statcvs.util.LookaheadReader;
10 import net.sf.statsvn.output.SvnConfigurationOptions;
11
12 /**
13 * Utility class that verifies if the correct version of subversion is used.
14 *
15 * @author Jean-Philippe Daigle <jpdaigle@softwareengineering.ca>
16 *
17 * @version $Id: SvnStartupUtils.java 351 2008-03-28 18:46:26Z benoitx $
18 */
19 public final class SvnStartupUtils {
20 private static final String SVN_VERSION_COMMAND = "svn --version";
21
22 private static final String SVN_MINIMUM_VERSION = "1.3.0";
23
24 private static final String SVN_MINIMUM_VERSION_DIFF_PER_REV = "1.4.0";
25
26 private static final String SVN_VERSION_LINE_PATTERN = ".* [0-9]+\\.[0-9]+\\.[0-9]+.*";
27
28 private static final String SVN_VERSION_PATTERN = "[0-9]+\\.[0-9]+\\.[0-9]+";
29
30
31 private static final String SVN_INFO_WITHREPO_LINE_PATTERN = ".*<root>.+</root>.*";
32
33 private static final String SVN_REPO_ROOT_NOTFOUND = "Repository root not available - verify that the project was checked out with svn version "
34 + SVN_MINIMUM_VERSION + " or above.";
35
36 /**
37 * A utility class (only static methods) should be final and have
38 * a private constructor.
39 */
40 private SvnStartupUtils() {
41 }
42
43 /**
44 * Verifies that the current revision of SVN is SVN_MINIMUM_VERSION
45 *
46 * @throws SvnVersionMismatchException
47 * if SVN executable not found or version less than
48 * SVN_MINIMUM_VERSION
49 * @return the version string
50 */
51 public static synchronized String checkSvnVersionSufficient() throws SvnVersionMismatchException {
52 ProcessUtils pUtils = null;
53 try {
54
55 pUtils = ProcessUtils.call(SVN_VERSION_COMMAND);
56 final InputStream istream = pUtils.getInputStream();
57 final LookaheadReader reader = new LookaheadReader(new InputStreamReader(istream));
58
59 while (reader.hasNextLine()) {
60 final String line = reader.nextLine();
61 if (line.matches(SVN_VERSION_LINE_PATTERN)) {
62
63 final Pattern pRegex = Pattern.compile(SVN_VERSION_PATTERN);
64 final Matcher m = pRegex.matcher(line);
65 if (m.find()) {
66 final String versionString = line.substring(m.start(), m.end());
67
68
69 if (versionString.compareTo(SVN_MINIMUM_VERSION) >= 0) {
70 return versionString;
71 } else {
72 throw new SvnVersionMismatchException(versionString, SVN_MINIMUM_VERSION);
73 }
74 }
75 }
76 }
77
78 if (pUtils.hasErrorOccured()) {
79 throw new IOException(pUtils.getErrorMessage());
80 }
81 } catch (final IOException e) {
82 SvnConfigurationOptions.getTaskLogger().info(e.getMessage());
83 } catch (final RuntimeException e) {
84 SvnConfigurationOptions.getTaskLogger().info(e.getMessage());
85 } finally {
86 if (pUtils != null) {
87 try {
88 pUtils.close();
89 } catch (final IOException e) {
90 SvnConfigurationOptions.getTaskLogger().info(e.getMessage());
91 }
92 }
93 }
94
95 throw new SvnVersionMismatchException();
96 }
97
98 /**
99 * Verifies that the "svn info" command can return the repository root
100 * (info available in svn >= 1.3.0)
101 *
102 * @throws SvnVersionMismatchException
103 * if <tt>svn info</tt> failed to provide a non-empty repository root
104 */
105 public static synchronized void checkRepoRootAvailable() throws SvnVersionMismatchException {
106 ProcessUtils pUtils = null;
107 try {
108 final boolean rootOnlyTrue = true;
109 pUtils = SvnInfoUtils.getSvnInfo(rootOnlyTrue);
110 final InputStream istream = pUtils.getInputStream();
111 final LookaheadReader reader = new LookaheadReader(new InputStreamReader(istream));
112
113 while (reader.hasNextLine()) {
114 final String line = reader.nextLine();
115 if (line.matches(SVN_INFO_WITHREPO_LINE_PATTERN)) {
116
117
118 istream.close();
119 return;
120 }
121 }
122
123 if (pUtils.hasErrorOccured()) {
124 throw new IOException(pUtils.getErrorMessage());
125 }
126 } catch (final Exception e) {
127 SvnConfigurationOptions.getTaskLogger().info(e.getMessage());
128 } finally {
129 if (pUtils != null) {
130 try {
131 pUtils.close();
132 } catch (final IOException e) {
133 SvnConfigurationOptions.getTaskLogger().info(e.getMessage());
134 }
135 }
136 }
137
138 throw new SvnVersionMismatchException(SVN_REPO_ROOT_NOTFOUND);
139
140 }
141
142 public static synchronized boolean checkDiffPerRevPossible(final String version) {
143
144 return version.compareTo(SVN_MINIMUM_VERSION_DIFF_PER_REV) >= 0;
145 }
146 }