All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.terminaldriver.tn5250j.TerminalDriver Maven / Gradle / Ivy

There is a newer version: 0.0.5
Show newest version
package com.terminaldriver.tn5250j;

import static com.terminaldriver.tn5250j.util.Wait.sleep;

import java.io.Closeable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.tn5250j.Session5250;
import org.tn5250j.TN5250jConstants;
import org.tn5250j.event.ScreenListener;
import org.tn5250j.event.ScreenOIAListener;
import org.tn5250j.event.SessionChangeEvent;
import org.tn5250j.event.SessionListener;
import org.tn5250j.framework.common.SessionManager;
import org.tn5250j.framework.tn5250.ScreenOIA;
import org.tn5250j.tools.logging.TN5250jLogFactory;
import org.tn5250j.tools.logging.TN5250jLogger;

import com.terminaldriver.common.TerminalDriverChangeListener;
import com.terminaldriver.tn5250j.annotation.ScreenAttribute;
import com.terminaldriver.tn5250j.obj.By;
import com.terminaldriver.tn5250j.obj.KeyStrokes;
import com.terminaldriver.tn5250j.obj.ScreenDataContainer;
import com.terminaldriver.tn5250j.obj.ScreenElement;
import com.terminaldriver.tn5250j.obj.ScreenField;
import com.terminaldriver.tn5250j.obj.ScreenTextBlock;
import com.terminaldriver.tn5250j.util.ScreenFieldReader;
import com.terminaldriver.tn5250j.util.ScreenUtils;

public class TerminalDriver implements Closeable {

	/**
	 * Host of the 5250 server.
	 */
	String host;
	
	/**
	 * Port where the 5250 server is listening.
	 */
	int port;
	
	/**
	 * Standard code page is <37>.
	 */
	String codePage = "37";

	/**
	 * SSL Type, no default.
	 */
	String sslType;

	/**
	 * 5250 session object
	 */
	Session5250 session;
	
	public String getCodePage() {
		return codePage;
	}

	public void setCodePage(String codePage) {
		this.codePage = codePage;
	}

	public String getSslType() {
		return sslType;
	}

	public void setSslType(String sslType) {
		this.sslType = sslType;
	}

	public Session5250 getSession() {
		return session;
	}

	public String getHost() {
		return host;
	}

	public int getPort() {
		return port;
	}

	KeyStrokes keys = new KeyStrokes(this);

	public KeyStrokes getKeys() {
		return keys;
	}

	final TerminalDriverSessionListener driverSessionListener = new TerminalDriverSessionListener();
	final TerminalDriverScreenListener driverScreenListener = new TerminalDriverScreenListener();
	final TerminDriverScreenOIAListener driverScreenOIAListener = new TerminDriverScreenOIAListener();
	final List listeners = new ArrayList();
	long markedUpdate;

	public TerminalDriver() {
		super();
	}

	/**
	 * Connect with default configuration.
	 * @param host hostname
	 * @param port the port we want to connect to
	 */
	public void connectTo(final String host, final int port) {
		this.host = host;
		this.port = port;
		createConn(host, port);
	}

	/**
	 * Connect with given configuration.
	 * @param aHost hostname
	 * @param aPort port
	 * @param someConfigs specification for some more configs, e.g. code page, ssl,..
	 */
	public void connectTo(final String aHost, final int aPort, final Map someConfigs) {
		this.host = aHost;
		this.port = aPort;
		
		if (someConfigs.containsKey("codePage")) {
			this.codePage = (String)someConfigs.get("codePage");
		}
		
		if (someConfigs.containsKey("SSL_TYPE")) {
			this.sslType = (String)someConfigs.get("SSL_TYPE");
		}
		createConn(this.host, this.port);
	}
	
	public String getScreenText() {
		return new String(session.getScreen().getCharacters());
	}

	public int getScreenColumns() {
		return session.getScreen().getColumns();
	}

	public int getScreenRows() {
		return session.getScreen().getRows();
	}

	public ScreenDataContainer getCurrentScreenData() {
		return new ScreenDataContainer(session.getScreen());
	}

	public void dumpScreen() {
		session.getScreen().dumpScreen();
	}
	
