1 | /*
|
---|
2 | * Copyright 2002-2004 The Apache Software Foundation
|
---|
3 | *
|
---|
4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
---|
5 | * you may not use this file except in compliance with the License.
|
---|
6 | * You may obtain a copy of the License at
|
---|
7 | *
|
---|
8 | * http://www.apache.org/licenses/LICENSE-2.0
|
---|
9 | *
|
---|
10 | * Unless required by applicable law or agreed to in writing, software
|
---|
11 | * distributed under the License is distributed on an "AS IS" BASIS,
|
---|
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
---|
13 | * See the License for the specific language governing permissions and
|
---|
14 | * limitations under the License.
|
---|
15 | *
|
---|
16 | */
|
---|
17 | package org.apache.tools.ant.taskdefs.optional.starteam;
|
---|
18 |
|
---|
19 | import com.starbase.starteam.File;
|
---|
20 | import com.starbase.starteam.Folder;
|
---|
21 | import com.starbase.starteam.Item;
|
---|
22 | import com.starbase.starteam.Status;
|
---|
23 | import com.starbase.starteam.View;
|
---|
24 | import com.starbase.starteam.ViewConfiguration;
|
---|
25 | import java.io.IOException;
|
---|
26 | import java.text.SimpleDateFormat;
|
---|
27 | import java.util.Enumeration;
|
---|
28 | import org.apache.tools.ant.BuildException;
|
---|
29 | import org.apache.tools.ant.Project;
|
---|
30 |
|
---|
31 | /**
|
---|
32 | * Produces a listing of the contents of the StarTeam repository
|
---|
33 | * at the specified view and StarTeamFolder.
|
---|
34 | *
|
---|
35 | * Created: Tue Dec 25 06:51:14 2001
|
---|
36 | *
|
---|
37 | * @version 1.0
|
---|
38 | *
|
---|
39 | * @ant.task name="stlist" category="scm"
|
---|
40 | */
|
---|
41 |
|
---|
42 | public class StarTeamList extends TreeBasedTask {
|
---|
43 | private boolean listUncontrolled = true;
|
---|
44 | /**
|
---|
45 | * List files, dates, and statuses as of this label; optional.
|
---|
46 | * The label must exist in starteam or an exception will be thrown.
|
---|
47 | * If not specified, the most recent version of each file will be listed.
|
---|
48 | *
|
---|
49 | * @param label the label to be listed
|
---|
50 | */
|
---|
51 | public void setLabel(String label) {
|
---|
52 | _setLabel(label);
|
---|
53 | }
|
---|
54 |
|
---|
55 | /**
|
---|
56 | * List files, dates, and statuses as of this date; optional.
|
---|
57 | * If not specified, the most recent version of each file will be listed.
|
---|
58 | *
|
---|
59 | * @param asOfDateParam the date as of which the listing to be made
|
---|
60 | * @since Ant 1.6
|
---|
61 | */
|
---|
62 | public void setAsOfDate(String asOfDateParam) {
|
---|
63 | _setAsOfDate(asOfDateParam);
|
---|
64 | }
|
---|
65 |
|
---|
66 | /**
|
---|
67 | * Date Format with which asOfDate parameter to be parsed; optional.
|
---|
68 | * Must be a SimpleDateFormat compatible string.
|
---|
69 | * If not specified, and asOfDateParam is specified, parse will use ISO8601
|
---|
70 | * datetime and date formats.
|
---|
71 | *
|
---|
72 | * @param asOfDateFormat the SimpleDateFormat-compatible format string
|
---|
73 | * @since Ant 1.6
|
---|
74 | */
|
---|
75 | public void setAsOfDateFormat(String asOfDateFormat) {
|
---|
76 | _setAsOfDateFormat(asOfDateFormat);
|
---|
77 | }
|
---|
78 |
|
---|
79 |
|
---|
80 | /**
|
---|
81 | * Override of base-class abstract function creates an
|
---|
82 | * appropriately configured view for checkoutlists - either
|
---|
83 | * the current view or a view from this.label.
|
---|
84 | *
|
---|
85 | * @param raw the unconfigured <code>View</code>
|
---|
86 | * @return the snapshot <code>View</code> appropriately configured.
|
---|
87 | */
|
---|
88 | protected View createSnapshotView(View raw) {
|
---|
89 |
|
---|
90 | int labelID = getLabelID(raw);
|
---|
91 |
|
---|
92 | // if a label has been supplied, use it to configure the view
|
---|
93 | // otherwise use current view
|
---|
94 | if (labelID >= 0) {
|
---|
95 | return new View(raw, ViewConfiguration.createFromLabel(labelID));
|
---|
96 | }
|
---|
97 | // if a date has been supplied use a view configured to the date.
|
---|
98 | View view = getViewConfiguredByDate(raw);
|
---|
99 | if (view != null) {
|
---|
100 | return view;
|
---|
101 | }
|
---|
102 | // otherwise, use this view configured as the tip.
|
---|
103 | else {
|
---|
104 | return new View(raw, ViewConfiguration.createTip());
|
---|
105 | }
|
---|
106 | }
|
---|
107 |
|
---|
108 | /**
|
---|
109 | * Required base-class abstract function implementation checks for
|
---|
110 | * incompatible parameters.
|
---|
111 | *
|
---|
112 | * @exception BuildException thrown on incompatible params specified
|
---|
113 | */
|
---|
114 | protected void testPreconditions() throws BuildException {
|
---|
115 | if (null != getLabel() && null != getAsOfDate()) {
|
---|
116 | throw new BuildException(
|
---|
117 | "Both label and asOfDate specified. "
|
---|
118 | + "Unable to process request.");
|
---|
119 | }
|
---|
120 | }
|
---|
121 |
|
---|
122 | /**
|
---|
123 | * extenders should emit to the log an entry describing the parameters
|
---|
124 | * that will be used by this operation.
|
---|
125 | *
|
---|
126 | * @param starteamrootFolder
|
---|
127 | * root folder in StarTeam for the operation
|
---|
128 | * @param targetrootFolder
|
---|
129 | * root local folder for the operation (whether specified by the user or not.
|
---|
130 | */
|
---|
131 | protected void logOperationDescription(Folder starteamrootFolder,
|
---|
132 | java.io.File targetrootFolder) {
|
---|
133 | log((this.isRecursive() ? "Recursive" : "Non-recursive")
|
---|
134 | + " Listing of: " + starteamrootFolder.getFolderHierarchy());
|
---|
135 |
|
---|
136 | log("Listing against local folder"
|
---|
137 | + (null == getRootLocalFolder() ? " (default): " : ": ")
|
---|
138 | + targetrootFolder.getAbsolutePath(),
|
---|
139 | Project.MSG_INFO);
|
---|
140 | logLabel();
|
---|
141 | logAsOfDate();
|
---|
142 | logIncludes();
|
---|
143 | logExcludes();
|
---|
144 |
|
---|
145 |
|
---|
146 | }
|
---|
147 | /**
|
---|
148 | * Implements base-class abstract function to perform the checkout
|
---|
149 | * operation on the files in each folder of the tree.
|
---|
150 | *
|
---|
151 | * @param starteamFolder the StarTeam folder from which files to be
|
---|
152 | * checked out
|
---|
153 | * @param targetFolder the local mapping of rootStarteamFolder
|
---|
154 | */
|
---|
155 | protected void visit(Folder starteamFolder, java.io.File targetFolder)
|
---|
156 | throws BuildException {
|
---|
157 | try {
|
---|
158 | if (null != getRootLocalFolder()) {
|
---|
159 | starteamFolder.setAlternatePathFragment(
|
---|
160 | targetFolder.getAbsolutePath());
|
---|
161 |
|
---|
162 | }
|
---|
163 | Folder[] subFolders = starteamFolder.getSubFolders();
|
---|
164 | Item[] files = starteamFolder.getItems(getTypeNames().FILE);
|
---|
165 |
|
---|
166 | UnmatchedFileMap ufm =
|
---|
167 | new UnmatchedListingMap().init(
|
---|
168 | targetFolder.getAbsoluteFile(), starteamFolder);
|
---|
169 |
|
---|
170 | log("");
|
---|
171 | log("Listing StarTeam folder "
|
---|
172 | + starteamFolder.getFolderHierarchy());
|
---|
173 | log(" against local folder " + targetFolder.getAbsolutePath());
|
---|
174 |
|
---|
175 |
|
---|
176 | // For all Files in this folder, we need to check
|
---|
177 | // if there have been modifications.
|
---|
178 |
|
---|
179 | for (int i = 0; i < files.length; i++) {
|
---|
180 | File eachFile = (File) files[i];
|
---|
181 | String filename = eachFile.getName();
|
---|
182 | java.io.File localFile =
|
---|
183 | new java.io.File(targetFolder, filename);
|
---|
184 |
|
---|
185 | ufm.removeControlledItem(localFile);
|
---|
186 |
|
---|
187 | // If the file doesn't pass the include/exclude tests, skip it.
|
---|
188 | if (!shouldProcess(filename)) {
|
---|
189 | continue;
|
---|
190 | }
|
---|
191 |
|
---|
192 | list(eachFile, localFile);
|
---|
193 | }
|
---|
194 |
|
---|
195 |
|
---|
196 | // Now we recursively call this method on all sub folders in this
|
---|
197 | // folder unless recursive attribute is off.
|
---|
198 | for (int i = 0; i < subFolders.length; i++) {
|
---|
199 | java.io.File targetSubfolder =
|
---|
200 | new java.io.File(targetFolder, subFolders[i].getName());
|
---|
201 | ufm.removeControlledItem(targetSubfolder);
|
---|
202 | if (isRecursive()) {
|
---|
203 | visit(subFolders[i], targetSubfolder);
|
---|
204 | }
|
---|
205 | }
|
---|
206 | if (this.listUncontrolled) {
|
---|
207 | ufm.processUncontrolledItems();
|
---|
208 | }
|
---|
209 |
|
---|
210 | } catch (IOException e) {
|
---|
211 | throw new BuildException(e);
|
---|
212 | }
|
---|
213 | }
|
---|
214 |
|
---|
215 | private static final SimpleDateFormat SDF =
|
---|
216 | new SimpleDateFormat("yyyy-MM-dd hh:mm:ss zzz");
|
---|
217 |
|
---|
218 | protected void list(File reposFile, java.io.File localFile)
|
---|
219 | throws IOException {
|
---|
220 | StringBuffer b = new StringBuffer();
|
---|
221 | int status = reposFile.getStatus();
|
---|
222 | java.util.Date displayDate = null;
|
---|
223 | if (status == Status.NEW) {
|
---|
224 | displayDate = new java.util.Date(localFile.lastModified());
|
---|
225 | } else {
|
---|
226 | displayDate = reposFile.getModifiedTime().createDate();
|
---|
227 | }
|
---|
228 | b.append(pad(Status.name(status), 12)).append(' ');
|
---|
229 | b.append(pad(getUserName(reposFile.getLocker()), 20))
|
---|
230 | .append(' ')
|
---|
231 | .append(SDF.format(displayDate))
|
---|
232 | .append(rpad(String.valueOf(reposFile.getSize()), 9))
|
---|
233 | .append(' ')
|
---|
234 | .append(reposFile.getName());
|
---|
235 |
|
---|
236 | log(b.toString());
|
---|
237 | }
|
---|
238 |
|
---|
239 | private static final String blankstr = blanks(30);
|
---|
240 |
|
---|
241 | private static String blanks(int len) {
|
---|
242 | StringBuffer b = new StringBuffer();
|
---|
243 | for (int i = 0; i < len; i++) {
|
---|
244 | b.append(' ');
|
---|
245 | }
|
---|
246 | return b.toString();
|
---|
247 | }
|
---|
248 |
|
---|
249 | protected static String pad(String s, int padlen) {
|
---|
250 | return (s + blankstr).substring(0, padlen);
|
---|
251 | }
|
---|
252 |
|
---|
253 | protected static String rpad(String s, int padlen) {
|
---|
254 | s = blankstr + s;
|
---|
255 | return s.substring(s.length() - padlen);
|
---|
256 | }
|
---|
257 |
|
---|
258 | /**
|
---|
259 | * handles the list of uncontrolled items
|
---|
260 | */
|
---|
261 | private class UnmatchedListingMap extends UnmatchedFileMap {
|
---|
262 |
|
---|
263 | protected boolean isActive() {
|
---|
264 | return StarTeamList.this.listUncontrolled;
|
---|
265 | }
|
---|
266 |
|
---|
267 | /**
|
---|
268 | * lists uncontrolled items from the local tree. It is assumed
|
---|
269 | * that this method will not be called until all the items in the
|
---|
270 | * corresponding folder have been processed, and that the internal map
|
---|
271 | * will contain only uncontrolled items.
|
---|
272 | */
|
---|
273 | void processUncontrolledItems() throws BuildException {
|
---|
274 | if (this.isActive()) {
|
---|
275 | Enumeration e = this.keys();
|
---|
276 |
|
---|
277 | // handle the files so they appear first
|
---|
278 | while (e.hasMoreElements()) {
|
---|
279 | java.io.File local = (java.io.File) e.nextElement();
|
---|
280 | Item remoteItem = (Item) this.get(local);
|
---|
281 |
|
---|
282 | // once we find a folder that isn't in the repository,
|
---|
283 | // we know we can add it.
|
---|
284 | if (local.isFile()) {
|
---|
285 | com.starbase.starteam.File remoteFile =
|
---|
286 | (com.starbase.starteam.File) remoteItem;
|
---|
287 | try {
|
---|
288 | list(remoteFile, local);
|
---|
289 | } catch (IOException ie) {
|
---|
290 | throw new BuildException("IOError in stlist", ie);
|
---|
291 | }
|
---|
292 | }
|
---|
293 | }
|
---|
294 | // now do it again for the directories so they appear last.
|
---|
295 | e = this.keys();
|
---|
296 | while (e.hasMoreElements()) {
|
---|
297 | java.io.File local = (java.io.File) e.nextElement();
|
---|
298 | Item remoteItem = (Item) this.get(local);
|
---|
299 |
|
---|
300 | // once we find a folder that isn't in the repository,
|
---|
301 | // we know we can add it.
|
---|
302 | if (local.isDirectory()) {
|
---|
303 | Folder folder = (Folder) remoteItem;
|
---|
304 | if (isRecursive()) {
|
---|
305 | log("Listing uncontrolled folder "
|
---|
306 | + folder.getFolderHierarchy()
|
---|
307 | + " from " + local.getAbsoluteFile());
|
---|
308 | UnmatchedFileMap submap =
|
---|
309 | new UnmatchedListingMap().init(local, folder);
|
---|
310 | submap.processUncontrolledItems();
|
---|
311 | }
|
---|
312 | }
|
---|
313 | }
|
---|
314 | }
|
---|
315 | }
|
---|
316 | }
|
---|
317 | }
|
---|
318 |
|
---|
319 |
|
---|