/*******************************************************************************
* Copyright (c) 2012 OpenLegacy Inc.
* All rights reserved. This program and the accompanying materials
* are 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:
* OpenLegacy Inc. - initial API and implementation
*******************************************************************************/
package org.openlegacy.terminal.support;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openlegacy.exceptions.EntityNotFoundException;
import org.openlegacy.loaders.support.PartPositionAnnotationLoader;
import org.openlegacy.terminal.ScreenEntity;
import org.openlegacy.terminal.TerminalSendAction;
import org.openlegacy.terminal.TerminalSnapshot;
import org.openlegacy.terminal.mock.MockTerminalConnection;
import org.openlegacy.terminal.wait_conditions.WaitCondition;
import org.openlegacy.utils.ProxyUtil;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* A mock-up implementation for a terminal session. Main purpose is to be able to navigate between entities relatively easily, and
* sync with the terminal connection. Coupled by design to the mock terminal connection.
*
*/
public class MockupTerminalSession extends DefaultTerminalSession {
private static final long serialVersionUID = 1L;
private final static Log logger = LogFactory.getLog(PartPositionAnnotationLoader.class);
private Map<Class<?>, SnapshotsList> snapshotsMap = new HashMap<Class<?>, SnapshotsList>();
@Override
public TerminalSnapshot getSnapshot() {
return super.getSnapshot();
}
@Override
public <S> S getEntity(Class<S> screenEntityClass, Object... keys) throws EntityNotFoundException {
setupMockup(screenEntityClass);
return super.getEntity(screenEntityClass, keys);
}
@SuppressWarnings("unchecked")
private <S> void setupMockup(Class<S> screenEntityClass) {
screenEntityClass = (Class<S>)ProxyUtil.getOriginalClass(screenEntityClass);
SnapshotInfo snapshotInfo = snapshotsMap.get(screenEntityClass).getCurrent();
getTerminalConnection().setCurrentIndex(snapshotInfo.getIndexInSession());
}
@Override
protected void doTerminalAction(TerminalSendAction sendAction, WaitCondition... waitConditions) {
ScreenEntity currentEntity = getEntity();
super.doTerminalAction(sendAction, waitConditions);
progressSnapshot(currentEntity);
}
private void progressSnapshot(ScreenEntity result) {
if (result == null) {
return;
}
Class<?> screenEntityClass = ProxyUtil.getOriginalClass(result.getClass());
SnapshotsList snapshotsList = snapshotsMap.get(screenEntityClass);
snapshotsList.next();
}
@Override
protected void notifyModulesAfterSend() {
super.notifyModulesAfterSend();
}
public void setTerminalConnection(MockTerminalConnection terminalConnection) {
super.setTerminalConnection(terminalConnection);
preserveSnapshots(terminalConnection);
}
private void preserveSnapshots(MockTerminalConnection terminalConnection) {
List<TerminalSnapshot> snapshots = terminalConnection.getSnapshots();
int count = 0;
for (TerminalSnapshot terminalSnapshot : snapshots) {
Class<?> matchedClass = getScreensRecognizer().match(terminalSnapshot);
if (matchedClass == null) {
logger.warn("An unrecognized snapshot was found in the trail:");
logger.warn(terminalSnapshot);
} else {
SnapshotsList snapshotsList = snapshotsMap.get(matchedClass);
if (snapshotsMap.get(matchedClass) == null) {
snapshotsList = new SnapshotsList();
snapshotsMap.put(matchedClass, snapshotsList);
}
snapshotsList.add(terminalSnapshot, count);
}
count++;
}
}
@Override
public void disconnect() {
super.disconnect();
Collection<SnapshotsList> snapshotLists = snapshotsMap.values();
for (SnapshotsList snapshotsList : snapshotLists) {
snapshotsList.setCurrent(0);
}
}
@Override
protected MockTerminalConnection getTerminalConnection() {
return (MockTerminalConnection)super.getTerminalConnection();
}
/**
* A mock-up helper class which manage a list of snapshots and knows always what is the current one
*
*/
private static class SnapshotsList implements Serializable {
private static final long serialVersionUID = 1L;
private List<SnapshotInfo> terminalSnapshots = new ArrayList<SnapshotInfo>();
private int current;
public void add(TerminalSnapshot terminalSnapshot, int indexInSession) {
// don't put duplicates
if (!terminalSnapshots.contains(terminalSnapshot)) {
terminalSnapshots.add(new SnapshotInfo(terminalSnapshot, indexInSession));
}
}
public void setCurrent(int current) {
this.current = current;
}
public SnapshotInfo getCurrent() {
return terminalSnapshots.get(current);
}
public void next() {
if (current < terminalSnapshots.size() - 1) {
current++;
} else {
current = 0;
}
}
}
private static class SnapshotInfo implements Serializable {
private static final long serialVersionUID = 1L;
private TerminalSnapshot terminalSnapshot;
private int indexInSession;
public SnapshotInfo(TerminalSnapshot terminalSnapshot, int indexInSession) {
this.terminalSnapshot = terminalSnapshot;
this.indexInSession = indexInSession;
}
public int getIndexInSession() {
return indexInSession;
}
@SuppressWarnings("unused")
public TerminalSnapshot getTerminalSnapshot() {
return terminalSnapshot;
}
}
}