	public String getDumpScreen() {
		return session.getScreen().getDumpScreen();
	}

	public void sendKeys(final String keys) {
		fireSendKeys(keys);
		session.getScreen().sendKeys(keys);
	}

	private Session5250 createConn(final String host, final int port) {
		final Properties sessionProperties = new Properties();
		sessionProperties.put("SESSION_HOST", host);
		sessionProperties.put("SESSION_HOST_PORT", String.valueOf(port));
		sessionProperties.put("SESSION_CODE_PAGE", codePage);
		sessionProperties.put(TN5250jConstants.SSL_TYPE, TN5250jConstants.SSL_TYPE_SSLv3);

		TN5250jLogFactory.setLogLevels(TN5250jLogger.INFO);

		session = SessionManager.instance().openSession(sessionProperties, "", "");
		session.addSessionListener(driverSessionListener);

		session.getScreen().addScreenListener(driverScreenListener);
		session.getScreen().getOIA().addOIAListener(driverScreenOIAListener);
		session.connect();

		for (int i = 1; i < 200 && !session.isConnected(); i++) {
			sleep(100);
		}
		waitForScreen(5000);
		waitForInputNotInhibited(5000);

		return session;
	}
	
	public void setSession(Session5250 session){
		this.session=session;
		session.addSessionListener(driverSessionListener);

		session.getScreen().addScreenListener(driverScreenListener);
		session.getScreen().getOIA().addOIAListener(driverScreenOIAListener);
		
	}

	public void addScreenListener(final ScreenListener listener) {
		session.getScreen().addScreenListener(listener);
	}

	public void addSessionListener(final SessionListener listener) {
		session.addSessionListener(listener);
	}

	@Override
	public void close() throws IOException {
		session.disconnect();
		for (final TerminalDriverChangeListener listener : listeners) {
			if (listener instanceof Closeable) {
				((Closeable) listener).close();
			}
		}
	}

	public boolean waitForScreen(final long timeOutMillis) {
		final long screenChange = driverScreenListener.getLastScreenChange();
		final long stopTime = System.currentTimeMillis() + timeOutMillis;
		while (System.currentTimeMillis() < stopTime) {
			if (screenChange != driverScreenListener.getLastScreenChange()) {
				sleep(50);
				return true;
			}
			sleep(100);
		}
		// sleep(50);
		return false;
	}

	public boolean waitForInputNotInhibited(final long timeOutMillis) {
		final long stopTime = System.currentTimeMillis() + timeOutMillis;
		while (System.currentTimeMillis() < stopTime) {
			if (acceptingInput()) {
				sleep(50);
				return true;
			}
			sleep(100);
		}
		return false;
	}

	public boolean acceptingInput() {
		return session.getScreen().getOIA().getInputInhibited() == ScreenOIA.INPUTINHIBITED_NOTINHIBITED;
	}

	public boolean waitForUpdate(final long timeOutMillis) {
		driverScreenListener.markUpdate();
		final long stopTime = System.currentTimeMillis() + timeOutMillis;
		final boolean isChanged = driverScreenListener.waitForUpdate(stopTime);
		return isChanged;
	}

	public boolean waitForField(final By by, final long timeOutMillis) {
		driverScreenListener.markUpdate();
		final long stopTime = System.currentTimeMillis() + timeOutMillis;
		boolean isChanged = false;
		do {
			for (final ScreenField field : getScreenFields()) {
				if (by.matches(field)) {
					return true;
				}
			}
			isChanged = driverScreenListener.waitForUpdate(stopTime);
		} while (isChanged);
		return false;
	}

	public boolean waitFor(final By by, final long timeOutMillis) {
		driverScreenListener.markUpdate();
		final long stopTime = System.currentTimeMillis() + timeOutMillis;
		boolean isChanged = false;
		do {
			if (by.findElement(this) != null) {
				return true;
			}
			isChanged = driverScreenListener.waitForUpdate(stopTime);
		} while (isChanged);
		return false;
	}

	public ScreenElement findElement(final By by) {
		return by.findElement(this);
	}

