/******************************************************************************* * Copyright (c) 2003, 2011 IBM Corporation 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: * IBM Corporation - Initial API and implementation *******************************************************************************/ package org.eclipse.wst.server.core.internal; import java.io.ByteArrayInputStream; import java.util.*; import org.eclipse.core.runtime.*; import org.eclipse.core.resources.*; import org.eclipse.wst.server.core.*; import org.eclipse.wst.server.core.model.ServerDelegate; import org.eclipse.wst.server.core.util.ProjectModuleFactoryDelegate; /** * ResourceManager handles the mappings between resources * and servers or server configurations, and creates * notification of servers or server configurations * being added and removed. * * <p>Servers and server configurations may be a single * resource, or they may be a folder that contains a group * of files. Folder-resource may not contain other servers * or configurations.</p> */ public class ResourceManager { private static final String SERVER_DATA_FILE = "servers.xml"; private static final byte EVENT_ADDED = 0; private static final byte EVENT_CHANGED = 1; private static final byte EVENT_REMOVED = 2; private static ResourceManager instance = new ResourceManager(); // currently active runtimes and servers protected List<IRuntime> runtimes; protected List<IServer> servers; // lifecycle listeners protected List<IRuntimeLifecycleListener> runtimeListeners = new ArrayList<IRuntimeLifecycleListener>(3); protected List<IServerLifecycleListener> serverListeners = new ArrayList<IServerLifecycleListener>(3); // cache for disposing servers & runtimes protected List<String> activeBundles; // resource change listeners private IResourceChangeListener resourceChangeListener; private Preferences.IPropertyChangeListener pcl; protected boolean ignorePreferenceChanges = false; protected List moduleServerEventHandlers; protected List moduleServerEventHandlerIndexes; private static boolean initialized; private static boolean initializing; protected static List<String> serverProjects = new ArrayList<String>(2); /** * Server resource change listener. * * Resource listener - tracks changes on server resources so that * we can reload/drop server instances and configurations that * may change outside of our control. * Listens for two types of changes: * 1. Servers or configurations being added or removed * from their respective folders. (in the future, including * the addition or removal of a full server project, which * we currently can't listen for because there is no nature * attached to the project at this point - OTI defect) * 2. Projects being deleted. */ protected class ServerResourceChangeListener implements IResourceChangeListener { /** * Create a new ServerResourceChangeListener. */ public ServerResourceChangeListener() { super(); } /** * Listen for projects being added or removed and act accordingly. * * @param event a resource change event */ public void resourceChanged(final IResourceChangeEvent event) { IResourceDelta delta = event.getDelta(); if (delta == null) return; // ignore clean builds if (event.getBuildKind() == IncrementalProjectBuilder.CLEAN_BUILD) return; if (Trace.RESOURCES) { Trace.trace(Trace.STRING_RESOURCES, "->- ServerResourceChangeListener responding to resource change: " + event.getType() + " ->-"); } IResourceDelta[] children = delta.getAffectedChildren(); if (children != null) { int size = children.length; for (int i = 0; i < size; i++) { IResource resource = children[i].getResource(); if (resource != null && resource instanceof IProject) { projectChanged((IProject) resource, children[i]); } } } // search for changes to any project using a visitor try { delta.accept(new IResourceDeltaVisitor() { public boolean visit(IResourceDelta visitorDelta) { IResource resource = visitorDelta.getResource(); // only respond to project changes if (resource != null && resource instanceof IProject) { publishHandleProjectChange(visitorDelta, event); return false; } return true; } }); } catch (Exception e) { if (Trace.SEVERE) { Trace.trace(Trace.STRING_SEVERE, "Error responding to resource change", e); } } if (Trace.RESOURCES) { Trace.trace(Trace.STRING_RESOURCES, "-<- Done ServerResourceChangeListener responding to resource change -<-"); } } /** * React to a change within a possible server project. * * @param project a project * @param delta a resource delta */ protected void projectChanged(IProject project, IResourceDelta delta) { String projectName = project.getName(); if (!ServerPlugin.getProjectProperties(project).isServerProject()) { if (!serverProjects.contains(projectName)) { if (Trace.RESOURCES) { Trace.trace(Trace.STRING_RESOURCES, "Not a server project: " + project.getName()); } return; } serverProjects.remove(projectName); } else if (!serverProjects.contains(projectName)) serverProjects.add(projectName); IResourceDelta[] children = delta.getAffectedChildren(); int size = children.length; for (int i = 0; i < size; i++) { IResourceDelta child = children[i]; // look for servers and server configurations try { child.accept(new IResourceDeltaVisitor() { public boolean visit(IResourceDelta delta2) { return handleResourceDelta(delta2); } }); } catch (Exception e) { if (Trace.SEVERE) { Trace.trace(Trace.STRING_SEVERE, "Error responding to resource change", e); } } } } } /** * Cannot directly create a ResourceManager. Use * ServersCore.getResourceManager(). */ private ResourceManager() { super(); } /** * Execute the server startup extension points. */ private static synchronized void executeStartups() { if (Trace.EXTENSION_POINT) { Trace.trace(Trace.STRING_EXTENSION_POINT, "->- Loading .startup extension point ->-"); } IExtensionRegistry registry = Platform.getExtensionRegistry(); IConfigurationElement[] cf = registry.getConfigurationElementsFor(ServerPlugin.PLUGIN_ID, "internalStartup"); int size = cf.length; for (int i = 0; i < size; i++) { try { IStartup startup = (IStartup) cf[i].createExecutableExtension("class"); try { startup.startup(); } catch (Exception ex) { if (Trace.SEVERE) { Trace.trace(Trace.STRING_SEVERE, "Startup failed" + startup.toString(), ex); } } if (Trace.EXTENSION_POINT) { Trace.trace(Trace.STRING_EXTENSION_POINT, " Loaded startup: " + cf[i].getAttribute("id")); } } catch (Throwable t) { ServerPlugin.logExtensionFailure(cf[i].getAttribute("id"), t); } } if (Trace.EXTENSION_POINT) { Trace.trace(Trace.STRING_EXTENSION_POINT, "-<- Done loading .startup extension point -<-"); } } protected synchronized void init() { if (initialized || initializing) return; initializing = true; // see who's triggering API startup /*try { throw new NumberFormatException(); } catch (Exception e) { e.printStackTrace(); }*/ servers = new ArrayList<IServer>(); activeBundles = new ArrayList<String>(); loadRuntimesList(); loadServersList(); executeStartups(); pcl = new Preferences.IPropertyChangeListener() { public void propertyChange(Preferences.PropertyChangeEvent event) { if (ignorePreferenceChanges) return; String property = event.getProperty(); if (property.equals("runtimes")) { loadRuntimesList(); saveRuntimesList(); } } }; ServerPlugin.getInstance().getPluginPreferences().addPropertyChangeListener(pcl); resolveServers(); // keep track of future changes to the file system resourceChangeListener = new ServerResourceChangeListener(); ResourcesPlugin.getWorkspace().addResourceChangeListener(resourceChangeListener, IResourceChangeEvent.POST_BUILD | IResourceChangeEvent.PRE_CLOSE | IResourceChangeEvent.PRE_DELETE); if (Trace.FINER) { Trace.trace(Trace.STRING_FINER, "Loading workspace servers and server configurations"); } IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects(); if (projects != null) { int size = projects.length; for (int i = 0; i < size; i++) { if (ServerPlugin.getProjectProperties(projects[i]).isServerProject()) { String projectName = projects[i].getName(); if (!serverProjects.contains(projectName)) serverProjects.add(projectName); loadFromProject(projects[i]); } } } addServerLifecycleListener(ServerListener.getInstance()); initialized = true; } /** * Load all of the servers and server configurations from the given project. */ protected static void loadFromProject(IProject project) { if (Trace.FINER) { Trace.trace(Trace.STRING_FINER, "Initial server resource load for " + project.getName(), null); } final ResourceManager rm = ResourceManager.getInstance(); try { project.accept(new IResourceProxyVisitor() { public boolean visit(IResourceProxy proxy) { if (proxy.getType() == IResource.FILE && Server.FILE_EXTENSION.equals(getFileExtension(proxy.getName()))) { IFile file = (IFile) proxy.requestResource(); try { rm.handleNewFile(file, null); } catch (Exception e) { if (Trace.SEVERE) { Trace.trace(Trace.STRING_SEVERE, "Error during initial server resource load", e); } } return false; } return true; } }, 0); } catch (Exception e) { if (Trace.SEVERE) { Trace.trace(Trace.STRING_SEVERE, "Could not load server project " + project.getName(), e); } } } protected static String getFileExtension(String name) { int index = name.lastIndexOf('.'); if (index == -1) return null; if (index == (name.length() - 1)) return ""; //$NON-NLS-1$ return name.substring(index + 1); } public static ResourceManager getInstance() { return instance; } public static void shutdown() { if (instance == null) return; try { instance.shutdownImpl(); } catch (Exception e) { if (Trace.SEVERE) { Trace.trace(Trace.STRING_SEVERE, "Error during shutdown", e); } } } protected boolean isActiveBundle(String bundleId) { if (activeBundles == null) return false; return activeBundles.contains(bundleId); } protected void shutdownBundle(String id) { if (!initialized) return; // dispose servers Iterator iterator = servers.iterator(); while (iterator.hasNext()) { Server server = (Server) iterator.next(); try { ServerType serverType = (ServerType) server.getServerType(); if (serverType != null && id.equals(serverType.getNamespace())) { //server.stop(true); server.dispose(); } } catch (Exception e) { if (Trace.WARNING) { Trace.trace(Trace.STRING_WARNING, "Error disposing server", e); } } } // dispose runtimes iterator = runtimes.iterator(); while (iterator.hasNext()) { Runtime runtime = (Runtime) iterator.next(); try { RuntimeType runtimeType = (RuntimeType) runtime.getRuntimeType(); if (runtimeType != null && id != null && id.equals(runtimeType.getNamespace())) { runtime.dispose(); } } catch (Exception e) { if (Trace.WARNING) { Trace.trace(Trace.STRING_WARNING, "Error disposing server", e); } } } try { Thread.sleep(1000); } catch (Exception e) { // ignore } } protected void shutdownImpl() { if(!initialized) { return; } IWorkspace workspace = ResourcesPlugin.getWorkspace(); if (workspace != null && resourceChangeListener != null) { workspace.removeResourceChangeListener(resourceChangeListener); } if (pcl != null) { ServerPlugin.getInstance().getPluginPreferences().removePropertyChangeListener(pcl); } removeServerLifecycleListener(ServerListener.getInstance()); } /* * */ public void addRuntimeLifecycleListener(IRuntimeLifecycleListener listener) { if (Trace.LISTENERS) { Trace.trace(Trace.STRING_LISTENERS, "Adding runtime lifecycle listener " + listener + " to " + this); } synchronized (runtimeListeners) { runtimeListeners.add(listener); } } /* * */ public void removeRuntimeLifecycleListener(IRuntimeLifecycleListener listener) { if (Trace.LISTENERS) { Trace.trace(Trace.STRING_LISTENERS, "Removing runtime lifecycle listener " + listener + " from " + this); } synchronized (runtimeListeners) { runtimeListeners.remove(listener); } } /* * */ public void addServerLifecycleListener(IServerLifecycleListener listener) { if (Trace.LISTENERS) { Trace.trace(Trace.STRING_LISTENERS, "Adding server lifecycle listener " + listener + " to " + this); } synchronized (serverListeners) { serverListeners.add(listener); } } /* * */ public void removeServerLifecycleListener(IServerLifecycleListener listener) { if (Trace.LISTENERS) { Trace.trace(Trace.STRING_LISTENERS, "Removing server lifecycle listener " + listener + " from " + this); } synchronized (serverListeners) { serverListeners.remove(listener); } } /** * Deregister an existing runtime. * * @param runtime */ private void deregisterRuntime(IRuntime runtime) { if (runtime == null) return; if (Trace.RESOURCES) { Trace.trace(Trace.STRING_RESOURCES, "Deregistering runtime: " + runtime.getName()); } runtimes.remove(runtime); fireRuntimeEvent(runtime, EVENT_REMOVED); ((Runtime)runtime).dispose(); } /** * Deregister an existing server resource. * * @param server */ private void deregisterServer(IServer server) { if (server == null) return; if (Trace.RESOURCES) { Trace.trace(Trace.STRING_RESOURCES, "Deregistering server: " + server.getName()); } ((Server) server).deleteMetadata(); servers.remove(server); fireServerEvent(server, EVENT_REMOVED); ((Server)server).dispose(); } /** * Fire a runtime event. */ private void fireRuntimeEvent(final IRuntime runtime, byte b) { if (Trace.LISTENERS) { Trace.trace(Trace.STRING_LISTENERS, "->- Firing runtime event: " + runtime.getName() + " ->-"); } if (runtimeListeners.isEmpty()) return; List<IRuntimeLifecycleListener> clone = new ArrayList<IRuntimeLifecycleListener>(); clone.addAll(runtimeListeners); for (IRuntimeLifecycleListener srl : clone) { if (Trace.LISTENERS) { Trace.trace(Trace.STRING_LISTENERS, " Firing runtime event to " + srl); } try { if (b == EVENT_ADDED) srl.runtimeAdded(runtime); else if (b == EVENT_CHANGED) srl.runtimeChanged(runtime); else srl.runtimeRemoved(runtime); } catch (Exception e) { if (Trace.SEVERE) { Trace.trace(Trace.STRING_SEVERE, " Error firing runtime event to " + srl, e); } } } if (Trace.LISTENERS) { Trace.trace(Trace.STRING_LISTENERS, "-<- Done firing runtime event -<-"); } } /** * Fire a server event. */ private void fireServerEvent(final IServer server, byte b) { if (Trace.LISTENERS) { Trace.trace(Trace.STRING_LISTENERS, "->- Firing server event: " + server.getName() + " ->-"); } if (serverListeners.isEmpty()) return; List<IServerLifecycleListener> clone = new ArrayList<IServerLifecycleListener>(); clone.addAll(serverListeners); for (IServerLifecycleListener srl : clone) { if (Trace.LISTENERS) { Trace.trace(Trace.STRING_LISTENERS, " Firing server event to " + srl); } try { if (b == EVENT_ADDED) srl.serverAdded(server); else if (b == EVENT_CHANGED) srl.serverChanged(server); else srl.serverRemoved(server); } catch (Exception e) { if (Trace.SEVERE) { Trace.trace(Trace.STRING_SEVERE, " Error firing server event to " + srl, e); } } } if (Trace.LISTENERS) { Trace.trace(Trace.STRING_LISTENERS, "-<- Done firing server event -<-"); } } protected void saveRuntimesList() { try { ignorePreferenceChanges = true; XMLMemento memento = XMLMemento.createWriteRoot("runtimes"); Iterator iterator = runtimes.iterator(); while (iterator.hasNext()) { Runtime runtime = (Runtime) iterator.next(); IMemento child = memento.createChild("runtime"); runtime.save(child); } String xmlString = memento.saveToString(); Preferences prefs = ServerPlugin.getInstance().getPluginPreferences(); prefs.setValue("runtimes", xmlString); ServerPlugin.getInstance().savePluginPreferences(); } catch (Exception e) { if (Trace.SEVERE) { Trace.trace(Trace.STRING_SEVERE, "Could not save runtimes", e); } } ignorePreferenceChanges = false; } private void saveServersList() { String filename = ServerPlugin.getInstance().getStateLocation().append(SERVER_DATA_FILE).toOSString(); try { XMLMemento memento = XMLMemento.createWriteRoot("servers"); Iterator iterator = servers.iterator(); while (iterator.hasNext()) { Server server = (Server) iterator.next(); if (server.getFile() == null) { IMemento child = memento.createChild("server"); server.save(child); } } memento.saveToFile(filename); } catch (Exception e) { if (Trace.SEVERE) { Trace.trace(Trace.STRING_SEVERE, "Could not save servers", e); } } } protected void loadRuntimesList() { if (Trace.FINEST) { Trace.trace(Trace.STRING_FINEST, "Loading runtime info"); } Preferences prefs = ServerPlugin.getInstance().getPluginPreferences(); String xmlString = prefs.getString("runtimes"); runtimes = new ArrayList<IRuntime>(); if (xmlString != null && xmlString.length() > 0) { try { ByteArrayInputStream in = new ByteArrayInputStream(xmlString.getBytes("UTF-8")); IMemento memento = XMLMemento.loadMemento(in); IMemento[] children = memento.getChildren("runtime"); int size = children.length; for (int i = 0; i < size; i++) { Runtime runtime = new Runtime(null); runtime.loadFromMemento(children[i], null); runtimes.add(runtime); } } catch (Exception e) { if (Trace.WARNING) { Trace.trace(Trace.STRING_WARNING, "Could not load runtimes", e); } } } } protected void loadServersList() { if (Trace.FINEST) { Trace.trace(Trace.STRING_FINEST, "Loading server info"); } String filename = ServerPlugin.getInstance().getStateLocation().append(SERVER_DATA_FILE).toOSString(); try { IMemento memento = XMLMemento.loadMemento(filename); IMemento[] children = memento.getChildren("server"); int size = children.length; for (int i = 0; i < size; i++) { Server server = new Server(null); server.loadFromMemento(children[i], null); servers.add(server); } } catch (Exception e) { if (Trace.WARNING) { Trace.trace(Trace.STRING_WARNING, "Could not load servers", e); } } } protected void addRuntime(IRuntime runtime) { if (runtime == null) return; if (!initialized) init(); if (!runtimes.contains(runtime)) registerRuntime(runtime); else fireRuntimeEvent(runtime, EVENT_CHANGED); saveRuntimesList(); resolveServers(); } protected void removeRuntime(IRuntime runtime) { if (!initialized) init(); if (runtimes.contains(runtime)) { deregisterRuntime(runtime); saveRuntimesList(); resolveServers(); } } protected void addServer(IServer server) { if (server == null) return; if (!initialized) init(); if (!servers.contains(server)) registerServer(server); else fireServerEvent(server, EVENT_CHANGED); saveServersList(); resolveServers(); } protected void removeServer(IServer server) { if (!initialized) init(); if (servers.contains(server)) { deregisterServer(server); saveServersList(); resolveServers(); } } /** * Returns an array of all runtimes. * * @return an array of runtimes */ public IRuntime[] getRuntimes() { if (!initialized) init(); List<IRuntime> list = new ArrayList<IRuntime>(runtimes); IRuntime[] r = new IRuntime[list.size()]; list.toArray(r); return r; } /** * Returns the runtime with the given id. * * @param id a runtime id * @return IRuntime */ public IRuntime getRuntime(String id) { if (id == null) throw new IllegalArgumentException(); if (!initialized) init(); Iterator iterator = runtimes.iterator(); while (iterator.hasNext()) { IRuntime runtime = (IRuntime) iterator.next(); if (runtime.getId().equals(id)) return runtime; } return null; } public void resolveRuntimes() { if (!initialized) init(); Iterator iterator = runtimes.iterator(); while (iterator.hasNext()) { Runtime runtime = (Runtime) iterator.next(); runtime.resolve(); } } public void resolveServers() { if (!initialized) init(); Iterator iterator = servers.iterator(); while (iterator.hasNext()) { Server server = (Server) iterator.next(); server.resolve(); } } /** * Returns an array containing all servers. * * @return an array containing all servers */ public IServer[] getServers() { if (!initialized) init(); IServer[] servers2 = new IServer[servers.size()]; servers.toArray(servers2); return servers2; } /** * Returns the server with the given id. * * @param id a server id * @return a server */ public IServer getServer(String id) { if (!initialized) init(); if (id == null) throw new IllegalArgumentException(); Iterator iterator = servers.iterator(); while (iterator.hasNext()) { Server server = (Server) iterator.next(); if (id.equals(server.getId())) return server; } return null; } /** * Returns true if the resource change was handled. * * @param delta org.eclipse.core.resources.IResourceDelta * @return boolean */ protected boolean handleResourceDelta(IResourceDelta delta) { int kind = delta.getKind(); int flags = delta.getFlags(); IResource resource2 = delta.getResource(); // ignore markers if (kind == IResourceDelta.CHANGED && (flags & IResourceDelta.MARKERS) != 0) return false; if (Trace.RESOURCES) { Trace.trace(Trace.STRING_RESOURCES, "Resource changed: " + resource2 + " " + kind); } if (resource2 instanceof IFile) { IFile file = (IFile) resource2; if (Server.FILE_EXTENSION.equals(file.getFileExtension())) { IProgressMonitor monitor = null; if ((flags & IResourceDelta.MOVED_FROM) != 0 || (flags & IResourceDelta.MOVED_TO) != 0) handleMovedFile(file, delta, monitor); else if (kind == IResourceDelta.ADDED) handleNewFile(file, monitor); else if (kind == IResourceDelta.REMOVED) handleRemovedFile(file); else handleChangedFile(file, monitor); } return false; } IFolder folder = (IFolder) resource2; Iterator iterator = servers.iterator(); while (iterator.hasNext()) { IServer server = (IServer) iterator.next(); if (server.getServerType() != null && server.getServerType().hasServerConfiguration() && folder.equals(server.getServerConfiguration()) && server.getAdapter(ServerDelegate.class) != null) { try { ((Server)server).getDelegate(null).configurationChanged(); } catch (Exception e) { if (Trace.WARNING) { Trace.trace(Trace.STRING_WARNING, "Server failed on configuration change"); } } } } return true; } protected IServer loadServer(IFile file, IProgressMonitor monitor) throws CoreException { Server server = new Server(file); server.loadFromFile(monitor); return server; } /** * Tries to load a new server resource from the given resource. * Returns true if the load and register were successful. * * @param file * @param monitor * @return boolean */ protected boolean handleNewFile(IFile file, IProgressMonitor monitor) { if (Trace.RESOURCES) { Trace.trace(Trace.STRING_RESOURCES, "handleNewFile: " + file); } monitor = ProgressUtil.getMonitorFor(monitor); monitor.beginTask("", 2000); // try loading a server if (file.getFileExtension().equals(Server.FILE_EXTENSION)) { try { IServer server = loadServer(file, ProgressUtil.getSubMonitorFor(monitor, 1000)); if (server != null) { if (getServer(server.getId()) == null) addServer(server); monitor.done(); return true; } } catch (Exception e) { if (Trace.SEVERE) { Trace.trace(Trace.STRING_SEVERE, "Error loading server", e); } } } monitor.done(); return false; } /** * Tries to load a new server resource from the given resource. * Returns true if the load and register were successful. * * @param file * @param monitor * @return boolean */ private boolean handleMovedFile(IFile file, IResourceDelta delta, IProgressMonitor monitor) { if (Trace.RESOURCES) { Trace.trace(Trace.STRING_RESOURCES, "handleMovedFile: " + file); } monitor = ProgressUtil.getMonitorFor(monitor); monitor.beginTask("", 2000); IPath fromPath = delta.getMovedFromPath(); if (fromPath != null) { IFile fromFile = ResourcesPlugin.getWorkspace().getRoot().getFile(fromPath); if (ServerPlugin.getProjectProperties(fromFile.getProject()).isServerProject()) { Server server = (Server) findServer(fromFile); if (server != null) server.file = file; } else { handleNewFile(file, monitor); } } else { IPath toPath = delta.getMovedToPath(); IFile toFile = ResourcesPlugin.getWorkspace().getRoot().getFile(toPath); if (ServerPlugin.getProjectProperties(toFile.getProject()).isServerProject()) { Server server = (Server) findServer(file); if (server != null) server.file = toFile; } else { handleRemovedFile(file); } } monitor.done(); return false; } /** * Returns the server that came from the given file, or <code>null</code> * if none. This convenience method searches the list of known * servers ({@link #getServers()}) for the one with a matching * location ({@link Server#getFile()}). The file may not be null. * * @param file a server file * @return the server instance, or <code>null</code> if * there is no server associated with the given file */ public static IServer findServer(IFile file) { if (file == null) throw new IllegalArgumentException(); IServer[] servers = ServerCore.getServers(); if (servers != null) { int size = servers.length; for (int i = 0; i < size; i++) { if (file.equals(((Server)servers[i]).getFile())) return servers[i]; } } return null; } /** * Tries to handle a resource change. Returns true if the reload * was successful. * * @param file a file * @param monitor * @return boolean */ private boolean handleChangedFile(IFile file, IProgressMonitor monitor) { if (Trace.RESOURCES) { Trace.trace(Trace.STRING_RESOURCES, "handleChangedFile: " + file); } monitor = ProgressUtil.getMonitorFor(monitor); monitor.beginTask("", 1000); boolean found = false; IServer server = findServer(file); if (server != null) { found = true; try { if (Trace.RESOURCES) { Trace.trace(Trace.STRING_RESOURCES, "Reloading server: " + server); } ((Server) server).loadFromFile(monitor); fireServerEvent(server, EVENT_CHANGED); } catch (Exception e) { if (Trace.SEVERE) { Trace.trace(Trace.STRING_SEVERE, "Error reloading server " + server.getName() + " from " + file, e); } removeServer(server); } } else if (Trace.RESOURCES) { Trace.trace(Trace.STRING_RESOURCES, "No server found at: " + file); } monitor.done(); return found; } /** * Tries to remove a current resource. Returns true if the * deregistering was successful. * * @param file a file * @return boolean */ private boolean handleRemovedFile(IFile file) { if (Trace.RESOURCES) { Trace.trace(Trace.STRING_RESOURCES, "handleRemovedFile: " + file); } IServer server = findServer(file); if (server != null) { removeServer(server); return true; } if (Trace.RESOURCES) { Trace.trace(Trace.STRING_RESOURCES, "No server found at: " + file); } return false; } /** * A project has changed. If this is an add or remove, check * to see if it is part of a current server configuration. * * @param delta org.eclipse.core.resources.IResourceDelta */ protected void publishHandleProjectChange(IResourceDelta delta) { publishHandleProjectChange(delta, null); } /** * A project has changed. If this is an add or remove, check * to see if it is part of a current server configuration. * * @param delta org.eclipse.core.resources.IResourceDelta * @param buildEvent whether this event was a build event */ protected void publishHandleProjectChange(IResourceDelta delta, IResourceChangeEvent event) { if (Trace.FINEST) { Trace.trace(Trace.STRING_FINEST, "> publishHandleProjectChange " + delta.getResource()); } IProject project = (IProject) delta.getResource(); if (project == null) return; IServer[] servers2 = getPublishRequiredServers(delta); // process module changes ProjectModuleFactoryDelegate.handleGlobalProjectChange(project, delta); IModule[] modules = ServerUtil.getModules(project); if (modules == null) return; if (Trace.FINEST) { Trace.trace(Trace.STRING_FINEST, "- publishHandleProjectChange"); } int size = modules.length; int size2 = servers2.length; for (int i = 0; i < size; i++) { for (int j = 0; j < size2; j++) { if (servers2[j].getAdapter(ServerDelegate.class) != null) ((Server) servers2[j]).handleModuleProjectChange(modules[i], event); } } if (Trace.FINEST) { Trace.trace(Trace.STRING_FINEST, "< publishHandleProjectChange"); } } private IServer[] getPublishRequiredServers(IResourceDelta delta){ // The list of servers that will require publish final List<IServer> servers2 = new ArrayList<IServer>(); // wrksServers = Workspaces Servers final IServer[] wrksServers = getServers(); try { delta.accept(new IResourceDeltaVisitor() { public boolean visit(IResourceDelta delta2) throws CoreException { // servers2 is the same size as the list of servers in the workspace, all servers require // publishing. Exit the visitor if (servers2.size() == wrksServers.length) return false; // has this deltaResource been changed? if (delta2.getKind() == IResourceDelta.NO_CHANGE) return false; if (delta2.getResource() instanceof IFile) { if (delta2.getKind() == IResourceDelta.CHANGED && (delta2.getFlags() & IResourceDelta.CONTENT) == 0 && (delta2.getFlags() & IResourceDelta.REPLACED) == 0 && (delta2.getFlags() & IResourceDelta.SYNC) == 0){ // this resource is effectively a no change return true; } // This is a changed file. // Iterate through all servers for each changed resource, if the server needs publishing // for one single resource and the server is not on the list(servers2) then add it, as it // will require publishing for (IServer server:wrksServers){ if (ServerCore.isPublishRequired(server,delta2)){ if (!servers2.contains(server)) servers2.add(server); } } return false; } // This is a changed folder, so visit the child elements. return true; } }); } catch (Exception e) { // ignore } //Trace.trace(Trace.FINEST, "Delta contains change: " + t.b); return servers2.toArray(new IServer[0]); } /** * Returns <code>true</code> if at least one file in the delta is changed, * and <code>false</code> otherwise. * * @param delta a resource delta * @return <code>true</code> if at least one file in the delta is changed, * and <code>false</code> otherwise */ public static boolean deltaContainsChangedFiles(IResourceDelta delta) { final boolean[] b = new boolean[1]; try { delta.accept(new IResourceDeltaVisitor() { public boolean visit(IResourceDelta delta2) throws CoreException { if (b[0]) return false; //Trace.trace(Trace.FINEST, delta2.getResource() + " " + delta2.getKind() + " " + delta2.getFlags()); if (delta2.getKind() == IResourceDelta.NO_CHANGE) return false; if (delta2.getResource() instanceof IFile) { if (delta2.getKind() == IResourceDelta.CHANGED && (delta2.getFlags() & IResourceDelta.CONTENT) == 0 && (delta2.getFlags() & IResourceDelta.REPLACED) == 0 && (delta2.getFlags() & IResourceDelta.SYNC) == 0) return true; //if (delta2.getKind() == IResourceDelta.CHANGED) { // && delta2.getAffectedChildren().length == 0) { b[0] = true; return false; //return true; //} } return true; } }); } catch (Exception e) { // ignore } //Trace.trace(Trace.FINEST, "Delta contains change: " + t.b); return b[0]; } /** * Registers a new runtime. * * @param runtime a runtime */ private void registerRuntime(IRuntime runtime) { if (runtime == null) return; if (Trace.RESOURCES) { Trace.trace(Trace.STRING_RESOURCES, "Registering runtime: " + runtime.getName()); } runtimes.add(runtime); fireRuntimeEvent(runtime, EVENT_ADDED); RuntimeType runtimeType = (RuntimeType) runtime.getRuntimeType(); String bundleId = runtimeType.getNamespace(); if (activeBundles != null && !activeBundles.contains(bundleId)) activeBundles.add(bundleId); } /** * Registers a new server. * * @param server a server */ private void registerServer(IServer server) { if (server == null) return; if (Trace.RESOURCES) { Trace.trace(Trace.STRING_RESOURCES, "Registering server: " + server.getName()); } servers.add(server); fireServerEvent(server, EVENT_ADDED); ServerType serverType = (ServerType) server.getServerType(); if (serverType != null) { String bundleId = serverType.getNamespace(); if (activeBundles != null && !activeBundles.contains(bundleId)) activeBundles.add(bundleId); } } public String toString() { return "Server resource manager"; } }