~ubuntu-branches/ubuntu/trusty/netbeans/trusty

« back to all changes in this revision

Viewing changes to javacvs/libsrc/org/netbeans/lib/cvsclient/command/log/LogBuilder.java

  • Committer: Bazaar Package Importer
  • Author(s): Marek Slama
  • Date: 2008-01-29 14:11:22 UTC
  • Revision ID: james.westby@ubuntu.com-20080129141122-fnzjbo11ntghxfu7
Tags: upstream-6.0.1
ImportĀ upstreamĀ versionĀ 6.0.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 
3
 *
 
4
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
 
5
 *
 
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]"
 
23
 *
 
24
 * Contributor(s):
 
25
 *
 
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.
 
29
 *
 
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.
 
40
 */
 
41
package org.netbeans.lib.cvsclient.command.log;
 
42
 
 
43
import java.io.*;
 
44
import java.util.*;
 
45
import java.text.SimpleDateFormat;
 
46
import java.text.ParseException;
 
47
 
 
48
import org.netbeans.lib.cvsclient.command.*;
 
49
import org.netbeans.lib.cvsclient.event.*;
 
50
import org.netbeans.lib.cvsclient.util.*;
 
51
 
 
52
/**
 
53
 * Handles the building of a log information object and the firing of
 
54
 * events when complete objects are built.
 
55
 * @author Milos Kleint
 
56
 */
 