	public List findElements(final By by) {
		return by.findElements(this);
	}

	public ScreenField findFieldById(final int id) {
		for (final org.tn5250j.framework.tn5250.ScreenField fielditem : getRawScreenFields()) {
			if (fielditem.getFieldId() == id) {
				return new ScreenField(this, fielditem);
			}
		}
		return null;
	}

	public List findFieldsById(final int id) {
		final List items = new ArrayList();
		items.add(findFieldById(id));
		return items;
	}

	public ScreenElement findElementByLabelText(final String label,
			final com.terminaldriver.tn5250j.obj.By.ByLabelText.Position position) {
		// TODO
		return null;
	}

	public List findElementsByLabelText(final String label,
			final com.terminaldriver.tn5250j.obj.By.ByLabelText.Position position) {
		final List items = new ArrayList();
		items.add(findElementByLabelText(label, position));
		return items;
	}

	public ScreenElement findElementByText(final String text) {
		final ScreenFieldReader reader = new ScreenFieldReader(this);
		ScreenTextBlock field = null;
		while ((field = reader.readField()) != null) {
			if (text != null && field.getString() != null && text.trim().equals(field.getString().trim())) {
				return field;
			}
		}
		return null;
	}

	public List findElementsByText(final String text) {
		final List items = new ArrayList();
		final ScreenFieldReader reader = new ScreenFieldReader(this);
		ScreenTextBlock field = null;
		while ((field = reader.readField()) != null) {
			if (text != null && field.getString() != null && text.trim().equals(ScreenUtils.scrubZeros(field.getString().trim()))) {
				items.add(field);
			}
		}
		return items;
	}

	public ScreenElement findElementByAttribute(final ScreenAttribute attribute) {
		final ScreenFieldReader reader = new ScreenFieldReader(this);
		ScreenTextBlock field = null;
		while ((field = reader.readField()) != null) {
			if (attribute == ScreenAttribute.UNSET || field.getAttr().equals(attribute.getCode())) {
				return field;
			}
		}
		return null;
	}

	public List findElementsByAttribute(final ScreenAttribute attribute) {
		final List items = new ArrayList();
		final ScreenFieldReader reader = new ScreenFieldReader(this);
		ScreenTextBlock field = null;
		while ((field = reader.readField()) != null) {
			if (attribute == ScreenAttribute.UNSET || field.getAttr().equals(attribute.getCode())) {
				items.add(field);
			}
		}
		return items;
	}

	public ScreenElement findElementByPosition(final Integer row, final Integer column, final Integer length) {
		final ScreenFieldReader reader = new ScreenFieldReader(this);
		ScreenTextBlock field = null;
		// If both row and column are specified, return a (potential) partial
		// text block
		if (row != null && column != null) {
			if (length != null) {
				return reader.read(row, column, length);
			} else {
				return reader.readField(row, column);
			}
		}
		while ((field = reader.readField()) != null) {
			if ((column == null || field.startCol() == column) && (row == null || field.startRow() == row)) {
				return field;
			}
		}
		return null;
	}

	public List findElementsByPosition(final Integer row, final Integer column, final Integer length) {
		final List items = new ArrayList();
		final ScreenFieldReader reader = new ScreenFieldReader(this);
		ScreenTextBlock field = null;
		if (row != null && column != null) {
			items.add(findElementByPosition(row, column, length));
		} else {
			while ((field = reader.readField()) != null) {
				if ((column == null || field.startCol() == column) && (row == null || field.startRow() == row)) {
					items.add(field);
				}
			}
		}
		return items;
	}

	public List getScreenFields() {
		final List retval = new ArrayList();
		for (final org.tn5250j.framework.tn5250.ScreenField field : getRawScreenFields()) {
			retval.add(new ScreenField(this, field));
		}
		return retval;
	}

	private List getRawScreenFields() {
		return Arrays.asList(session.getScreen().getScreenFields().getFields());
	}

	public class TerminalDriverScreenListener implements ScreenListener {

		boolean suppressFullScreenEmpty = true;

		public void setSuppressFullScreenEmpty(boolean suppressFullScreenEmpty) {
			this.suppressFullScreenEmpty = suppressFullScreenEmpty;
		}

