/*******************************************************************************
 * Copyright (c) 2004, 2006 Subclipse project and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Subclipse project committers - initial API and implementation
 ******************************************************************************/
package org.tigris.subversion.subclipse.core.commands;

import java.io.File;
import java.util.LinkedHashSet;
import java.util.Set;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IProgressMonitor;
import org.tigris.subversion.subclipse.core.ISVNCoreConstants;
import org.tigris.subversion.subclipse.core.SVNException;
import org.tigris.subversion.subclipse.core.client.OperationManager;
import org.tigris.subversion.subclipse.core.client.OperationProgressNotifyListener;
import org.tigris.subversion.subclipse.core.resources.SVNWorkspaceRoot;
import org.tigris.subversion.svnclientadapter.ISVNClientAdapter;
import org.tigris.subversion.svnclientadapter.ISVNConflictResolver;
import org.tigris.subversion.svnclientadapter.SVNClientException;
import org.tigris.subversion.svnclientadapter.SVNRevision;

/**
 * Update the given resources in the given project to the given revision
 * 
 * @author Cedric Chabanois (cchab at tigris.org)
 */
public class UpdateResourcesCommand implements ISVNCommand {
    private SVNWorkspaceRoot root;
    private IResource[] resources;
    private SVNRevision revision; 
    private int depth = ISVNCoreConstants.DEPTH_UNKNOWN;
    private boolean setDepth = false;
    private boolean ignoreExternals = false;
    private boolean force = true;
    private Set<IResource> updatedResources = new LinkedHashSet<IResource>();
    private ISVNConflictResolver conflictResolver;
    
    /**
     * Update the given resources.
     * BEWARE ! The resource array has to be sorted properly, so parent folder (incoming additions) are updated sooner than their children.
     * BEWARE ! For incoming deletions, it has to be opposite. 
     * WATCH OUT ! These two statements mean that you CANNOT have both additions and deletions within the same call !!!
     * When doing recursive call, it's obviously not an issue ... 
     * @param root
     * @param resources
     * @param revision
     */
    public UpdateResourcesCommand(SVNWorkspaceRoot root, IResource[] resources, SVNRevision revision) {
        this.root = root;
        this.resources = resources;
        this.revision = revision;
    }
    
	/* (non-Javadoc)
	 * @see org.tigris.subversion.subclipse.core.commands.ISVNCommand#run(org.eclipse.core.runtime.IProgressMonitor)
	 */
	public void run(final IProgressMonitor monitor) throws SVNException {
		ISVNClientAdapter svnClient = root.getRepository().getSVNClient();
		if (conflictResolver != null) {
			svnClient.addConflictResolutionCallback(conflictResolver);
		}
        try {
            monitor.beginTask(null, 100 * resources.length);                    
           
            OperationManager.getInstance().beginOperation(svnClient, new OperationProgressNotifyListener(monitor, svnClient));
    		if (resources.length == 1)
    		{
                monitor.subTask(resources[0].getName());
                svnClient.update(resources[0].getLocation().toFile(),revision, depth, setDepth, ignoreExternals, force);
                updatedResources.add(resources[0]);
                monitor.worked(100);    			
    		}
    		else
    		{
    			File[] files = new File[resources.length];
    			for (int i = 0; i < resources.length; i++) {
					files[i] = resources[i].getLocation().toFile();
					updatedResources.add(resources[i]);
				}
   				svnClient.update(files, revision, depth, setDepth, ignoreExternals, force);   				
   				monitor.worked(100);
    		}
        } catch (SVNClientException e) {
            throw SVNException.wrapException(e);
        } finally {
    		Set<IResource> refreshResources = new LinkedHashSet<IResource>();
    		for (IResource resource : updatedResources) {
    			refreshResources.add(resource);
    			OperationManager.getInstance().onNotify(resource.getLocation().toFile(), null);
    		}
    		OperationManager.getInstance().endOperation(true, refreshResources);
    		if (conflictResolver != null) {
    			svnClient.addConflictResolutionCallback(null);
    		}
    		root.getRepository().returnSVNClient(svnClient);
            monitor.done();
        }        
	}

	public void setConflictResolver(ISVNConflictResolver conflictResolver) {
		this.conflictResolver = conflictResolver;
	}

	public void setDepth(int depth) {
		this.depth = depth;
	}
	
	public void setSetDepth(boolean setDepth) {
		this.setDepth = setDepth;
	}   

	public void setIgnoreExternals(boolean ignoreExternals) {
		this.ignoreExternals = ignoreExternals;
	}

	public void setForce(boolean force) {
		this.force = force;
	}    
    
}

@@ -1045,24 +1045,103 @@
 fyListener;%0A
+import org.tigris.subversion.subclipse.core.client.OperationResourceCollector;%0A
 import org.t
@@ -1200,16 +1200,16 @@
 ceRoot;%0A
-
 import o
@@ -2064,24 +2064,131 @@
 olver;%0A    %0A
+    private OperationResourceCollector operationResourceCollector = new OperationResourceCollector();%0A    %0A
     /**%0A    
@@ -3358,32 +3358,103 @@
                %0A
+%0A            svnClient.addNotifyListener(operationResourceCollector);%0A 
            %0A    
@@ -3445,24 +3445,24 @@
            %0A
-
             
@@ -4120,16 +4120,19 @@
 ;%0A%09%09%09%09%7D%0A
+  %0A
    %09%09%09%09s
@@ -4367,268 +4367,110 @@
     
-%09%09Set%3CIResource%3E refreshResources = new LinkedHashSet%3CIResource%3E();%0A    %09%09for (IResource resource : updatedResources) %7B%0A    %09%09%09refreshResources.add(resource);%0A    %09%09%09OperationManager.getInstance().onNotify(resource.getLocation().toFile(), null
+    %09Set%3CIResource%3E operationResources = operationResourceCollector.getOperationResources(
 );%0A    
-%09%09%7D%0A
     %09
-%09
 Oper
@@ -4519,15 +4519,17 @@
 ue, 
-refresh
+operation
 Reso
@@ -4628,24 +4628,24 @@
 (null);%0A
-
     %09%09%7D%0A
     %09%09ro
@@ -4632,24 +4632,91 @@
 l);%0A    %09%09%7D%0A
+    %09%09 svnClient.removeNotifyListener(operationResourceCollector);%0A
     %09%09root.g

Fix refresh of Sync view after update. Issue #: 1336