/******************************************************************************* * Copyright (c) 2007 Exadel, Inc. and Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is 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: * Exadel, Inc. and Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.common.model.project; import java.util.*; import org.jboss.tools.common.model.markers.ResourceMarkers; import org.jboss.tools.common.model.*; import org.jboss.tools.common.model.event.*; import org.jboss.tools.common.model.filesystems.FileSystemsHelper; import org.jboss.tools.common.model.plugin.ModelPlugin; import org.jboss.tools.common.model.util.EclipseResourceUtil; import org.jboss.tools.common.model.util.ModelFeatureFactory; public class Watcher implements XModelTreeListener { public static Watcher getInstance(XModel model) { Watcher instance = (Watcher)model.getManager("Watcher"); //$NON-NLS-1$ if(instance == null) { instance = new Watcher(); instance.setModel(model); model.addManager("Watcher", instance); //$NON-NLS-1$ model.addModelTreeListener(instance); } return instance; } protected XModel model; protected Map<String,IWatcherContributor> contributors = new HashMap<String, IWatcherContributor>(); private boolean lock = false; class WatcherRunnable implements XJob.XRunnable { String id = "Watcher - " + XModelConstants.getWorkspace(model); //$NON-NLS-1$ public String getId() { return id; } public void run() { Watcher.this.updateAll(); } } private Watcher() { } void updateContributors() { if(model == null) return; ModelNatureExtension[] es = ModelNatureExtension.getInstances(); for (int i = 0; i < es.length; i++) { String nature = es[i].getName(); if(EclipseResourceUtil.hasNature(model, nature)) { if(contributors.containsKey(nature)) { continue; } else { String contributorName = es[i].getWatcherContributor(); Object watcher = ModelFeatureFactory.getInstance().createFeatureInstance(contributorName); if(watcher instanceof IWatcherContributor) { IWatcherContributor c = (IWatcherContributor)watcher; c.init(model); contributors.put(nature, c); } else if(ModelPlugin.isDebugEnabled()) { ModelPlugin.getPluginLog().logInfo("Class is not implemented IWatcherContributor interface!"); //$NON-NLS-1$ } } } else { contributors.remove(nature); } } } public void setModel(XModel model) { this.model = model; } public void forceUpdate() { if(model.getProperties().getProperty(IModelNature.ECLIPSE_PROJECT) == null) return; XJob.addRunnable(new WatcherRunnable()); } private void updateAll() { if(lock) return; lock(); updateContributors(); try { String err = null; for (IWatcherContributor c : contributors.values()) { if(!c.isActive()) continue; c.update(); if(err == null) { err = c.getError(); } } setError(err); setCorrect(err == null); for (IWatcherContributor c : contributors.values()) { if(!c.isActive()) continue; c.updateProject(); } } finally { unlock(); } } public void lock() { lock = true; } public void unlock() { lock = false; } public void structureChanged(XModelTreeEvent event) { XModel model = event.getModelObject().getModel(); if (event.kind() == XModelTreeEvent.STRUCTURE_CHANGED && event.getModelObject() == model.getRoot()) { model.removeModelTreeListener(this); /// stopped = true; model.removeManager("Watcher"); //$NON-NLS-1$ return; } forceUpdate(); } public void nodeChanged(XModelTreeEvent event) { forceUpdate(); } String error = "initial"; //$NON-NLS-1$ ResourceMarkers markers = null; class RM extends ResourceMarkers { public RM() { super(ResourceMarkers.JST_WEB_PROBLEM, ResourceMarkers.OLD_JST_WEB_PROBLEM); } protected String[] getErrors() { return (error == null) ? new String[0] : new String[]{error}; } } public void setError(String err) { if(markers == null) { markers = new RM(); markers.setModelObject(FileSystemsHelper.getFileSystems(model)); markers.clear(); } boolean changed = (error == null) ? (err != null) : !error.equals(err); if(changed) { error = err; markers.update(); } } private void setCorrect(boolean correct) { XModelObject fs = FileSystemsHelper.getFileSystems(model); if(fs == null) return; boolean b = !XModelObjectConstants.YES.equals(fs.get("_hasErrors_")); //$NON-NLS-1$ if(b == correct) return; fs.set("_hasErrors_", (correct) ? "" : XModelObjectConstants.YES); //$NON-NLS-1$ //$NON-NLS-2$ fs.fireObjectChanged("_hasErrors_"); //$NON-NLS-1$ } }