/*license*\
XBN-Java: Copyright (C) 2014, Jeff Epstein (aliteralmind __DASH__ github __AT__ yahoo __DOT__ com)
This software is dual-licensed under the:
- Lesser General Public License (LGPL) version 3.0 or, at your option, any later version;
- Apache Software License (ASL) version 2.0.
Either license may be applied at your discretion. More information may be found at
- http://en.wikipedia.org/wiki/Multi-licensing.
The text of both licenses is available in the root directory of this project, under the names "LICENSE_lgpl-3.0.txt" and "LICENSE_asl-2.0.txt". The latest copies may be downloaded at:
- LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt
- ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt
\*license*/
package com.github.xbn.linefilter.entity.raw;
import com.github.xbn.number.LengthInRange;
import com.github.xbn.io.TextAppenter;
import com.github.xbn.linefilter.entity.LineEntityException;
import com.github.xbn.analyze.validate.NullnessValidator;
import com.github.xbn.analyze.alter.NeedsToBeDeleted;
import com.github.xbn.analyze.alter.Altered;
import com.github.xbn.lang.CrashIfObject;
import com.github.xbn.linefilter.entity.raw.z.RawStealthBlockEntity_Fieldable;
import com.github.xbn.analyze.validate.ValueValidator;
/**
<p>A specialized and simplified block-entity used only to prevent {@code RawBlockEntity}s from incorrectly matching start or end-lines (preventing false-positives). The lines matched by a stealth-block are never kept. More accurately, the lines in a stealth block are only kept if its parent block keeps its {@linkplain com.github.xbn.linefilter.entity.raw.RawBlockEntity#doKeepMidLines() mid-lines}.</p>
<!--
Originates in
com.github.xbn.linefilter.StealthBlockEntity
required by
com.github.xbn.linefilter.entity.raw.RawStealthBlockEntity
...START
-->
<A NAME="cfg"></a><h3>Builder Configuration: {@link com.github.xbn.linefilter.entity.raw.z.RawStealthBlockEntity_Cfg RawStealthBlockEntity_Cfg}</h3>
<p><ul>
<li>{@link com.github.xbn.linefilter.entity.raw.z.RawStealthBlockEntity_CfgForNeeder#startValidator(ValueValidator) startValidator}, {@link com.github.xbn.linefilter.entity.raw.z.RawStealthBlockEntity_CfgForNeeder#endValidator(ValueValidator) endValidator}</li>
<li>{@link com.github.xbn.linefilter.entity.raw.z.RawStealthBlockEntity_CfgForNeeder#debugLineNumbers(Appendable) debugLineNumbers}, {@link com.github.xbn.linefilter.entity.raw.z.RawStealthBlockEntity_CfgForNeeder#filter(RawOnOffEntityFilter) filter}</li>
<li>{@link com.github.xbn.linefilter.entity.raw.z.RawStealthBlockEntity_CfgForNeeder#keepLines(boolean) keepLines}(b), {@link com.github.xbn.linefilter.entity.raw.z.RawStealthBlockEntity_CfgForNeeder#keepLines() keepLines}(), {@link com.github.xbn.linefilter.entity.raw.z.RawStealthBlockEntity_CfgForNeeder#discardLines() discardLines}(), </li>
<li><b>Other:</b> {@link com.github.xbn.linefilter.entity.raw.z.RawStealthBlockEntity_CfgForNeeder#reset() reset}, {@link com.github.xbn.linefilter.entity.raw.z.RawStealthBlockEntity_CfgForNeeder#chainID(boolean, Object) chainID}</li>
</ul></p>
<!--
Originates in
com.github.xbn.linefilter.StealthBlockEntity
required by
com.github.xbn.linefilter.entity.raw.RawStealthBlockEntity
...END
-->
* @since 0.1.0
* @author Copyright (C) 2014, Jeff Epstein ({@code aliteralmind __DASH__ github __AT__ yahoo __DOT__ com}), dual-licensed under the LGPL (version 3.0 or later) or the ASL (version 2.0). See source code for details. <a href="http://xbnjava.aliteralmind.com">{@code http://xbnjava.aliteralmind.com}</a>, <a href="https://github.com/aliteralmind/xbnjava">{@code https://github.com/aliteralmind/xbnjava}</a>
**/
public class RawStealthBlockEntity<L> extends RawBlockEntityBase<L> {
private final ValueValidator<L> startVldtr;
private final ValueValidator<L> endVldtr ;
private final boolean doKeep ;
/**
<p>YYY</p>
* @param fieldable May not be {@code null}.
*/
public RawStealthBlockEntity(RawStealthBlockEntity_Fieldable<L> fieldable) {
super(fieldable);
startVldtr = fieldable.getStartValidator();
endVldtr = fieldable.getEndValidator();
doKeep = fieldable.doKeepLines();
}
protected RawStealthBlockEntity(RawStealthBlockEntity<L> to_copy, int levels_belowRoot, RawParentEntity<L> parent, TextAppenter dbgAptrEveryLine_ifUseable, LengthInRange range_forEveryLineDebug) {
super(to_copy, levels_belowRoot, parent, dbgAptrEveryLine_ifUseable, range_forEveryLineDebug);
startVldtr = RawStealthBlockEntity.getVldtrCopyCINotRestricted(
to_copy.getStartValidator(), "Start");
endVldtr = RawStealthBlockEntity.getVldtrCopyCINotRestricted(
to_copy.getEndValidator(), "End");
doKeep = to_copy.doKeepJustAnalyzed();
resetStateBSE();
resetCountsBSE();
}
private static final <L> ValueValidator<L> getVldtrCopyCINotRestricted(ValueValidator<L> validator, String start_orEnd) {
try {
if(!validator.getRuleType().isRestricted()) {
throw new IllegalArgumentException("to_copy.get" + start_orEnd + "Validator().getRuleType() (" + validator.getRuleType() + ") is not RESTRICTED.");
}
} catch(RuntimeException rx) {
throw CrashIfObject.nullOrReturnCause(validator,
"to_copy.get" + start_orEnd + "Validator()", null, rx);
}
return validator.getObjectCopy();
}
public void resetState() {
super.resetState();
resetStateBSE();
}
protected void resetStateBSE() {
getStartValidator().resetState();
getEndValidator().resetState();
}
public void resetCounts() {
super.resetCounts();
resetCountsBSE();
}
protected void resetCountsBSE() {
getStartValidator().resetCounts();
getEndValidator().resetCounts();
}
protected ValueValidator<L> getStartValidator() {
return startVldtr;
}
protected ValueValidator<L> getEndValidator() {
return endVldtr;
}
public boolean doKeepJustAnalyzed() {
return doKeep;
}
public RawStealthBlockEntity<L> getCopyWithParentAssigned(int levels_belowRoot, RawParentEntity<L> parent, TextAppenter dbgAptrEveryLine_ifUseable, LengthInRange range_forEveryLineDebug) {
return new RawStealthBlockEntity<L>(this, levels_belowRoot, parent, dbgAptrEveryLine_ifUseable, range_forEveryLineDebug);
}
public StringBuilder appendRules(StringBuilder to_appendTo) {
try {
to_appendTo.append("getStartValidator()=[");
} catch(RuntimeException rx) {
throw CrashIfObject.nullOrReturnCause(to_appendTo, "to_appendTo", null, rx);
}
getStartValidator().appendRules(to_appendTo);
to_appendTo.append("], getEndValidator()=[");
getEndValidator().appendRules(to_appendTo);
return to_appendTo.append("]");
}
public L getAlteredPostResetCheck(L line_toValidate, L line_toAlter) {
if(!resetStartEndPreFilter_isActiveOrOn(line_toValidate)) {
return line_toAlter;
}
boolean isStart2 = NullnessValidator.isValidDefensive(
getStartValidator(), line_toValidate,
"getStartValidator()", "line_toValidate");
boolean isEnd2 = NullnessValidator.isValidDefensive(
getEndValidator(), line_toValidate,
"getEndValidator()", "line_toValidate");
if(isStart2 && isEnd2) {
throw new LineEntityException(getMostRecentLineNum(), line_toValidate, this, "Start and end lines found on the same line");
}
//Not both
if(!isActive()) {
if(isStart2) {
declareStartLine(true);
return declareAlteredReturnLineBodyUnchanged(line_toValidate, line_toAlter, "start");
}
//Not active
//Not start line
if(isEnd2) {
throw new LineEntityException(getMostRecentLineNum(), line_toValidate, this, "End-line found before stealth block started");
}
//Not active
//Not start line
//Not end line
declareAltered(Altered.NO, NeedsToBeDeleted.NO);
postFilter(line_toAlter);
return line_toAlter;
}
//Active
if(isStart2) {
throw new LineEntityException(getMostRecentLineNum(), line_toValidate, this, "Start-line found before previous block closed");
}
//Active
//Not start line
if(isEnd2) {
//isActive set to false on next iteratation.
declareEndLine(true);
return declareAlteredReturnLineBodyUnchanged(line_toValidate, line_toAlter, "end");
}
//isActive()=true
//isStartLine()=false
//isEndLine()=false, so...
//isMidLine()=true
declareMidLine(true);
return declareAlteredReturnLineBodyUnchanged(line_toValidate, line_toAlter, "mid");
}
private L declareAlteredReturnLineBodyUnchanged(L line_toValidate, L line_toAlter, String start_midEnd) {
declareAltered(Altered.YES, NeedsToBeDeleted.NO);
if(isEveryLineAptrUseableAndInRange()) {
getDebugAptrEveryLine().appentln(getDebuggingPrefix() + " " + start_midEnd + " line");
}
postFilter(line_toAlter);
return line_toAlter;
}
public void declareEndOfInput() {
if(isMidLine()) {
throw new LineEntityException(-1, null, this, "End of output reached, but block not closed");
}
crashIfRequiredAndNeverActive();
}
/**
* @param to_appendTo May not be {@code null}.
* @see #toString()
*/
public StringBuilder appendToString(StringBuilder to_appendTo) {
try {
to_appendTo.append("getStartValidator()=[").append(getStartValidator()).
append("], getEndValidator()=[").append(getEndValidator()).append("], ");
} catch(RuntimeException rx) {
throw CrashIfObject.nullOrReturnCause(to_appendTo, "to_appendTo", null, rx);
}
super.appendToString(to_appendTo);
return to_appendTo;
}
public String getDebuggingPrefix() {
return getDebuggingPrefixPrefixBldr().append("]").toString();
}
}