/******************************************************************************* * 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.seam.pages.xml.model.helpers; import java.util.*; import org.jboss.tools.common.model.*; import org.jboss.tools.common.model.event.*; import org.jboss.tools.seam.pages.xml.SeamPagesXMLPlugin; import org.jboss.tools.seam.pages.xml.model.SeamPagesConstants; import org.jboss.tools.seam.pages.xml.model.impl.SeamPagesDiagramImpl; public class SeamPagesPageRefUpdateManager implements XModelTreeListener, Runnable, SeamPagesConstants { public static SeamPagesPageRefUpdateManager getInstance(XModel model) { SeamPagesPageRefUpdateManager instance = (SeamPagesPageRefUpdateManager)model.getManager("SeamPagesPageRefUpdateManager"); if(instance == null) { instance = new SeamPagesPageRefUpdateManager(); instance.model = model; instance.init(); model.addManager("SeamPagesPageRefUpdateManager", instance); model.addModelTreeListener(instance); } return instance; } private static long id = 0; private XModel model; private Map<String,PageLinks> pages = new HashMap<String,PageLinks>(); private int lock = 0; protected boolean stopped = false; PageUpdateRunnable runnable = new PageUpdateRunnable(); public SeamPagesPageRefUpdateManager() {} private void init() { } public void updatePage(SeamPagesDiagramHelper h, XModelObject page) { PageLinks pl = getPageLinks(page); if(pl == null) return; pl.h = h; pl.update(); } PageLinks getPageLinks(XModelObject page) { String pid = page.get("_page_id"); if(pid == null) { pid = "" + (++id); page.set("_page_id", pid); } PageLinks pl = pages.get(pid); if(pl == null) { pl = new PageLinks(); pl.setPage(page); pages.put(pid, pl); } return pl; } public void updateAll() { if(isLocked()) return; lock(); try { String[] ks = pages.keySet().toArray(new String[0]); for (int i = 0; i < ks.length; i++) { PageLinks pl = pages.get(ks[i]); if(pl == null) continue; if(!pl.page.isActive()) { pages.remove(ks[i]); } else { pl.update(); } } } finally { unlock(); } } public boolean isLocked() { return lock > 0; } public void lock() { lock++; } public void unlock() { lock--; } public void structureChanged(XModelTreeEvent event) { XModel model = event.getModelObject().getModel(); if (event.kind() == XModelTreeEvent.STRUCTURE_CHANGED && event.getModelObject() == model.getRoot()) { model.removeModelTreeListener(this); SeamPagesPageRefUpdateManager instance = (SeamPagesPageRefUpdateManager)model.getManager("JSFPageUpdateManager"); if(instance != null) { instance.stopped = true; model.removeManager("JSFPageUpdateManager"); } return; } else if(event.kind() == XModelTreeEvent.CHILD_ADDED) { onChildAdded(event); } if(isLocked()) return; XJob.addRunnable(runnable); } private void onChildAdded(XModelTreeEvent event) { XModelObject c = (XModelObject)event.getInfo(); if(!c.getModelEntity().getName().equals(SeamPagesConstants.ENT_DIAGRAM_ITEM)) return; SeamPagesDiagramImpl pi = (SeamPagesDiagramImpl)event.getModelObject(); PageLinks pl = getPageLinks(c); if(pl == null || pi.getHelper() == null) return; pl.h = pi.getHelper(); } public void nodeChanged(XModelTreeEvent event) { if(isLocked()) return; XJob.addRunnable(runnable); } public void run() { while(!stopped) { synchronized(this) { try { wait(); } catch (InterruptedException e) { //ignore } } try { Thread.sleep(250); } catch (InterruptedException e) { //ignore } if(stopped) break; if(!isLocked()) { updateAll(); } } } class PageUpdateRunnable implements XJob.XRunnable { public String getId() { return "Seam Pages Reference Update -" + XModelConstants.getWorkspace(model); } public void run() { if(!isLocked()) { updateAll(); } } } } class PageLinks implements SeamPagesConstants { SeamPagesDiagramHelper h; XModelObject page; XModelObject jsp; boolean confirmed = false; long jspTimeStamp; long pageTimeStamp; public void setPage(XModelObject page) { this.page = page; } public void update() { if(page.getParent() == null) return; // boolean modified = (pageTimeStamp != page.getTimeStamp()); pageTimeStamp = page.getTimeStamp(); String path = page.getAttributeValue(ATTR_PATH); if(path == null) { jsp = null; setConfirmed(false); jspTimeStamp = -1; return; } boolean isPattern = SeamPagesDiagramStructureHelper.instance.isPattern(page); if(path.indexOf('?') >= 0) { path = path.substring(0, path.indexOf('?')); } XModelObject jsp1 = (isPattern) ? null : page.getModel().getByPath(path); if(jsp == null || !jsp.isActive() || jsp != jsp1) { jsp = jsp1; setConfirmed(jsp != null); jspTimeStamp = -1; } } private void setConfirmed(boolean b) { confirmed = b; if(confirmed == ("true".equals(page.get("confirmed")))) return; page.setAttributeValue("confirmed", "" + confirmed); } }