Package de.innovationgate.eclipse.wgadesigner.team

Source Code of de.innovationgate.eclipse.wgadesigner.team.WGARemoteServerSubscriber

/*******************************************************************************
* Copyright (c) 2009, 2010 Innovation Gate GmbH.
* 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:
*     Innovation Gate GmbH - initial API and implementation
******************************************************************************/
package de.innovationgate.eclipse.wgadesigner.team;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.core.subscribers.Subscriber;
import org.eclipse.team.core.subscribers.SubscriberChangeEvent;
import org.eclipse.team.core.synchronize.SyncInfo;
import org.eclipse.team.core.variants.IResourceVariant;
import org.eclipse.team.core.variants.IResourceVariantComparator;

import de.innovationgate.eclipse.utils.wga.WGADesignStructureHelper;
import de.innovationgate.eclipse.wgadesigner.WGADesignerPlugin;
import de.innovationgate.eclipse.wgadesigner.editors.helpers.WGADeployment;
import de.innovationgate.eclipse.wgadesigner.editors.helpers.WGADeploymentManager;
import de.innovationgate.eclipse.wgadesigner.models.WGADistribution;
import de.innovationgate.eclipse.wgadesigner.models.WGARemoteServer;
import de.innovationgate.eclipse.wgadesigner.natures.WGARuntime;
import de.innovationgate.eclipse.wgadesigner.tomcat.TomcatUtils;
import de.innovationgate.utils.WGUtils;
import de.innovationgate.wgaservices.types.FSDesignResourceState;
import de.innovationgate.wgaservices.types.PluginInfo;
import de.innovationgate.wgaservices.types.Version;

public class WGARemoteServerSubscriber extends Subscriber {

  private WGAFSDesignResourceVariantComparator _comparator;
  private WGAPluginResourceVariantComparator _pluginComparator;
 
  private WGARuntime _runtime;
  private WGARemoteServer _server;
 
  // local and remote states mapped by their paths relative to the wga designroot
  private Map<IPath, LocalFSDesignResourceState> _localStates = new HashMap<IPath, LocalFSDesignResourceState>();
  private Map<IPath, FSDesignResourceState> _remoteStates = new HashMap<IPath, FSDesignResourceState>();
 
  // local and remote states mapped by resource
  private Map<IResource, LocalFSDesignResourceState> _localStatesByResource =new HashMap<IResource, LocalFSDesignResourceState>();
  private Map<IResource, FSDesignResourceState> _remoteStatesByResource =new HashMap<IResource, FSDesignResourceState>();
 
    private Map<IResource, PluginInfo> _localPluginInfos = new HashMap<IResource, PluginInfo>();
    private Map<IResource, PluginInfo> _remotePluginInfos = new HashMap<IResource, PluginInfo>();
 
  // lock for update progress
    private Object _refreshLock = new Object();
    private Version _remoteWGAVersion;

 
  public WGARemoteServerSubscriber(WGARemoteServer server, WGARuntime runtime) {
    _server = server;
    _runtime = runtime;   
    _comparator = new WGAFSDesignResourceVariantComparator();
    _pluginComparator = new WGAPluginResourceVariantComparator();
    refresh(roots(), IResource.DEPTH_INFINITE, new NullProgressMonitor());   
  }
 
  public String getName() {
    return "Subscriber for '" + _runtime.getName() + "'.";
  }

