org.openl.ie.constrainer.impl.SubjectImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.openl.rules.constrainer Show documentation
Show all versions of org.openl.rules.constrainer Show documentation
OpenL Constraint Programming engine
package org.openl.ie.constrainer.impl;
import java.util.Collection;
import java.util.HashSet;
import org.openl.ie.constrainer.*;
import org.openl.ie.tools.FastVector;
import org.openl.ie.tools.Reusable;
import org.openl.ie.tools.ReusableFactory;
/**
* A generic implementation of the Subject interface.
*/
public abstract class SubjectImpl extends UndoableOnceImpl implements Subject {
/**
* Undo Class for attached Observers.
*/
static final class UndoAttachObserver extends UndoImpl {
static final ReusableFactory _factory = new ReusableFactory() {
@Override
protected Reusable createNewElement() {
return new UndoAttachObserver();
}
};
Observer _observer;
static UndoAttachObserver getUndo(Subject subject, Observer observer) {
UndoAttachObserver undo = (UndoAttachObserver) _factory.getElement();
undo.undoable(subject);
undo._observer = observer;
return undo;
}
/**
* Returns a String representation of this object.
*
* @return a String representation of this object.
*/
@Override
public String toString() {
return "UndoAttachObserver " + _observer;
}
@Override
public void undo() {
Subject subject = (Subject) undoable();
subject.forcedDetachObserver(_observer);
}
} // ~UndoAttachObserver
/**
* Undo Class for detach Observers.
*/
static final class UndoDetachObserver extends UndoImpl {
static final ReusableFactory _factory = new ReusableFactory() {
@Override
protected Reusable createNewElement() {
return new UndoDetachObserver();
}
};
private Observer _observer;
static UndoDetachObserver getUndo(Subject subject, Observer observer) {
UndoDetachObserver undo = (UndoDetachObserver) _factory.getElement();
undo.undoable(subject);
undo._observer = observer;
return undo;
}
/**
* Returns a String representation of this object.
*
* @return a String representation of this object.
*/
@Override
public String toString() {
return "UndoDetachObserver " + _observer;
}
@Override
public void undo() {
Subject subject = (Subject) undoable();
subject.forcedAttachObserver(_observer);
}
} // ~UndoDetachObserver
/**
* Undo Class for Subject.
*/
public static class UndoSubject extends UndoImpl {
static final ReusableFactory _factory = new ReusableFactory() {
@Override
protected Reusable createNewElement() {
return new UndoSubject();
}
};
private int _event_mask;
static UndoSubject getUndo() {
return (UndoSubject) _factory.getElement();
}
/**
* Returns a String representation of this object.
*
* @return a String representation of this object.
*/
@Override
public String toString() {
return "UndoSubject " + undoable() + ": mask=" + _event_mask;
}
@Override
public void undo() {
Subject subject = (Subject) undoable();
subject.forcePublisherMask(_event_mask);
super.undo();
}
@Override
public void undoable(Undoable u) {
super.undoable(u);
Subject subject = (Subject) u;
_event_mask = subject.publisherMask();
}
} // ~UndoSubject
protected final FastVector _observers;
protected boolean _in_process;
protected int _publisher_mask;
public SubjectImpl(Constrainer constrainer) {
this(constrainer, "");
}
public SubjectImpl(Constrainer constrainer, String name) {
super(constrainer, name);
if (constrainer.showVariableNames()) {
_name = name;
}
_observers = new FastVector(); // 10,5);
_in_process = false;
}
public void addToPropagationQueue() {
if (!_in_process) {
constrainer().addToPropagationQueue(this);
_in_process = true;
}
}
@Override
public Collection allDependents() {
HashSet dependendts = new HashSet();
for (int i = 0; i < _observers.size(); ++i) {
Observer obs = (Observer) _observers.elementAt(i);
Object master = obs.master();
if (master == null) {
continue;
}
if (dependendts.contains(master)) {
continue;
}
dependendts.add(master);
if (master instanceof Subject) {
dependendts.addAll(((Subject) master).allDependents());
}
}
return dependendts;
}
@Override
public void attachObserver(Observer observer) {
// Debug.on(); Debug.print(this + " Attach: " + observer); Debug.off();
_observers.addElement(observer);
publisherMask(_publisher_mask | observer.subscriberMask());
constrainer().addUndo(UndoAttachObserver.getUndo(this, observer));
}
@Override
public Undo createUndo() {
return UndoSubject.getUndo();
}
@Override
public void detachObserver(Observer observer) {
// Debug.on(); Debug.print(this + " Detach: " + observer); Debug.off();
_observers.removeElement(observer);
constrainer().addUndo(UndoDetachObserver.getUndo(this, observer));
}
@Override
public void forcedAttachObserver(Observer observer) {
// Debug.on(); Debug.print(this + " AttachForced: " + observer);
// Debug.off();
_observers.addElement(observer);
}
@Override
public void forcedDetachObserver(Observer observer) {
// Debug.on(); Debug.print(this + " DetachForced: " + observer);
// Debug.off();
_observers.removeElement(observer);
}
@Override
public void forcePublisherMask(int mask) {
_publisher_mask = mask;
}
@Override
public void inProcess(boolean flag) {
_in_process = flag;
}
@Override
final public void notifyObservers(EventOfInterest interest) throws Failure {
// Debug.on(); Debug.print("* "+interest); Debug.off();
// FastVector observers = (FastVector)_observers.clone();
FastVector observers = _observers;
_constrainer.incrementNumberOfNotifications();
int size = observers.size();
for (int i = 0; i < size; ++i) {
Observer observer = (Observer) observers.elementAt(i);
if (observer.interestedIn(interest)) {
// Debug.on(); Debug.print("Observer "+i+":
// "+observer);Debug.off();
observer.update(this, interest);
}
}
interest.free();
}
public void onMaskChange() {
}
@Override
public abstract void propagate() throws Failure;
@Override
public void publish(int mask) {
publisherMask(_publisher_mask | mask);
}
@Override
public int publisherMask() {
return _publisher_mask;
}
@Override
public void publisherMask(int mask) {
if (mask != _publisher_mask) {
// System.out.println("Pub Mask: " + mask + " for: " + this + "
// old:" + _publisher_mask);
_publisher_mask = mask;
onMaskChange();
addUndo();
}
}
@Override
public void reattachObserver(Observer observer) {
publisherMask(_publisher_mask | observer.subscriberMask());
}
@Override
public void trace() {
class ObserverTraceAll extends Observer {
@Override
public Object master() {
return null;
}
@Override
public int subscriberMask() {
return EventOfInterest.ALL;
}
@Override
public void update(Subject var, EventOfInterest interest) throws Failure {
System.out.println("Trace " + interest + ": " + var);
}
} // ~ ObserverTraceAll
attachObserver(new ObserverTraceAll());
}
@Override
public void trace(int event_type) {
class ObserverTrace extends Observer {
private final int _event_type;
ObserverTrace(int event_type) {
_event_type = event_type;
}
@Override
public Object master() {
return null;
}
/*
* public boolean interestedIn(EventOfInterest event) { switch(_event_type) { case EventOfInterest.MAX:
* return event.isMaxEvent(); case EventOfInterest.MIN: return event.isMinEvent(); case
* EventOfInterest.VALUE: return event.isValueEvent(); case EventOfInterest.REMOVE: return
* event.isRemoveEvent(); } return true; }
*/
@Override
public int subscriberMask() {
return _event_type;
}
@Override
public void update(Subject var, EventOfInterest interest) throws Failure {
System.out.println("Trace " + interest + ": " + var);
}
} // ~ ObserverTrace
attachObserver(new ObserverTrace(event_type));
}
} // ~SubjectImpl
© 2015 - 2024 Weber Informatics LLC | Privacy Policy