Package org.eclipse.m2e.wtp.overlay.internal.servers

Source Code of org.eclipse.m2e.wtp.overlay.internal.servers.OverlayResourceChangeListener

/*******************************************************************************
* Copyright (c) 2011 Sonatype, Inc.
* 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
*******************************************************************************/
package org.eclipse.m2e.wtp.overlay.internal.servers;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.m2e.wtp.overlay.OverlayConstants;
import org.eclipse.m2e.wtp.overlay.internal.modulecore.OverlaySelfComponent;
import org.eclipse.m2e.wtp.overlay.modulecore.IOverlayVirtualComponent;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.ModuleCoreNature;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
import org.eclipse.wst.server.core.IModule;
import org.eclipse.wst.server.core.IServer;
import org.eclipse.wst.server.core.ServerCore;
import org.eclipse.wst.server.core.internal.Server;

/**
* Listens to overlaid project changes to force server redeployment.
*
* @author Fred Bricon
*
*/
public class OverlayResourceChangeListener implements IResourceChangeListener {

  @Override
  public void resourceChanged(IResourceChangeEvent event) {
    IResourceDelta delta =  event.getDelta();
    if (delta == null) {
      return;
    }

    IServer[] servers = ServerCore.getServers();
    if (servers.length == 0) {
      //No servers defined, so nothing to do
      return;
    }
   
    IResourceDelta[] projectDeltas = delta.getAffectedChildren();
    if (projectDeltas == null || projectDeltas.length == 0) {
      return;
    }
    
    boolean buildOccurred = hasBuildOccurred(event);
      
    Set<IProject> changedProjects  = getChangedProjects(projectDeltas);
    if (changedProjects.isEmpty()) {
      return;
    }
   
    Map<IServer, List<IModule>> republishableServers = new HashMap<IServer, List<IModule>>(servers.length);
   
    for (IServer server : servers) {
      modules : for (IModule module : server.getModules()) {
        IProject moduleProject = module.getProject();
        for (IProject changedProject : changedProjects) {
          if (hasOverlayChanged(changedProject, moduleProject, delta)) {
            List<IModule> republishableModules = republishableServers.get(server);
            if (republishableModules == null) {
              republishableModules = new ArrayList<IModule>(server.getModules().length);
              republishableServers.put(server, republishableModules);
            }
            republishableModules.add(module);
            break modules;
          }
        }
      }
    }
   
    if (republishableServers.isEmpty()) {
      return;
    }
   
    boolean isPublishOverlaysEnabled = isPublishOverlaysEnabled();
    for(Map.Entry<IServer, List<IModule>> entries : republishableServers.entrySet()) {
      IServer iserver = entries.getKey();
      boolean shouldPublish = isPublishOverlaysEnabled;
      if (iserver instanceof Server) {
        Server server = ((Server)iserver);
        List<IModule> modules = entries.getValue();
        IModule[] mod = new IModule[modules.size()];
        modules.toArray(mod);
        server.setModulePublishState(mod, IServer.PUBLISH_STATE_INCREMENTAL);
        int autoPublishSetting = server.getAutoPublishSetting();
        shouldPublish = shouldPublish && (autoPublishSetting == Server.AUTO_PUBLISH_RESOURCE ||
                            (autoPublishSetting == Server.AUTO_PUBLISH_BUILD && buildOccurred));
      }
      if (shouldPublish && iserver.getServerState() == IServer.STATE_STARTED) {
        iserver.publish(IServer.PUBLISH_INCREMENTAL, new NullProgressMonitor());
      }
    }
  }

  private boolean isPublishOverlaysEnabled() {
    boolean isEnabled = InstanceScope.INSTANCE.getNode(OverlayConstants.PLUGIN_ID)
                        .getBoolean(OverlayConstants.P_REPUBLISH_ON_PROJECT_CHANGE, true);
    return isEnabled;
  }

  private Set<IProject> getChangedProjects(IResourceDelta[] projectDeltas) {
    Set<IProject> projects = new HashSet<IProject>();
    if (projectDeltas != null) {
      for (IResourceDelta delta : projectDeltas) {
        IResource resource = delta.getResource();
        if (resource != null && resource instanceof IProject) {
          projects.add((IProject) resource);
        }
      }
    }
    return projects;
  }
 
  /**
   * Return true if moduleProject references changedProject as an IOverlayComponent
   * @param changedProject
   * @param projectDeployedOnServer
   * @param delta
   * @return true if moduleProject references changedProject as an IOverlayComponent
   */
  private boolean hasOverlayChanged(IProject changedProject, IProject projectDeployedOnServer, IResourceDelta delta) {
    if (!ModuleCoreNature.isFlexibleProject(projectDeployedOnServer)) {
      return false;
    }
    IVirtualComponent component = ComponentCore.createComponent(projectDeployedOnServer);
    if (component == null) {
      return false;
    }
    IVirtualReference[] references = component.getReferences();
    if (references == null || references.length == 0) {
      return false;
    }
    for (IVirtualReference reference : references) {
      IVirtualComponent vc = reference.getReferencedComponent();
      if (vc instanceof IOverlayVirtualComponent){
        IProject overlaidProject = vc.getProject();
        if (vc instanceof OverlaySelfComponent) {
          IPath componentFilePath = overlaidProject.getFile(".settings/org.eclipse.wst.common.component").getFullPath(); //$NON-NLS-1$
          if (delta.findMember(componentFilePath) != null) {
            return true;
          }
        } else if (!vc.isBinary() && overlaidProject.equals(changedProject)){
          return true;
        }
      }
    }
    return false;
  }

     private boolean hasBuildOccurred(IResourceChangeEvent event) {
       if (event == null) {
         return false;
       }
         int kind = event.getBuildKind();
         return (kind == IncrementalProjectBuilder.INCREMENTAL_BUILD) ||
                (kind == IncrementalProjectBuilder.FULL_BUILD) ||
                ((kind == IncrementalProjectBuilder.AUTO_BUILD && ResourcesPlugin.getWorkspace().isAutoBuilding()));
     }

}
TOP

Related Classes of org.eclipse.m2e.wtp.overlay.internal.servers.OverlayResourceChangeListener

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.