  public boolean isSupervised(IResource resource) {
      synchronized (_refreshLock) {
          return _localStatesByResource.containsKey(resource) || _remoteStatesByResource.containsKey(resource) || isPluginResource(resource);   
        }   
//    if (resource.getProject().equals(_runtime.getProject())) {
//      return _runtime.getDesignRoot().getFullPath().isPrefixOf(resource.getFullPath());
//    } else {
//      return  false;
//    }
  }

 
  public IResource[] members(IResource resource) throws TeamException {
      synchronized (_refreshLock ) {
        Map<IPath, IResource> existingChildren = new HashMap<IPath, IResource>()
        for (IPath path : _localStates.keySet()) {
            if (isAffected(path, true)) {
              IResource child = convertToResource(_localStates.get(path));
              if (child != null) {
                _localStatesByResource.put(child, _localStates.get(path));
                // add highest parent
                IResource parent = child;
                while (parent != null) {
                  IResource grandParent = parent.getParent();
                  if (grandParent != null && grandParent.getFullPath().equals(resource.getFullPath())) {
                    existingChildren.put(parent.getFullPath(), parent);
                    break;
                  }
                  parent = grandParent;               
                }
              }
            }
        }
        for (IPath path : _remoteStates.keySet()) {
          if (isAffected(path, false)) {
            IResource child = convertToResource(_remoteStates.get(path));
            if (child != null) {
              _remoteStatesByResource.put(child, _remoteStates.get(path));
              // add highest parent
              IResource parent = child;
              while (parent != null) {
                IResource grandParent = parent.getParent();
                if (grandParent != null && grandParent.getFullPath().equals(resource.getFullPath())) {
                  existingChildren.put(parent.getFullPath(), parent);           
                  break;
                }
                parent = grandParent;             
              }
            }
          }
        }

        IResource virtualPluginRoot = retrieveVirtualPluginRoot(_runtime);
        if (resource instanceof IProject) {            
            existingChildren.put(virtualPluginRoot.getFullPath(), virtualPluginRoot);
        } else if (resource.getFullPath().equals(virtualPluginRoot.getFullPath())) {
            for (IResource virtualPluginResource : _localPluginInfos.keySet()) {
                existingChildren.put(virtualPluginResource.getFullPath(), virtualPluginResource);
            }
            for (IResource virtualPluginResource : _remotePluginInfos.keySet()) {
                    existingChildren.put(virtualPluginResource.getFullPath(), virtualPluginResource);
                }
        }
       
        return (IResource[]) existingChildren.values().toArray(new IResource[existingChildren.size()]);
      }
  }
 
  /**
   * checks if the given design resource path has a change
   * @param path path rooted at the wga design root
   * @param local true if this is a local path / false if path is remote
   * @return
   */
  private boolean isAffected(IPath path, boolean local) {
    FSDesignResourceState stateA = null;
    FSDesignResourceState stateB = null;
    if (local) {
      stateA = _localStates.get(path);
      stateB = _remoteStates.get(path);
    } else {           
      stateA = _remoteStates.get(path);
      stateB = _localStates.get(path);
    }
    if (stateA == null) {
      return false;
    }
    if (stateA.getType() == FSDesignResourceState.TYPE_FILE) {
      return (stateB == null || stateB.getLastmodified() != stateA.getLastmodified());     
    } else if (stateA.getType() == FSDesignResourceState.TYPE_FOLDER) {
      if (stateB == null) {
        // this is a folder deletion
        return true;
      } else {
        // check if child folders or files are affected
        for (IPath childPath : _localStates.keySet()) {
          if (path.isPrefixOf(childPath) && !path.equals(childPath)) {
            boolean childIsAffected = isAffected(childPath, local);
            if (childIsAffected) {
              return true;
            }
          }
        }
      }
    }
    return false;   
  }

  public IResource[] roots() {
    List<IResource> roots = new ArrayList<IResource>();
    roots.add(_runtime.getProject());
    IFolder[] designFolders = _runtime.getDesignsAsFolder(false);
    for (IFolder designFolder : designFolders) {
      if (WGADesignStructureHelper.isDirlinkFolder(designFolder)) {
        IContainer dirlinkTarget = WGADesignStructureHelper.resolveDirLink(designFolder.getFile(WGUtils.DIRLINK_FILE));
        roots.add(dirlinkTarget.getProject());
      }
    }
    return roots.toArray(new IResource[0]);
  }