		/**
		 * Time in milliseconds of the last time the full screen was changed
		 */
		long lastScreenChange;
		public long getLastScreenChange() {
			return lastScreenChange;
		}

		/**
		 * Time in milliseconds of the last time the screen was partially
		 * updated
		 */
		long lastScreenUpdate;

		public long getLastScreenUpdate() {
			return lastScreenUpdate;
		}

		@Override
		public void onScreenChanged(final int arg0, final int row1, final int col1, final int row2, final int col2) {

			if (row1 == 0 && col1 == 0 && row2 >= 23 && col2 >= 79) {
				fireScreenChanged();
				// Suppress notification of a completely empty screen. Assuming
				// content will follow promptly.
				if (suppressFullScreenEmpty && getScreenText().trim().isEmpty()) {
					return;
				}
				// Auto close messages window.
				final ScreenElement element = findElement(By.and(By.row(1), By.attribute(ScreenAttribute.WHT)));
				if (element != null && (element.getString().trim().equals("Display Program Messages")
						 || element.getString().trim().equals("Display Messages"))
						&& acceptingInput()) {
					fireNote("Closing messages window");
					keys().enter();
				}
				lastScreenChange = System.currentTimeMillis();
			} else {
				fireScreenPartialsUpdate(row1, col1, row2, col2);
			}
			lastScreenUpdate = System.currentTimeMillis();
		}

		@Override
		public void onScreenSizeChanged(final int cols, final int rows) {
			fireScreenSizeChanged(cols, rows);
		}

		public void markUpdate() {
			markedUpdate = lastScreenUpdate;
		}

		public boolean waitForUpdate(final long untilTime) {
			while (System.currentTimeMillis() < untilTime) {
				if (markedUpdate != lastScreenUpdate) {
					return true;
				}
				sleep(100);
			}
			return false;
		}
	}

	public static class TerminalDriverSessionListener implements SessionListener {

		@Override
		public void onSessionChanged(final SessionChangeEvent arg0) {
		}
	}

	public class TerminDriverScreenOIAListener implements ScreenOIAListener {

		@Override
		public void onOIAChanged(final ScreenOIA arg0, final int arg1) {
			if(arg1==ScreenOIAListener.OIA_CHANGED_INPUTINHIBITED){
				fireInputInhibited(arg0.getInputInhibited() != ScreenOIA.INPUTINHIBITED_NOTINHIBITED);
			}
		}
	}

	public KeyStrokes keys() {
		return keys;
	}

	public void fireFieldSetString(final ScreenField screenField, final String inputValue) {
		String value = inputValue;
		if (ScreenAttribute.getAttrEnum(screenField.getAttr().charAt(0)).isNonDisplay()) {
			value = value.replaceAll(".", "*");
		}
		for (final TerminalDriverChangeListener listener : listeners) {
			listener.fieldSetString(this, screenField, value);
		}
	}

	private void fireSendKeys(final String keys) {
		for (final TerminalDriverChangeListener listener : listeners) {
			listener.sendKeys(this, keys);
		}
	}

	private void fireScreenSizeChanged(final int cols, final int rows) {
		for (final TerminalDriverChangeListener listener : listeners) {
			listener.screenSizeChanged(this, cols, rows);
		}
	}

	private void fireScreenPartialsUpdate(final int row1, final int col1, final int row2, final int col2) {
		for (final TerminalDriverChangeListener listener : listeners) {
			listener.screenPartialsUpdate(this, row1, col1, row2, col2);
		}
	}

	private void fireScreenChanged() {
		for (final TerminalDriverChangeListener listener : listeners) {
			listener.screenChanged(this);
		}
	}

	private void fireNote(final String note) {
		for (final TerminalDriverChangeListener listener : listeners) {
			listener.note(note);
		}
	}
	
	private void fireInputInhibited(final boolean inhibited) {
		for (final TerminalDriverChangeListener listener : listeners) {
			listener.inputInhibited(inhibited);
		}
	}

	public void addTerminalDriverChangeListener(final TerminalDriverChangeListener listener) {
		listeners.add(listener);
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy