Skip to main content
aboutsummaryrefslogblamecommitdiffstats
blob: 084b697af2ee98c1a6be7fe84750db9fd9f9bfa7 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
                                                                                


                                                                       
                                                           
                                            

                

                                                                                 

                                                   
                   
 

                                             

                                                                                   
                                                                         









                                                                               

                                                      




















                                                                                                           
         
                                                                              


                                                                               
         







                                                                         
                                                









                                                                                                     
                 
         




































                                                                                                       




                                                                                                                       
 
                                      



























                                                                                                        
                                                                                                                               


                                                             
                                                                           

                                                                                                                     

                                                                                                                                   
                                         
                                                       
                                 
                                        

                                                                                                                                                                      
                                 
                                                                                                               
                                                            
                                                        



                                                                                                     


                                                                             





                                                                                              
                                                   

                                                                          
                                                                                                     










                                                                                                                                     
                                                                                                                                                         
                                                                                                          




                                                                                                                                      
                                                                         
                                                                                                                                                     
                                                                                                  




                                                                                                                              
                                                                                                                                                   
                                                                                                  





                                                                                                                              
                                                                                               








                                                                                                                                     
                                           


                                                                                    
                                                    



                                                                                                                                               






                                                                                                                                 
 
/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.team.internal.ccvs.core.client;

import java.util.*;

import org.eclipse.core.runtime.*;
import org.eclipse.team.internal.ccvs.core.*;
import org.eclipse.team.internal.ccvs.core.client.listeners.ICommandOutputListener;
import org.eclipse.team.internal.ccvs.core.client.listeners.IConsoleListener;
import org.eclipse.team.internal.ccvs.core.connection.CVSServerException;

/**
 * Abstract base class for requests that are to be sent to the server.
 */
public abstract class Request {
	public static final ExpandModules EXPAND_MODULES = new ExpandModules();
	public static final ValidRequests VALID_REQUESTS = new ValidRequests();

	/*** Response handler map ***/
	private static final Map responseHandlers = new HashMap();
	
	private static void initializeHandlerCache() {
		synchronized(responseHandlers) {
			registerResponseHandler(new CheckedInHandler());
			registerResponseHandler(new CopyHandler());
			registerResponseHandler(new ModTimeHandler());
			registerResponseHandler(new NewEntryHandler());
			registerResponseHandler(new RemovedHandler());
			registerResponseHandler(new RemoveEntryHandler());
			registerResponseHandler(new StaticHandler(true));
			registerResponseHandler(new StaticHandler(false));
			registerResponseHandler(new StickyHandler(true));
			registerResponseHandler(new StickyHandler(false));
			registerResponseHandler(new UpdatedHandler(UpdatedHandler.HANDLE_UPDATED));
			registerResponseHandler(new UpdatedHandler(UpdatedHandler.HANDLE_UPDATE_EXISTING));
			registerResponseHandler(new UpdatedHandler(UpdatedHandler.HANDLE_CREATED));
			registerResponseHandler(new UpdatedHandler(UpdatedHandler.HANDLE_MERGED));
			registerResponseHandler(new ValidRequestsHandler());
			registerResponseHandler(new ModuleExpansionHandler());
			registerResponseHandler(new MTHandler());
			registerResponseHandler(new NotifiedHandler());
			registerResponseHandler(new TemplateHandler());
		}
	}
	private static void registerResponseHandler(ResponseHandler handler) {
		synchronized(responseHandlers) {
			responseHandlers.put(handler.getResponseID(), handler);
		}
	}
	
	/**
	 * This method is invoked by Session to get a mutable copy of the
	 * global list of acceptable response handlers.
	 * 
	 * @return a map of reponse handlers
	 */
	protected static Map getReponseHandlerMap() {
		synchronized(responseHandlers) {
			if (responseHandlers.isEmpty()) {
				initializeHandlerCache();
			}
			Map copy = new HashMap();
			for (Iterator iter = responseHandlers.values().iterator(); iter.hasNext();) {
				ResponseHandler handler = (ResponseHandler) iter.next();
				copy.put(handler.getResponseID(), handler.getInstance());
				
			}
			return copy;
		}
	}
	/**
	 * Prevents client code from instantiating us.
	 */
	protected Request() { }

	/**
	 * Returns the string used to invoke this request on the server.
	 * [template method]
	 * 
	 * @return the request identifier string
	 */
	protected abstract String getRequestId();

