blob: 97d1d7a4f6a9f6ffbfe5b9e98abb9071b5bf9581 [file] [log] [blame]
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.cvsSupport2.cvsoperations.cvsMessages;
import com.intellij.cvsSupport2.application.CvsEntriesManager;
import com.intellij.cvsSupport2.cvshandlers.CvsMessagePattern;
import com.intellij.cvsSupport2.cvsoperations.common.UpdatedFilesManager;
import com.intellij.util.PatternUtil;
import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
import org.netbeans.lib.cvsclient.admin.Entry;
import org.netbeans.lib.cvsclient.command.update.UpdateFileInfo;
import org.netbeans.lib.cvsclient.command.update.UpdatedFileInfo;
import org.netbeans.lib.cvsclient.event.EventManager;
import org.netbeans.lib.cvsclient.event.IEntryListener;
import org.netbeans.lib.cvsclient.event.IFileInfoListener;
import org.netbeans.lib.cvsclient.event.IMessageListener;
import org.netbeans.lib.cvsclient.file.FileObject;
import org.netbeans.lib.cvsclient.file.ICvsFileSystem;
import java.io.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.regex.Pattern;
/**
* author: lesya
*/
public class CvsMessagesTranslator implements IFileInfoListener, IMessageListener, IEntryListener {
@NonNls private static final CvsMessagePattern[] ERRORS_PATTERNS = new CvsMessagePattern[]{
new CvsMessagePattern("cvs [* aborted]*"),
new CvsMessagePattern("Usage: cvs* server*"),
new CvsMessagePattern("cvs*: invalid option*"),
new CvsMessagePattern(new String[]{"cvs checkout: could not check out ", "*"}, 2),
new CvsMessagePattern("cvs* update: could not merge revision * of *: No such file or directory"),
new CvsMessagePattern(new String[]{"cvs* update: could not patch ", "*", "; will refetch"}, 2),
new CvsMessagePattern("dying gasps from * unexpected"),
new CvsMessagePattern("end of file from server (consult above messages if any)"),
new CvsMessagePattern("\\*PANIC\\* administration files missing"),
new CvsMessagePattern(new String[]{"cvs*: Up-to-date check failed for `", "*", "'"}, 2),
new CvsMessagePattern("cvs*: cannot add file on non-branch tag *"),
new CvsMessagePattern("Cannot access *"),
new CvsMessagePattern("error Permission denied"),
new CvsMessagePattern(new String[]{"cvs*: ", "*", " already exists, with version number *"}, 2),
new CvsMessagePattern(new String[]{"cvs*: cannot commit with sticky date for file `", "*", "'"}, 2),
new CvsMessagePattern(new String[]{"cvs*: nothing known about `", "*", "'"}, 2),
new CvsMessagePattern("cvs*: sticky tag `*' for file `*' is not a branch"),
new CvsMessagePattern("cvs*: ERROR: cannot mkdir * -- not added: No such file or directory"),
new CvsMessagePattern(new String[]{"cvs: nothing known about ", "*"}, 2),
new CvsMessagePattern("Root * must be an absolute pathname"),
new CvsMessagePattern("protocol error: *"),
new CvsMessagePattern("cvs* tag: nothing known about *"),
new CvsMessagePattern("cvs* tag: cannot*"),
new CvsMessagePattern("cvs* tag:* failed*"),
new CvsMessagePattern("cvs* tag: Not removing branch tag `*' from `*,v'."),
new CvsMessagePattern("cvs tag: *: Not moving branch tag `*' from * to *."),
new CvsMessagePattern(new String[]{"cvs*: failed to create lock directory for `", "*", "' (*/#cvs.lock): No such file or directory"}, 2)
};
private static final CvsMessagePattern[] WARNINGS_PATTERNS = new CvsMessagePattern[]{
new CvsMessagePattern("cvs server: cannot open *: Permission denied"),
new CvsMessagePattern("cvs server: cannot make path to *: Permission denied"),
new CvsMessagePattern("cvs server: cannot find module `*' - ignored"),
new CvsMessagePattern("W * : * already exists on version * : NOT MOVING tag to version *"),
new CvsMessagePattern("W * : * already exists on branch * : NOT MOVING tag to branch *"),
new CvsMessagePattern(new String[]{"cvs server: ", "*", " added independently by second party"}, 2),
new CvsMessagePattern("cvs server: failed to create lock directory for `*' (*#cvs.lock): No such file or directory"),
new CvsMessagePattern("cvs server: failed to obtain dir lock in repository `*'"),
new CvsMessagePattern("cvs*: warning: *")
};
private static final Pattern[] FILE_MESSAGE_PATTERNS = new Pattern[]{PatternUtil.fromMask("cvs*: Updating*"),
PatternUtil.fromMask("Directory * added to the repository"), PatternUtil.fromMask("cvs*: scheduling file `*' for addition"),
PatternUtil.fromMask("cvs *: [*] waiting for *'s lock in *"), PatternUtil.fromMask("RCS file: *,v"),
PatternUtil.fromMask("cvs*: Tagging*"), PatternUtil.fromMask("cvs add: scheduling file `*' for addition"),
PatternUtil.fromMask("cvs rlog: Logging*")
};
private static final Pattern[] MESSAGE_PATTERNS = new Pattern[]{PatternUtil.fromMask("cvs *: [*] waiting for *'s lock in *")};
private final CvsMessagesListener myListener;
private final ICvsFileSystem myCvsFileSystem;
private final UpdatedFilesManager myUpdatedFilesManager;
private final String myCvsRoot;
private final Map<File, Object> myFileToInfoMap = new HashMap<File, Object>();
private final Collection<String> myPreviousErrorMessages = new ArrayList<String>();
@NonNls private static final String CORRECT_ABOVE_ERRORS_FIRST_PREFIX = "correct above errors first";
enum MessageType { MESSAGE, FILE_MESSAGE, WARNING, ERROR }
private MessageType lastMessage = null;
public CvsMessagesTranslator(CvsMessagesListener listener,
ICvsFileSystem cvsFileSystem,
UpdatedFilesManager mergedFilesCollector,
String cvsroot) {
myListener = listener;
myCvsFileSystem = cvsFileSystem;
myUpdatedFilesManager = mergedFilesCollector;
myCvsRoot = cvsroot;
}
public void fileInfoGenerated(Object info) {
if (info instanceof UpdateFileInfo) {
final UpdateFileInfo updateFileInfo = (UpdateFileInfo)info;
final File file = updateFileInfo.getFile();
if (!myUpdatedFilesManager.fileIsNotUpdated(file) && !myFileToInfoMap.containsKey(file)) {
myFileToInfoMap.put(file, updateFileInfo);
}
}
else if (info instanceof UpdatedFileInfo) {
final UpdatedFileInfo updatedFileInfo = (UpdatedFileInfo)info;
final File file = updatedFileInfo.getFile();
if (!myUpdatedFilesManager.fileIsNotUpdated(file)) {
myFileToInfoMap.put(file, updatedFileInfo);
}
}
}
public void gotEntry(FileObject fileObject, Entry entry) {}
public void messageSent(String message, final byte[] byteMessage, boolean error, boolean tagged) {
myListener.addMessage(new MessageEvent(message, error, tagged));
if (message.isEmpty()) {
return;
}
if (isFileMessage(message)) {
lastMessage = MessageType.FILE_MESSAGE;
myListener.addFileMessage(message, myCvsFileSystem);
return;
}
if (isMessage(message)) {
lastMessage = MessageType.MESSAGE;
myListener.addMessage(message);
return;
}
final CvsMessagePattern errorMessagePattern = getErrorMessagePattern(message, ERRORS_PATTERNS);
if (errorMessagePattern != null) {
if (message.contains(CORRECT_ABOVE_ERRORS_FIRST_PREFIX)) {
for (String s : myPreviousErrorMessages) {
myListener.addError(s, null, myCvsFileSystem, myCvsRoot, false);
}
myPreviousErrorMessages.clear();
return;
}
final String relativeFileName = errorMessagePattern.getRelativeFileName(message);
lastMessage = MessageType.ERROR;
myListener.addError(message, relativeFileName, myCvsFileSystem, myCvsRoot, false);
return;
}
final CvsMessagePattern warningMessagePattern = getErrorMessagePattern(message, WARNINGS_PATTERNS);
if (warningMessagePattern != null) {
lastMessage = MessageType.WARNING;
myListener.addError(message,warningMessagePattern.getRelativeFileName(message), myCvsFileSystem, myCvsRoot, true);
return;
}
if (message.trim().isEmpty()) return;
if (lastMessage == MessageType.ERROR) {
myListener.addError(message, null, myCvsFileSystem, myCvsRoot, false);
} else if (lastMessage == MessageType.WARNING) {
myListener.addError(message, null, myCvsFileSystem, myCvsRoot, true);
} else if (error) {
myPreviousErrorMessages.add(message);
}
}
private static boolean isFileMessage(String message) {
for (Pattern pattern : FILE_MESSAGE_PATTERNS) {
if (pattern.matcher(message).matches()) return true;
}
return false;
}
private static boolean isMessage(String message) {
for (Pattern pattern : MESSAGE_PATTERNS) {
if (pattern.matcher(message).matches()) return true;
}
return false;
}
@Nullable
private static CvsMessagePattern getErrorMessagePattern(String message, CvsMessagePattern[] patterns) {
for (CvsMessagePattern pattern : patterns) {
if (pattern.matches(message)) {
return pattern;
}
}
return null;
}
public void registerTo(EventManager eventManager) {
eventManager.addFileInfoListener(this);
eventManager.addMessageListener(this);
}
public void operationCompleted() {
if (!CvsEntriesManager.getInstance().isActive()) {
return;
}
for (File file : myFileToInfoMap.keySet()) {
addFileMessage(myFileToInfoMap.get(file), file);
}
}
private void addFileMessage(Object info, File file) {
if (info instanceof UpdateFileInfo) {
addUpdateFileInfo(file, (UpdateFileInfo)info);
}
else if (info instanceof UpdatedFileInfo) {
addUpdatedFileInfo(file, (UpdatedFileInfo)info);
}
}
private void addUpdatedFileInfo(File file, UpdatedFileInfo updatedFileInfo) {
if (!myUpdatedFilesManager.fileIsNotUpdated(file)) {
myListener.addFileMessage(new FileMessage(updatedFileInfo, myUpdatedFilesManager));
}
}
private void addUpdateFileInfo(File file, UpdateFileInfo updateFileInfo) {
if (!myUpdatedFilesManager.fileIsNotUpdated(file)) {
myListener.addFileMessage(new FileMessage(updateFileInfo, myUpdatedFilesManager, myUpdatedFilesManager));
}
}
public void binaryMessageSent(final byte[] bytes) {}
}