1 package org.apache.maven.vsslib;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 import java.io.FileNotFoundException;
22 import java.io.IOException;
23
24 import java.text.SimpleDateFormat;
25
26 import java.util.Collection;
27 import java.util.Date;
28 import java.util.Locale;
29
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32 import org.apache.maven.changelog.AbstractChangeLogGenerator;
33 import org.apache.maven.changelog.ChangeLogParser;
34 import org.apache.tools.ant.taskdefs.Execute;
35 import org.apache.tools.ant.types.Commandline;
36
37
38 /*******************************************************************************
39 * A Visual Source Safe implementation of the
40 * {@link org.apache.maven.changelog.ChangeLogGenerator}interface realized
41 * extending the {@link org.apache.maven.changelog.AbstractChangeLogGenerator}.
42 *
43 * The command line build by this class uses the <code>ss History</code> VSS
44 * command and formats the output in a way the VssChangeLogParser can
45 * understand. Due to this fact this implementations works only if used within a
46 * vss view.
47 *
48 * The command looks like this:
49 * <p>
50 * set ssdir=vssRepositoryPath ss History vssProject -YvssUserId,vssUserPassword
51 * -R -Vd01/12/04~23/11/04 -I-Y
52 *
53 * @author Freddy Mallet
54 */
55 public class VssChangeLogGenerator extends AbstractChangeLogGenerator
56 {
57 /**
58 * Log
59 */
60 private static final Log LOG =
61 LogFactory.getLog( VssChangeLogGenerator.class );
62
63 /***************************************************************************
64 * Constructs the appropriate command line to execute the scm's log command.
65 * For Clearcase it's lshistory.
66 *
67 * @see org.apache.maven.changelog.AbstractChangeLogGenerator#getScmLogCommand()
68 * @return The command line to be executed.
69 */
70 protected Commandline getScmLogCommand()
71 {
72 VssConnection vssConnection = new VssConnection( getConnection() );
73 Commandline command = new Commandline();
74
75 command.setExecutable( "ss" );
76 command.createArgument().setValue( "History" );
77 command.createArgument().setValue( "$"
78 + vssConnection.getVssProject() );
79
80
81 if ( vssConnection.getVssUserInf() != null )
82 {
83 command.createArgument().setValue( "-Y"
84 + vssConnection.getVssUserInf() );
85 }
86
87
88 command.createArgument().setValue( "-R" );
89
90
91 command.createArgument().setValue( "-I-" );
92
93
94 if ( dateRange != null )
95 {
96 command.createArgument().setValue( "-Vd" + dateRange );
97 }
98
99 return command;
100 }
101
102 /***************************************************************************
103 * Construct the command-line argument that is passed to the scm client to
104 * specify the appropriate date range.
105 *
106 * @param before
107 * The starting point.
108 * @param to
109 * The ending point.
110 * @return A string that can be used to specify a date to a scm system.
111 *
112 * @see org.apache.maven.changelog.AbstractChangeLogGenerator#getScmDateArgument(java.util.Date,
113 * java.util.Date)
114 */
115 protected String getScmDateArgument( Date before, Date to )
116 {
117 SimpleDateFormat sdf =
118 new SimpleDateFormat( "dd/MM/yyyy", Locale.ENGLISH );
119 String result = sdf.format( to ) + "~" + sdf.format( before );
120
121 return result;
122 }
123
124 protected String getScmTagArgument( String tagStart, String tagEnd )
125 {
126 throw new UnsupportedOperationException(
127 "Cannot presently use tags for SCM operations on VSS" );
128 }
129
130 /**
131 * Convert date range from 'number of days' format to 'date to date' format
132 *
133 * @param numDaysString
134 * String
135 */
136 public void setDateRange( String numDaysString )
137 {
138 int days = Integer.parseInt( numDaysString );
139
140 Date before =
141 new Date( System.currentTimeMillis()
142 - ( (long) days * 24 * 60 * 60 * 1000 ) );
143 Date to =
144 new Date( System.currentTimeMillis()
145 + ( (long) 1 * 24 * 60 * 60 * 1000 ) );
146 }
147
148 /***************************************************************************
149 * Execute vss client driving the given parser. This method has been
150 * overwritten to be able to set 'SSDIR' environment variable. This variable
151 * set the vss repository
152 *
153 * @param parser
154 * A {@link ChangeLogParser parser}to process the vss output.
155 * @return A collection of {@link ChangeLogEntry entries}parsed from the
156 * vss output.
157 * @throws IOException
158 * When there are issues executing vss.
159 * @see ChangeLogGenerator#getEntries(ChangeLogParser)
160 */
161 public Collection getEntries( ChangeLogParser parser )
162 throws IOException
163 {
164 if ( parser == null )
165 {
166 throw new NullPointerException( "parser cannot be null" );
167 }
168
169 if ( base == null )
170 {
171 throw new NullPointerException( "basedir must be set" );
172 }
173
174 if ( !base.exists() )
175 {
176 throw new FileNotFoundException( "Cannot find base dir "
177 + base.getAbsolutePath() );
178 }
179
180 clParser = parser;
181
182 try
183 {
184 VssConnection vssConnection =
185 new VssConnection( getConnection() );
186
187 Execute exe = new Execute( this );
188
189 String[] env = exe.getEnvironment();
190
191 if ( env == null )
192 {
193 env = new String[0];
194 }
195
196 String[] newEnv = new String[env.length + 1];
197
198 for ( int i = 0; i < env.length; i++ )
199 {
200 newEnv[i] = env[i];
201 }
202
203 newEnv[env.length] = "SSDIR=" + vssConnection.getVssDir();
204
205 exe.setEnvironment( newEnv );
206 exe.setCommandline( getScmLogCommand().getCommandline() );
207
208
209 exe.setWorkingDirectory( base );
210 logExecute( exe, base );
211
212 exe.execute();
213
214
215 String errors = errorReader.toString().trim();
216
217 if ( errors.length() > 0 )
218 {
219 LOG.error( errors );
220 }
221 }
222 catch ( IOException ioe )
223 {
224 handleParserException( ioe );
225 }
226
227 return entries;
228 }
229 }