  public SyncInfo getSyncInfo(IResource resource) throws TeamException {
      synchronized (_refreshLock) {           
        try {
            if (isPluginResource(resource)) {
                IResourceVariant variant = null;
                PluginInfo remotePluginInfo = _remotePluginInfos.get(resource);
                if (remotePluginInfo != null) {
                    variant = new WGAPluginResourceVariant(_server, remotePluginInfo);
                }
               
                PluginInfo localPluginInfo = _localPluginInfos.get(resource);
               
                SyncInfo info = new WGAPluginResourceSyncInfo(_runtime, _server, resource, localPluginInfo, variant, _remoteWGAVersion);
                info.init();
                return info;
            } else {
              IResourceVariant variant = null;
              FSDesignResourceState state = _remoteStatesByResource.get(resource);
              if (state != null) {
                variant = new WGAFSDesignResourceVariant(_server, state);
              }
              LocalFSDesignResourceState localState = _localStatesByResource.get(resource);
              SyncInfo info = new WGAFSDesignResourceSyncInfo(_runtime, _server, resource, localState, variant, variant, _comparator);
              info.init();
              return info;
            }
        } catch (CoreException e) {
          throw TeamException.asTeamException(e);
        }
      }
  }

  private boolean isPluginResource(IResource resource) {
        if (resource != null && resource.getProject().getFolder("plugins").getFullPath().isPrefixOf(resource.getFullPath())) {
            return true;
        }
        return false;
    }

    public IResourceVariantComparator getResourceComparator() {
    return _comparator;
  }

