Skip to content

Commit

Permalink
- Update to doip-junit:1.0.8
Browse files Browse the repository at this point in the history
- Modified file doip.library.util.LookupEntry, it now can process strings which have an empty result.
- Added some unit tests for LookupTable ans LookupEntry
- Added new features for LookupTable: It can now handle references to th search string and can have modifiers which modify the table at runtime
  • Loading branch information
marco-wehnert authored and doip committed Jan 18, 2020
1 parent 11b4cca commit 4649943
Show file tree
Hide file tree
Showing 10 changed files with 349 additions and 25 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
/.project
/.settings/
/bin/
doip-library.log
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ repositories {

dependencies {
implementation 'com.github.doip:doip-logging:1.1.5'
testImplementation 'com.github.doip:doip-junit:1.0.7'
testImplementation 'com.github.doip:doip-junit:1.0.8'
testImplementation 'junit:junit:4.12'
}

2 changes: 1 addition & 1 deletion src/main/java/doip/library/comm/DoipUdpMessageHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ public boolean processDatagramByLookupTable(DatagramPacket packet) {
logger.debug("Search request in UDP lookup table");
}
byte[] request = Arrays.copyOf(packet.getData(), packet.getLength());
response = lookupTable.findResult(request);
response = lookupTable.findResultAndApplyModifiers(request);
}

// Check if response had been found
Expand Down
58 changes: 52 additions & 6 deletions src/main/java/doip/library/util/LookupEntry.java
Original file line number Diff line number Diff line change
@@ -1,24 +1,66 @@
package doip.library.util;

import java.util.LinkedList;

