2
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
6
* The contents of this file are subject to the terms of either the GNU
7
* General Public License Version 2 only ("GPL") or the Common
8
* Development and Distribution License("CDDL") (collectively, the
9
* "License"). You may not use this file except in compliance with the
10
* License. You can obtain a copy of the License at
11
* http://www.netbeans.org/cddl-gplv2.html
12
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
* specific language governing permissions and limitations under the
14
* License. When distributing the software, include this License Header
15
* Notice in each file and include the License file at
16
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
17
* particular file as subject to the "Classpath" exception as provided
18
* by Sun in the GPL Version 2 section of the License file that
19
* accompanied this code. If applicable, add the following below the
20
* License Header, with the fields enclosed by brackets [] replaced by
21
* your own identifying information:
22
* "Portions Copyrighted [year] [name of copyright owner]"
26
* The Original Software is NetBeans. The Initial Developer of the Original
27
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
* Microsystems, Inc. All Rights Reserved.
30
* If you wish your version of this file to be governed by only the CDDL
31
* or only the GPL Version 2, indicate your decision by adding
32
* "[Contributor] elects to include this software in this distribution
33
* under the [CDDL or GPL Version 2] license." If you do not indicate a
34
* single choice of license, a recipient has the option to distribute
35
* your version of this file under either the CDDL, the GPL Version 2 or
36
* to extend the choice of license to its licensees as provided above.
37
* However, if you add GPL Version 2 code and therefore, elected the GPL
38
* Version 2 license, then the option applies only if the new code is
39
* made subject to such option by the copyright holder.
42
package org.netbeans.lib.cvsclient.command.commit;
46
import org.netbeans.lib.cvsclient.command.*;
47
import org.netbeans.lib.cvsclient.event.*;
50
* Handles the building of update information object and the firing of
51
* events when complete objects are built.
53
* @author Milos Kleint
55
public class CommitBuilder
61
public static final String UNKNOWN = "commit: nothing known about `"; //NOI18N
62
public static final String EXAM_DIR = ": Examining"; //NOI18N
63
public static final String REMOVING = "Removing "; //NOI18N
64
public static final String NEW_REVISION = "new revision:"; //NOI18N
65
public static final String INITIAL_REVISION = "initial revision:"; //NOI18N
66
public static final String DELETED_REVISION = "delete"; //NOI18N
67
public static final String DONE = "done"; //NOI18N
68
public static final String RCS_FILE = "RCS file: "; //NOI18N
69
public static final String ADD = "commit: use `cvs add' to create an entry for "; //NOI18N
70
public static final String COMMITTED = " <-- "; // NOI18N
73
* The status object that is currently being built.
75
private CommitInformation commitInformation;
78
* The directory in which the file being processed lives. This is
79
* absolute inside the local directory
81
private File fileDirectory;
84
* The event manager to use.
86
private final EventManager eventManager;
88
private final String localPath;
90
private final String repositoryRoot;
92
private boolean isAdding;
94
public CommitBuilder(EventManager eventManager, String localPath, String repositoryRoot) {
95
this.eventManager = eventManager;
96
this.localPath = localPath;
97
this.repositoryRoot = repositoryRoot;
100
public void outputDone() {
101
if (commitInformation != null) {
102
eventManager.fireCVSEvent(new FileInfoEvent(this, commitInformation));
103
commitInformation = null;
107
public void parseLine(String line, boolean isErrorMessage) {
109
if (line.indexOf(UNKNOWN) >= 0) {
111
processUnknownFile(line.substring(line.indexOf(UNKNOWN) + UNKNOWN.length()).trim());
113
else if (line.indexOf(ADD) > 0) {
114
processToAddFile(line.substring(line.indexOf(ADD) + ADD.length()).trim());
116
else if ((c = line.indexOf(COMMITTED)) > 0) {
118
String fileName = line.substring(c + COMMITTED.length()).trim();
119
int nameIndex = fileName.lastIndexOf('/');
120
if (nameIndex != -1) { //#73181 happens with 1.12 servers: /usr/cvsrepo/Java112/nbproject/project.properties,v <-- nbproject/project.properties
121
fileName = fileName.substring(nameIndex+1);
124
if (fileDirectory == null) {
125
String reposPath = line.substring(0, c).trim();
126
if (reposPath.startsWith(repositoryRoot)) {
127
reposPath = reposPath.substring(repositoryRoot.length());
128
if (reposPath.startsWith("/")) reposPath = reposPath.substring(1);
130
c = reposPath.lastIndexOf('/');
131
if (c > 0) reposPath = reposPath.substring(0, c); // remove the file name
132
file = findFile(fileName, reposPath);
134
file = new File(fileDirectory, fileName);
138
commitInformation.setType(CommitInformation.ADDED);
142
commitInformation.setType(CommitInformation.CHANGED);
145
else if (line.startsWith(REMOVING)) {
147
processFile(line.substring(REMOVING.length(), line.length() - 1));
148
// - 1 means to cut the ';' character
149
commitInformation.setType(CommitInformation.REMOVED);
151
else if (line.indexOf(EXAM_DIR) >= 0) {
152
fileDirectory = new File(localPath, line.substring(line.indexOf(EXAM_DIR) + EXAM_DIR.length()).trim());
154
else if (line.startsWith(RCS_FILE)) {
157
else if (line.startsWith(DONE)) {
160
else if (line.startsWith(INITIAL_REVISION)) {
161
processRevision(line.substring(INITIAL_REVISION.length()));
162
commitInformation.setType(CommitInformation.ADDED);
164
else if (line.startsWith(NEW_REVISION)) {
165
processRevision(line.substring(NEW_REVISION.length()));
169
private File createFile(String fileName) {
170
return new File(localPath, fileName);
173
private void processUnknownFile(String line) {
174
commitInformation = new CommitInformation();
175
commitInformation.setType(CommitInformation.UNKNOWN);
176
int index = line.indexOf('\'');
177
String fileName = line.substring(0, index).trim();
178
commitInformation.setFile(createFile(fileName));
182
private void processToAddFile(String line) {
183
commitInformation = new CommitInformation();
184
commitInformation.setType(CommitInformation.TO_ADD);
185
String fileName = line.trim();
186
if (fileName.endsWith(";")) { //NOI18N
187
fileName = fileName.substring(0, fileName.length() - 2);
189
commitInformation.setFile(createFile(fileName));
193
private void processFile(String filename) {
194
if (commitInformation == null) {
195
commitInformation = new CommitInformation();
198
if (filename.startsWith("no file")) { //NOI18N
199
filename = filename.substring(8);
201
commitInformation.setFile(createFile(filename));
204
private void processFile(File file) {
205
if (commitInformation == null) {
206
commitInformation = new CommitInformation();
209
commitInformation.setFile(file);
212
private void processRevision(String revision) {
213
int index = revision.indexOf(';');
215
revision = revision.substring(0, index);
217
revision = revision.trim();
218
if (DELETED_REVISION.equals(revision)) {
219
commitInformation.setType(CommitInformation.REMOVED);
221
commitInformation.setRevision(revision);
224
public void parseEnhancedMessage(String key, Object value) {
227
private File findFile(String fileName, String reposPath) {
228
File dir = new File(localPath);
229
// happens when adding a new file to a branch
230
if (reposPath.endsWith("/Attic")) {
231
reposPath = reposPath.substring(0, reposPath.length() - 6);
233
// use quick finder and fallback to original algorithm just in case
234
File file = quickFindFile(dir, fileName, reposPath);
235
if (file != null) return file;
236
return findFile(dir, fileName, reposPath);
239
private File findFile(File dir, String fileName, String reposPath) {
240
if (isWorkForRepository(dir, reposPath)) {
241
return new File(dir, fileName);
244
File[] subFiles = dir.listFiles();
245
if (subFiles != null) {
246
for (int i = 0; i < subFiles.length; i++) {
247
if (subFiles[i].isDirectory()) {
248
file = findFile(subFiles[i], fileName, reposPath);
249
if (file != null) break;
257
private File quickFindFile(File dir, String fileName, String reposPath) {
259
File deepDir = new File(dir, reposPath);
260
if (isWorkForRepository(deepDir, reposPath)) {
261
return new File(deepDir, fileName);
263
dir = dir.getParentFile();
264
if (dir == null) return null;
268
private boolean isWorkForRepository(File dir, String reposPath) {
270
String repository = eventManager.getClientServices().getRepositoryForDirectory(dir);
271
String root = eventManager.getClientServices().getRepository();
272
if (repository.startsWith(root)) repository = repository.substring(root.length() + 1);
273
return reposPath.equals(repository);
274
} catch (IOException e) {