1 12 package org.eclipse.team.internal.ccvs.core.client; 13 14 import java.io.*; 15 import java.util.ArrayList ; 16 import java.util.Arrays ; 17 import java.util.Collection ; 18 import java.util.Date ; 19 import java.util.Iterator ; 20 import java.util.List ; 21 import java.util.Map ; 22 23 import java.util.zip.GZIPInputStream ; 24 import java.util.zip.GZIPOutputStream ; 25 26 import org.eclipse.core.resources.IResource; 27 import org.eclipse.core.runtime.*; 28 import org.eclipse.osgi.util.NLS; 29 import org.eclipse.team.core.RepositoryProvider; 30 import org.eclipse.team.internal.ccvs.core.*; 31 import org.eclipse.team.internal.ccvs.core.client.Command.GlobalOption; 32 import org.eclipse.team.internal.ccvs.core.client.Command.QuietOption; 33 import org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation; 34 import org.eclipse.team.internal.ccvs.core.connection.Connection; 35 import org.eclipse.team.internal.ccvs.core.syncinfo.NotifyInfo; 36 import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo; 37 import org.eclipse.team.internal.ccvs.core.util.Util; 38 import org.eclipse.team.internal.core.streams.*; 39 40 60 public class Session { 61 public static final String CURRENT_LOCAL_FOLDER = "."; public static final String CURRENT_REMOTE_FOLDER = ""; public static final String SERVER_SEPARATOR = "/"; 65 private static final int TRANSFER_BUFFER_SIZE = 8192; 67 private static final int TRANSFER_PROGRESS_INCREMENT = 32768; 70 71 public static final boolean IS_CRLF_PLATFORM = Arrays.equals( 72 System.getProperty("line.separator").getBytes(), new byte[] { '\r', '\n' }); 74 private CVSRepositoryLocation location; 75 private ICVSFolder localRoot; 76 private boolean outputToConsole; 77 private Connection connection = null; 78 private String validRequests = null; 79 private Date modTime = null; 80 private boolean noLocalChanges = false; 81 private boolean createBackups = true; 82 private int compressionLevel = 0; 83 private List expansions; 84 private Collection textTransferOverrideSet = null; 85 86 private boolean ignoringLocalChanges = false; 88 89 private String sendFileTitleMessage; 91 private Map responseHandlers; 92 93 private List errors = new ArrayList (); 95 96 private Command currentCommand; 97 98 105 public Session(ICVSRepositoryLocation location, ICVSFolder localRoot) { 106 this(location, localRoot, true); 107 } 108 109 116 public Session(ICVSRepositoryLocation location, ICVSFolder localRoot, boolean outputToConsole) { 117 this.location = (CVSRepositoryLocation) location; 118 this.localRoot = localRoot; 119 this.outputToConsole = outputToConsole; 120 } 121 122 126 protected void addModuleExpansion(String expansion) { 127 expansions.add(expansion); 128 } 129 130 134 protected void resetModuleExpansion() { 135 if (expansions == null) 136 expansions = new ArrayList (); 137 else 138 expansions.clear(); 139 } 140 141 148 public void open(IProgressMonitor monitor) throws CVSException { 149 open(monitor, true ); 150 } 151 152 public void open(IProgressMonitor monitor, boolean writeAccess) throws CVSException { 153 if (connection != null) throw new IllegalStateException (); 154 monitor = Policy.monitorFor(monitor); 155 monitor.beginTask(null, 100); 156 boolean opened = false; 157 158 try { 159 connection = getLocationForConnection(writeAccess).openConnection(Policy.subMonitorFor(monitor, 50)); 160 161 boolean useMT = ! (location.getServerPlatform() == CVSRepositoryLocation.CVS_SERVER); 164 if ( ! useMT) { 165 removeResponseHandler("MT"); } 167 168 connection.writeLine("Valid-responses " + makeResponseList()); connection.flush(); 172 173 IStatus status = Request.VALID_REQUESTS.execute(this, Policy.subMonitorFor(monitor, 40)); 175 if (!status.isOK()) { 176 throw new CVSException(status); 177 } 178 179 connection.writeLine("Root " + getRepositoryRoot()); 182 compressionLevel = CVSProviderPlugin.getPlugin().getCompressionLevel(); 184 if (compressionLevel != 0 && isValidRequest("gzip-file-contents")) { connection.writeLine("gzip-file-contents " + Integer.toString(compressionLevel)); } else { 193 compressionLevel = 0; 194 } 195 196 if (CVSProviderPlugin.getPlugin().isDetermineVersionEnabled() && location.getServerPlatform() == CVSRepositoryLocation.UNDETERMINED_PLATFORM) { 198 Command.VERSION.execute(this, location, Policy.subMonitorFor(monitor, 10)); 199 } 200 opened = true; 201 } finally { 202 if (connection != null && ! opened) { 203 close(); 204 } 205 monitor.done(); 206 } 207 } 208 209 212 private CVSRepositoryLocation getLocationForConnection(boolean writeAccess) { 213 return location; 214 } 215 216 221 public void close() { 222 if (connection != null) { 223 connection.close(); 224 connection = null; 225 validRequests = null; 226 } 227 } 228 229 235 public boolean isValidRequest(String request) { 236 return (validRequests == null) || 237 (validRequests.indexOf(" " + request + " ") != -1); } 239 240 public boolean isCVSNT() { 241 if (location.getServerPlatform() == CVSRepositoryLocation.UNDETERMINED_PLATFORM) { 242 return location.getRootDirectory().indexOf(':') == 1; 243 } else { 244 return location.getServerPlatform() == CVSRepositoryLocation.CVSNT_SERVER; 245 } 246 } 247 248 257 public ICVSFolder getLocalRoot() { 258 return localRoot; 259 } 260 261 267 public String [] getModuleExpansions() { 268 if (expansions == null) return new String [0]; 269 return (String []) expansions.toArray(new String [expansions.size()]); 270 } 271 272 281 public String getRepositoryRoot() { 282 return location.getRootDirectory(); 283 } 284 285 290 public ICVSRepositoryLocation getCVSRepositoryLocation() { 291 return location; 292 } 293 294 299 public String readLine() throws CVSException { 300 return connection.readLine(); 301 } 302 303 308 public void writeLine(String line) throws CVSException { 309 connection.writeLine(line); 310 } 311 312 323 public void sendArgument(String arg) throws CVSException { 324 connection.write("Argument "); int oldPos = 0; 326 for (;;) { 327 int pos = arg.indexOf('\n', oldPos); 328 if (pos == -1) break; 329 connection.writeLine(stripTrainingCR(arg.substring(oldPos, pos))); 330 connection.write("Argumentx "); oldPos = pos + 1; 332 } 333 connection.writeLine(stripTrainingCR(arg.substring(oldPos))); 334 } 335 336 339 private String stripTrainingCR(String string) { 340 if (string.endsWith("\r")) { return string.substring(0, string.length() - 1); 342 } 343 return string; 344 } 345 346 351 public void sendRequest(String requestId) throws CVSException { 352 connection.writeLine(requestId); 353 connection.flush(); 354 } 355 356 378 public void sendIsModified(ICVSFile file, boolean isBinary, IProgressMonitor monitor) 379 throws CVSException { 380 if (isValidRequest("Is-modified")) { connection.writeLine("Is-modified " + file.getName()); } else { 383 sendModified(file, isBinary, monitor); 384 } 385 } 386 387 395 public void sendStaticDirectory() throws CVSException { 396 connection.writeLine("Static-directory"); } 398 399 414 public void sendConstructedDirectory(String localDir) throws CVSException { 415 String path = Util.appendPath(getRepositoryRoot(), localDir); 416 sendDirectory(localDir, path); 417 } 418 419 430 public void sendDirectory(String localDir, String remoteDir) throws CVSException { 431 if (localDir.length() == 0) localDir = CURRENT_LOCAL_FOLDER; 432 connection.writeLine("Directory " + localDir); connection.writeLine(remoteDir); 434 } 435 436 439 public void sendLocalRootDirectory() throws CVSException { 440 sendDirectory(CURRENT_LOCAL_FOLDER, localRoot.getRemoteLocation(localRoot)); 441 } 442 443 450 public void sendConstructedRootDirectory() throws CVSException { 451 sendConstructedDirectory(""); } 453 454 467 public void sendEntry(byte[] syncBytes, String serverTimestamp) throws CVSException { 468 connection.write("Entry "); if (serverTimestamp == null) { 470 serverTimestamp = ""; } 472 int start = Util.getOffsetOfDelimeter(syncBytes, (byte)'/', 0, 3); 473 if (start == -1) { 474 connection.writeLine(new String (syncBytes)); 477 return; 478 } 479 int end = Util.getOffsetOfDelimeter(syncBytes, (byte)'/', start + 1, 1); 480 if (end == -1) { 481 connection.writeLine(new String (syncBytes)); 484 return; 485 } 486 connection.write(new String (syncBytes, 0, start + 1)); 487 connection.write(serverTimestamp); 488 connection.writeLine(new String (syncBytes, end, syncBytes.length - end)); 489 } 490 491 500 public void sendGlobalOption(String option) throws CVSException { 501 connection.writeLine("Global_option " + option); } 503 504 516 public void sendUnchanged(ICVSFile file) throws CVSException { 517 connection.writeLine("Unchanged " + file.getName()); } 519 520 523 public void sendNotify(ICVSFolder parent, NotifyInfo info) 524 throws CVSException { 525 526 String filename = info.getName(); 527 connection.writeLine("Notify " + filename); connection.writeLine(info.getServerLine(parent)); 529 } 530 531 545 public void sendQuestionable(ICVSResource resource) throws CVSException { 546 connection.writeLine("Questionable " + resource.getName()); } 548 549 558 public void sendSticky(String tag) throws CVSException { 559 connection.writeLine("Sticky " + tag); } 561 562 583 public void sendModified(ICVSFile file, boolean isBinary, IProgressMonitor monitor) 584 throws CVSException { 585 sendModified(file, isBinary, true, monitor); 586 } 587 588 public void sendModified(ICVSFile file, boolean isBinary, boolean sendBinary, IProgressMonitor monitor) 589 throws CVSException { 590 591 String filename = file.getName(); 592 connection.writeLine("Modified " + filename); if (file.isExecutable()) { 595 connection.writeLine(ResourceSyncInfo.getDefaultExecutablePermissions()); 596 } else { 597 connection.writeLine(ResourceSyncInfo.getDefaultPermissions()); 598 } 599 sendFile(file, isBinary, sendBinary, monitor); 600 } 601 602 615 public void sendFile(ICVSStorage file, boolean isBinary, boolean sendBinary, IProgressMonitor monitor) throws CVSException { 616 if (textTransferOverrideSet != null && 618 textTransferOverrideSet.contains(file)) isBinary = false; 619 620 final String title = NLS.bind(getSendFileTitleMessage(), (new Object []{ Util.toTruncatedPath(file, localRoot, 3) })); 622 monitor.subTask(NLS.bind(CVSMessages.Session_transferNoSize, new String [] { title })); 623 try { 624 InputStream in = null; 625 long length; 626 try { 627 if (isBinary && !sendBinary) { 628 byte[] bytes = "hello".getBytes(); sendUncompressedBytes(new ByteArrayInputStream(bytes), bytes.length); 630 return; 631 } 632 633 if (compressionLevel == 0) { 634 in = file.getContents(); 635 if (!isBinary && IS_CRLF_PLATFORM){ 636 byte[] buffer = new byte[TRANSFER_BUFFER_SIZE]; 638 in = new CRLFtoLFInputStream(in); 639 ByteCountOutputStream counter = new ByteCountOutputStream(); 640 try { 641 for (int count; (count = in.read(buffer)) != -1;) counter.write(buffer, 0, count); 642 } finally { 643 counter.close(); 644 } 645 in.close(); 646 length = counter.getSize(); 647 in = new CRLFtoLFInputStream(file.getContents()); 648 } else { 649 length = file.getSize(); 651 } 652 in = new ProgressMonitorInputStream(in, length, TRANSFER_PROGRESS_INCREMENT, monitor) { 653 protected void updateMonitor(long bytesRead, long bytesTotal, IProgressMonitor monitor) { 654 if (bytesRead == 0) return; 655 Assert.isTrue(bytesRead <= bytesTotal); 656 monitor.subTask(NLS.bind(CVSMessages.Session_transfer, (new Object [] { title, Long.toString(bytesRead >> 10), Long.toString(bytesTotal >> 10) }))); 657 } 658 }; 659 sendUncompressedBytes(in, length); 660 } else { 661 monitor.subTask(NLS.bind(CVSMessages.Session_calculatingCompressedSize, new String [] { Util.toTruncatedPath(file, localRoot, 3) })); 662 in = file.getContents(); 663 byte[] buffer = new byte[TRANSFER_BUFFER_SIZE]; 664 ByteCountOutputStream counter = new ByteCountOutputStream(); 665 OutputStream zout = new GZIPOutputStream (counter); 666 if (!isBinary && IS_CRLF_PLATFORM) in = new CRLFtoLFInputStream(in); 667 try { 668 for (int count; (count = in.read(buffer)) != -1;) zout.write(buffer, 0, count); 669 } finally { 670 zout.close(); 671 } 672 in.close(); 673 in = file.getContents(); 674 in = new ProgressMonitorInputStream(in, file.getSize(), TRANSFER_PROGRESS_INCREMENT, monitor) { 675 protected void updateMonitor(long bytesRead, long bytesTotal, IProgressMonitor monitor) { 676 if (bytesRead == 0) return; 677 Assert.isTrue(bytesRead <= bytesTotal); 678 monitor.subTask(NLS.bind(CVSMessages.Session_transfer, (new Object [] { title, Long.toString(bytesRead >> 10), Long.toString(bytesTotal >> 10) }))); 679 } 680 }; 681 if (!isBinary && IS_CRLF_PLATFORM) in = new CRLFtoLFInputStream(in); 682 sendCompressedBytes(in, counter.getSize()); 683 } 684 } finally { 685 if (in != null) in.close(); 686 } 687 } catch (IOException e) { 688 throw CVSException.wrapException(e); 689 } 690 } 691 692 697 private void sendCompressedBytes(InputStream in, long length) throws IOException, CVSException { 698 String sizeLine = "z" + Long.toString(length); writeLine(sizeLine); 700 OutputStream out = connection.getOutputStream(); 701 GZIPOutputStream zo = new GZIPOutputStream (out); 702 byte[] buffer = new byte[TRANSFER_BUFFER_SIZE]; 703 for (int count; 704 (count = in.read(buffer)) != -1;) 705 zo.write(buffer, 0, count); 706 zo.finish(); 707 } 708 709 714 private void sendUncompressedBytes(InputStream in, long length) throws IOException, CVSException { 715 OutputStream out = connection.getOutputStream(); 716 String sizeLine = Long.toString(length); 717 writeLine(sizeLine); 718 byte[] buffer = new byte[TRANSFER_BUFFER_SIZE]; 719 for (int count; (count = in.read(buffer)) != -1;) out.write(buffer, 0, count); 720 } 721 722 723 724 725 740 public void receiveFile(ICVSStorage file, boolean isBinary, int responseType, IProgressMonitor monitor) 741 throws CVSException { 742 if (textTransferOverrideSet != null && 744 textTransferOverrideSet.contains(file)) isBinary = false; 745 746 final String title = NLS.bind(CVSMessages.Session_receiving, (new Object []{ Util.toTruncatedPath(file, localRoot, 3) })); 748 monitor.subTask(NLS.bind(CVSMessages.Session_transferNoSize, new String [] { title })); 749 long size; 751 boolean compressed = false; 752 String sizeLine = null; 753 try { 754 sizeLine = readLine(); 755 if (sizeLine.charAt(0) == 'z') { 756 compressed = true; 757 sizeLine = sizeLine.substring(1); 758 } 759 size = Long.parseLong(sizeLine, 10); 760 } catch (NumberFormatException e) { 761 if (sizeLine != null && sizeLine.startsWith("E")) { handleErrorLine(sizeLine.substring(1).trim(), org.eclipse.core.runtime.Status.OK_STATUS); 764 return; 765 } else { 766 IStatus status = new CVSStatus(IStatus.ERROR,CVSStatus.ERROR,CVSMessages.Session_badInt, e, localRoot); 767 throw new CVSException(status); 768 } 769 } 770 InputStream in = new SizeConstrainedInputStream(connection.getInputStream(), size, true ); 772 in = new ProgressMonitorInputStream(in, size, TRANSFER_PROGRESS_INCREMENT, monitor) { 774 protected void updateMonitor(long bytesRead, long bytesTotal, IProgressMonitor monitor) { 775 if (bytesRead == 0) return; 776 monitor.subTask(NLS.bind(CVSMessages.Session_transfer, (new Object [] { title, Long.toString(bytesRead >> 10), Long.toString(bytesTotal >> 10) }))); 777 } 778 }; 779 if (compressed) { 781 try { 782 in = new GZIPInputStream (in); 783 } catch (IOException e) { 784 throw CVSException.wrapException(e); 785 } 786 } 787 if (! isBinary) { 789 if (IS_CRLF_PLATFORM && CVSProviderPlugin.getPlugin().isUsePlatformLineend()) { 791 in = new CRLFtoLFInputStream(in); 793 in = new LFtoCRLFInputStream(in); 795 } else { 796 in = new CRLFDetectInputStream(in, file); 798 } 799 } 800 file.setContents(in, responseType, true, new NullProgressMonitor()); 802 } 803 804 808 void setModTime(Date modTime) { 809 this.modTime = modTime; 810 } 811 812 816 Date getModTime() { 817 return modTime; 818 } 819 820 824 void setNoLocalChanges(boolean noLocalChanges) { 825 this.noLocalChanges = noLocalChanges; 826 } 827 828 832 boolean isNoLocalChanges() { 833 return noLocalChanges; 834 } 835 836 840 void setValidRequests(String validRequests) { 841 this.validRequests = " " + validRequests + " "; } 843 844 public boolean isOutputToConsole() { 845 return outputToConsole; 846 } 847 848 852 void setCreateBackups(boolean createBackups) { 853 this.createBackups = createBackups; 854 } 855 856 859 boolean isCreateBackups() { 860 return createBackups; 861 } 862 863 867 String getSendFileTitleMessage() { 868 if (sendFileTitleMessage == null) 869 return CVSMessages.Session_sending; 870 return sendFileTitleMessage; 871 } 872 873 877 public void setSendFileTitleKey(String sendFileTitleMessage) { 878 this.sendFileTitleMessage = sendFileTitleMessage; 879 } 880 881 887 public void setTextTransferOverride(Collection textTransferOverrideSet) { 888 this.textTransferOverrideSet = textTransferOverrideSet; 889 } 890 891 900 protected GlobalOption[] filterGlobalOptions(GlobalOption[] globalOptions) { 901 if (! Command.DO_NOT_CHANGE.isElementOf(globalOptions)) { 902 QuietOption quietOption = CVSProviderPlugin.getPlugin().getQuietness(); 904 if (quietOption != null) { 905 globalOptions = quietOption.addToEnd(globalOptions); 906 } 907 if (isWatchEditEnabled()) { 909 if (!Command.MAKE_READ_ONLY.isElementOf(globalOptions)) { 910 globalOptions = Command.MAKE_READ_ONLY.addToEnd(globalOptions); 911 } 912 } 913 } 914 return globalOptions; 915 } 916 917 private boolean isWatchEditEnabled() { 918 if (CVSProviderPlugin.getPlugin().getPluginPreferences().getBoolean(CVSProviderPlugin.READ_ONLY)) { 920 return true; 921 } 922 try { 924 IResource resource = getLocalRoot().getIResource(); 925 if (resource != null && resource.getType() != IResource.ROOT) { 926 RepositoryProvider provider = RepositoryProvider.getProvider(resource.getProject(), CVSProviderPlugin.getTypeId()); 927 if (provider != null) { 928 return ((CVSTeamProvider) provider).isWatchEditEnabled(); 929 } 930 } 931 } catch (CVSException e) { 932 CVSProviderPlugin.log(e); 933 } 934 return false; 935 } 936 937 941 protected void setIgnoringLocalChanges(boolean b) { 942 ignoringLocalChanges = b; 943 } 944 948 protected boolean isIgnoringLocalChanges() { 949 return ignoringLocalChanges; 950 } 951 952 956 protected Map getReponseHandlers() { 957 if (responseHandlers == null) { 958 responseHandlers = Request.getReponseHandlerMap(); 959 } 960 return responseHandlers; 961 } 962 963 967 private String makeResponseList() { 968 StringBuffer result = new StringBuffer ("ok error M E"); Iterator elements = getReponseHandlers().keySet().iterator(); 970 while (elements.hasNext()) { 971 result.append(' '); 972 result.append((String ) elements.next()); 973 } 974 975 return result.toString(); 976 } 977 public void registerResponseHandler(ResponseHandler handler) { 978 getReponseHandlers().put(handler.getResponseID(), handler); 979 } 980 981 public void removeResponseHandler(String responseID) { 982 getReponseHandlers().remove(responseID); 983 } 984 985 public ResponseHandler getResponseHandler(String responseID) { 986 return (ResponseHandler)getReponseHandlers().get(responseID); 987 } 988 989 994 public void addError(IStatus status) { 995 if (!status.isOK()) 996 errors.add(status); 997 } 998 999 public boolean hasErrors() { 1000 return !errors.isEmpty(); 1001 } 1002 1003 public IStatus[] getErrors() { 1004 return (IStatus[]) errors.toArray(new IStatus[errors.size()]); 1005 } 1006 1007 public void clearErrors() { 1008 errors.clear(); 1009 } 1010 1011 public void setCurrentCommand(Command c) { 1012 currentCommand = c; 1013 } 1014 1015 public Command getCurrentCommand() { 1016 return currentCommand; 1017 } 1018 1019 1024 public void handleErrorLine(String line, IStatus status) { 1025 ConsoleListeners.getInstance().errorLineReceived(this, line, status); 1026 } 1027 1028 1034 public void handleResponseError(IStatus status) { 1035 addError(status); 1036 handleErrorLine(NLS.bind(CVSMessages.Session_0, new String [] { status.getMessage() }), status); 1037 } 1038} 1039 | Popular Tags |