/**
* Copyright 2004-2016 Riccardo Solmi. All rights reserved.
* This file is part of the Whole Platform.
*
* The Whole Platform is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Whole Platform is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the Whole Platform. If not, see <http://www.gnu.org/licenses/>.
*/
package org.whole.lang.model;
import java.io.IOException;
import java.io.Serializable;
import java.util.Collections;
import java.util.List;
import org.whole.lang.commands.ICommand;
import org.whole.lang.commands.NullCommand;
import org.whole.lang.events.CompositeChangeEventHandler;
import org.whole.lang.events.IChangeEventHandler;
import org.whole.lang.events.IPropertyChangeObserver;
import org.whole.lang.events.IRequestEventHandler;
import org.whole.lang.events.IdentityChangeEventHandler;
import org.whole.lang.events.IdentityRequestEventHandler;
import org.whole.lang.events.MappingChangeEventHandler;
import org.whole.lang.events.PropertyChangeEventHandler;
import org.whole.lang.lifecycle.HistoryManager;
import org.whole.lang.lifecycle.IHistoryManager;
import org.whole.lang.lifecycle.Status;
/**
* Responsible for event notification
*
* @author Riccardo Solmi
*/
public class CompoundModel extends CompositeChangeEventHandler implements ICompoundModel, Serializable, IHistoryManager {
private static final long serialVersionUID = 1L;
transient private IRequestEventHandler requestEventHandler = IdentityRequestEventHandler.instance;
transient private IHistoryManager historyManager;
transient private PropertyChangeEventHandler propertyChangeEventHandler;
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
requestEventHandler = IdentityRequestEventHandler.instance;
historyManager = this;
}
public CompoundModel() {
super(
IdentityChangeEventHandler.instance, // placeholder for HistoryManager
IdentityChangeEventHandler.instance, // placeholder for propertyChangeEventHandler
new MappingChangeEventHandler.LanguageReactionsChangeEventMapper());
historyManager = this;
}
public boolean equals(IHistoryManager other) {
if (historyManager != this)
return historyManager.equals(other);
if (other instanceof ICompoundModel) {
ICompoundModel otherModel = (ICompoundModel) other;
if (otherModel.getHistoryManager() != otherModel)
return other.equals(this);
}
return super.equals(other);
}
//assume that subCompoundModel will be gc
public ICompoundModel merge(ICompoundModel subCompoundModel, boolean mergeHistory) {
if (subCompoundModel instanceof CompoundModel) {
CompoundModel compoundModel = (CompoundModel) subCompoundModel;
if (compoundModel.hasPropertyChangeEventHandler())
getPropertyChangeEventHandler().addAllEventListeners(compoundModel.getPropertyChangeEventHandler().getEventListeners());
compoundModel.setHistoryManager(getHistoryManager(), mergeHistory);
}
return this;
}
public IRequestEventHandler getRequestEventHandler() {
return requestEventHandler;
}
public IRequestEventHandler addRequestEventHandler(IRequestEventHandler eventHandler) {
return this.requestEventHandler = this.requestEventHandler.addRequestEventHandler(eventHandler);
}
public IChangeEventHandler getChangeEventHandler() {
return this;
}
public IHistoryManager getHistoryManager() {
return historyManager;
}
public void setHistoryManager(IHistoryManager historyManager, boolean mergeHistory) {
if (this.historyManager.equals(historyManager))
return;
if (mergeHistory)
historyManager.mergeHistory(this.historyManager);
else
this.historyManager.clearHistory();
setHistoryManager(historyManager);
}
protected boolean hasPropertyChangeEventHandler() {
return propertyChangeEventHandler != null;
}
public PropertyChangeEventHandler getPropertyChangeEventHandler() {
if (propertyChangeEventHandler == null)
setChangeEventHandler(1, propertyChangeEventHandler = new PropertyChangeEventHandler());
return propertyChangeEventHandler;
}
public synchronized void addEventListener(IPropertyChangeObserver l) {
getPropertyChangeEventHandler().addEventListener(l);
}
public synchronized void removeEventListener(IPropertyChangeObserver l) {
getPropertyChangeEventHandler().removeEventListener(l);
}
public void fireNotationEvent(IEntity source, String name, Object data) {
getPropertyChangeEventHandler().notifyEvent(source, name, data);
}
public boolean isObserved(IEntity entity) {
if (hasPropertyChangeEventHandler())
for (IPropertyChangeObserver o : getPropertyChangeEventHandler().getEventListeners())
if (o.isObserving(entity))
return true;
return false;
}
public boolean isHistoryEvent() {
if (historyManager != this)
return historyManager.isHistoryEvent();
return false;
}
public boolean isHistoryEnabled() {
if (historyManager != this)
return historyManager.isHistoryEnabled();
return false;
}
public boolean setHistoryEnabled(boolean value) {
if (historyManager != this)
return historyManager.setHistoryEnabled(value);
if (value) {
initHistoryManager();
return historyManager.setHistoryEnabled(true);
} else
return false;
}
protected void initHistoryManager() {
setHistoryManager(new HistoryManager());
}
protected void setHistoryManager(IHistoryManager historyManager) {
this.historyManager = historyManager;
setChangeEventHandler(0, (IChangeEventHandler) this.historyManager);
}
public int getHistoryCapacity() {
if (historyManager != this)
return historyManager.getHistoryCapacity();
return Integer.MAX_VALUE;
}
public void setHistoryCapacity(int size) {
if (historyManager == this)
initHistoryManager();
historyManager.setHistoryCapacity(size);
}
public void trimHistory(int size) {
if (historyManager != this)
historyManager.trimHistory(size);
}
public void clearHistory() {
if (historyManager != this)
historyManager.clearHistory();
}
public IHistoryManager mergeHistory(IHistoryManager target) {
if (historyManager != this)
return historyManager.mergeHistory(target);
if (target.getUndoSize() > 0)
setHistoryManager(target);
return historyManager;
}
public int getUndoSize() {
if (historyManager != this)
return historyManager.getUndoSize();
return 0;
}
public int getRedoSize() {
if (historyManager != this)
return historyManager.getRedoSize();
return 0;
}
public List<ICommand> getUndoCommands() {
if (historyManager != this)
return historyManager.getUndoCommands();
return Collections.emptyList();
}
public List<ICommand> getRedoCommands() {
if (historyManager != this)
return historyManager.getRedoCommands();
return Collections.emptyList();
}
public ICommand getUndoCommand() {
if (historyManager != this)
return historyManager.getUndoCommand();
else
return NullCommand.instance;
}
public ICommand getRedoCommand() {
if (historyManager != this)
return historyManager.getRedoCommand();
else
return NullCommand.instance;
}
public void undo() {
if (historyManager == this)
throw new IllegalStateException();
historyManager.undo();
}
public void redo() {
if (historyManager == this)
throw new IllegalStateException();
historyManager.redo();
}
public Status getStatus() {
if (historyManager != this)
return historyManager.getStatus();
return Status.NO_TRANSACTION;
}
public void begin() {
if (historyManager == this)
initHistoryManager();
historyManager.begin();
}
public ICommand commit() {
if (historyManager == this)
throw new IllegalStateException();
return historyManager.commit();
}
public ICommand mergeCommit(ICommand command) {
if (historyManager == this)
throw new IllegalStateException();
return historyManager.mergeCommit(command);
}
public void rollback() {
if (historyManager == this)
throw new IllegalStateException();
historyManager.rollback();
}
public void setRollbackOnly() {
if (historyManager == this)
throw new IllegalStateException();
historyManager.setRollbackOnly();
}
@Override
public String toString() {
if (historyManager != this)
return historyManager.toString();
return "History Manager (enabled=false size=0u0r capacity=*)";
}
}