/*******************************************************************************
* 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.event;
import java.util.*;
import org.jboss.tools.common.model.*;
public class XModelChangeManager {
private ArrayList<OLBind> binds = new ArrayList<OLBind>();
public XModelChangeManager() {}
public synchronized void createListener(XModelObject object, XModelChangeListener listener) {
binds.add(new OLBind(object, listener));
}
public synchronized void removeListener(XModel model, String path, XModelChangeListener listener) {
XModelObject object = model.getByPath(path);
if(object == null) return;
OLBind bind = new OLBind(object, listener);
int l = binds.size();
for (int i = l - 1; i >= 0; i--) {
if(bind.equals((OLBind)binds.get(i))) binds.remove(i);
}
}
public synchronized void removeListener(XModelChangeListener listener) {
int l = binds.size();
for (int i = l - 1; i >= 0; i--) {
OLBind bind = (OLBind)binds.get(i);
if(listener == bind.listener) binds.remove(i);
}
}
public boolean canFire() {
int l = binds.size();
for (int i = l - 1; i >= 0; i--) {
OLBind bind = (OLBind)binds.get(i);
if(bind.canFire()) return true;
}
return false;
}
public synchronized void fire() {
int l = binds.size();
for (int i = l - 1; i >= 0; i--) {
OLBind bind = (OLBind)binds.get(i);
bind.fire();
if(bind.isDead()) binds.remove(i);
}
}
public List<OLBind> getBindList() {
return Collections.unmodifiableList(binds);
}
}
class OLBind {
private XModelObject object = null;
private String path = null;
XModelChangeListener listener = null;
private long timestamp = 0;
public OLBind(XModelObject object, XModelChangeListener listener) {
this.object = object;
path = object.getPath();
timestamp = object.getTimeStamp();
this.listener = listener;
}
public void fire() {
if(isDead()) return;
XModelObject o = object;
if(!object.isActive()) {
object = object.getModel().getByPath(path);
}
if(isDead()) {
listener.delete(o);
} else if(timestamp != object.getTimeStamp()) {
timestamp = object.getTimeStamp();
path = object.getPath();
listener.update(object);
}
}
public boolean isDead() {
return (object == null);
}
public boolean canFire() {
if(isDead()) return false;
return (!object.isActive() || timestamp != object.getTimeStamp());
}
public boolean equals(OLBind bind) {
return (object == bind.object && listener == bind.listener);
}
}