	/**
	 * Executes a request and processes the responses.
	 * 
	 * @param session the open CVS session
	 * @param listener the command output listener, or null to discard all messages
	 * @param monitor the progress monitor
	 * @return a status code indicating success or failure of the operation
	 */
	protected IStatus executeRequest(Session session, ICommandOutputListener listener,
		IProgressMonitor monitor) throws CVSException {
		// send request
		session.sendRequest(getRequestId());

		// This number can be tweaked if the monitor is judged to move too
		// quickly or too slowly. After some experimentation this is a good
		// number for both large projects (it doesn't move so quickly as to
		// give a false sense of speed) and smaller projects (it actually does
		// move some rather than remaining still and then jumping to 100).
		final int TOTAL_WORK = 300;
		monitor.beginTask(Policy.bind("Command.receivingResponses"), TOTAL_WORK); //$NON-NLS-1$
		int halfWay = TOTAL_WORK / 2;
		int currentIncrement = 4;
		int nextProgress = currentIncrement;
		int worked = 0;
		
		// If the session is connected to a CVSNT server (1.11.1.1), we'll need to do some special handling for
		// some errors. Unfortunately, CVSNT 1.11.1.1 will drop the connection after so some functionality is
		// still effected
		boolean isCVSNT = session.isCVSNT();

		session.clearErrors();
		for (;;) {
			// update monitor work amount
			if (--nextProgress <= 0) {
				monitor.worked(1);
				worked++;
				if (worked >= halfWay) {
					// we have passed the current halfway point, so double the
					// increment and reset the halfway point.
					currentIncrement *= 2;
					halfWay += (TOTAL_WORK - halfWay) / 2;				
				}
				// reset the progress counter to another full increment
				nextProgress = currentIncrement;
			}			
			Policy.checkCanceled(monitor);

			// retrieve a response line
			String response = session.readLine();
			int spacePos = response.indexOf(' ');
			String argument;
			if (spacePos != -1) {
				argument = response.substring(spacePos + 1);
				response = response.substring(0, spacePos);
			} else argument = "";  //$NON-NLS-1$

			// handle completion responses
			if (response.equals("ok")) {  //$NON-NLS-1$
				break;
			} else if (response.equals("error") || (isCVSNT && response.equals(""))) {  //$NON-NLS-1$ //$NON-NLS-2$
				argument = argument.trim();
				boolean serious = false;
				if (argument.length() == 0) {
					argument = getServerErrorMessage();
				} else {
					argument = Policy.bind("Command.seriousServerError", argument); //$NON-NLS-1$
					if (!session.hasErrors()) {
						session.addError(new CVSStatus(CVSStatus.ERROR, CVSStatus.SERVER_ERROR, argument));
					}
					serious = true;
				}
					
				if (!session.hasErrors()) {
				    session.addError(new CVSStatus(CVSStatus.ERROR, CVSStatus.SERVER_ERROR, Policy.bind("Command.noMoreInfoAvailable")));//$NON-NLS-1$
				}
				IStatus status = new MultiStatus(CVSProviderPlugin.ID, CVSStatus.SERVER_ERROR, 
				        session.getErrors(),
					argument, null);
				if (serious) {
					throw new CVSServerException(status);
				} else {
					// look for particularly bad errors in the accumulated statii
				    IStatus[] errors = session.getErrors();
				    for (int i = 0; i < errors.length; i++) {
                        IStatus s = errors[i];
						if (s.getCode() == CVSStatus.PROTOCOL_ERROR) {
							throw new CVSServerException(status);
						}
					}
				}
				return status;
			// handle message responses
			} else if (response.equals("MT")) {  //$NON-NLS-1$
				// Handle the MT response
				MTHandler handler = (MTHandler) session.getResponseHandler(response);
				if (handler != null) {
					handler.handle(session, argument, monitor);
				} else {
					throw new CVSException(new org.eclipse.core.runtime.Status(IStatus.ERROR,
						CVSProviderPlugin.ID, CVSException.IO_FAILED,
						Policy.bind("Command.unsupportedResponse", response, argument), null)); //$NON-NLS-1$
				}
				// If a line is available, pass it on to the message listener 
				// and console as if it were an M response
				if (handler.isLineAvailable()) {
					String line = handler.getLine();
					IStatus status = listener.messageLine(line, session.getCVSRepositoryLocation(), session.getLocalRoot(), monitor);
					if (status != ICommandOutputListener.OK) session.addError(status);
					if (session.isOutputToConsole()) {
						IConsoleListener consoleListener = CVSProviderPlugin.getPlugin().getConsoleListener();
						if (consoleListener != null) consoleListener.messageLineReceived(line);
					}
				}
			} else if (response.equals("M")) {  //$NON-NLS-1$
				IStatus status = listener.messageLine(argument, session.getCVSRepositoryLocation(), session.getLocalRoot(), monitor);
				if (status != ICommandOutputListener.OK) session.addError(status);
				if (session.isOutputToConsole()) {
					IConsoleListener consoleListener = CVSProviderPlugin.getPlugin().getConsoleListener();
					if (consoleListener != null) consoleListener.messageLineReceived(argument);
				}
			} else if (response.equals("E")) { //$NON-NLS-1$
				IStatus status = listener.errorLine(argument, session.getCVSRepositoryLocation(), session.getLocalRoot(), monitor);
				if (status != ICommandOutputListener.OK) session.addError(status);
				if (session.isOutputToConsole()) {
					IConsoleListener consoleListener = CVSProviderPlugin.getPlugin().getConsoleListener();
					if (consoleListener != null) consoleListener.errorLineReceived(argument);
				}
			// handle other responses
			} else {
				ResponseHandler handler = session.getResponseHandler(response);
				if (handler != null) {
					handler.handle(session, argument, monitor);
				} else {
					throw new CVSException(new org.eclipse.core.runtime.Status(IStatus.ERROR,
						CVSProviderPlugin.ID, CVSException.IO_FAILED,
						Policy.bind("Command.unsupportedResponse", response, argument), null)); //$NON-NLS-1$
				}
			}
		}
		if (!session.hasErrors()) {
			return ICommandOutputListener.OK;
		} else {
			return new MultiStatus(CVSProviderPlugin.ID, CVSStatus.INFO,
				session.getErrors(),
				Policy.bind("Command.warnings", Policy.bind("Command." + getRequestId())), null);  //$NON-NLS-1$  //$NON-NLS-2$
		}
	}
	
	/*
	 * Provide the message that is used for the status that is generated when the server
	 * reports as error.
	 */
	protected String getServerErrorMessage() {
		return Policy.bind("Command.serverError", Policy.bind("Command." + getRequestId())); //$NON-NLS-1$  //$NON-NLS-2$
	}
}

Back to the top