use of com.twinsoft.convertigo.beans.extractionrules.JavelinExtractionRuleResult in project convertigo by convertigo.
the class CommandVdx method execute.
public JavelinExtractionRuleResult execute(iJavelin javelin, Block block, BlockFactory blockFactory, org.w3c.dom.Document dom) {
JavelinExtractionRuleResult xrs = new JavelinExtractionRuleResult();
String textBlock = block.getText().trim();
XMLVector<XMLVector<String>> keywordTable = getKeywordTable();
boolean foundStar = false;
// handle keyword ending with a dot, ie : "Somm."
if (textBlock.endsWith("."))
textBlock = textBlock.substring(0, textBlock.length() - 1);
// handle keyword like "*Envoi", "*+Envoi", "* Envoi", "* + Envoi"
if (isStarFlag()) {
Block prevBlock = blockFactory.getPreviousBlock(block);
// in one block
if (textBlock.startsWith("*")) {
foundStar = true;
textBlock = textBlock.substring(1, textBlock.length());
if (textBlock.startsWith(" ")) {
textBlock = textBlock.substring(1, textBlock.length());
}
if (textBlock.startsWith("+")) {
textBlock = textBlock.substring(1, textBlock.length());
}
if (textBlock.startsWith(" ")) {
textBlock = textBlock.substring(1, textBlock.length());
}
}
// in several blocks
if ((prevBlock != null) && (prevBlock.getText().equals(" "))) {
prevBlock = blockFactory.getPreviousBlock(prevBlock);
}
if ((prevBlock != null) && (prevBlock.getText().equals("+"))) {
prevBlock = blockFactory.getPreviousBlock(prevBlock);
}
if ((prevBlock != null) && (prevBlock.getText().equals(" "))) {
prevBlock = blockFactory.getPreviousBlock(prevBlock);
}
if ((prevBlock != null) && (prevBlock.getText().equals("*"))) {
foundStar = true;
}
}
// test if the current block matches a keyword
for (int i = 0; i < keywordTable.size(); i++) {
XMLVector<String> keyword = keywordTable.get(i);
String textKeyword = keyword.get(0);
String dataKeyword = keyword.get(1);
String replaceTextKeyword = keyword.get(2);
String actionKeyword = keyword.get(3);
if (textBlock.equals(textKeyword) || (textBlock.equalsIgnoreCase(textKeyword) && !isCaseDependency())) {
// set its type to "keyword"
block.type = "keyword";
// set the "data" attribute to *
if (foundStar)
block.setOptionalAttribute("data", "*");
// may contains a "*"
if (dataKeyword.length() != 0) {
String data = block.getOptionalAttribute("data");
if (data != null)
block.setOptionalAttribute("data", data + dataKeyword);
else
block.setOptionalAttribute("data", dataKeyword);
} else // otherwise it keeps the old value
if (block.getOptionalAttribute("data") == null)
block.setOptionalAttribute("data", "");
// keep the original size
if (replaceTextKeyword.length() != 0) {
int len = block.length;
block.setText(replaceTextKeyword);
block.length = len;
}
// set the "action" attribute
if (actionKeyword.length() != 0) {
block.setOptionalAttribute("action", actionKeyword);
} else // otherwise it keeps the old value
if (block.getOptionalAttribute("action") == null)
block.setOptionalAttribute("action", "");
xrs.hasMatched = true;
xrs.newCurrentBlock = block;
return xrs;
}
}
xrs.hasMatched = false;
xrs.newCurrentBlock = block;
return xrs;
}
use of com.twinsoft.convertigo.beans.extractionrules.JavelinExtractionRuleResult in project convertigo by convertigo.
the class TranslateText method execute.
/**
* Applies the extraction rule to the current iJavelin object.
*
* @param javelin the Javelin object.
* @param block the current block to analyze.
* @param blockFactory the block context of the current block.
* @param dom the XML DOM.
*
* @return an ExtractionRuleResult object containing the result of
* the query.
*/
public JavelinExtractionRuleResult execute(iJavelin javelin, Block block, BlockFactory blockFactory, org.w3c.dom.Document dom) {
JavelinExtractionRuleResult xrs = new JavelinExtractionRuleResult();
String lang = dom.getDocumentElement().getAttribute("lang");
if (lang == null || lang.length() > 0) {
// retrieve fullpath of the dictionary
String filepath = Engine.theApp.filePropertyManager.getFilepathFromProperty(dictionary + "_" + lang + ".txt", getProject().getName());
String orphanspath = null;
if (generateOrphans) {
orphanspath = Engine.theApp.filePropertyManager.getFilepathFromProperty(dictionary + "_" + lang + "_orphans.txt", getProject().getName());
}
Engine.logBeans.trace("(TranslateText) Waiting for chachedDictionaries for " + filepath);
// retrieve the previous loaded dictionary
DictionaryEntry dictionaryEntry;
synchronized (cachedDictionaries) {
dictionaryEntry = cachedDictionaries.get(filepath);
if (dictionaryEntry == null) {
Engine.logBeans.debug("(TranslateText) Create a new dictionaryEntry for " + filepath);
dictionaryEntry = new DictionaryEntry();
cachedDictionaries.put(filepath, dictionaryEntry);
}
}
// check dictionary validity
Map<String, String> words;
synchronized (dictionaryEntry) {
File file = new File(filepath);
if (!file.exists()) {
file.getParentFile().mkdirs();
Engine.logBeans.error("(TranslateText) The dictionary file \"" + filepath + "\" does not exist");
} else {
if (file.lastModified() > dictionaryEntry.lastModified) {
dictionaryEntry.lastModified = -1;
}
// read the dictionary
if (dictionaryEntry.lastModified == -1) {
Engine.logBeans.trace("(TranslateText) Dictionary change for " + filepath);
dictionaryEntry.lastModified = file.lastModified();
dictionaryEntry.words.clear();
try {
FileUtils.loadProperties(dictionaryEntry.words, file, encoding);
Engine.logBeans.debug("(TranslateText) Dictionary had load " + dictionaryEntry.words.size() + " rules");
} catch (Exception e) {
dictionaryEntry.words.clear();
Engine.logBeans.error("(TranslateText) Error while opening dictionary.\nCannot read the dictionary file \"" + filepath + "\" :\n" + e.getMessage() + "\nPlease refer to the rule documentation.");
}
}
}
if (generateOrphans) {
if (dictionaryEntry.orphans == null) {
dictionaryEntry.orphans = Collections.synchronizedMap(new LinkedHashMap<String, String>());
Engine.logBeans.trace("(TranslateText) Prepare to generate orphans words");
try {
FileUtils.loadProperties(dictionaryEntry.orphans, new File(orphanspath), encoding);
} catch (Exception e) {
Engine.logBeans.debug("(TranslateText) The optional dictionary file \"" + orphanspath + "\" cannot be load :\n" + e.getMessage());
}
}
} else {
dictionaryEntry.orphans = null;
}
words = dictionaryEntry.words;
}
// Translate the block text
String txt = block.getText();
Engine.logBeans.debug("(TranslateText) Search translation for the string \"" + txt + "\"");
if (txt.length() != 0) {
String txtTranslated = words.get(txt);
if (txtTranslated != null) {
Engine.logBeans.debug("(TranslateText) Translated to \"" + txtTranslated + "\"");
block.setText(txtTranslated);
} else if (generateOrphans) {
synchronized (dictionaryEntry.orphans) {
Object ex = dictionaryEntry.orphans.put(txt, txt);
File file = new File(orphanspath);
if (ex == null || !file.exists()) {
try {
Engine.logBeans.debug("(TranslateText) New orphan word \"" + txt + "\", write to " + orphanspath);
FileUtils.saveProperties(dictionaryEntry.orphans, file, encoding);
} catch (IOException e) {
Engine.logBeans.warn("(TranslateText) Cannot write the orphan dictionary file \"" + orphanspath + "\" :\n" + e.getMessage());
}
}
}
}
}
} else {
Engine.logBeans.debug("(TranslateText) No lang, no translation.");
}
xrs.hasMatched = true;
xrs.newCurrentBlock = block;
return xrs;
}
use of com.twinsoft.convertigo.beans.extractionrules.JavelinExtractionRuleResult in project convertigo by convertigo.
the class Table method execute.
/**
* Applies the extraction rule to the current iJavelin object.
*
* @param javelin the Javelin object.
* @param block the current block to analyze.
* @param blockFactory the block context of the current block.
*
* @return an ExtractionRuleResult object containing the result of
* the query.
*/
public JavelinExtractionRuleResult execute(iJavelin javelin, Block block, BlockFactory blockFactory, org.w3c.dom.Document dom) {
try {
JavelinExtractionRuleResult xrs = new JavelinExtractionRuleResult();
Block row;
Block item;
Block curBlock;
int curLine, firstColumn;
boolean automaticColumn = false;
table = null;
colonDispatch = new LinkedList<Block>();
firstLine = getSelectionScreenZone().y;
firstColumn = getSelectionScreenZone().x;
if (accumulatedData == null) {
// not accumulating, create a new table element
try {
// create the main block of the table
table = new Block();
table.tagName = this.tagName;
table.name = "table";
table.type = "table";
table.setText("");
table.bRender = true;
table.line = firstLine;
table.column = firstColumn;
table.setOptionalAttribute("offset", "" + getOffset());
// table.setOptionalAttribute("autoValidate", "" + isAutoValidate());
// insert this block before the current block
blockFactory.insertBlock(table, blockFactory.getPreviousBlock(block));
curBlock = block;
// create the table of actions if needed
if (columnSelection >= 0) {
boolean hasExtractActions = extractActions(blockFactory, dom, table);
if (!hasExtractActions) {
if (actions == null || actions.isEmpty())
Engine.logBeans.debug("Warning: no actions defined.");
else {
Block actionsDefined = new Block();
actionsDefined.name = "";
actionsDefined.type = "actionsTable";
actionsDefined.tagName = "actionsTable";
actionsDefined.setText("");
for (List<String> myAction : actions) {
Element element = dom.createElement("action");
element.setAttribute("char", myAction.get(0));
element.setAttribute("key", myAction.get(1));
element.setAttribute("label", myAction.get(2));
actionsDefined.addOptionalChildren(element);
}
table.addOptionalChildren(actionsDefined);
}
}
}
// create the first row
row = new Block();
row.name = "";
row.type = "row";
row.tagName = "row";
row.setText("");
row.setOptionalAttribute("index", Integer.toString(indexRow));
indexRow++;
row.setOptionalAttribute("page", Integer.toString(numPage));
// append the row block as a child to the main block only if we include titles
if (!doNotIncludeTitles) {
table.addOptionalChildren(row);
}
// note the current line.
curLine = curBlock.line;
} catch (Exception e) {
xrs.hasMatched = false;
xrs.newCurrentBlock = block;
return xrs;
}
} else {
// there is accumulated data, use it
table = accumulatedData;
// As we are in accumulate mode, some new actions may have been defined, exract them
extractActions(blockFactory, dom, table);
// prepare a new row in the table
row = new Block();
row.name = "";
row.type = "row";
row.tagName = "row";
row.setText("");
row.line = block.line;
row.column = block.column;
row.setOptionalAttribute("index", Integer.toString(indexRow));
indexRow++;
row.setOptionalAttribute("page", Integer.toString(numPage));
// set the first row in the table
// table.appendChild(row);
table.addOptionalChildren(row);
curBlock = block;
curLine = curBlock.line;
}
Engine.logBeans.trace("First block in the table, line: " + curBlock.line + " col: " + curBlock.column + " len : " + curBlock.length);
if (columns.size() == 0) {
Block temp;
// no columns were defined, so assume the first row will define the columns
// set the automatic Column mode flag.
automaticColumn = true;
curBlock = block;
while (curBlock != null && (curBlock.line == curLine)) {
if (!canBlockBeSelected(curBlock)) {
curBlock = blockFactory.getNextBlock(curBlock);
continue;
}
String title = StringUtils.normalize(curBlock.getText());
columns.add(new TableColumn(title, curBlock.column, curBlock.column + curBlock.length, 0));
Engine.logBeans.trace("Table defining '" + curBlock.getText() + "' from column: " + curBlock.column + " to column: " + (curBlock.column + curBlock.length));
temp = blockFactory.getNextBlock(curBlock);
blockFactory.removeBlock(curBlock);
curBlock = temp;
}
curLine = curBlock.line;
}
// we do not accumulate
if (accumulatedData == null) {
if (!doNotIncludeTitles) {
if (columnsBlocks == null) {
int tableSize = 0;
for (TableColumn tc : columns) {
item = new Block();
item.setText("");
item.name = "";
item.type = "item";
item.tagName = "Title";
item.column = tc.startColumn;
item.line = curBlock.line - 1;
item.setOptionalAttribute("size", Integer.toString(tc.endColumn - tc.startColumn + 1));
tableSize += tc.endColumn - tc.startColumn + 1;
row.addOptionalChildren(item);
String title = tc.title;
StringTokenizer st = new StringTokenizer(title, "\\", false);
if (st.countTokens() > titleH) {
titleH = st.countTokens();
}
String titleLabel;
Block titleBlock;
try {
while (true) {
titleLabel = st.nextToken();
titleBlock = new Block();
titleBlock.setText(titleLabel);
titleBlock.line = item.line - st.countTokens();
titleBlock.column = item.column;
item.addOptionalChildren(titleBlock);
}
} catch (NoSuchElementException e) {
// normal exit
}
}
table.setOptionalAttribute("size", "" + tableSize);
} else {
int tableSize = 0;
for (TableColumn tc : columns) {
item = new Block();
item.setText("");
item.name = "";
item.type = "item";
item.tagName = "Title";
item.column = tc.startColumn;
item.setOptionalAttribute("size", Integer.toString(tc.endColumn - tc.startColumn + 1));
tableSize += tc.endColumn - tc.startColumn + 1;
row.addOptionalChildren(item);
for (Block columnBlock : columnsBlocks) {
if ((tc.startColumn <= columnBlock.column) && (columnBlock.column <= tc.endColumn)) {
item.line = Math.min(item.line, columnBlock.line);
item.addOptionalChildren(columnBlock);
}
}
}
table.setOptionalAttribute("size", "" + tableSize);
}
}
row = new Block();
row.name = "";
row.type = "row";
row.tagName = "row";
row.setText("");
row.line = block.line;
row.column = block.column;
// set the first row in the table
table.addOptionalChildren(row);
row.setOptionalAttribute("index", Integer.toString(indexRow));
indexRow++;
row.setOptionalAttribute("page", Integer.toString(numPage));
// store table in accumulatedData
accumulatedData = table;
}
// we found a matching block; scan all other blocks to get other table items
while (curBlock != null) {
Block temp;
if (!canBlockBeSelected(curBlock)) {
curBlock = blockFactory.getNextBlock(curBlock);
continue;
}
if ((curBlock.line - row.line) > max_index) {
// calc the number of lines skipped
// this will handle the empty lines...
int skip = (curBlock.line - row.line) / (max_index + 1);
for (int i = 0; i < skip; i++) {
// we changed line, so write all the columns built in the prevous row held in colonDispatch
writeColumns(row);
// clear the colonDispatch vector for next row
colonDispatch = new LinkedList<Block>();
// set the line reference
curLine = curBlock.line;
// build a new row
row = new Block();
row.name = "";
row.type = "row";
row.tagName = "row";
row.setText("");
// row line depends on lines skipped
row.line = curBlock.line - skip + i + 1;
row.column = curBlock.column;
table.addOptionalChildren(row);
row.setOptionalAttribute("index", Integer.toString(indexRow));
indexRow++;
row.setOptionalAttribute("page", Integer.toString(numPage));
if (keepEmptyLines && skip > 1) {
// if we skipped lines (Empty lines) insert a fake block as the writeColumns function
// will discard any empty block.
Block fakeBlock = new Block();
fakeBlock.line = row.line;
fakeBlock.column = row.column;
fakeBlock.setText("");
fakeBlock.name = "";
fakeBlock.type = "static";
dispatchBlockInColumn(fakeBlock);
}
}
}
dispatchBlockInColumn(curBlock);
temp = blockFactory.getNextBlock(curBlock);
blockFactory.removeBlock(curBlock);
curBlock = temp;
}
// write the last row
writeColumns(row);
if (automaticColumn)
columns = new XMLVector<TableColumn>();
table.setOptionalAttribute("rows", Integer.toString(indexRow - 1));
table.setOptionalAttribute("titleheight", "" + titleH);
int tableWidth = getSelectionScreenZone().width;
int tableHeight = getSelectionScreenZone().height;
Engine.logBeans.debug("SelectionScreenZone tableWidth : " + tableWidth + "tableHeight" + tableHeight);
if (tableWidth != -1)
table.setOptionalAttribute("width", Integer.toString(tableWidth));
else
table.setOptionalAttribute("width", Integer.toString(javelin.getScreenWidth()));
if (tableHeight != -1)
table.setOptionalAttribute("height", Integer.toString(tableHeight + resize));
else
table.setOptionalAttribute("height", Integer.toString(javelin.getScreenHeight() + resize));
addMashupAttribute(table);
xrs.hasMatched = true;
xrs.newCurrentBlock = block;
return xrs;
} finally {
if (doNotAccumulate) {
accumulatedData = null;
} else {
numPage++;
}
}
}
use of com.twinsoft.convertigo.beans.extractionrules.JavelinExtractionRuleResult in project convertigo by convertigo.
the class TagName method execute.
/**
* Applies the extraction rule to the current iJavelin object.
*
* @param javelin the Javelin object.
* @param block the current block to analyze.
* @param blockFactory the block context of the current block.
*
* @return an ExtractionRuleResult object containing the result of
* the query.
*/
public JavelinExtractionRuleResult execute(iJavelin javelin, Block block, BlockFactory blockFactory, org.w3c.dom.Document dom) {
JavelinExtractionRuleResult xrs = new JavelinExtractionRuleResult();
String tagName = "";
Block prevBlock;
xrs.hasMatched = false;
xrs.newCurrentBlock = block;
// test if we have a tag name explicitly defined, if it is the case return the tag name
if (this.tagName.length() != 0) {
Engine.logBeans.trace("FieldName extraction rule matched by explicitly defined tag : " + this.tagName);
block.tagName = this.tagName;
block.setOptionalAttribute("history", (bSaveHistory ? "true" : "false"));
addMashupAttribute(block);
xrs.hasMatched = true;
xrs.newCurrentBlock = block;
return xrs;
}
// first search in our list of described fields for a field matching with
// coordinates
tagName = findFieldByCoord(block);
if (labelPolicy == TagName.LABEL_POLICY_EXPLICIT) {
if (tagName.length() == 0) {
throw new IllegalArgumentException("TagName extraction rule: \"" + getName() + "\"\nThe label policy is set to 'Explicit' while the tag name property is empty!");
}
block.tagName = tagName;
Engine.logBeans.trace("FieldName extraction rule matched by coord. tag is : " + block.tagName);
block.setOptionalAttribute("history", (bSaveHistory ? "true" : "false"));
addMashupAttribute(block);
xrs.hasMatched = true;
xrs.newCurrentBlock = block;
return xrs;
}
// we did not match by coordinates, so try to get a valid tag name by scanning all
// the prevous or next blocks on the same line according to the scanForward setting
prevBlock = block;
String blockName;
while (prevBlock.line == block.line) {
if (labelPolicy == TagName.LABEL_POLICY_FROM_PREVIOUS_BLOCK)
prevBlock = blockFactory.getPreviousBlock(prevBlock);
else if (labelPolicy == TagName.LABEL_POLICY_FROM_NEXT_BLOCK)
prevBlock = blockFactory.getNextBlock(prevBlock);
if (prevBlock != null) {
if (prevBlock.type.equalsIgnoreCase("static")) {
blockName = prevBlock.getText();
tagName = StringUtils.normalize(blockName, false);
Engine.logBeans.trace("Found tag name: " + tagName + " (from " + blockName + ")");
if (tagName.length() != 0) {
if (prevBlock.line == block.line) {
// we created a valid tag, so stop here
break;
} else {
// the block is not on the same line, prepare for artificial tag
tagName = "";
}
} else {
tagName = "default-tagname";
}
}
} else {
tagName = "block";
break;
}
}
if (tagName.length() == 0) {
// we did not find on the same line a valid tag, so create one artificially
tagName = "default-tagname";
}
// we have a valid tagName, search in our Field list if we have a literal
String temp = findFieldByLiteral(tagName);
if (temp.length() != 0) {
block.tagName = temp;
Engine.logBeans.trace("FieldName extraction rule matched by literal tag is : " + block.tagName);
} else {
block.tagName = tagName;
Engine.logBeans.trace("FieldName extraction rule matched tag is : " + block.tagName);
}
addMashupAttribute(block);
block.setOptionalAttribute("history", (bSaveHistory ? "true" : "false"));
xrs.hasMatched = true;
xrs.newCurrentBlock = block;
return xrs;
}
use of com.twinsoft.convertigo.beans.extractionrules.JavelinExtractionRuleResult in project convertigo by convertigo.
the class Record method execute.
public JavelinExtractionRuleResult execute(iJavelin javelin, Block block, BlockFactory blockFactory, org.w3c.dom.Document dom) {
JavelinExtractionRuleResult xrs = new JavelinExtractionRuleResult();
Block curBlock = block, eorBlock = block, temp;
boolean found = false;
// recreate the regular expression object.
if (borRE == null) {
try {
setBorType(borType);
} catch (RESyntaxException e) {
Engine.logBeans.error("Unable to create the regular expression object for BOR type", e);
}
}
if (eorRE == null) {
try {
setEorType(eorType);
} catch (RESyntaxException e) {
Engine.logBeans.error("Unable to create the regular expression object for EOR type", e);
}
}
if (perPage) {
Engine.logBeans.trace("Applying Record rule to the current page");
// Test if it's the first block of the page
if (blockFactory.getPreviousBlock(block) != null) {
Engine.logBeans.trace("The block isn't the first block of the page, aborting ...");
xrs.hasMatched = false;
xrs.newCurrentBlock = block;
return xrs;
}
// Creation and initialisation of the parent bloc of the record
Block record = new Block();
Engine.logBeans.trace("Creation du bloc parent");
record.type = "record";
record.setText("");
record.name = "";
if (this.tagName.length() != 0)
record.tagName = this.tagName;
else
record.tagName = "record";
// Insert the main bloc in the blockFactory in first position
blockFactory.insertBlock(record, null);
Engine.logBeans.trace("Insertion du bloc parent");
// After being added, each block is deleted
while (curBlock != null) {
record.addOptionalChildren(curBlock);
Engine.logBeans.trace("appending child " + curBlock.tagName + " to record " + record.tagName);
temp = blockFactory.getNextBlock(curBlock);
blockFactory.removeBlock(curBlock);
curBlock = temp;
}
xrs.hasMatched = true;
xrs.newCurrentBlock = record;
return xrs;
} else {
Engine.logBeans.trace("Applying Record rule to block " + block.name);
// Tests if the block is in the specified zone and if it's a bor block
if (isBor(block)) {
// we look for an eor block
while ((curBlock = blockFactory.getNextBlock(curBlock)) != null) {
if (!canBlockBeSelected(curBlock))
continue;
if (isEor(curBlock)) {
eorBlock = curBlock;
found = true;
break;
}
}
// If the end of the screen has been reached, set the 'found' flag to true.
if (curBlock == null) {
found = true;
}
}
// of the main block of the record
if (found) {
Engine.logBeans.trace("Begining and End of Record " + this.tagName + " found");
Block recordBlock;
recordBlock = new Block();
Engine.logBeans.trace("Creation du bloc BOR");
recordBlock.type = "record";
recordBlock.setText("");
recordBlock.name = "";
recordBlock.line = block.line;
recordBlock.column = block.column;
if (this.tagName.length() != 0)
recordBlock.tagName = this.tagName;
// Insert the main block in the blockFactory in first position
blockFactory.insertBlock(recordBlock, blockFactory.getPreviousBlock(block));
Engine.logBeans.trace("BOR block inserted ...");
// Starts the block just after the bor
curBlock = blockFactory.getNextBlock(recordBlock);
Block nextBlock = null;
if (eorBlock != null) {
nextBlock = blockFactory.getNextBlock(eorBlock);
}
// and deleted from memory
while (curBlock != null) {
if (isEor(curBlock)) {
if (bor.equals(eor)) {
if (recordBlock.hasOptionalChildren()) {
break;
}
} else {
break;
}
}
recordBlock.addOptionalChildren(curBlock);
Engine.logBeans.trace("Appending child " + curBlock.tagName + " to record " + recordBlock.tagName);
temp = blockFactory.getNextBlock(curBlock);
blockFactory.removeBlock(curBlock);
curBlock = temp;
}
// Deletes the eor separator only if it's followed by a bor separator
// and sets the new current block
xrs.newCurrentBlock = recordBlock;
if (isBor(nextBlock) || (nextBlock == null)) {
if (eorBlock != null) {
blockFactory.removeBlock(eorBlock);
}
}
xrs.hasMatched = true;
return xrs;
}
}
xrs.hasMatched = false;
xrs.newCurrentBlock = block;
return xrs;
}
Aggregations