public class LookupEntry {

private String regex;

private String result;

private LinkedList<LookupEntry> modifiers = new LinkedList<LookupEntry>();

public LookupEntry(String pattern) {
this.setUp(pattern);
}

public LookupEntry(String regex, String result) {
this.regex = regex;
this.result = result;
}

/**
* Setup a lookup entry by a given string. The string shall contain two strings
* separated by a colon character (=":"). All white spaces will be removed before
* splitting the string. A string also can be empty (that is the different way from
* standard split function in Java). In the Java split the string "1003:" will only produce
* one element. The method which has been implemented here will produce two elements where
* the second element it an empty string.
* @param text
*/
public void setUp(String text) {
text = text.replace(" ", "");
text = text.replace("\t", "");
// At first remove all white spaces. White spaces are only there to make the text more readable.
text = text.replaceAll(" ", "");
text = text.replaceAll("\t", "");

// Now we need to apply a small trick. for example "10 83:".split(":") will only
// return an array with one element. What we want is strings containing nothing will
// also produce an element in split function. We replace ":" with " : ", so empty
// elements also will produce an element in the result.

text = text.replace(":", " : ");

// Now we create a split
String[] texts = text.split(":");
if (texts.length != 2) {
throw new IllegalArgumentException();

// check the number of elements produced by split, it should be two or more entries.
if (texts.length < 2) {
throw new IllegalArgumentException("The argument <text> is not well formatted. It shall contain two strings which are separated by a colon character (=':'). But the he given string is " + text);
}

// Now remove white spaces which had been added before to implement correct behavior of our split.
this.regex = texts[0].replaceAll(" ", "");
this.result = texts[1].replaceAll(" ", "");

if (texts.length > 2 ) {
int numberOfModifiers = (texts.length / 2) - 1;
for (int i = 0; i < numberOfModifiers; i++) {
int index = (i + 1) * 2;
String modifierRegex = texts[index].replaceAll(" ", "");
String modifierResult = texts[index + 1].replaceAll(" ", "");
modifiers.add(new LookupEntry(modifierRegex, modifierResult));
}
}
this.regex = texts[0];
this.result = texts[1];
}

public String getRegex() {
Expand All @@ -36,4 +78,8 @@ public String getResult() {
public void setResult(String result) {
this.result = result;
}

public LinkedList<LookupEntry> getModifiers() {
return this.modifiers;
}
}
98 changes: 87 additions & 11 deletions src/main/java/doip/library/util/LookupTable.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import doip.logging.LogManager;
import doip.logging.Logger;

/**
* This class holds a sequence of expression-result pairs. The expression is a
Expand All @@ -13,10 +17,10 @@
* The first expression which matches the text will be returned as a result. If
* none of the expression matches then null will be returned.
*
* @author Marco Wehnert
*
*/
public class LookupTable {

private static Logger logger = LogManager.getLogger(LookupTable.class);

LinkedList<LookupEntry> lookupEntries = new LinkedList<LookupEntry>();

Expand All @@ -30,7 +34,7 @@ public class LookupTable {
* @param filename
* @throws IOException
*/
public void appendLookupEntriesFromFile(String filename) throws IOException {
public void addLookupEntriesFromFile(String filename) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(filename));
String line = br.readLine();
while (line != null) {
Expand All @@ -44,10 +48,10 @@ public void appendLookupEntriesFromFile(String filename) throws IOException {
br.close();
}

public void appendLookupEntriesFromFiles(String path, String[] files) throws IOException {
public void addLookupEntriesFromFiles(String path, String[] files) throws IOException {
for (int i = 0; i < files.length; i++) {
String fileWithPath = path + files[i];
this.appendLookupEntriesFromFile(fileWithPath);
this.addLookupEntriesFromFile(fileWithPath);
}
}

Expand All @@ -60,18 +64,22 @@ public void appendLookupEntriesFromFiles(String path, String[] files) throws IOE
* @return Returns the result if a entry could be found where the text matches
* the regular expression. If no entry will match it returns null.
*/
public String findResult(String text) {
public String findResultAndApplyModifiers(String text) {
for (LookupEntry lookupEntry : lookupEntries) {
if (text.matches(lookupEntry.getRegex())) {
return lookupEntry.getResult();
applyModifiers(lookupEntry.getModifiers());

String result = lookupEntry.getResult();
result = resolveReferences(text, result);
return result;
}
}

return null;
}

/**
* Simular to functon "String findResult(String text)", but here the parameter
* Similar to function "String findResult(String text)", but here the parameter
* and the return value is a byte array. The argument "bytes" will be first
* converted to a hex string, then call findResult(String text), and if the
* return value is not null it assumes that the return value is a hex string and
Expand All @@ -80,11 +88,79 @@ public String findResult(String text) {
* @param bytes
* @return
*/
public byte[] findResult(byte[] bytes) {
public byte[] findResultAndApplyModifiers(byte[] bytes) {
String text = Conversion.byteArrayToHexString(bytes);
String result = this.findResult(text);
String result = this.findResultAndApplyModifiers(text);
if (result == null)
return null;
return Conversion.hexStringToByteArray(result);
}

public void applyModifiers(List<LookupEntry> modifiers) {
for (LookupEntry modifier : modifiers) {
for (LookupEntry entry : this.lookupEntries) {
if (entry.getRegex().equals(modifier.getRegex())) {
entry.setResult(modifier.getResult());
}
}
}
}

public String resolveReferences(String request, String response) {
logger.trace(">>> public String resolveReferences(String request, String response)");
logger.debug("request = " + request);
logger.debug("response = " + response);

int mode = 0;

char[] responseChars = response.toCharArray();
int length = responseChars.length;
StringBuilder result = new StringBuilder(length);
StringBuilder reference = null;

int i = 0;
while (i < responseChars.length) {
logger.debug("Handle character " + i + " = '"+responseChars[i]+"'");
if (mode == 0) {
if (responseChars[i] == '[') {
logger.debug("Switch to mode 1");
mode = 1;

reference = new StringBuilder();
} else {
result.append(responseChars[i]);
}
} else {
if (responseChars[i] == ']') {
logger.debug("Switch to mode 0");
mode = 0;
int index = Integer.parseInt(reference.toString());
logger.debug("Reference number = " + index);
if ((index * 2) < request.length()) {
result.append(request.charAt(index * 2));
result.append(request.charAt(index * 2 + 1));
} else {
result.append("00");
}
} else {
reference.append(responseChars[i]);
}
}

i++;
}

logger.debug("Return " + result.toString());

logger.trace("<<< public String resolveReferences(String request, String response)");
return result.toString();
}

public void addEntry(LookupEntry entry) {
this.lookupEntries.add(entry);
}

public LinkedList<LookupEntry> getLookupEntries() {
return this.lookupEntries;
}
}
11 changes: 8 additions & 3 deletions src/test/java/doip/library/util/TestConversion.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,18 @@

import org.junit.Test;

import doip.junit.Assert;
import doip.library.util.Conversion;

public class TestConversion {

@Test
public void test() {
Assert.assertArrayEquals(new byte[] {0x00, (byte)0xA0}, Conversion.hexStringToByteArray("00 A0"));
public void testA() {
assertArrayEquals(new byte[] {0x00, (byte)0xA0}, Conversion.hexStringToByteArray("00 A0"));
}

@Test
public void testB() {
assertArrayEquals(new byte[0], Conversion.hexStringToByteArray(""));

}
}
88 changes: 88 additions & 0 deletions src/test/java/doip/library/util/TestLookupEntry.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package doip.library.util;

import doip.junit.Assert;

import java.util.LinkedList;
import java.util.List;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import doip.logging.LogManager;
import doip.logging.Logger;

public class TestLookupEntry {

private static Logger logger = LogManager.getLogger(TestLookupEntry.class);

@BeforeClass
public static void setUpBeforeClass() throws Exception {
logger.info("-----------------------------------------------------------------------------");
logger.info(">>> public static void setUpBeforeClass()");
logger.info("<<< public static void setUpBeforeClass()");
logger.info("-----------------------------------------------------------------------------");
}

@AfterClass
public static void tearDownAfterClass() throws Exception {
logger.info("-----------------------------------------------------------------------------");
logger.info(">>> public static void tearDownAfterClass()");
logger.info("<<< public static void tearDownAfterClass()");
logger.info("-----------------------------------------------------------------------------");
}

@Before
public void setUp() throws Exception {
logger.info("-----------------------------------------------------------------------------");
logger.info(">>> public void setUp()");
logger.info("<<< public void setUp()");
logger.info("-----------------------------------------------------------------------------");
}

@After
public void tearDown() throws Exception {
logger.info("-----------------------------------------------------------------------------");
logger.info(">>> public void tearDown()");
logger.info("<<< public void tearDown()");
logger.info("-----------------------------------------------------------------------------");
}

/**
* Test the string "1083:". Expected behavior is a lookup entry where result is just an empty string.
*/
@Test
public void test1083Colon() {
logger.info("#############################################################################");
logger.info(">>> public void test1083Colon()");

LookupEntry entry = new LookupEntry("1083:");
Assert.assertEquals("1083", entry.getRegex());
Assert.assertEquals("", entry.getResult());

logger.info("<<< public void test1083Colon()");
logger.info("#############################################################################");
}

@Test
public void test4Items() {
logger.info("#############################################################################");
logger.info(">>> public void test4Items()");

LookupEntry entry = new LookupEntry("10 03 : 50 03: 31010203 : 71010203");
Assert.assertEquals("1003", entry.getRegex());
Assert.assertEquals("5003", entry.getResult());
List<LookupEntry> modifiers = entry.getModifiers();
Assert.assertEquals(1, modifiers.size());
Assert.assertEquals("31010203", modifiers.get(0).getRegex());
Assert.assertEquals("71010203", modifiers.get(0).getResult());

logger.info("<<< public void test4Items()");
logger.info("#############################################################################");

}


}
Loading

0 comments on commit 4649943

Please sign in to comment.