/* * (c) Copyright 2010-2011 AgileBirds * * This file is part of OpenFlexo. * * OpenFlexo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * OpenFlexo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>. * */ package org.netbeans.lib.cvsclient.response; import java.io.File; import java.io.IOException; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import org.netbeans.lib.cvsclient.admin.Entry; import org.netbeans.lib.cvsclient.event.FileUpdatedEvent; import org.netbeans.lib.cvsclient.file.FileHandler; import org.netbeans.lib.cvsclient.util.LoggedDataInputStream; /** * Sends a diff of a particular file, indicating that the file currently checked-out needs to be updated by the patch sent with this * response. * * @author Milos Kleint */ class RcsDiffResponse implements Response { private static final boolean DEBUG = false; /** * The local path of the new file. */ private String localPath; /** * The full repository path of the file. */ private String repositoryPath; /** * The entry line. */ private String entryLine; /** * The file mode. */ private String mode; /** * fullpath to the file being processed. */ protected String localFile; /** * The date Formatter used to parse and format dates. Format is: "EEE MMM dd HH:mm:ss yyyy" */ private DateFormat dateFormatter; /** * Process the data for the response. * * @param r * the buffered reader allowing the client to read the server's response. Note that the actual response name has already been * read and the reader is positioned just before the first argument, if any. * @param services * various services that are useful to response handlers * @throws ResponseException * if something goes wrong handling this response */ @Override public void process(LoggedDataInputStream dis, ResponseServices services) throws ResponseException { try { localPath = dis.readLine(); repositoryPath = dis.readLine(); entryLine = dis.readLine(); mode = dis.readLine(); String nextLine = dis.readLine(); boolean useGzip = nextLine.charAt(0) == 'z'; int length = Integer.parseInt(useGzip ? nextLine.substring(1) : nextLine); if (DEBUG) { System.err.println("Got update response."); // NOI18N System.err.println("LocalPath is : " + localPath); // NOI18N System.err.println("Repository path is : " + repositoryPath); // NOI18N System.err.println("Entries line is : " + entryLine); // NOI18N System.err.println("Mode is : " + mode); // NOI18N System.err.println("Next line (length) is : " + nextLine); // NOI18N System.err.println("File length is : " + length); // NOI18N } // now read in the file final String filePath = services.convertPathname(localPath, repositoryPath); final File newFile = new File(filePath); if (services.getGlobalOptions().isExcluded(newFile)) { while (length > 0) { length -= dis.skip(length); } return; } localFile = newFile.getAbsolutePath(); final Entry entry = new Entry(entryLine); FileHandler fileHandler = useGzip ? services.getGzipFileHandler() : services.getUncompressedFileHandler(); // FileHandler fileHandler = useGzip ? getGzippedFileHandler() // : getUncompressedFileHandler(); fileHandler.setNextFileDate(services.getNextFileDate()); // check if the file is binary if (entry.isBinary()) { // should actually not happen. it's possible to send pathces for text files only.. // TODO add BugLog print here } else { fileHandler.writeRcsDiffFile(filePath, mode, dis, length); } // we set the date the file was last modified in the Entry line // so that we can easily determine whether the file has been // untouched // for files with conflicts skip the setting of the conflict field. // NOT SURE THIS IS NESSESARY HERE.. String conflictString = null; if (entry.getConflict() != null && entry.getConflict().charAt(0) == Entry.HAD_CONFLICTS) { if (entry.getConflict().charAt(1) == Entry.TIMESTAMP_MATCHES_FILE) { final Date d = new Date(newFile.lastModified()); conflictString = getEntryConflict(d, true); } else { conflictString = entry.getConflict().substring(1); } } else { final Date d = new Date(newFile.lastModified()); conflictString = getEntryConflict(d, false); } entry.setConflict(conflictString); // update the admin files (i.e. within the CVS directory) services.updateAdminData(localPath, repositoryPath, entry); FileUpdatedEvent e = new FileUpdatedEvent(this, filePath); services.getEventManager().fireCVSEvent(e); // System.err.println("Finished writing file"); } catch (IOException e) { throw new ResponseException(e); } } /** * Returns the Conflict field for the file's entry. Can be overriden by subclasses. (For example the MergedResponse that sets the * "result of merge" there.) * * @param date * the date to put in * @param hadConflicts * if there were conflicts (e.g after merge) * @return the conflict field */ protected String getEntryConflict(Date date, boolean hadConflicts) { return getDateFormatter().format(date); } /** * Is this a terminal response, i.e. should reading of responses stop after this response. This is true for responses such as OK or an * error response */ @Override public boolean isTerminalResponse() { return false; } /** * Returns the DateFormatter instance that parses and formats date Strings. The exact format matches the one in * Entry.getLastModifiedDateFormatter() method. * */ protected DateFormat getDateFormatter() { if (dateFormatter == null) { dateFormatter = new SimpleDateFormat(Entry.getLastModifiedDateFormatter().toPattern(), Locale.US); dateFormatter.setTimeZone(Entry.getTimeZone()); } return dateFormatter; } }