57
public class LogBuilder implements Builder {
 
58
    private static final String LOGGING_DIR = ": Logging "; //NOI18N
 
59
    private static final String RCS_FILE = "RCS file: "; //NOI18N
 
60
    private static final String WORK_FILE = "Working file: "; //NOI18N
 
61
    private static final String REV_HEAD = "head: "; //NOI18N
 
62
    private static final String BRANCH = "branch: "; //NOI18N
 
63
    private static final String LOCKS = "locks: "; //NOI18N
 
64
    private static final String ACCESS_LIST = "access list: "; //NOI18N
 
65
    private static final String SYM_NAME = "symbolic names:"; //NOI18N
 
66
    private static final String KEYWORD_SUBST = "keyword substitution: "; //NOI18N
 
67
    private static final String TOTAL_REV = "total revisions: "; //NOI18N
 
68
    private static final String SEL_REV = ";\tselected revisions: "; //NOI18N
 
69
    private static final String DESCRIPTION = "description:"; //NOI18N
 
70
    private static final String REVISION = "revision "; //NOI18N
 
71
    private static final String DATE = "date: "; //NOI18N
 
72
    private static final String BRANCHES = "branches: "; //NOI18N
 
73
    private static final String AUTHOR = "author: "; //NOI18N
 
74
    private static final String STATE = "state: "; //NOI18N
 
75
    private static final String LINES = "lines: "; //NOI18N
 
76
    private static final String COMMITID = "commitid: "; //NOI18N
 
77
    private static final String SPLITTER = "----------------------------"; //NOI18N
 
78
    private static final String FINAL_SPLIT = "============================================================================="; //NOI18N
 
79
    private static final String ERROR = ": nothing known about "; //NOI18N
 
80
    private static final String NO_FILE = "no file"; //NOI18N
 
81
    /**
 
82
     * The event manager to use
 
83
     */
 
84
    protected EventManager eventManager;
 
85
    protected BasicCommand logCommand;
 
86
    /**
 
87
     * The log object that is currently being built
 
88
     */
 
89
    protected LogInformation logInfo;
 
90
    protected LogInformation.Revision revision;
 
91
    /**
 
92
     * The directory in which the file being processed lives. This is
 
93
     * relative to the local directory
 
94
     */
 
95
    protected String fileDirectory;
 
96
    private boolean addingSymNames;
 
97
    private boolean addingDescription;
 
98
    private boolean addingLogMessage;
 
99
    private StringBuffer tempBuffer = null;
 
100
    
 
101
    private List messageList;
 
102
 
 
103
    private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z"); //NOI18N
 
104
    
 
105
    public LogBuilder(EventManager eventMan, BasicCommand command) {
 
106
        logCommand = command;
 
107
        eventManager = eventMan;
 
108
        addingSymNames = false;
 
109
        addingDescription = false;
 
110
        addingLogMessage = false;
 
111
        logInfo = null;
 
112
        revision = null;
 
113
        messageList = new ArrayList(500);
 
114
    }
 
115
 
 
116
    public void outputDone() {
 
117
        if (logInfo != null) {
 
118
            eventManager.fireCVSEvent(new FileInfoEvent(this, logInfo));
 
119
            logInfo = null;
 
120
            messageList = null;
 
121
        }
 
122
    }
 
123
 
 
124
    public void parseLine(String line, boolean isErrorMessage) {
 
125
        if (line.equals(FINAL_SPLIT)) {
 
126
            if (addingDescription) {
 
127
                addingDescription = false;
 
128
                logInfo.setDescription(tempBuffer.toString());
 
129
            }
 
130
            if (addingLogMessage) {
 
131
                addingLogMessage = false;
 
132
                revision.setMessage(CommandUtils.findUniqueString(tempBuffer.toString(), messageList));
 
133
            }
 
134
            if (revision != null) {
 
135
                logInfo.addRevision(revision);
 
136
                revision = null;
 
137
            }
 
138
            // fire the event and exit
 
139
            if (logInfo != null) {
 
140
                eventManager.fireCVSEvent(new FileInfoEvent(this, logInfo));
 
141
                logInfo = null;
 
142
                tempBuffer = null;
 
143
            }
 
144
            return;
 
145
        }
 
146
        if (addingLogMessage) {
 
147
            // first check for the branches tag
 
148
            if (line.startsWith(BRANCHES)) {
 
149
                processBranches(line.substring(BRANCHES.length()));
 
150
            }
 
151
            else {
 
152
                processLogMessage(line);
 
153
                return;
 
154
            }
 
155
        }
 
156
        if (addingSymNames) {
 
157
            processSymbolicNames(line);
 
158
        }
 
159
        if (addingDescription) {
 
160
            processDescription(line);
 
161
        }
 
162
        // revision stuff first -> will be  the most common to parse
 
163
        if (line.startsWith(REVISION)) {
 
164
            processRevisionStart(line);
 
165
        }
 
166
        if (line.startsWith(DATE)) {
 
167
            processRevisionDate(line);
 
168
        }
 
169
 
 
170
        if (line.startsWith(KEYWORD_SUBST)) {
 
171
            logInfo.setKeywordSubstitution(line.substring(KEYWORD_SUBST.length()).trim().intern());
 
172
            addingSymNames = false;
 
173
            return;
 
174
        }
 
175
 
 
176
        if (line.startsWith(DESCRIPTION)) {
 
177
            tempBuffer = new StringBuffer(line.substring(DESCRIPTION.length()));
 
178
            addingDescription = true;
 
179
        }
 
180
 
 
181
        if (line.indexOf(LOGGING_DIR) >= 0) {
 
182
            fileDirectory = line.substring(line.indexOf(LOGGING_DIR) + LOGGING_DIR.length()).trim();
 
183
            return;
 
184
        }
 
185
        if (line.startsWith(RCS_FILE)) {
 
186
            processRcsFile(line.substring(RCS_FILE.length()));
 
187
            return;
 
188
        }
 
189
        if (line.startsWith(WORK_FILE)) {
 
190
            processWorkingFile(line.substring(WORK_FILE.length()));
 
191
            return;
 
192
        }
 
193
        if (line.startsWith(REV_HEAD)) {
 
194
            logInfo.setHeadRevision(line.substring(REV_HEAD.length()).trim().intern());
 
195
            return;
 
196
        }
 
197
        if (line.startsWith(BRANCH)) {
 
198
            logInfo.setBranch(line.substring(BRANCH.length()).trim().intern());
 
199
        }
 
200
        if (line.startsWith(LOCKS)) {
 
201
            logInfo.setLocks(line.substring(LOCKS.length()).trim().intern());
 
202
        }
 
203
        if (line.startsWith(ACCESS_LIST)) {
 
204
            logInfo.setAccessList(line.substring(ACCESS_LIST.length()).trim().intern());
 
205
        }
 
206
        if (line.startsWith(SYM_NAME)) {
 
207
            addingSymNames = true;
 
208
        }
 
209
        if (line.startsWith(TOTAL_REV)) {
 
210
            int ind = line.indexOf(';');
 
211
            if (ind < 0) {
 
212
                // no selected revisions here..
 
213
                logInfo.setTotalRevisions(line.substring(TOTAL_REV.length()).trim().intern());
 
214
                logInfo.setSelectedRevisions("0"); //NOI18N
 
215
            }
 
216
            else {
 
217
                String total = line.substring(0, ind);
 
218
                String select = line.substring(ind, line.length());
 
219
                logInfo.setTotalRevisions(total.substring(TOTAL_REV.length()).trim().intern());
 
220
                logInfo.setSelectedRevisions(select.substring(SEL_REV.length()).trim().intern());
 
221
            }
 
222
        }
 
223
    }
 
224
 
 
225
    private String findUniqueString(String name, List list) {
 
226
        if (name == null) {
 
227
            return null;
 
228
        }
 
229
        int index = list.indexOf(name);
 
230
        if (index >= 0) {
 
231
            return (String)list.get(index);
 
232
        }
 
233
        else {
 
234
            String newName = name;
 
235
            list.add(newName);
 
236
            return newName;
 
237
        }
 
238
    }
 
239
    
 
240
    private void processRcsFile(String line) {
 
241
        if (logInfo != null) {
 
242
            //do fire logcreated event;
 
243
        }
 
244
        logInfo = new LogInformation();
 
245
        logInfo.setRepositoryFilename(line.trim());
 
246
    }
 
247
 
 
248
    private void processWorkingFile(String line) {
 
249
        String fileName = line.trim();
 
250
        if (fileName.startsWith(NO_FILE)) {
 
251
            fileName = fileName.substring(8);
 
252
        }
 
253
 
 
254
        logInfo.setFile(createFile(line));
 
255
    }
 
256
 
 
257
    private void processBranches(String line) {
 
258
        int ind = line.lastIndexOf(';');
 
259
        if (ind > 0) {
 
260
            line = line.substring(0, ind);
 
261
        }
 
262
        revision.setBranches(line.trim());
 
263
    }
 
264
 
 
265
    private void processLogMessage(String line) {
 
266
        if (line.startsWith(SPLITTER)) {
 
267
            addingLogMessage = false;
 
268
            revision.setMessage(findUniqueString(tempBuffer.toString(), messageList));
 
269
            return;
 
270
        }
 
271
        tempBuffer.append(line + "\n"); //NOI18N
 
272
    }
 
273
 
 
274
    private void processSymbolicNames(String line) {
 
275
        if (!line.startsWith(KEYWORD_SUBST)) {
 
276
            line = line.trim();
 
277
            int index = line.indexOf(':');
 
278
            if (index > 0) {
 
279
                String symName = line.substring(0, index).trim();
 
280
                String revName = line.substring(index + 1, line.length()).trim();
 
281
                logInfo.addSymbolicName(symName.intern(), revName.intern());
 
282
            }
 
283
        }
 
284
    }
 
285
 
 
286
    private void processDescription(String line) {
 
287
        if (line.startsWith(SPLITTER)) {
 
288
            addingDescription = false;
 
289
            logInfo.setDescription(tempBuffer.toString());
 
290
            return;
 
291
        }
 
292
        tempBuffer.append(line);
 
293
    }
 
294
 
 
295
    private void processRevisionStart(String line) {
 
296
        if (revision != null) {
 
297
            logInfo.addRevision(revision);
 
298
        }
 
299
        revision = logInfo.createNewRevision(
 
300
                    line.substring(REVISION.length()).intern());
 
301
    }
 
302
 
 
303
    private void processRevisionDate(String line) {
 
304
        StringTokenizer tokenizer = new StringTokenizer(line, ";", false); //NOI18N
 
305
        while (tokenizer.hasMoreTokens()) {
 
306
            String token = tokenizer.nextToken().trim();
 
307
            if (token.startsWith(DATE)) {
 
308
                String dateString = token.substring(DATE.length());
 
309
                Date date = null;
 
310
                try {
 
311
                    // some servers use dashes to separate date components, so replace with slashes
 
312
                    // also add a default GMT timezone at the end, if the server already put one in this one will be ignored by the parser
 
313
                    dateString = dateString.replace('/', '-') + " +0000"; //NOI18N
 
314
                    date = dateFormat.parse(dateString);
 
315
                } catch (ParseException e) {
 
316
                    BugLog.getInstance().bug("Couldn't parse date " + dateString); //NOI18N
 
317
                }
 
318
                revision.setDate(date, dateString);
 
319
            }
 
320
            else if (token.startsWith(AUTHOR)) revision.setAuthor(token.substring(AUTHOR.length()));
 
321
            else if (token.startsWith(STATE)) revision.setState(token.substring(STATE.length()));
 
322
            else if (token.startsWith(LINES)) revision.setLines(token.substring(LINES.length()));
 
323
            else if (token.startsWith(COMMITID)) revision.setCommitID(token.substring(COMMITID.length()));
 
324
        }
 
325
        addingLogMessage = true;
 
326
        tempBuffer = new StringBuffer();
 
327
    }
 
328
 
 
329
    /**
 
330
     * @param fileName relative URL-path to command execution directory
 
331
     */
 
332
    protected File createFile(String fileName) {
 
333
        StringBuffer path = new StringBuffer();
 
334
        path.append(logCommand.getLocalDirectory());
 
335
        path.append(File.separator);
 
336
 
 
337
        path.append(fileName.replace('/', File.separatorChar));  // NOI18N
 
338
        return new File(path.toString());
 
339
    }
 
340
 
 
341
    public void parseEnhancedMessage(String key, Object value) {
 
342
    }
 
343
}