001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */
004: package org.terracotta.dso;
005:
006: import org.eclipse.core.resources.IFile;
007: import org.eclipse.core.resources.IProject;
008: import org.eclipse.core.resources.IResource;
009: import org.eclipse.core.resources.IResourceDelta;
010: import org.eclipse.core.resources.IResourceDeltaVisitor;
011: import org.eclipse.core.runtime.CoreException;
012: import org.eclipse.core.runtime.IPath;
013: import org.eclipse.core.runtime.IProgressMonitor;
014: import org.eclipse.core.runtime.IStatus;
015: import org.eclipse.core.runtime.NullProgressMonitor;
016: import org.eclipse.core.runtime.Status;
017: import org.eclipse.core.runtime.jobs.Job;
018: import org.eclipse.debug.core.DebugException;
019: import org.eclipse.debug.core.DebugPlugin;
020: import org.eclipse.debug.core.ILaunch;
021: import org.eclipse.debug.core.ILaunchConfiguration;
022: import org.eclipse.debug.core.ILaunchConfigurationType;
023: import org.eclipse.debug.core.ILaunchManager;
024: import org.eclipse.jdt.core.JavaCore;
025: import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
026: import org.eclipse.swt.widgets.Display;
027: import org.eclipse.swt.widgets.Shell;
028: import org.terracotta.dso.actions.ManageServerAction;
029: import org.terracotta.dso.dialogs.RelaunchDialog;
030:
031: import com.tc.server.ServerConstants;
032: import com.tc.util.Assert;
033:
034: import java.util.ArrayList;
035: import java.util.HashMap;
036: import java.util.Iterator;
037: import java.util.List;
038: import java.util.Map;
039:
040: /**
041: * Invoked when a project resource change occurs. First test to see if
042: * the config file content changed and, if so, clear the config session
043: * information. Next check if a module has been compiled and, if so, inspect
044: * the module for terracotta artifacts.
045: *
046: * @see org.eclipse.core.resources.IResourceDeltaVisitor
047: * @see org.eclipse.ui.IWorkbench.addResourceChangeListener
048: * @see TcPlugin.ResourceListener
049: */
050:
051: public class ResourceDeltaVisitor implements IResourceDeltaVisitor {
052: private static final boolean debug = Boolean
053: .getBoolean("ResourceDeltaVisitor.debug");
054:
055: boolean fIgnoreNextConfigChange;
056:
057: public boolean visit(IResourceDelta delta) {
058: final TcPlugin plugin = TcPlugin.getDefault();
059: int kind = delta.getKind();
060: int flags = delta.getFlags();
061: IResource res = delta.getResource();
062: final IProject project = res.getProject();
063:
064: if (debug) {
065: dump(delta);
066: }
067:
068: if (plugin == null || !plugin.hasTerracottaNature(project)) {
069: return true;
070: }
071:
072: switch (kind) {
073: case IResourceDelta.CHANGED: {
074: if ((flags & IResourceDelta.CONTENT) != 0) {
075: if (res instanceof IFile) {
076: IFile file = (IFile) res;
077: IPath path = file.getLocation();
078: String ext = path.getFileExtension();
079:
080: if (ext.equals("xml")) {
081: // if((flags & IResourceDelta.MARKERS) != 0) {
082: // return false;
083: // }
084: if (plugin.getConfigurationFile(project)
085: .equals(res)) {
086: final boolean queryRestart = plugin
087: .getQueryRestartOption(project);
088: final boolean wasIgnoringChange = fIgnoreNextConfigChange;
089: if (fIgnoreNextConfigChange) {
090: fIgnoreNextConfigChange = false;
091: }
092: try {
093: if (!wasIgnoringChange) {
094: Job job = new Job(
095: "Reloading DSO Configuration") {
096: public IStatus run(
097: IProgressMonitor monitor) {
098: plugin
099: .reloadConfiguration(project);
100: if (queryRestart) {
101: queryRelaunchAll(project);
102: }
103: return Status.OK_STATUS;
104: }
105: };
106: job.schedule();
107: } else if (queryRestart) {
108: Job job = new Job("Restart?") {
109: public IStatus run(
110: IProgressMonitor monitor) {
111: queryRelaunchAll(project);
112: return Status.OK_STATUS;
113: }
114: };
115: job.schedule();
116: }
117: } catch (Exception e) {
118: e.printStackTrace();
119: }
120: return false;
121: }
122: }
123: }
124: }
125: break;
126: }
127: case IResourceDelta.ADDED: {
128: if ((flags & IResourceDelta.MOVED_FROM) != 0) {
129: if (res instanceof IFile) {
130: plugin.fileMoved((IFile) res, delta
131: .getMovedFromPath());
132: }
133: } else if (res instanceof IProject) {
134: IProject aProject = (IProject) res;
135:
136: if (plugin.getConfigurationFile(aProject) == null) {
137: plugin.staleProjectAdded(aProject);
138: }
139: }
140: break;
141: }
142: case IResourceDelta.REMOVED: {
143: if ((flags & IResourceDelta.MOVED_TO) == 0) {
144: if (res instanceof IFile) {
145: plugin.fileRemoved((IFile) res);
146: }
147: }
148: break;
149: }
150: }
151:
152: return true;
153: }
154:
155: private void queryRelaunchAll(final IProject project) {
156: ILaunchManager launchManager = DebugPlugin.getDefault()
157: .getLaunchManager();
158: final List<ILaunch> launches = new ArrayList<ILaunch>();
159: final Map<String, ILaunch> serverLaunches = new HashMap<String, ILaunch>();
160:
161: for (ILaunch launch : launchManager.getLaunches()) {
162: if (launch.isTerminated())
163: continue;
164: ILaunchConfiguration launchConfig = launch
165: .getLaunchConfiguration();
166: try {
167: String mainClass = launchConfig
168: .getAttribute(
169: IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME,
170: (String) null);
171: if (mainClass != null
172: && mainClass
173: .equals(ServerConstants.SERVER_MAIN_CLASS_NAME)) {
174: String serverLaunchName = launchConfig.getName();
175: String[] launchNameElems = decomposeServerLaunchName(serverLaunchName);
176: String projName = launchNameElems[0];
177: String serverName = launchNameElems[1];
178: if (projName.equals(project.getName())) {
179: serverLaunches.put(serverName, launch);
180: }
181: } else {
182: ILaunchConfigurationType launchConfigType = launchConfig
183: .getType();
184: String id = launchConfigType.getIdentifier();
185: if (id.equals("launch.configurationDelegate")) {
186: String projName = launchConfig
187: .getAttribute(
188: IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME,
189: (String) null);
190: if (projName != null
191: && projName.equals(project.getName())) {
192: launches.add(launch);
193: }
194: }
195: }
196: } catch (CoreException ce) {/**/
197: }
198: }
199:
200: if (launches.size() > 0 || serverLaunches.size() > 0) {
201: Display display = Display.getDefault();
202: display.syncExec(new Runnable() {
203: public void run() {
204: Shell shell = Display.getCurrent().getActiveShell();
205: RelaunchDialog relaunchDialog = new RelaunchDialog(
206: shell, project, serverLaunches, launches);
207: final int returnCode = relaunchDialog.open();
208: if (returnCode == RelaunchDialog.CONTINUE_ID) {
209: return;
210: }
211: new Job("Restarting Terracotta") {
212: public IStatus run(IProgressMonitor monitor) {
213: if (monitor == null) {
214: monitor = new NullProgressMonitor();
215: }
216:
217: ArrayList<ILaunch> allLaunches = new ArrayList<ILaunch>(
218: launches);
219: allLaunches.addAll(serverLaunches.values());
220: for (ILaunch launch : allLaunches) {
221: safeTerminateLaunch(launch);
222: }
223:
224: if (returnCode == RelaunchDialog.TERMINATE_ID) {
225: return Status.OK_STATUS;
226: }
227:
228: for (Iterator<String> iter = serverLaunches
229: .keySet().iterator(); iter
230: .hasNext();) {
231: try {
232: ManageServerAction msa = new ManageServerAction(
233: JavaCore.create(project),
234: iter.next());
235: msa.run(monitor);
236: } catch (Exception e) {
237: e.printStackTrace();
238: }
239: }
240: for (ILaunch launch : launches) {
241: ILaunchConfiguration launchConfig = launch
242: .getLaunchConfiguration();
243: try {
244: launchConfig.launch(launch
245: .getLaunchMode(), monitor);
246: } catch (CoreException ce) {
247: ce.printStackTrace();
248: }
249: }
250: return Status.OK_STATUS;
251: }
252: }.schedule();
253: }
254: });
255: }
256: }
257:
258: /*
259: * Terracotta server launch configuration names are of the form projectName.serverName.
260: * result[0] -> projectName
261: * result[1] -> serverName
262: */
263: private static String[] decomposeServerLaunchName(String launchName) {
264: Assert.assertNotNull("Server launch name is null", launchName);
265: int separator = launchName.indexOf('.');
266: Assert.assertTrue(
267: "Server launch name doesn't include dot separator",
268: separator != -1);
269: return new String[] { launchName.substring(0, separator),
270: launchName.substring(separator + 1) };
271: }
272:
273: private static void safeTerminateLaunch(ILaunch launch) {
274: try {
275: launch.terminate();
276: } catch (DebugException de) {
277: /**/
278: }
279: }
280:
281: private void dump(IResourceDelta delta) {
282: int kind = delta.getKind();
283: int flags = delta.getFlags();
284: StringBuffer sb = new StringBuffer();
285:
286: sb.append(delta.getResource().getFullPath());
287:
288: switch (kind) {
289: case IResourceDelta.NO_CHANGE:
290: sb.append(" NO_CHANGE");
291: break;
292: case IResourceDelta.ADDED:
293: sb.append(" ADDED");
294: break;
295: case IResourceDelta.REMOVED:
296: sb.append(" REMOVED");
297: break;
298: case IResourceDelta.CHANGED:
299: sb.append(" CHANGED");
300: break;
301: case IResourceDelta.ADDED_PHANTOM:
302: sb.append(" ADDED_PHANTOM");
303: break;
304: case IResourceDelta.REMOVED_PHANTOM:
305: sb.append(" REMOVED_PHANTOM");
306: break;
307: }
308:
309: if ((flags & IResourceDelta.CONTENT) != 0) {
310: sb.append(" CONTENT");
311: }
312: if ((flags & IResourceDelta.MOVED_FROM) != 0) {
313: sb.append(" MOVED_FROM");
314: }
315: if ((flags & IResourceDelta.MOVED_TO) != 0) {
316: sb.append(" MOVED_TO");
317: }
318: if ((flags & IResourceDelta.OPEN) != 0) {
319: sb.append(" OPEN");
320: }
321: if ((flags & IResourceDelta.TYPE) != 0) {
322: sb.append(" TYPE");
323: }
324: if ((flags & IResourceDelta.SYNC) != 0) {
325: sb.append(" SYNC");
326: }
327: if ((flags & IResourceDelta.MARKERS) != 0) {
328: sb.append(" MARKERS");
329: }
330: if ((flags & IResourceDelta.REPLACED) != 0) {
331: sb.append(" REPLACED");
332: }
333: if ((flags & IResourceDelta.DESCRIPTION) != 0) {
334: sb.append(" DESCRIPTION");
335: }
336: if ((flags & IResourceDelta.ENCODING) != 0) {
337: sb.append(" ENCODING");
338: }
339:
340: System.out.println(sb.toString());
341: }
342: }
|