| package org.netbeans.lib.cvsclient.response; |
| |
| import org.jetbrains.annotations.NonNls; |
| import org.netbeans.lib.cvsclient.IClientEnvironment; |
| import org.netbeans.lib.cvsclient.IConnectionStreams; |
| import org.netbeans.lib.cvsclient.io.StreamUtilities; |
| import org.netbeans.lib.cvsclient.util.BugLog; |
| |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.util.Date; |
| |
| /** |
| * @author Thomas Singer |
| */ |
| public final class ResponseParser { |
| |
| // Fields ================================================================= |
| |
| private final IResponseHandler responseProcessor; |
| private final StreamUtilities myStreamUtilities; |
| @NonNls public static final String PREFIX_TO_REMOVE = "-f "; |
| |
| // Setup ================================================================== |
| |
| public ResponseParser(IResponseHandler responseProcessor, String charset) { |
| BugLog.getInstance().assertNotNull(responseProcessor); |
| BugLog.getInstance().assertNotNull(charset); |
| |
| this.responseProcessor = responseProcessor; |
| myStreamUtilities = new StreamUtilities(charset); |
| } |
| |
| // Implemented ============================================================ |
| |
| @SuppressWarnings({"HardCodedStringLiteral"}) |
| public Boolean processResponse(String responseName, |
| IConnectionStreams connectionStreams, |
| IResponseServices responseServices, |
| IClientEnvironment clientEnvironment) throws IOException { |
| InputStream loggedInputStream = connectionStreams.getLoggedInputStream(); |
| if (responseName.equalsIgnoreCase("E")) { |
| final byte[] line = StreamUtilities.readLineBytes(loggedInputStream); |
| responseProcessor.processErrorMessageResponse(prepareMessageAccordingToScr39148(line), responseServices); |
| return null; |
| } |
| else if (responseName.equalsIgnoreCase("M")) { |
| final byte[] line = StreamUtilities.readLineBytes(loggedInputStream); |
| responseProcessor.processMessageResponse(prepareMessageAccordingToScr39148(line), responseServices); |
| return null; |
| } |
| |
| else if (responseName.equalsIgnoreCase("MBinary")) { |
| final String fileLengthString = myStreamUtilities.readLine(loggedInputStream); |
| try { |
| int fileLength = Integer.parseInt(fileLengthString); |
| responseProcessor.processBinaryMessageResponse(fileLength, readFromStream(connectionStreams, fileLength), responseServices); |
| } |
| catch (NumberFormatException e) { |
| //ignore |
| } |
| return null; |
| } |
| |
| else if (responseName.equalsIgnoreCase("MT")) { |
| final byte[] text = StreamUtilities.readLineBytes(loggedInputStream); |
| responseProcessor.processMessageTaggedResponse(text, responseServices); |
| return null; |
| } |
| else if (responseName.equalsIgnoreCase("Updated")) { |
| final String relativeLocalDirectory = myStreamUtilities.readLine(loggedInputStream); |
| final String repositoryFilePath = myStreamUtilities.readLine(loggedInputStream); |
| final String entryLine = myStreamUtilities.readLine(loggedInputStream); |
| final String mode = myStreamUtilities.readLine(loggedInputStream); |
| final String fileLengthString = myStreamUtilities.readLine(loggedInputStream); |
| |
| final int fileLength; |
| try { |
| fileLength = Integer.parseInt(fileLengthString); |
| responseProcessor.processUpdatedResponse(relativeLocalDirectory, repositoryFilePath, entryLine, mode, fileLength, clientEnvironment, |
| responseServices, connectionStreams); |
| } |
| catch (NumberFormatException ex) { |
| // ignore |
| } |
| return null; |
| } |
| else if (responseName.equalsIgnoreCase("Merged")) { |
| final String relativeLocalDirectory = myStreamUtilities.readLine(loggedInputStream); |
| final String repositoryFilePath = myStreamUtilities.readLine(loggedInputStream); |
| final String entryLine = myStreamUtilities.readLine(loggedInputStream); |
| final String mode = myStreamUtilities.readLine(loggedInputStream); |
| final String fileLengthString = myStreamUtilities.readLine(loggedInputStream); |
| |
| final int fileLength; |
| try { |
| fileLength = Integer.parseInt(fileLengthString); |
| responseProcessor.processMergedResponse(relativeLocalDirectory, repositoryFilePath, entryLine, mode, fileLength, clientEnvironment, |
| responseServices, connectionStreams); |
| } |
| catch (NumberFormatException ex) { |
| // ignore |
| } |
| return null; |
| } |
| else if (responseName.equalsIgnoreCase("Checked-in")) { |
| final String relativeLocalDirectory = myStreamUtilities.readLine(loggedInputStream); |
| final String repositoryFilePath = myStreamUtilities.readLine(loggedInputStream); |
| final String entryLine = myStreamUtilities.readLine(loggedInputStream); |
| responseProcessor |
| .processCheckedInResponse(relativeLocalDirectory, repositoryFilePath, entryLine, responseServices, clientEnvironment); |
| return null; |
| } |
| else if (responseName.equalsIgnoreCase("New-entry")) { |
| final String relativeLocalDirectory = myStreamUtilities.readLine(loggedInputStream); |
| final String repositoryFilePath = myStreamUtilities.readLine(loggedInputStream); |
| final String entryLine = myStreamUtilities.readLine(loggedInputStream); |
| responseProcessor.processNewEntryResponse(relativeLocalDirectory, repositoryFilePath, responseServices, entryLine, clientEnvironment); |
| return null; |
| } |
| else if (responseName.equalsIgnoreCase("Set-static-directory")) { |
| final String relativeLocalDirectory = myStreamUtilities.readLine(loggedInputStream); |
| final String repositoryFilePath = myStreamUtilities.readLine(loggedInputStream); |
| responseProcessor.processSetStaticDirectoryResponse(relativeLocalDirectory, repositoryFilePath, responseServices, clientEnvironment); |
| return null; |
| } |
| else if (responseName.equalsIgnoreCase("Clear-static-directory")) { |
| final String relativeLocalDirectory = myStreamUtilities.readLine(loggedInputStream); |
| final String repositoryDirectoryPath = myStreamUtilities.readLine(loggedInputStream); |
| responseProcessor |
| .processClearStaticDirectoryResponse(relativeLocalDirectory, repositoryDirectoryPath, responseServices, clientEnvironment); |
| return null; |
| } |
| else if (responseName.equalsIgnoreCase("Set-sticky")) { |
| final String relativeLocalDirectory = myStreamUtilities.readLine(loggedInputStream); |
| final String repositoryFilePath = myStreamUtilities.readLine(loggedInputStream); |
| final String tag = myStreamUtilities.readLine(loggedInputStream); |
| responseProcessor.processSetStickyResponse(relativeLocalDirectory, repositoryFilePath, tag, clientEnvironment); |
| return null; |
| } |
| else if (responseName.equalsIgnoreCase("Clear-sticky")) { |
| final String relativeLocalDirectory = myStreamUtilities.readLine(loggedInputStream); |
| final String repositoryFilePath = myStreamUtilities.readLine(loggedInputStream); |
| responseProcessor.processClearStickyResponse(relativeLocalDirectory, repositoryFilePath, clientEnvironment); |
| return null; |
| } |
| else if (responseName.equalsIgnoreCase("Notified")) { |
| final String relativeLocalDirectory = myStreamUtilities.readLine(loggedInputStream); |
| final String repositoryFilePath = myStreamUtilities.readLine(loggedInputStream); |
| responseProcessor.processNotifiedResponse(relativeLocalDirectory, repositoryFilePath, clientEnvironment); |
| return null; |
| } |
| else if (responseName.equalsIgnoreCase("Removed")) { |
| final String relativeLocalDirectory = myStreamUtilities.readLine(loggedInputStream); |
| final String repositoryFileName = myStreamUtilities.readLine(loggedInputStream); |
| responseProcessor.processRemovedResponse(relativeLocalDirectory, repositoryFileName, responseServices, clientEnvironment); |
| return null; |
| } |
| else if (responseName.equalsIgnoreCase("Remove-entry")) { |
| final String relativeLocalDirectory = myStreamUtilities.readLine(loggedInputStream); |
| final String repositoryFilePath = myStreamUtilities.readLine(loggedInputStream); |
| responseProcessor.processRemoveEntryResponse(relativeLocalDirectory, repositoryFilePath, responseServices, clientEnvironment); |
| return null; |
| } |
| else if (responseName.equalsIgnoreCase("Copy-file")) { |
| final String relativeLocalDirectory = myStreamUtilities.readLine(loggedInputStream); |
| final String repositoryFilePath = myStreamUtilities.readLine(loggedInputStream); |
| final String newName = myStreamUtilities.readLine(loggedInputStream); |
| responseProcessor.processCopyFileResponse(relativeLocalDirectory, repositoryFilePath, newName, clientEnvironment); |
| return null; |
| } |
| else if (responseName.equalsIgnoreCase("Mod-time")) { |
| final String dateString = myStreamUtilities.readLine(loggedInputStream); |
| try { |
| final Date modifiedDate = ResponseUtils.parseDateString(dateString); |
| responseProcessor.processModTimeResponse(modifiedDate, responseServices); |
| } |
| catch (Exception ex) { |
| BugLog.getInstance().showException(ex); |
| } |
| return null; |
| } |
| else if (responseName.equalsIgnoreCase("Mode")) { |
| final String mode = myStreamUtilities.readLine(loggedInputStream); |
| responseProcessor.processModeResponse(mode, responseServices); |
| return null; |
| } |
| else if (responseName.equalsIgnoreCase("Template")) { |
| final String relativeLocalDirectory = myStreamUtilities.readLine(loggedInputStream); |
| final String repositoryFilePath = myStreamUtilities.readLine(loggedInputStream); |
| final String lengthString = myStreamUtilities.readLine(loggedInputStream); |
| final int length; |
| try { |
| // the following line can be sent by the server, when the template file is not available on the server |
| // "E cvs server: Couldn't open rcsinfo template file /cvsroot/geotools/CVSROOT/gtTemplate: No such file or directory" |
| length = Integer.parseInt(lengthString); |
| responseProcessor.processTemplateResponse(relativeLocalDirectory, repositoryFilePath, length, clientEnvironment, connectionStreams); |
| } |
| catch (NumberFormatException ex) { |
| // ignore |
| } |
| return null; |
| } |
| else if (responseName.equalsIgnoreCase("Module-expansion")) { |
| final String localPath = myStreamUtilities.readLine(loggedInputStream); |
| responseProcessor.processModuleExpansionResponse(localPath, responseServices); |
| return null; |
| } |
| else if (responseName.equalsIgnoreCase("ok")) { |
| responseProcessor.processOkResponse(responseServices); |
| return Boolean.TRUE; |
| } |
| else if (responseName.equalsIgnoreCase("error")) { |
| final byte[] message = StreamUtilities.readLineBytes(loggedInputStream); |
| responseProcessor.processErrorResponse(message, responseServices); |
| return Boolean.FALSE; |
| } |
| else if (responseName.equals("EntriesExtra")) { |
| // ignore for now |
| StreamUtilities.readLineBytes(loggedInputStream); |
| return null; |
| } |
| else if (responseName.equalsIgnoreCase("Valid-requests")) { |
| final String validRequests = myStreamUtilities.readLine(loggedInputStream); |
| responseProcessor.processValidRequestsResponse(validRequests, responseServices); |
| return null; |
| } |
| else { |
| throw new IOException("Unhandled response: " + responseName + "."); |
| } |
| } |
| |
| private static byte[] readFromStream(final IConnectionStreams connectionStreams, final int fileLength) throws IOException { |
| final byte[] buffer = new byte[fileLength]; |
| int read = 0; |
| while (read < fileLength) { |
| read += connectionStreams.getInputStream().read(buffer, read, fileLength - read); |
| } |
| return buffer; |
| } |
| |
| private static byte[] prepareMessageAccordingToScr39148(byte[] line) { |
| if (line.length < 3) return line; |
| if (startsWith(PREFIX_TO_REMOVE, line)) { |
| final byte[] result = new byte[line.length - 3]; |
| System.arraycopy(line, 3, result, 0, result.length); |
| return result; |
| } |
| return line; |
| } |
| |
| private static boolean startsWith(final String s, final byte[] line) { |
| for (int i = 0; i < s.length(); i++) { |
| if (line[i] == s.charAt(i)) continue; |
| return false; |
| } |
| return true; |
| } |
| |
| } |