| /******************************************************************************* |
| * Copyright (c) 2004, 2007 Boeing. |
| * 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: |
| * Boeing - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.osee.ote.message.elements; |
| |
| import java.util.Arrays; |
| import java.util.BitSet; |
| import java.util.Collection; |
| import java.util.ListIterator; |
| import java.util.logging.Level; |
| |
| import org.eclipse.osee.framework.logging.OseeLog; |
| import org.eclipse.osee.ote.core.MethodFormatter; |
| import org.eclipse.osee.ote.core.environment.interfaces.ITestEnvironmentAccessor; |
| import org.eclipse.osee.ote.core.testPoint.CheckGroup; |
| import org.eclipse.osee.ote.core.testPoint.CheckPoint; |
| import org.eclipse.osee.ote.message.Message; |
| import org.eclipse.osee.ote.message.data.MemoryResource; |
| import org.eclipse.osee.ote.message.data.MessageData; |
| import org.eclipse.osee.ote.message.elements.nonmapping.NonMappingCharElement; |
| import org.eclipse.osee.ote.message.interfaces.ITestAccessor; |
| import org.eclipse.osee.ote.message.listener.MessageSystemListener; |
| |
| /** |
| * @author John Butler |
| * @author Robert A. Fisher |
| */ |
| public class CharElement extends DiscreteElement<Character> { |
| |
| public CharElement(Message message, String elementName, MessageData messageData, int byteOffset, int msb, int lsb) { |
| this(message, elementName, messageData, byteOffset, msb, lsb, msb, lsb); |
| } |
| |
| public CharElement(Message message, String elementName, MessageData messageData, int byteOffset, int msb, int lsb, int originalLsb, int originalMsb) { |
| super(message, elementName, messageData, byteOffset, msb, lsb, originalLsb, originalMsb); |
| } |
| |
| public CharElement(Message message, String elementName, MessageData messageData, int bitOffset, int bitLength) { |
| super(message, elementName, messageData, bitOffset, bitLength); |
| } |
| |
| @SuppressWarnings("rawtypes") |
| @Override |
| public CharElement findElementInMessages(Collection<? extends Message> messages) { |
| return (CharElement) super.findElementInMessages(messages); |
| } |
| |
| @Override |
| public CharElement switchMessages(Collection<? extends Message<?,?,?>> messages) { |
| return (CharElement) super.switchMessages(messages); |
| } |
| |
| /** |
| * Checks that this element correctly forwards a message sent from cause with the value passed. |
| * |
| * @param cause The originator of the signal |
| * @param value The value sent by cause and being forwarded by this element |
| */ |
| public void checkForwarding(ITestAccessor accessor, CharElement cause, Character value) throws InterruptedException { |
| /* check for 0 to begine */ |
| check(accessor, (char) 0, 0); |
| |
| /* Set the DP1 Mux Signal */ |
| cause.set(accessor, value); |
| |
| /* Chk Value on DP2 */ |
| check(accessor, value, 1000); |
| |
| /* Set DP1 to 0 */ |
| cause.set(accessor, (char) 0); |
| |
| /* Init DP2 Mux to 0 */ |
| set(accessor, (char) 0); |
| |
| /* Chk Value on DP2 is still set */ |
| check(accessor, value, 500); |
| |
| /* Chk DP2 is 0 for two-pulse signals and high for four-oulse signal */ |
| check(accessor, (char) 0, 500); |
| |
| } |
| |
| /** |
| * Verifies that the element is Not set to "value" within the number of "milliseconds" passed. |
| * |
| * @param value Expected value. |
| * @param milliseconds Number of milliseconds to wait for the element to equal the "value". |
| * @return If the check passed. |
| */ |
| public boolean checkNot(ITestAccessor accessor, String value, int milliseconds) throws InterruptedException { |
| return this.checkNot(accessor, (CheckGroup) null, value, milliseconds); |
| } |
| |
| /** |
| * Verifies that the element is Not set to "value" within the number of "milliseconds" passed. |
| * |
| * @param checkGroup If this check is part of a larger set of checks which another method is going to log then the |
| * reference to the CheckGroup must be passed and this method will add the result of the check to the group with out |
| * logging a point. |
| * <p> |
| * If an outside method is not going to log the check then a <b>null </b> reference should be passed and this method |
| * will log the test point. |
| * @param value Expected value. |
| * @param milliseconds Number of milliseconds to wait for the element to equal the "value". |
| * @return If the check passed. |
| */ |
| public boolean checkNot(ITestAccessor accessor, CheckGroup checkGroup, String value, int milliseconds) throws InterruptedException { |
| if (accessor == null) { |
| throw new IllegalArgumentException("accessor cannot be null"); |
| } |
| accessor.getLogger().methodCalledOnObject(accessor, this.getFullName(), |
| new MethodFormatter().add(value).add(milliseconds), getMessage()); |
| |
| long time = accessor.getEnvTime(); |
| String currentValue; |
| boolean result; |
| if (milliseconds > 0) { |
| final MessageSystemListener listener = getMessage().getListener(); |
| org.eclipse.osee.ote.core.environment.interfaces.ICancelTimer cancelTimer = |
| accessor.setTimerFor(listener, milliseconds); |
| |
| accessor.getLogger().debug(accessor, "waiting............", true); |
| |
| while (result = !(currentValue = getString(accessor, value.length())).equals(value)) { |
| listener.waitForData(); // will also return if the timer (set above) |
| // expires |
| /* |
| * NOTE: had to add isTimedOut() because we were getting data at the same time we're timing out, so the |
| * notifyAll() isn't guaranteed to work since we would not be in a waiting state at that time - so we're |
| * forced to save the fact that we timed out. |
| */ |
| if (listener.isTimedOut()) { |
| break; |
| } |
| } |
| cancelTimer.cancelTimer(); |
| accessor.getLogger().debug(accessor, "done waiting", true); |
| } else { |
| result = !(currentValue = getString(accessor, value.length())).equals(value); |
| } |
| time = accessor.getEnvTime() - time; |
| CheckPoint passFail = new CheckPoint(this.getFullName(), "Not " + value, currentValue, result, time); |
| |
| if (checkGroup == null) { |
| accessor.getLogger().testpoint(accessor, accessor.getTestScript(), accessor.getTestCase(), passFail); |
| } else { |
| checkGroup.add(passFail); |
| } |
| |
| if (accessor != null) { |
| accessor.getLogger().methodEnded(accessor); |
| } |
| return passFail.isPass(); |
| } |
| |
| /** |
| * Verifies that the element is set to "value" within the number of "milliseconds" passed. |
| * |
| * @param value Expected value. |
| * @param milliseconds Number of milliseconds to wait for the element to equal the "value". |
| * @return If the check passed. |
| */ |
| public boolean check(ITestAccessor accessor, String value, int milliseconds) throws InterruptedException { |
| return this.check(accessor, (CheckGroup) null, value, milliseconds); |
| } |
| |
| /** |
| * Verifies that the element is set to "value" within the number of "milliseconds" passed. |
| * |
| * @param checkGroup If this check is part of a larger set of checks which another method is going to log then the |
| * reference to the CheckGroup must be passed and this method will add the result of the check to the group with out |
| * logging a point. |
| * <p> |
| * If an outside method is not going to log the check then a <b>null </b> reference should be passed and this method |
| * will log the test point. |
| * @param value Expected value. |
| * @param milliseconds Number of milliseconds to wait for the element to equal the "value". |
| * @return If the check passed. |
| */ |
| public boolean check(ITestAccessor accessor, CheckGroup checkGroup, String value, int milliseconds) throws InterruptedException { |
| if (accessor == null) { |
| throw new IllegalArgumentException("accessor cannot be null"); |
| } |
| accessor.getLogger().methodCalledOnObject(accessor, this.getFullName(), |
| new MethodFormatter().add(value).add(milliseconds), this.getMessage()); |
| long time = accessor.getEnvTime(); |
| String currentValue; |
| if (milliseconds > 0) { |
| MessageSystemListener listener = getMessage().getListener(); |
| org.eclipse.osee.ote.core.environment.interfaces.ICancelTimer cancelTimer = |
| accessor.setTimerFor(listener, milliseconds); |
| |
| accessor.getLogger().debug(accessor, "waiting............", true); |
| |
| while (!compareString(currentValue = getString(accessor, value.length()), value)) { |
| listener.waitForData(); // will also return if the timer (set above) |
| // expires |
| /* |
| * NOTE: had to add isTimedOut() because we were getting data at the same time we're timing out, so the |
| * notifyAll() isn't guaranteed to work since we would not be in a waiting state at that time - so we're |
| * forced to save the fact that we timed out. |
| */ |
| if (listener.isTimedOut()) { |
| break; |
| } |
| } |
| |
| cancelTimer.cancelTimer(); |
| accessor.getLogger().debug(accessor, "done waiting", true); |
| } else { |
| currentValue = getString(accessor, value.length()); |
| } |
| time = accessor.getEnvTime() - time; |
| CheckPoint passFail = |
| new CheckPoint(this.getFullName(), value, currentValue, compareString(currentValue, value), time); |
| |
| if (checkGroup == null) { |
| accessor.getLogger().testpoint(accessor, accessor.getTestScript(), accessor.getTestCase(), passFail); |
| } else { |
| checkGroup.add(passFail); |
| } |
| |
| if (accessor != null) { |
| accessor.getLogger().methodEnded(accessor); |
| } |
| return passFail.isPass(); |
| } |
| |
| private boolean compareString(String string, String value) { |
| return string.equals(value); |
| } |
| |
| /** |
| * Verifies that the string starting at the element is not set to "value". |
| * |
| * @param value Expected value |
| * @return if the check passed |
| */ |
| public boolean checkNot(ITestAccessor accessor, String value) { |
| return this.checkNot(accessor, (CheckGroup) null, value); |
| } |
| |
| /** |
| * Verifies that the string starting at the element is not set to "value". |
| * |
| * @param checkGroup If this check is part of a larger set of checks which another method is going to log then the |
| * reference to the CheckGroup must be passed and this method will add the result of the check to the group with out |
| * logging a point. |
| * <p> |
| * If an outside method is not going to log the check then a <b>null </b> reference should be passed and this method |
| * will log the test point. |
| * @param value Expected value |
| * @return if the check passed |
| */ |
| public boolean checkNot(ITestAccessor accessor, CheckGroup checkGroup, String value) { |
| if (accessor != null) { |
| accessor.getLogger().methodCalledOnObject(accessor, this.getFullName(), new MethodFormatter().add(value), |
| this.getMessage()); |
| } |
| |
| String actualValue = getString(accessor, value.length()); |
| |
| CheckPoint passFail = |
| new CheckPoint(this.getFullName(), "Not " + value, actualValue, value.compareTo(actualValue) != 0, 0); |
| |
| if (checkGroup == null) { |
| accessor.getLogger().testpoint(accessor, accessor.getTestScript(), accessor.getTestCase(), passFail); |
| } else { |
| checkGroup.add(passFail); |
| } |
| |
| if (accessor != null) { |
| accessor.getLogger().methodEnded(accessor); |
| } |
| return passFail.isPass(); |
| |
| } |
| |
| /** |
| * Verifies that the string starting at the element is set to "value". |
| * |
| * @param value Expected value |
| * @return if the check passed |
| */ |
| public boolean check(ITestAccessor accessor, String value) { |
| return this.check(accessor, (CheckGroup) null, value); |
| } |
| |
| /** |
| * Verifies that the string starting at the element is set to "value". |
| * |
| * @param checkGroup If this check is part of a larger set of checks which another method is going to log then the |
| * reference to the CheckGroup must be passed and this method will add the result of the check to the group with out |
| * logging a point. |
| * <p> |
| * If an outside method is not going to log the check then a <b>null </b> reference should be passed and this method |
| * will log the test point. |
| * @param value Expected value |
| * @return if the check passed |
| */ |
| public boolean check(ITestAccessor accessor, CheckGroup checkGroup, String value) { |
| if (accessor != null) { |
| accessor.getLogger().methodCalledOnObject(accessor, this.getFullName(), new MethodFormatter().add(value), |
| this.getMessage()); |
| } |
| String actualValue = getString(accessor, value.length()); |
| |
| CheckPoint passFail = |
| new CheckPoint(this.getFullName(), value, actualValue, value.compareTo(actualValue) == 0, 0); |
| |
| if (checkGroup == null) { |
| if (accessor != null) { |
| accessor.getLogger().testpoint(accessor, accessor.getTestScript(), accessor.getTestCase(), passFail); |
| } |
| } else { |
| checkGroup.add(passFail); |
| } |
| |
| if (accessor != null) { |
| accessor.getLogger().methodEnded(accessor); |
| } |
| return passFail.isPass(); |
| } |
| |
| /** |
| * Returns the string of length "stringLength" starting as the position of the element. |
| * |
| * @param stringLength the length of the string to return |
| * @return the string starting with this element |
| */ |
| public String getString(ITestEnvironmentAccessor accessor, int stringLength) { |
| if (getBitLength() == 8) { |
| return getASCIIString(stringLength); |
| } else { |
| ListIterator<Element> iter = getMessage().getElementIterator(this); |
| char[] chars = new char[stringLength]; |
| for (int i = 0; i < stringLength; i++) { |
| Element element = iter.next(); |
| if (element instanceof CharElement) { |
| chars[i] = ((CharElement) element).getValue(); |
| } else { |
| // we ran into a non char element we should abort string extraction |
| break; |
| } |
| } |
| return new String(chars); |
| } |
| } |
| |
| /** |
| * <p> |
| * Sets the element's value. Can be [ab]used to set subsequent, contiguous bytes but, while widespread, this use is |
| * discouraged and may be removed in a future release. The behavior of this method differs depending on the length of |
| * string passed in and whether the underlying element is eight bits. |
| * </p> |
| * <p> |
| * For an empty string it sets the element to the null character, '\0', using {@link #setValue(Character)}, which |
| * properly accounts for cases where the element is not eight bits. |
| * </p> |
| * <p> |
| * If the string has a length of one it calls {@link #setValue(Character)} with value.charAt(0). |
| * </p> |
| * <p> |
| * If the string length is greater than one it will assume this and all subsequent elements are eight bits and set |
| * them. <b>Note</b> that it does nothing to ensure the subsequent bytes are character elements or eight bits. It |
| * will throw IllegalArgumentException if setting subsequent elements would overflow. If the element is not eight |
| * bits in size it will set as above and log a warning and stack trace but not throw an exception. |
| * </p> |
| * |
| * @param accessor |
| * @param value the string to set the bytes to |
| */ |
| @Override |
| public void parseAndSet(ITestEnvironmentAccessor accessor, String value) { |
| if (value.length() + this.getByteOffset() > this.getMessage().getData().length) { |
| throw new IllegalArgumentException("Setting a String whose length exceeds the Message bounds!"); |
| } |
| |
| if (accessor != null) { |
| accessor.getLogger().methodCalledOnObject(accessor, this.getFullName(), new MethodFormatter().add(value), |
| this.getMessage()); |
| } |
| |
| switch (value.length()) { |
| case 0: |
| setValue('\0'); |
| break; |
| case 1: |
| setValue(value.charAt(0)); |
| break; |
| default: |
| setASCIIString(value); |
| break; |
| } |
| |
| if (accessor != null) { |
| accessor.getLogger().methodEnded(accessor); |
| } |
| } |
| |
| /** |
| * This method uses {@link #parseAndSet(ITestEnvironmentAccessor, String)} and has all the associate risks and |
| * limitations. |
| * |
| * @param accessor |
| * @param value |
| */ |
| public void set(ITestEnvironmentAccessor accessor, String value) { |
| parseAndSet(accessor, value); |
| } |
| |
| /** |
| * This method uses {@link #parseAndSet(ITestEnvironmentAccessor, String)} and has all the associate risks and |
| * limitations. |
| * |
| * @param value |
| */ |
| public void setValue(String value) { |
| parseAndSet(null, value); |
| } |
| |
| /** |
| * This method uses {@link #parseAndSet(ITestEnvironmentAccessor, String)} and has all the associate risks and |
| * limitations. After setting it sends the message. |
| * |
| * @param accessor |
| * @param value |
| */ |
| public void setAndSend(ITestEnvironmentAccessor accessor, String value) { |
| this.parseAndSet(accessor, value); |
| super.sendMessage(); |
| } |
| |
| /** |
| * This method uses {@link #parseAndSet(ITestEnvironmentAccessor, String)} and has all the associate risks and |
| * limitations. |
| * |
| * @param accessor |
| * @param value |
| */ |
| public void setNoLog(ITestEnvironmentAccessor accessor, String value) { |
| this.parseAndSet(accessor, value); |
| } |
| |
| /** |
| * Sets the element to the "value" passed and immediately sends the meessage that contains it.. |
| * |
| * @param value The value to set. |
| */ |
| public void setAndSend(ITestEnvironmentAccessor accessor, Character value) { |
| this.set(accessor, value); |
| super.sendMessage(); |
| } |
| |
| /** |
| * Waits until the element equals the "value" passed. Returns last value observed upon a timout. |
| * |
| * @param value The expected value to wait for. |
| * @param milliseconds Number of milliseconds to wait before failing. |
| * @return last value found. Either value expected or value found at timeout. |
| */ |
| protected String waitForValue(ITestEnvironmentAccessor accessor, String value, int milliseconds) throws InterruptedException { |
| if (accessor != null) { |
| accessor.getLogger().methodCalledOnObject(accessor, this.getFullName(), |
| new MethodFormatter().add(value).add(milliseconds), this.getMessage()); |
| } |
| String currentValue; |
| if (milliseconds > 0) { |
| MessageSystemListener listener = getMessage().getListener(); |
| org.eclipse.osee.ote.core.environment.interfaces.ICancelTimer cancelTimer = |
| accessor.setTimerFor(listener, milliseconds); |
| |
| accessor.getLogger().debug(accessor, "waiting............", true); |
| |
| while ((currentValue = getString(accessor, value.length())).equals(value)) { |
| listener.waitForData(); // will also return if the timer (set above) |
| // expires |
| /* |
| * NOTE: had to add isTimedOut() because we were getting data at the same time we're timing out, so the |
| * notifyAll() isn't guaranteed to work since we would not be in a waiting state at that time - so we're |
| * forced to save the fact that we timed out. |
| */ |
| if (listener.isTimedOut()) { |
| break; |
| } |
| } |
| cancelTimer.cancelTimer(); |
| accessor.getLogger().debug(accessor, "done waiting", true); |
| } else { |
| currentValue = getString(accessor, value.length()); |
| } |
| if (accessor != null) { |
| accessor.getLogger().methodCalledOnObject(accessor, this.getFullName(), new MethodFormatter().add(value), |
| this.getMessage()); |
| } |
| return currentValue; |
| } |
| |
| /** |
| * Waits until the element does not equal the "value" passed. Returns last value observed upon a timout. |
| * |
| * @param value The expected value to wait for. |
| * @param milliseconds Number of milliseconds to wait before failing. |
| * @return last value found. Either value expected or value found at timeout. |
| */ |
| protected String waitForNotValue(ITestEnvironmentAccessor accessor, String value, int milliseconds) throws InterruptedException { |
| if (accessor != null) { |
| accessor.getLogger().methodCalledOnObject(accessor, this.getFullName(), |
| new MethodFormatter().add(value).add(milliseconds), this.getMessage()); |
| } |
| String currentValue; |
| if (milliseconds > 0) { |
| |
| MessageSystemListener listener = getMessage().getListener(); |
| org.eclipse.osee.ote.core.environment.interfaces.ICancelTimer cancelTimer = |
| accessor.setTimerFor(listener, milliseconds); |
| |
| accessor.getLogger().debug(accessor, "waiting............", true); |
| |
| while (!(currentValue = getString(accessor, value.length())).equals(value)) { |
| listener.waitForData(); // will also return if the timer (set above) |
| // expires |
| /* |
| * NOTE: had to add isTimedOut() because we were getting data at the same time we're timing out, so the |
| * notifyAll() isn't guaranteed to work since we would not be in a waiting state at that time - so we're |
| * forced to save the fact that we timed out. |
| */ |
| if (listener.isTimedOut()) { |
| break; |
| } |
| } |
| cancelTimer.cancelTimer(); |
| accessor.getLogger().debug(accessor, "done waiting", true); |
| } else { |
| currentValue = getString(accessor, value.length()); |
| } |
| if (accessor != null) { |
| accessor.getLogger().methodCalledOnObject(accessor, this.getFullName(), new MethodFormatter().add(value), |
| this.getMessage()); |
| } |
| return currentValue; |
| } |
| |
| /** |
| * Sets the element value, properly accounting for the bit-size of the element. |
| * |
| * @param value |
| */ |
| @Override |
| public void setValue(Character value) { |
| getMsgData().getMem().setInt(value, byteOffset, msb, lsb); |
| } |
| |
| @Override |
| public Character getValue() { |
| return (char) getMsgData().getMem().getInt(byteOffset, msb, lsb); |
| } |
| |
| @Override |
| public Character valueOf(MemoryResource otherMem) { |
| return Character.valueOf((char) otherMem.getInt(byteOffset, msb, lsb)); |
| } |
| |
| @Override |
| public String toString(Character obj) { |
| return obj.toString(); |
| } |
| |
| private String getASCIIString(int length) { |
| return getMsgData().getMem().getASCIIString(byteOffset, length); |
| } |
| |
| private void setASCIIString(String value) { |
| if (getBitLength() == 8) { |
| getMsgData().getMem().setASCIIString(value, byteOffset); |
| } else { |
| ListIterator<Element> iter = getMessage().getElementIterator(this); |
| for (int i = 0; i < value.length(); i++) { |
| Element element = iter.next(); |
| if (element instanceof CharElement) { |
| ((CharElement) element).setValue(value.charAt(i)); |
| } else { |
| // we ran into a non char element we should abort string extraction |
| return; |
| } |
| } |
| } |
| } |
| |
| @Override |
| public void visit(IElementVisitor visitor) { |
| visitor.asCharElement(this); |
| } |
| |
| @Override |
| protected NonMappingCharElement getNonMappingElement() { |
| return new NonMappingCharElement(this); |
| } |
| |
| @Override |
| public Character elementMask(Character value) { |
| return value; |
| } |
| } |