  public void refresh(IResource[] resources, int depth, IProgressMonitor monitor) {
      synchronized (_refreshLock) {
      try {
        _localStates.clear();
        _remoteStates.clear();
        _localStatesByResource.clear();
        _remoteStatesByResource.clear();
       
        _localPluginInfos.clear();
        _remotePluginInfos.clear();
       
        monitor.beginTask("retrieving local resource states", IProgressMonitor.UNKNOWN);
        IResource start = _runtime.getDesignRoot();

        List<LocalFSDesignResourceState> localStates = buildFSDesignResourceStates(start, _runtime.getDesignRoot().getFullPath());
        //print(localStates);
               
        monitor.setTaskName("connecting to remote server '" + _server.getName() + "'.");
        _server.connectToServer();       
        monitor.setTaskName("retrieving remote resouce states");
        List<FSDesignResourceState> remoteStates = _server.getServices().retrieveFSDesignResourceState(_server.getSession(), computeRelativPathFromDesignRoot(start).toString());
       
        // map states by path rooted to wga designroot
        for (LocalFSDesignResourceState state : localStates) {
          IPath path = new Path(state.getPath());
          _localStates.put(path.makeRelative(), state);
        }       
        for (FSDesignResourceState state : remoteStates) {
          IPath path = new Path(state.getPath());
          _remoteStates.put(path.makeRelative(), state);   
        }
       
        // perform steps for plugin sync if runtime is started
        if (TomcatUtils.getInstance().isRunning(_runtime)) {
            monitor.beginTask("connecting to local WGA server", IProgressMonitor.UNKNOWN);
            WGARemoteServer local = _runtime.createRemoteServer();
            local.connectToServer();
           
            Version localWGAVersion = null;
                    try {
                        monitor.beginTask("retrieving local WGA server version", IProgressMonitor.UNKNOWN);
                        localWGAVersion = local.getServices().getWGAVersion(local.getSession());
                    }
                    catch (Exception e) {
                        // this might happen if server version is < 5.3
                    }
                    try {
                        monitor.beginTask("retrieving remote WGA server version", IProgressMonitor.UNKNOWN);
                        _remoteWGAVersion = _server.getServices().getWGAVersion(_server.getSession());
                    }
                    catch (Exception e) {
                        // this might happen if server version is < 5.3
                    }
                   
                   
                    // check local and remote WGA version - plugin sync is available for WGA >= 5.3
                    if (localWGAVersion != null && localWGAVersion.isAtLeast(5, 3) && _remoteWGAVersion != null && _remoteWGAVersion.isAtLeast(5, 3)) {                               
                monitor.beginTask("retrieving local plugin infos", IProgressMonitor.UNKNOWN);
                               
                List<PluginInfo> infos = local.getServices().getPluginInformation(local.getSession());
                for (PluginInfo info : infos) {
                    // we will sync only active & valid plugins ... dev plugins & platform plugins are excluded
                    if (info.isActive() && info.isValid() && !info.isPlatformPlugin() && !info.isDeveloperPlugin()) {
                        IResource virtualPluginResource = buildVirtualPluginResource(_runtime, info);
                        _localPluginInfos.put(virtualPluginResource, info);
                    }
                }
               
                monitor.beginTask("retrieving remote plugin infos", IProgressMonitor.UNKNOWN);               
                        infos = _server.getServices().getPluginInformation(_server.getSession());
                        for (PluginInfo info : infos) {
                            // we will sync only active & valid plugins ... dev plugins & platform plugins are excluded
                            if (info.isActive() && info.isValid() && !info.isPlatformPlugin() && !info.isDeveloperPlugin()) {
                                IResource virtualPluginResource = buildVirtualPluginResource(_runtime, info);
                                _remotePluginInfos.put(virtualPluginResource, info);
                            }
                        }
                    }
        }
                      
       
        // fire subscriber events to notify listeners ofs syncstate change
        List<SubscriberChangeEvent> events = new ArrayList<SubscriberChangeEvent>();
        for (IResource root : roots()) {
          SubscriberChangeEvent eventA = new SubscriberChangeEvent(this, SubscriberChangeEvent.ROOT_REMOVED, root);
          SubscriberChangeEvent eventB = new SubscriberChangeEvent(this, SubscriberChangeEvent.ROOT_ADDED, root);
          events.add(eventA);
          events.add(eventB);
        }
        fireTeamResourceChange(events.toArray(new SubscriberChangeEvent[0]));
      } catch (Exception e) {
        List<SubscriberChangeEvent> events = new ArrayList<SubscriberChangeEvent>();
        for (IResource root : roots()) {
          SubscriberChangeEvent eventA = new SubscriberChangeEvent(this, SubscriberChangeEvent.ROOT_REMOVED, root);
          events.add(eventA);
        }
        fireTeamResourceChange(events.toArray(new SubscriberChangeEvent[0]));
        throw new RuntimeException(e);       
       
      } finally {
        monitor.done();
     
      }
  }

  private List<LocalFSDesignResourceState> buildFSDesignResourceStates(IResource resource, IPath base) throws CoreException {
    List<LocalFSDesignResourceState> states = new ArrayList<LocalFSDesignResourceState>();
 
    if (resource instanceof IFolder && WGADesignStructureHelper.isDirlinkFolder((IFolder)resource)) {
      // we have to resolve dirlink
      IContainer dirlinkTarget = WGADesignStructureHelper.resolveDirLink(((IFolder)resource).getFile(WGUtils.DIRLINK_FILE));
      if (dirlinkTarget != null && dirlinkTarget.isAccessible()) {
          states.addAll(buildDirLinkFSDesignResourceStates(dirlinkTarget, resource.getName(), dirlinkTarget));
      }
    } else {
      LocalFSDesignResourceState state = new LocalFSDesignResourceState();
      states.add(state);
      state.setFqPath(resource.getFullPath());
      state.setPath(computeRelativPathFrom(resource, base).makeRelative().toString());   
      if (resource instanceof IContainer) {
        state.setType(FSDesignResourceState.TYPE_FOLDER);
        IContainer container = (IContainer) resource;
        for (IResource child : container.members()) {
          List<LocalFSDesignResourceState> childStates = buildFSDesignResourceStates(child, base);
          states.addAll(childStates);
        }
      } else if (resource instanceof IFile) {
        IFile file = (IFile) resource;
        state.setType(FSDesignResourceState.TYPE_FILE);
        state.setLastmodified(file.getLocalTimeStamp());
        try {
          state.setMd5sum(WGUtils.createMD5HEX(file.getContents()));
        } catch (Exception e) {
          WGADesignerPlugin.getDefault().logError("Unable to compute md5 sum of resource '" + file.getLocation().toString() + "'.", e);
        }
      }
    }
    return states;
  }
 
 
  private List<LocalFSDesignResourceState> buildDirLinkFSDesignResourceStates(IContainer linkTarget, String linkName, IResource resource) throws CoreException {
    List<LocalFSDesignResourceState> states = new ArrayList<LocalFSDesignResourceState>();
    LocalFSDesignResourceState state = new LocalFSDesignResourceState();
    states.add(state);
    state.setDirLinkName(linkName);
    state.setDirLinkTarget(linkTarget);
    state.setFqPath(resource.getFullPath());   
    state.setPath(new Path(linkName).append(computeRelativPathFrom(resource, linkTarget.getFullPath()).makeRelative()).toString());   
    if (resource instanceof IContainer) {
      state.setType(FSDesignResourceState.TYPE_FOLDER);
      IContainer container = (IContainer) resource;
      for (IResource child : container.members()) {
        List<LocalFSDesignResourceState> childStates = buildDirLinkFSDesignResourceStates(linkTarget, linkName, child);
        states.addAll(childStates);
      }
    } else if (resource instanceof IFile) {
      IFile file = (IFile) resource;
      state.setType(FSDesignResourceState.TYPE_FILE);
      state.setLastmodified(file.getLocalTimeStamp());
      try {
        state.setMd5sum(WGUtils.createMD5HEX(file.getContents()));
      } catch (Exception e) {
        WGADesignerPlugin.getDefault().logError("Unable to compute md5 sum of resource '" + file.getLocation().toString() + "'.", e);
      }
    }   
    return states;
  }
 
 
  private IPath computeRelativPathFromDesignRoot(IResource resource) {
    int matchingSegments = resource.getFullPath().matchingFirstSegments(_runtime.getDesignRoot().getFullPath());
    return resource.getFullPath().removeFirstSegments(matchingSegments).makeRelative();
  }
 
  private IPath computeRelativPathFrom(IResource resource, IPath base) {
    int matchingSegments = resource.getFullPath().matchingFirstSegments(base);
    return resource.getFullPath().removeFirstSegments(matchingSegments).makeRelative();
  }
   
  private IResource convertToResource(FSDesignResourceState state) {
    // compute full qualified path to resource
    IPath path = null;
    if (state instanceof LocalFSDesignResourceState) {
      // local resource use full qualified path
      path = ((LocalFSDesignResourceState)state).getFqPath();
    } else {
      // remote state
      // compute design folder name
      String[] pathElements = state.getPath().split("/");
      if (pathElements != null && pathElements.length > 0) {
        String designFolderName = pathElements[0];
        // check if this design is internal or external
        IFolder designFolder = _runtime.getDesignRoot().getFolder(new Path(designFolderName));
        if (WGADesignStructureHelper.isDirlinkFolder(designFolder)) {
          // this is an external design
          IContainer linkTarget = WGADesignStructureHelper.resolveDirLink(designFolder.getFile(WGUtils.DIRLINK_FILE));
          path = linkTarget.getFullPath().append(new Path(state.getPath()).removeFirstSegments(1));
        } else {
          path = _runtime.getDesignRoot().getFullPath().append(new Path(state.getPath()));   
        }
      } else {
        path = _runtime.getDesignRoot().getFullPath().append(new Path(state.getPath()));
      }     
    }
   
    IResource resource = null;
    if (state.getType() == FSDesignResourceState.TYPE_FOLDER) {
      resource = ResourcesPlugin.getWorkspace().getRoot().getFolder(path);           
    } else {       
      resource = ResourcesPlugin.getWorkspace().getRoot().getFile(path);         
    }
    return resource;
  }
   
  public static IContainer retrieveVirtualPluginRoot(WGARuntime runtime) {
      IProject project = runtime.getProject();
      return project.getFolder("plugins");
  }
 
  public static IResource buildVirtualPluginResource(WGARuntime runtime, PluginInfo info) {
      return retrieveVirtualPluginRoot(runtime).getFile(new Path(info.getUniqueName() + "-" + info.getVersion() + ".wgaplugin"));
    }

 
}
TOP

Related Classes of de.innovationgate.eclipse.wgadesigner.team.WGARemoteServerSubscriber

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.