void prefixes() throws RegexException {
    /* literal string doesn't get any of this stuff */
        if (0 != (v.cflags & Flags.REG_QUOTE)) {
            return;
        }

    /* initial "***" gets special things */
        if (have(4) && next3('*', '*', '*')) {
            switch (charAtNowPlus(3)) {
            case '?':       /* "***?" error, msg shows version */
                throw new RegexException("REG_BADPAT");
            case '=':       /* "***=" shifts to literal string */
                v.note(Flags.REG_UNONPOSIX);
                v.cflags |= Flags.REG_QUOTE;
                v.cflags &= ~(Flags.REG_ADVANCED | Flags.REG_EXPANDED | Flags.REG_NEWLINE);
                v.now += 4;
                return;     /* and there can be no more prefixes */
            case ':':       /* "***:" shifts to AREs */
                v.note(Flags.REG_UNONPOSIX);
                v.cflags |= Flags.REG_ADVANCED;
                v.now += 4;
                break;
            default:        /* otherwise *** is just an error */
                throw new RegexException("REG_BADRPT");
            }
        }

    /* BREs and EREs don't get embedded options */
        if ((v.cflags & Flags.REG_ADVANCED) != Flags.REG_ADVANCED) {
            return;
        }

    /* embedded options (AREs only) */
        if (have(3) && next2('(', '?') && iscalpha(charAtNowPlus(2))) {
            v.note(Flags.REG_UNONPOSIX);
            v.now += 2;
            for (; !ateos() && iscalpha(charAtNow()); v.now++) {
                switch (charAtNow()) {
                case 'b':       /* BREs (but why???) */
                    v.cflags &= ~(Flags.REG_ADVANCED | Flags.REG_QUOTE);
                    break;
                case 'c':       /* case sensitive */
                    v.cflags &= ~Flags.REG_ICASE;
                    break;
                case 'e':       /* plain EREs */
                    v.cflags |= Flags.REG_EXTENDED;
                    v.cflags &= ~(Flags.REG_ADVF | Flags.REG_QUOTE);
                    break;
                case 'i':       /* case insensitive */
                    v.cflags |= Flags.REG_ICASE;
                    break;
                case 'm':       /* Perloid synonym for n */
                case 'n':       /* \n affects ^ $ . [^ */
                    v.cflags |= Flags.REG_NEWLINE;
                    break;
                case 'p':       /* ~Perl, \n affects . [^ */
                    v.cflags |= Flags.REG_NLSTOP;
                    v.cflags &= ~Flags.REG_NLANCH;
                    break;
                case 'q':       /* literal string */
                    v.cflags |= Flags.REG_QUOTE;
                    v.cflags &= ~Flags.REG_ADVANCED;
                    break;
                case 's':       /* single line, \n ordinary */
                    v.cflags &= ~Flags.REG_NEWLINE;
                    break;
                case 't':       /* tight syntax */
                    v.cflags &= ~Flags.REG_EXPANDED;
                    break;
                case 'w':       /* weird, \n affects ^ $ only */
                    v.cflags &= ~Flags.REG_NLSTOP;
                    v.cflags |= Flags.REG_NLANCH;
                    break;
                case 'x':       /* expanded syntax */
                    v.cflags |= Flags.REG_EXPANDED;
                    break;
                default:
                    throw new RegexException("REG_BADOPT");
                }
            }

            if (!next1(')')) {
                throw new RegexException("REG_BADOPT");
            }
            v.now++;
            if (0 != (v.cflags & Flags.REG_QUOTE)) {
                v.cflags &= ~(Flags.REG_EXPANDED | Flags.REG_NEWLINE);
            }
        }
    }

prefixes - implement various special prefixes


void lexnest(char[] interpolated) {
        assert v.savepattern == null;   /* only one level of nesting */
        v.savepattern = v.pattern;
        v.savenow = v.now;
        v.savestop = v.stop;
        v.savenow = v.now;
        v.pattern = interpolated;
        v.now = 0;
        v.stop = v.pattern.length;
    }

void
lexnest
(
char
[
]
interpolated
)
{
assert
v
.
savepattern
==
;
/* only one level of nesting */
v
.
savepattern
=
v
.
pattern
;
v
.
savenow
=
v
.
now
;
v
.
savestop
=
v
.
stop
;
v
.
savenow
=
v
.
now
;
v
.
pattern
=
interpolated
;
v
.
now
=
0
;
v
.
stop
=
v
.
pattern
.
length
;
}

lexnest - "call a subroutine", interpolating string at the lexical level
Note, this is not a very general facility.  There are a number of
implicit assumptions about what sorts of strings can be subroutines.

lexnest - call a subroutine interpolating string at the lexical level Note this is not a very general facility . There are a number of implicit assumptions about what sorts of strings can be subroutines .


short getcolor(int codepoint) {
        try {
            return fullMap.get(codepoint);
        } catch (NullPointerException npe) {
            throw new RuntimeException(String.format(" CP %08x no mapping", codepoint));
        }
    }

short
getcolor
(
int
codepoint
)
{
try
{
return
fullMap
.
get
(
codepoint
)
;
}
catch
(
NullPointerException
npe
)
{
throw
new
RuntimeException
(
String
.
format
(
" CP %08x no mapping"
,
codepoint
)
)
;
}
}

Retrieve the color for a full codepoint.
@param codepoint
@return

Retrieve the color for a full codepoint .


StateSet initialize(int start) {
        // Discard state sets; reuse would be faster if we kept them,
        // but then we'd need the real cache.
        stateSets.clear();
        StateSet stateSet = new StateSet(nstates, ncolors);
        stateSet.states.set(cnfa.pre);
        stateSet.noprogress = true;
        // Insert into hash table based on that one state.
        stateSets.put(stateSet.states, stateSet);
        stateSet.setLastSeen(start);
        return stateSet;
    }

Called at the start of a match.
arguably we could just construct a new DFA each time.

Called at the start of a match . arguably we could just construct a new DFA each time .


int lastcold() {
        int nopr = 0;

        for (StateSet ss : stateSets.values()) {
            if (ss.noprogress && nopr < ss.getLastSeen()) {
                nopr = ss.getLastSeen();
            }
        }
        return nopr;
    }

int lastcold ( ) { int nopr = 0 ; for ( StateSet ss : stateSets . values ( ) ) { if ( ss . noprogress && nopr < ss . getLastSeen ( ) ) { nopr = ss . getLastSeen ( ) ; } } return nopr ; }

lastcold - determine last point at which no progress had been made

@return offset or -1


static UnicodeSet eclass(char c, boolean cases) {

    /* otherwise, none */
        if (cases) {
            return allcases(c);
        } else {
            UnicodeSet set = new UnicodeSet();
            set.add(c);
            return set;
        }
    }

static
UnicodeSet
eclass
(
char
c
,
boolean
cases
)
{
/* otherwise, none */
if
(
cases
)
{
return
allcases
(
c
)
;
}
else
{
UnicodeSet
set
=
new
UnicodeSet
(
)
;
set
.
add
(
c
)
;
return
set
;
}
}

eclass - Because we have no MCCE support, this
just processing single characters.

eclass - Because we have no MCCE support this just processing single characters .


public static UnicodeSet cclass(String cclassName, boolean casefold) throws RegexException {
        try {
            if (casefold) {
                return KNOWN_SETS_CI.get(cclassName);
            } else {
                return KNOWN_SETS_CS.get(cclassName);
            }
        } catch (ExecutionException e) {
            Throwables.propagateIfInstanceOf(e.getCause(), RegexException.class);
            throw new RegexRuntimeException(e.getCause());
        }
    }

public static UnicodeSet cclass ( String cclassName , boolean casefold ) throws RegexException { try { if ( casefold ) { return KNOWN_SETS_CI . get ( cclassName ) ; } else { return KNOWN_SETS_CS . get ( cclassName ) ; } } catch ( ExecutionException e ) { Throwables . propagateIfInstanceOf ( e . getCause ( ) , RegexException . class ) ; throw new RegexRuntimeException ( e . getCause ( ) ) ; } }

Return a UnicodeSet for a character class name.
It appears that the names that TCL accepts are also acceptable to ICU.

@param cclassName class name
@param casefold whether to include casefolding
@return set

Return a UnicodeSet for a character class name . It appears that the names that TCL accepts are also acceptable to ICU .


void carcsort(int first, int last) {
        int p;
        int q;
        long tmp;

        if (last - first <= 1) {
            return;
        }

        for (p = first; p <= last; p++) {
            for (q = p; q <= last; q++) {
                short pco = Cnfa.carcColor(arcs[p]);
                short qco = Cnfa.carcColor(arcs[q]);
                int pto = Cnfa.carcTarget(arcs[p]);
                int qto = Cnfa.carcTarget(arcs[q]);
                if (pco > qco || (pco == qco && pto > qto)) {
                    assert p != q;
                    tmp = arcs[p];
                    arcs[p] = arcs[q];
                    arcs[q] = tmp;
                }
            }
        }
    }

void carcsort ( int first , int last ) { int p ; int q ; long tmp ; if ( last - first <= 1 ) { return ; } for ( p = first ; p <= last ; p ++ ) { for ( q = p ; q <= last ; q ++ ) { short pco = Cnfa . carcColor ( arcs [ p ] ) ; short qco = Cnfa . carcColor ( arcs [ q ] ) ; int pto = Cnfa . carcTarget ( arcs [ p ] ) ; int qto = Cnfa . carcTarget ( arcs [ q ] ) ; if ( pco > qco || ( pco == qco && pto > qto ) ) { assert p != q ; tmp = arcs [ p ] ; arcs [ p ] = arcs [ q ] ; arcs [ q ] = tmp ; } } } }

carcsort - sort compacted-NFA arcs by color
Really dumb algorithm, but if the list is long enough for that to matter,
you're in real trouble anyway.

carcsort - sort compacted - NFA arcs by color Really dumb algorithm but if the list is long enough for that to matter you re in real trouble anyway .


String dumpst(boolean nfapresent) {
        StringBuilder sb = new StringBuilder();
        sb.append(String.format("%s. `%c'", shortId(), op));

        if (0 != (flags & LONGER)) {
            sb.append(" longest");
        }
        if (0 != (flags & SHORTER)) {
            sb.append(" shortest");
        }
        if (0 != (flags & MIXED)) {
            sb.append(" hasmixed");
        }
        if (0 != (flags & CAP)) {
            sb.append(" hascapture");
        }
        if (0 != (flags & BACKR)) {
            sb.append(" hasbackref");
        }
        if (0 == (flags & INUSE)) {
            sb.append(" UNUSED");
        }
        if (subno != 0) {
            sb.append(String.format(" (#%d)", subno));
        }
        if (min != 1 || max != 1) {
            sb.append(String.format(" {%d,", min));
            if (max != Compiler.INFINITY) {
                sb.append(String.format("%d", max));
            }
            sb.append("}");
        }
        if (nfapresent) {
            sb.append(String.format(" %d-%d", begin.no, end.no));
        }
        if (left != null) {
            sb.append(String.format(" L:%s", left.toString()));
        }
        if (right != null) {
            sb.append(String.format(" R:%s", right.toString()));
        }

        sb.append("\n");
        if (left != null) {
            left.dumpst(nfapresent);
        }
        if (right != null) {
            right.dumpst(nfapresent);
        }

        return sb.toString();
    }

String
dumpst
(
boolean
nfapresent
)
{
StringBuilder
sb
=
new
StringBuilder
(
)
;
sb
.
append
(
String
.
format
(
"%s. `%c'"
,
shortId
(
)
,
op
)
)
;
if
(
0
!=
(
flags
&
LONGER
)
)
{
sb
.
append
(
" longest"
)
;
}
if
(
0
!=
(
flags
&
SHORTER
)
)
{
sb
.
append
(
" shortest"
)
;
}
if
(
0
!=
(
flags
&
MIXED
)
)
{
sb
.
append
(
" hasmixed"
)
;
}
if
(
0
!=
(
flags
&
CAP
)
)
{
sb
.
append
(
" hascapture"
)
;
}
if
(
0
!=
(
flags
&
BACKR
)
)
{
sb
.
append
(
" hasbackref"
)
;
}
if
(
0
==
(
flags
&
INUSE
)
)
{
sb
.
append
(
" UNUSED"
)
;
}
if
(
subno
!=
0
)
{
sb
.
append
(
String
.
format
(
" (#%d)"
,
subno
)
)
;
}
if
(
min
!=
1
||
max
!=
1
)
{
sb
.
append
(
String
.
format
(
" {%d,"
,
min
)
)
;
if
(
max
!=
Compiler
.
INFINITY
)
{
sb
.
append
(
String
.
format
(
"%d"
,
max
)
)
;
}
sb
.
append
(
"}"
)
;
}
if
(
nfapresent
)
{
sb
.
append
(
String
.
format
(
" %d-%d"
,
begin
.
no
,
end
.
no
)
)
;
}
if
(
left
!=
)
{
sb
.
append
(
String
.
format
(
" L:%s"
,
left
.
toString
(
)
)
)
;
}
if
(
right
!=
)
{
sb
.
append
(
String
.
format
(
" R:%s"
,
right
.
toString
(
)
)
)
;
}
sb
.
append
(
"\n"
)
;
if
(
left
!=
)
{
left
.
dumpst
(
nfapresent
)
;
}
if
(
right
!=
)
{
right
.
dumpst
(
nfapresent
)
;
}
return
sb
.
toString
(
)
;
}


State newstate(int flag) {
        State newState = new State();
        newState.no = nstates++; // a unique number.
        if (states == null) {
            states = newState;
        }
        if (slast != null) {
            assert slast.next == null;
            slast.next = newState;
        }
        newState.prev = slast;
        slast = newState;
        newState.flag = flag;
        return newState;
    }

State
newstate
(
int
flag
)
{
State
newState
=
new
State
(
)
;
newState
.
no
=
nstates
++
;
// a unique number.
if
(
states
==
)
{
states
=
newState
;
}
if
(
slast
!=
)
{
assert
slast
.
next
==
;
slast
.
next
=
newState
;
}
newState
.
prev
=
slast
;
slast
=
newState
;
newState
.
flag
=
flag
;
return
newState
;
}

Factory method for new states.

@return a new state wired into this Nfa.


void moveouts(State old, State newState) {
        Arc a;

        assert old != newState;

        while ((a = old.outs) != null) {
            cparc(a, newState, a.to);
            freearc(a);
        }
    }

void moveouts ( State old , State newState ) { Arc a ; assert old != newState ; while ( ( a = old . outs ) != null ) { cparc ( a , newState , a . to ) ; freearc ( a ) ; } }

moveouts - move all out arcs of a state to another state


void moveins(State old, State newState) {
        Arc a;

        assert old != newState;

        while ((a = old.ins) != null) {
            cparc(a, a.from, newState);
            freearc(a);
        }
        assert old.nins == 0;
        assert old.ins == null;
    }

void moveins ( State old , State newState ) { Arc a ; assert old != newState ; while ( ( a = old . ins ) != null ) { cparc ( a , a . from , newState ) ; freearc ( a ) ; } assert old . nins == 0 ; assert old . ins == null ; }

moveins - move all in arcs of a state to another state
You might think this could be done better by just updating the
existing arcs, and you would be right if it weren't for the desire
for duplicate suppression, which makes it easier to just make new
ones to exploit the suppression built into newarc.

moveins - move all in arcs of a state to another state You might think this could be done better by just updating the existing arcs and you would be right if it weren t for the desire for duplicate suppression which makes it easier to just make new ones to exploit the suppression built into newarc .


void copyins(State old, State newState) {
        Arc a;

        assert old != newState;

        for (a = old.ins; a != null; a = a.inchain) {
            cparc(a, a.from, newState);
        }
    }

void copyins ( State old , State newState ) { Arc a ; assert old != newState ; for ( a = old . ins ; a != null ; a = a . inchain ) { cparc ( a , a . from , newState ) ; } }

copyins - copy all in arcs of a state to another state


void copyouts(State old, State newState) {
        Arc a;

        assert old != newState;

        for (a = old.outs; a != null; a = a.outchain) {
            cparc(a, newState, a.to);
        }
    }

void copyouts ( State old , State newState ) { Arc a ; assert old != newState ; for ( a = old . outs ; a != null ; a = a . outchain ) { cparc ( a , newState , a . to ) ; } }

copyouts - copy all out arcs of a state to another state


void dropstate(State s) {
        Arc a;

        while ((a = s.ins) != null) {
            freearc(a);
        }

        while ((a = s.outs) != null) {
            freearc(a);
        }

        freestate(s);
    }

void dropstate ( State s ) { Arc a ; while ( ( a = s . ins ) != null ) { freearc ( a ) ; } while ( ( a = s . outs ) != null ) { freearc ( a ) ; } freestate ( s ) ; }

get rid of a state, releasing all its arcs.
I'm not sure that all this is needed, as opposed to depending on the GC.

@param s the state to dispose of.

get rid of a state releasing all its arcs . I m not sure that all this is needed as opposed to depending on the GC .


void freestate(State s) {
        assert s != null;
        assert s.nins == 0;
        assert s.nouts == 0;
        if (s.next != null) {
            s.next.prev = s.prev;
        } else {
            assert s == slast;
            slast = s.prev;
        }
        if (s.prev != null) {
            s.prev.next = s.next;
        } else {
            assert s == states;
            states = s.next;
        }
    }

void freestate ( State s ) { assert s != null ; assert s . nins == 0 ; assert s . nouts == 0 ; if ( s . next != null ) { s . next . prev = s . prev ; } else { assert s == slast ; slast = s . prev ; } if ( s . prev != null ) { s . prev . next = s . next ; } else { assert s == states ; states = s . next ; } }

Unwire a state from the NFA.

@param s the state


void cparc(Arc oa, State from, State to) {
        newarc(oa.type, oa.co, from, to);
    }

void cparc ( Arc oa , State from , State to ) { newarc ( oa . type , oa . co , from , to ) ; }

cparc - allocate a new arc within an NFA, copying details from old one

cparc - allocate a new arc within an NFA copying details from old one


void duptraverse(State s, State stmp) {
        Arc a;

        if (s.tmp != null) {
            return;     /* already done */
        }

        s.tmp = (stmp == null) ? newstate() : stmp;
        if (s.tmp == null) {
            return;
        }

        for (a = s.outs; a != null; a = a.outchain) {
            duptraverse(a.to, null);
            assert a.to.tmp != null;
            cparc(a, s.tmp, a.to.tmp);
        }
    }

void
duptraverse
(
State
s
,
State
stmp
)
{
Arc
a
;
if
(
s
.
tmp
!=
)
{
return
;
/* already done */
}
s
.
tmp
=
(
stmp
==
)
newstate
(
)
:
stmp
;
if
(
s
.
tmp
==
)
{
return
;
}
for
(
a
=
s
.
outs
;
a
!=
;
a
=
a
.
outchain
)
{
duptraverse
(
a
.
to
,
)
;
assert
a
.
to
.
tmp
!=
;
cparc
(
a
,
s
.
tmp
,
a
.
to
.
tmp
)
;
}
}


void specialcolors() {
    /* false colors for BOS, BOL, EOS, EOL */
        if (parent == null) {
            bos[0] = cm.pseudocolor();
            bos[1] = cm.pseudocolor();
            eos[0] = cm.pseudocolor();
            eos[1] = cm.pseudocolor();
        } else {
            assert parent.bos[0] != Constants.COLORLESS;
            bos[0] = parent.bos[0];
            assert parent.bos[1] != Constants.COLORLESS;
            bos[1] = parent.bos[1];
            assert parent.eos[0] != Constants.COLORLESS;
            eos[0] = parent.eos[0];
            assert parent.eos[1] != Constants.COLORLESS;
            eos[1] = parent.eos[1];
        }
    }

specialcolors - fill in special colors for an NFA


void dumpnfa() {
        if (!LOG.isDebugEnabled() || !IS_DEBUG) {
            return;
        }

        LOG.debug("dump nfa");

        StringBuilder sb = new StringBuilder();
        sb.append(String.format("pre %d, post %d init %d final %d", pre.no, post.no, init.no, finalState.no));

        if (bos[0] != Constants.COLORLESS) {
            sb.append(String.format(", bos [%d]", bos[0]));
        }
        if (bos[1] != Constants.COLORLESS) {
            sb.append(String.format(", bol [%d]", bos[1]));
        }
        if (eos[0] != Constants.COLORLESS) {
            sb.append(String.format(", eos [%d]", eos[0]));
        }
        if (eos[1] != Constants.COLORLESS) {
            sb.append(String.format(", eol [%d]", eos[1]));
        }
        LOG.debug(sb.toString());

        for (State s = states; s != null; s = s.next) {
            dumpstate(s);
        }
        if (parent == null) {
            cm.dumpcolors();
        }
    }

void
dumpnfa
(
)
{
if
(
!
LOG
.
isDebugEnabled
(
)
||
!
IS_DEBUG
)
{
return
;
}
LOG
.
debug
(
"dump nfa"
)
;
StringBuilder
sb
=
new
StringBuilder
(
)
;
sb
.
append
(
String
.
format
(
"pre %d, post %d init %d final %d"
,
pre
.
no
,
post
.
no
,
init
.
no
,
finalState
.
no
)
)
;
if
(
bos
[
0
]
!=
Constants
.
COLORLESS
)
{
sb
.
append
(
String
.
format
(
", bos [%d]"
,
bos
[
0
]
)
)
;
}
if
(
bos
[
1
]
!=
Constants
.
COLORLESS
)
{
sb
.
append
(
String
.
format
(
", bol [%d]"
,
bos
[
1
]
)
)
;
}
if
(
eos
[
0
]
!=
Constants
.
COLORLESS
)
{
sb
.
append
(
String
.
format
(
", eos [%d]"
,
eos
[
0
]
)
)
;
}
if
(
eos
[
1
]
!=
Constants
.
COLORLESS
)
{
sb
.
append
(
String
.
format
(
", eol [%d]"
,
eos
[
1
]
)
)
;
}
LOG
.
debug
(
sb
.
toString
(
)
)
;
for
(
State
s
=
states
;
s
!=
;
s
=
s
.
next
)
{
dumpstate
(
s
)
;
}
if
(
parent
==
)
{
cm
.
dumpcolors
(
)
;
}
}

dumpnfa - dump an NFA in human-readable form

dumpnfa - dump an NFA in human - readable form


void dumpstate(State s) {
        Arc a;

        if (!LOG.isDebugEnabled() || !IS_DEBUG) {
            return;
        }

        StringBuilder sb = new StringBuilder();
        sb.append(String.format("State %d%s%c", s.no, (s.tmp != null) ? "T" : "",
                (s.flag != 0) ? (char)s.flag : '.'));
        if (s.prev != null && s.prev.next != s) {
            sb.append(String.format("\tstate chain bad"));
        }
        if (s.nouts == 0) {
            sb.append("\tno out arcs");
        } else {
            dumparcs(s, sb);
        }

        LOG.debug(sb.toString());
        for (a = s.ins; a != null; a = a.inchain) {
            if (a.to != s) {
                LOG.debug(String.format("\tlink from %d to %d on %d's in-chain",
                        a.from.no, a.to.no, s.no));
            }
        }
    }

void
dumpstate
(
State
s
)
{
Arc
a
;
if
(
!
LOG
.
isDebugEnabled
(
)
||
!
IS_DEBUG
)
{
return
;
}
StringBuilder
sb
=
new
StringBuilder
(
)
;
sb
.
append
(
String
.
format
(
"State %d%s%c"
,
s
.
no
,
(
s
.
tmp
!=
)
"T"
:
""
,
(
s
.
flag
!=
0
)
(
char
)
s
.
flag
:
'
'
)
)
;
if
(
s
.
prev
!=
&&
s
.
prev
.
next
!=
s
)
{
sb
.
append
(
String
.
format
(
"\tstate chain bad"
)
)
;
}
if
(
s
.
nouts
==
0
)
{
sb
.
append
(
"\tno out arcs"
)
;
}
else
{
dumparcs
(
s
,
sb
)
;
}
LOG
.
debug
(
sb
.
toString
(
)
)
;
for
(
a
=
s
.
ins
;
a
!=
;
a
=
a
.
inchain
)
{
if
(
a
.
to
!=
s
)
{
LOG
.
debug
(
String
.
format
(
"\tlink from %d to %d on %d's in-chain"
,
a
.
from
.
no
,
a
.
to
.
no
,
s
.
no
)
)
;
}
}
}

dumpstate - dump an NFA state in human-readable form

dumpstate - dump an NFA state in human - readable form


void dumparcs(State s, StringBuilder sb) {
        int pos;

        assert s.nouts > 0;
    /* printing arcs in reverse order is usually clearer */
        pos = dumprarcs(s.outs, s, 1, sb);
        if (pos != 1) {
            //sb.append("\n");
        }
    }

dumparcs - dump out-arcs in human-readable form

dumparcs - dump out - arcs in human - readable form


int dumprarcs(Arc a, State s, int pos, StringBuilder sb) {
        if (a.outchain != null) {
            pos = dumprarcs(a.outchain, s, pos, sb);
        }
        dumparc(a, s, sb);
        if (pos == 5) {
            sb.append("\n");
            pos = 1;
        } else {
            pos++;
        }
        return pos;
    }

int dumprarcs ( Arc a , State s , int pos , StringBuilder sb ) { if ( a . outchain != null ) { pos = dumprarcs ( a . outchain , s , pos , sb ) ; } dumparc ( a , s , sb ) ; if ( pos == 5 ) { sb . append ( "\n" ) ; pos = 1 ; } else { pos ++ ; } return pos ; }

dumprarcs - dump remaining outarcs, recursively, in reverse order

@return resulting print position

dumprarcs - dump remaining outarcs recursively in reverse order


void dumparc(Arc a, State s, StringBuilder sb) {

        sb.append("\t");
        switch (a.type) {
        case Compiler.PLAIN:
            sb.append(String.format("[%d]", a.co));
            break;
        case Compiler.AHEAD:
            sb.append(String.format(">%d>", a.co));
            break;
        case Compiler.BEHIND:
            sb.append(String.format("<%d<", a.co));
            break;
        case Compiler.LACON:
            sb.append(String.format(":%d:", a.co));
            break;
        case '^':
        case '$':
            sb.append(String.format("%c%d", (char)a.type, a.co));
            break;
        case Compiler.EMPTY:
            break;
        default:
            sb.append(String.format("0x%x/0%d", a.type, a.co));
            break;
        }
        if (a.from != s) {
            sb.append(String.format("?%d?", a.from.no));
        }
        sb.append("->");
        if (a.to == null) {
            sb.append("null");
            Arc aa;
            for (aa = a.to.ins; aa != null; aa = aa.inchain) {
                if (aa == a) {
                    break;      /* NOTE BREAK OUT */
                }
            }
            if (aa == null) {
                LOG.debug("?!?");   /* missing from in-chain */
            }
        } else {
            sb.append(String.format("%d", a.to.no));
        }
    }

void
dumparc
(
Arc
a
,
State
s
,
StringBuilder
sb
)
{
sb
.
append
(
"\t"
)
;
switch
(
a
.
type
)
{
case
Compiler
.
PLAIN
:
sb
.
append
(
String
.
format
(
"[%d]"
,
a
.
co
)
)
;
break
;
case
Compiler
.
AHEAD
:
sb
.
append
(
String
.
format
(
">%d>"
,
a
.
co
)
)
;
break
;
case
Compiler
.
BEHIND
:
sb
.
append
(
String
.
format
(
"<%d<"
,
a
.
co
)
)
;
break
;
case
Compiler
.
LACON
:
sb
.
append
(
String
.
format
(
":%d:"
,
a
.
co
)
)
;
break
;
case
'
'
:
case
'
'
:
sb
.
append
(
String
.
format
(
"%c%d"
,
(
char
)
a
.
type
,
a
.
co
)
)
;
break
;
case
Compiler
.
EMPTY
:
break
;
default
:
sb
.
append
(
String
.
format
(
"0x%x/0%d"
,
a
.
type
,
a
.
co
)
)
;
break
;
}
if
(
a
.
from
!=
s
)
{
sb
.
append
(
String
.
format
(
"?%d?"
,
a
.
from
.
no
)
)
;
}
sb
.
append
(
"->"
)
;
if
(
a
.
to
==
)
{
sb
.
append
(
"null"
)
;
Arc
aa
;
for
(
aa
=
a
.
to
.
ins
;
aa
!=
;
aa
=
aa
.
inchain
)
{
if
(
aa
==
a
)
{
break
;
/* NOTE BREAK OUT */
}
}
if
(
aa
==
)
{
LOG
.
debug
(
"?!?"
)
;
/* missing from in-chain */
}
}
else
{
sb
.
append
(
String
.
format
(
"%d"
,
a
.
to
.
no
)
)
;
}
}

dumparc - dump one outarc in readable form, including prefixing tab

dumparc - dump one outarc in readable form including prefixing tab


long optimize() throws RegexException {
        LOG.debug("initial cleanup");
        cleanup();      /* may simplify situation */
        dumpnfa();
        LOG.debug("empties");
        fixempties();   /* get rid of EMPTY arcs */
        LOG.debug("constraints");
        pullback(); /* pull back constraints backward */
        pushfwd();  /* push fwd constraints forward */
        LOG.debug("final cleanup");
        cleanup();      /* final tidying */
        return analyze();   /* and analysis */
    }

long
optimize
(
)
throws
RegexException
{
LOG
.
debug
(
"initial cleanup"
)
;
cleanup
(
)
;
/* may simplify situation */
dumpnfa
(
)
;
LOG
.
debug
(
"empties"
)
;
fixempties
(
)
;
/* get rid of EMPTY arcs */
LOG
.
debug
(
"constraints"
)
;
pullback
(
)
;
/* pull back constraints backward */
pushfwd
(
)
;
/* push fwd constraints forward */
LOG
.
debug
(
"final cleanup"
)
;
cleanup
(
)
;
/* final tidying */
return
analyze
(
)
;
/* and analysis */
}

optimize - optimize an NFA

@return re_info bits


long analyze() {
        Arc a;
        Arc aa;

        if (pre.outs == null) {
            return Flags.REG_UIMPOSSIBLE;
        }
        for (a = pre.outs; a != null; a = a.outchain) {
            for (aa = a.to.outs; aa != null; aa = aa.outchain) {
                if (aa.to == post) {
                    return Flags.REG_UEMPTYMATCH;
                }
            }
        }
        return 0;
    }

long analyze ( ) { Arc a ; Arc aa ; if ( pre . outs == null ) { return Flags . REG_UIMPOSSIBLE ; } for ( a = pre . outs ; a != null ; a = a . outchain ) { for ( aa = a . to . outs ; aa != null ; aa = aa . outchain ) { if ( aa . to == post ) { return Flags . REG_UEMPTYMATCH ; } } } return 0 ; }

analyze - ascertain potentially-useful facts about an optimized NFA

@return re_info bits.

analyze - ascertain potentially - useful facts about an optimized NFA


int combine(Arc con, Arc a) throws RegexException {
        //# define  CA(ct,at)   (((ct)<<CHAR_BIT) | (at))

        //CA(con->type, a->type)) {
        switch ((con.type << 8) | a.type) {

        case '^' << 8 | Compiler.PLAIN:     /* newlines are handled separately */
        case '$' << 8 | Compiler.PLAIN:
            return INCOMPATIBLE;

        case Compiler.AHEAD << 8 | Compiler.PLAIN:      /* color constraints meet colors */
        case Compiler.BEHIND << 8 | Compiler.PLAIN:
            if (con.co == a.co) {
                return SATISFIED;
            }
            return INCOMPATIBLE;

        case '^' << 8 | '^':        /* collision, similar constraints */
        case '$' << 8 | '$':
        case Compiler.AHEAD << 8 | Compiler.AHEAD:
        case Compiler.BEHIND << 8 | Compiler.BEHIND:
            if (con.co == a.co) {       /* true duplication */
                return SATISFIED;
            }
            return INCOMPATIBLE;

        case '^' << 8 | Compiler.BEHIND:        /* collision, dissimilar constraints */
        case Compiler.BEHIND << 8 | '^':
        case '$' << 8 | Compiler.AHEAD:
        case Compiler.AHEAD << 8 | '$':
            return INCOMPATIBLE;

        case '^' << 8 | Compiler.AHEAD:
        case Compiler.BEHIND << 8 | '$':
        case Compiler.BEHIND << 8 | Compiler.AHEAD:
        case '$' << 8 | '^':
        case '$' << 8 | Compiler.BEHIND:
        case Compiler.AHEAD << 8 | '^':
        case Compiler.AHEAD << 8 | Compiler.BEHIND:
        case '^' << 8 | Compiler.LACON:
        case Compiler.BEHIND << 8 | Compiler.LACON:
        case '$' << 8 | Compiler.LACON:
        case Compiler.AHEAD << 8 | Compiler.LACON:
            return COMPATIBLE;
        default:
            throw new RuntimeException("Impossible arc");

        }
    }

combine - constraint lands on an arc, what happens?

@return result

combine - constraint lands on an arc what happens?


void cleanup() {
        State s;
        State nexts;
        int n;

    /* clear out unreachable or dead-end states */
    /* use pre to mark reachable, then post to mark can-reach-post */
        markreachable(pre, null, pre);
        markcanreach(post, pre, post);
        for (s = states; s != null; s = nexts) {
            nexts = s.next;
            if (s.tmp != post && 0 == s.flag) {
                dropstate(s);
            }
        }
        assert post.nins == 0 || post.tmp == post;

        cleartraverse(pre);

        assert post.nins == 0 || post.tmp == null;
    /* the nins==0 (final unreachable) case will be caught later */

    /* renumber surviving states */
        n = 0;
        for (s = states; s != null; s = s.next) {
            s.no = n++;
        }
        nstates = n;
    }

cleanup - clean up NFA after optimizations


void markreachable(State s, State okay, State mark) {
        Arc a;

        if (s.tmp != okay) {
            return;
        }

        s.tmp = mark;

        for (a = s.outs; a != null; a = a.outchain) {
            markreachable(a.to, okay, mark);
        }
    }

void markreachable ( State s , State okay , State mark ) { Arc a ; if ( s . tmp != okay ) { return ; } s . tmp = mark ; for ( a = s . outs ; a != null ; a = a . outchain ) { markreachable ( a . to , okay , mark ) ; } }

markreachable - recursive marking of reachable states

@param s    a state
@param okay consider only states with this mark.
@param mark the value to mark with


void markcanreach(State s, State okay, State mark) {
        Arc a;

        if (s.tmp != okay) {
            return;
        }
        s.tmp = mark;

        for (a = s.ins; a != null; a = a.inchain) {
            markcanreach(a.from, okay, mark);
        }
    }

void markcanreach ( State s , State okay , State mark ) { Arc a ; if ( s . tmp != okay ) { return ; } s . tmp = mark ; for ( a = s . ins ; a != null ; a = a . inchain ) { markcanreach ( a . from , okay , mark ) ; } }

markcanreach - recursive marking of states which can reach here


void fixempties() {
        State s;
        State nexts;
        Arc a;
        Arc nexta;
        boolean progress;

    /* find and eliminate empties until there are no more */
        do {
            progress = false;
            for (s = states; s != null; s = nexts) {
                nexts = s.next;
                for (a = s.outs; a != null; a = nexta) {
                    nexta = a.outchain;
                    if (a.type == Compiler.EMPTY && unempty(a)) {
                        progress = true;
                    }
                    assert nexta == null || s.no != State.FREESTATE;
                }
            }
            if (progress) {
                dumpnfa();
            }
        } while (progress);
    }


boolean unempty(Arc a) {
        State from = a.from;
        State to = a.to;
        boolean usefrom;        /* work on from, as opposed to to? */

        assert a.type == Compiler.EMPTY;
        assert from != pre && to != post;

        if (from == to) {       /* vacuous loop */
            freearc(a);
            return true;
        }

    /* decide which end to work on */
        usefrom = true;         /* default:  attack from */
        if (from.nouts > to.nins) {
            usefrom = false;
        } else if (from.nouts == to.nins) {
        /* decide on secondary issue:  move/copy fewest arcs */
            if (from.nins > to.nouts) {
                usefrom = false;
            }
        }

        freearc(a);
        if (usefrom) {
            if (from.nouts == 0) {
            /* was the state's only outarc */
                moveins(from, to);
                freestate(from);
            } else {
                copyins(from, to);
            }
        } else {
            if (to.nins == 0) {
            /* was the state's only inarc */
                moveouts(to, from);
                freestate(to);
            } else {
                copyouts(to, from);
            }
        }

        return true;
    }

unempty - optimize out an EMPTY arc, if possible
Actually, as it stands this function always succeeds, but the return
value is kept with an eye on possible future changes.

unempty - optimize out an EMPTY arc if possible Actually as it stands this function always succeeds but the return value is kept with an eye on possible future changes .


private Map<String, String> getRuleParameters() throws CliExecutionException {
        Map<String, String> ruleParameters;
        if (ruleParametersFile == null) {
            ruleParameters = Collections.emptyMap();
        } else {
            Properties properties = new Properties();
            try {
                properties.load(new FileInputStream(ruleParametersFile));
            } catch (IOException e) {
                throw new CliExecutionException("Cannot read rule parameters file '" + ruleParametersFile.getPath() + "'.");
            }
            ruleParameters = new TreeMap<>();
            for (String name : properties.stringPropertyNames()) {
                ruleParameters.put(name, properties.getProperty(name));
            }
        }
        return ruleParameters;
    }

private
Map
<
String
,
String
>
getRuleParameters
(
)
throws
CliExecutionException
{
Map
<
String
,
String
>
ruleParameters
;
if
(
ruleParametersFile
==
)
{
ruleParameters
=
Collections
.
emptyMap
(
)
;
}
else
{
Properties
properties
=
new
Properties
(
)
;
try
{
properties
.
load
(
new
FileInputStream
(
ruleParametersFile
)
)
;
}
catch
(
IOException
e
)
{
throw
new
CliExecutionException
(
"Cannot read rule parameters file '"
+
ruleParametersFile
.
getPath
(
)
+
"'."
)
;
}
ruleParameters
=
new
TreeMap
<>
(
)
;
for
(
String
name
:
properties
.
stringPropertyNames
(
)
)
{
ruleParameters
.
put
(
name
,
properties
.
getProperty
(
name
)
)
;
}
}
return
ruleParameters
;
}

Reads the given rule parameters file.

@return The map containing the rule parameters.
@throws CliExecutionException
If the file cannot be read.


private Map<String, Collection<RuleInterpreterPlugin>> getRuleInterpreterPlugins() throws CliExecutionException {
        try {
            return pluginRepository.getRuleInterpreterPluginRepository().getRuleInterpreterPlugins(Collections.<String, Object> emptyMap());
        } catch (PluginRepositoryException e) {
            throw new CliExecutionException("Cannot get report plugins.", e);
        }
    }

private
Map
<
String
,
Collection
<
RuleInterpreterPlugin
>
>
getRuleInterpreterPlugins
(
)
throws
CliExecutionException
{
try
{
return
pluginRepository
.
getRuleInterpreterPluginRepository
(
)
.
getRuleInterpreterPlugins
(
Collections
.
<
String
,
Object
>
emptyMap
(
)
)
;
}
catch
(
PluginRepositoryException
e
)
{
throw
new
CliExecutionException
(
"Cannot get report plugins."
,
e
)
;
}
}

Get all configured rule interpreter plugins.

@return The map of rule interpreter plugins grouped by their supported
languages.
@throws CliExecutionException
If the plugins cannot be loaded or configured.

Get all configured rule interpreter plugins .


private Map<String, ReportPlugin> getReportPlugins(ReportContext reportContext) throws CliExecutionException {
        ReportPluginRepository reportPluginRepository;
        try {
            reportPluginRepository = pluginRepository.getReportPluginRepository();
            return reportPluginRepository.getReportPlugins(reportContext, pluginProperties);
        } catch (PluginRepositoryException e) {
            throw new CliExecutionException("Cannot get report plugins.", e);
        }
    }

private
Map
<
String
,
ReportPlugin
>
getReportPlugins
(
ReportContext
reportContext
)
throws
CliExecutionException
{
ReportPluginRepository
reportPluginRepository
;
try
{
reportPluginRepository
=
pluginRepository
.
getReportPluginRepository
(
)
;
return
reportPluginRepository
.
getReportPlugins
(
reportContext
,
pluginProperties
)
;
}
catch
(
PluginRepositoryException
e
)
{
throw
new
CliExecutionException
(
"Cannot get report plugins."
,
e
)
;
}
}

Get all configured report plugins.

@param reportContext
The ReportContext.
@return The list of report plugins.
@throws CliExecutionException
If the plugins cannot be loaded or configured.
@param reportContext


protected RuleSelection getRuleSelection(RuleSet ruleSet) {
        return RuleSelection.select(ruleSet, groupIds,constraintIds, conceptIds);
    }

protected RuleSelection getRuleSelection ( RuleSet ruleSet ) { return RuleSelection . select ( ruleSet , groupIds , constraintIds , conceptIds ) ; }

Return the selection of rules.

@param ruleSet
The rule set.
@return The selection of rules.


public void run(String[] args) throws CliExecutionException {
        Options options = gatherOptions(taskFactory);
        CommandLine commandLine = getCommandLine(args, options);
        interpretCommandLine(commandLine, options, taskFactory);
    }

public void run ( String [ ] args ) throws CliExecutionException { Options options = gatherOptions ( taskFactory ) ; CommandLine commandLine = getCommandLine ( args , options ) ; interpretCommandLine ( commandLine , options , taskFactory ) ; }

Run tasks according to the given arguments.

@param args
The arguments.
@throws CliExecutionException
If execution fails.

Run tasks according to the given arguments .


private static String getErrorMessage(CliExecutionException e) {
        StringBuffer messageBuilder = new StringBuffer();
        Throwable current = e;
        do {
            messageBuilder.append("-> ");
            messageBuilder.append(current.getMessage());
            current = current.getCause();
        }
        while (current != null);
        return messageBuilder.toString();
    }

private
static
String
getErrorMessage
(
CliExecutionException
e
)
{
StringBuffer
messageBuilder
=
new
StringBuffer
(
)
;
Throwable
current
=
e
;
do
{
messageBuilder
.
append
(
"-> "
)
;
messageBuilder
.
append
(
current
.
getMessage
(
)
)
;
current
=
current
.
getCause
(
)
;
}
while
(
current
!=
)
;
return
messageBuilder
.
toString
(
)
;
}

Extract an error message from the given exception and its causes.

@param e
The exception.
@return The error message.

Extract an error message from the given exception and its causes .


@SuppressWarnings("static-access")
    private void gatherStandardOptions(final Options options) {
        options.addOption(OptionBuilder.withArgName("p").withDescription(
                "Path to property file; default is jqassistant.properties in the class path").withLongOpt("properties").hasArg().create("p"));
        options.addOption(new Option("help", "print this message"));
    }

Gathers the standard options shared by all tasks.

@param options
The standard options.

Gathers the standard options shared by all tasks .


private void gatherTasksOptions(TaskFactory taskFactory, Options options) {
        for (Task task : taskFactory.getTasks()) {
            for (Option option : task.getOptions()) {
                options.addOption(option);
            }
        }
    }

private void gatherTasksOptions ( TaskFactory taskFactory , Options options ) { for ( Task task : taskFactory . getTasks ( ) ) { for ( Option option : task . getOptions ( ) ) { options . addOption ( option ) ; } } }

Gathers the task specific options for all tasks.

@param options
The task specific options.

Gathers the task specific options for all tasks .


private String gatherTaskNames(TaskFactory taskFactory) {
        final StringBuilder builder = new StringBuilder();
        for (String taskName : taskFactory.getTaskNames()) {
            builder.append("'").append(taskName).append("' ");
        }
        return builder.toString().trim();
    }

private
String
gatherTaskNames
(
TaskFactory
taskFactory
)
{
final
StringBuilder
builder
=
new
StringBuilder
(
)
;
for
(
String
taskName
:
taskFactory
.
getTaskNames
(
)
)
{
builder
.
append
(
"'"
)
.
append
(
taskName
)
.
append
(
"' "
)
;
}
return
builder
.
toString
(
)
.
trim
(
)
;
}

Returns a string containing the names of all supported tasks.

@return The names of all supported tasks.

Returns a string containing the names of all supported tasks .


private void interpretCommandLine(CommandLine commandLine, Options options, TaskFactory taskFactory) throws CliExecutionException {
        if(commandLine.hasOption(OPTION_HELP)) {
            printUsage(options, null);
            System.exit(1);
        }

        List<String> taskNames = commandLine.getArgList();
        if (taskNames.isEmpty()) {
            printUsage(options, "A task must be specified, i.e. one  of " + gatherTaskNames(taskFactory));
            System.exit(1);
        }
        List<Task> tasks = new ArrayList<>();
        for (String taskName : taskNames) {
            Task task = taskFactory.fromName(taskName);
            if (task == null) {
                printUsage(options, "Unknown task " + taskName);
            }
            tasks.add(task);
        }
        Map<String, Object> properties = readProperties(commandLine);
        PluginRepository pluginRepository = getPluginRepository();
        try {
            executeTasks(tasks, options, commandLine, pluginRepository, properties);
        } catch (PluginRepositoryException e) {
            throw new CliExecutionException("Unexpected plugin repository problem while executing tasks.", e);
        }
    }

Parse the command line and execute the requested task.

@param commandLine
The command line.
@param options
The known options.
@throws CliExecutionException
If an error occurs.

Parse the command line and execute the requested task .


private CommandLine getCommandLine(String[] args, Options options) {
        final CommandLineParser parser = new BasicParser();
        CommandLine commandLine = null;
        try {
            commandLine = parser.parse(options, args);
        } catch (ParseException e) {
            printUsage(options, e.getMessage());
            System.exit(1);
        }
        return commandLine;
    }

private CommandLine getCommandLine ( String [ ] args , Options options ) { final CommandLineParser parser = new BasicParser ( ) ; CommandLine commandLine = null ; try { commandLine = parser . parse ( options , args ) ; } catch ( ParseException e ) { printUsage ( options , e . getMessage ( ) ) ; System . exit ( 1 ) ; } return commandLine ; }

Parse the command line

@param args
The arguments.
@param options
The known options.
@return The command line.


private void executeTask(Task task, Options option, CommandLine commandLine, PluginRepository pluginRepository,
            Map<String, Object> properties) throws CliExecutionException {
        try {
            task.withStandardOptions(commandLine);
            task.withOptions(commandLine);
        } catch (CliConfigurationException e) {
            printUsage(option, e.getMessage());
            System.exit(1);
        }
        task.initialize(pluginRepository, properties);
        task.run();
    }

private void executeTask ( Task task , Options option , CommandLine commandLine , PluginRepository pluginRepository , Map < String , Object > properties ) throws CliExecutionException { try { task . withStandardOptions ( commandLine ) ; task . withOptions ( commandLine ) ; } catch ( CliConfigurationException e ) { printUsage ( option , e . getMessage ( ) ) ; System . exit ( 1 ) ; } task . initialize ( pluginRepository , properties ) ; task . run ( ) ; }

Executes a task.

@param task
The task.
@param option
The option.
@param commandLine
The command line.
@param properties
The plugin properties
@throws IOException


private Map<String, Object> readProperties(CommandLine commandLine) throws CliConfigurationException {
        final Properties properties = new Properties();
        InputStream propertiesStream;
        if (commandLine.hasOption("p")) {
            File propertyFile = new File(commandLine.getOptionValue("p"));
            if (!propertyFile.exists()) {
                throw new CliConfigurationException("Property file given by command line does not exist: " + propertyFile.getAbsolutePath());
            }
            try {
                propertiesStream = new FileInputStream(propertyFile);
            } catch (FileNotFoundException e) {
                throw new CliConfigurationException("Cannot open property file.", e);
            }
        } else {
            propertiesStream = Main.class.getResourceAsStream("/jqassistant.properties");
        }
        Map<String, Object> result = new HashMap<>();
        if (propertiesStream != null) {
            try {
                properties.load(propertiesStream);
            } catch (IOException e) {
                throw new CliConfigurationException("Cannot load properties from file.", e);
            }
            for (String name : properties.stringPropertyNames()) {
                result.put(name, properties.getProperty(name));
            }
        }
        return result;
    }

Read the plugin properties file if specified on the command line or if it exists on the class path.

@param commandLine
The command line.
@return The plugin properties.
@throws CliConfigurationException
If an error occurs.

Read the plugin properties file if specified on the command line or if it exists on the class path .


private void printUsage(final Options options, final String errorMessage) {
        if(errorMessage != null) {
            System.out.println("Error: " + errorMessage);
        }
        final HelpFormatter formatter = new HelpFormatter();
        formatter.printHelp(Main.class.getCanonicalName() + " <task> [options]", options);
        System.out.println("Tasks are: " + gatherTaskNames(taskFactory));
        System.out.println("Example: " + Main.class.getCanonicalName() + " scan -f java:classpath::target/classes java:classpath::target/test-classes");
    }

Print usage information.

@param options
The known options.
@param errorMessage
The error message to append.


private File getHomeDirectory() {
        String dirName = System.getenv(ENV_JQASSISTANT_HOME);
        if (dirName != null) {
            File dir = new File(dirName);
            if (dir.exists()) {
                LOGGER.debug("Using JQASSISTANT_HOME '" + dir.getAbsolutePath() + "'.");
                return dir;
            } else {
                LOGGER.warn("JQASSISTANT_HOME '" + dir.getAbsolutePath() + "' points to a non-existing directory.");
                return null;
            }
        }
        LOGGER.warn("JQASSISTANT_HOME is not set.");
        return null;
    }

private
File
getHomeDirectory
(
)
{
String
dirName
=
System
.
getenv
(
ENV_JQASSISTANT_HOME
)
;
if
(
dirName
!=
)
{
File
dir
=
new
File
(
dirName
)
;
if
(
dir
.
exists
(
)
)
{
LOGGER
.
debug
(
"Using JQASSISTANT_HOME '"
+
dir
.
getAbsolutePath
(
)
+
"'."
)
;
return
dir
;
}
else
{
LOGGER
.
warn
(
"JQASSISTANT_HOME '"
+
dir
.
getAbsolutePath
(
)
+
"' points to a non-existing directory."
)
;
return
;
}
}
LOGGER
.
warn
(
"JQASSISTANT_HOME is not set."
)
;
return
;
}

Determine the JQASSISTANT_HOME directory.

@return The directory or `null`.

Determine the JQASSISTANT_HOME directory .


private ClassLoader createPluginClassLoader() throws CliExecutionException {
        ClassLoader parentClassLoader = Task.class.getClassLoader();
        File homeDirectory = getHomeDirectory();
        if (homeDirectory != null) {
            File pluginDirectory = new File(homeDirectory, DIRECTORY_PLUGINS);
            if (pluginDirectory.exists()) {
                final List<URL> urls = new ArrayList<>();
                final Path pluginDirectoryPath = pluginDirectory.toPath();
                SimpleFileVisitor<Path> visitor = new SimpleFileVisitor<Path>() {

                    @Override
                    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                        if (file.toFile().getName().endsWith(".jar")) {
                            urls.add(file.toFile().toURI().toURL());
                        }
                        return FileVisitResult.CONTINUE;
                    }
                };
                try {
                    Files.walkFileTree(pluginDirectoryPath, visitor);
                } catch (IOException e) {
                    throw new CliExecutionException("Cannot read plugin directory.", e);
                }
                LOGGER.debug("Using plugin URLs: " + urls);
                return new com.buschmais.jqassistant.commandline.PluginClassLoader(urls, parentClassLoader);
            }
        }
        return parentClassLoader;
    }

private
ClassLoader
createPluginClassLoader
(
)
throws
CliExecutionException
{
ClassLoader
parentClassLoader
=
Task
.
class
.
getClassLoader
(
)
;
File
homeDirectory
=
getHomeDirectory
(
)
;
if
(
homeDirectory
!=
)
{
File
pluginDirectory
=
new
File
(
homeDirectory
,
DIRECTORY_PLUGINS
)
;
if
(
pluginDirectory
.
exists
(
)
)
{
final
List
<
URL
>
urls
=
new
ArrayList
<>
(
)
;
final
Path
pluginDirectoryPath
=
pluginDirectory
.
toPath
(
)
;
SimpleFileVisitor
<
Path
>
visitor
=
new
SimpleFileVisitor
<
Path
>
(
)
{
@
Override
public
FileVisitResult
visitFile
(
Path
file
,
BasicFileAttributes
attrs
)
throws
IOException
{
if
(
file
.
toFile
(
)
.
getName
(
)
.
endsWith
(
".jar"
)
)
{
urls
.
add
(
file
.
toFile
(
)
.
toURI
(
)
.
toURL
(
)
)
;
}
return
FileVisitResult
.
CONTINUE
;
}
}
;
try
{
Files
.
walkFileTree
(
pluginDirectoryPath
,
visitor
)
;
}
catch
(
IOException
e
)
{
throw
new
CliExecutionException
(
"Cannot read plugin directory."
,
e
)
;
}
LOGGER
.
debug
(
"Using plugin URLs: "
+
urls
)
;
return
new
com
.
buschmais
.
jqassistant
.
commandline
.
PluginClassLoader
(
urls
,
parentClassLoader
)
;
}
}
return
parentClassLoader
;
}

Create the class loader to be used for detecting and loading plugins.

@return The plugin class loader.
@throws com.buschmais.jqassistant.commandline.CliExecutionException
If the plugins cannot be loaded.

Create the class loader to be used for detecting and loading plugins .


public Set<String> getContainingIds(
			double minLongitude, double minLatitude, double maxLongitude, double maxLatitude)
	{
		Set<String> ids = new HashSet<>();
		forCellsIn(minLongitude, minLatitude, maxLongitude, maxLatitude, cell ->
		{
			if(ids.isEmpty())
			{
				ids.addAll(cell.getContainingIds());
			}
			else
			{
				ids.retainAll(cell.getContainingIds());
			}
		});
		return ids;
	}

public Set < String > getContainingIds ( double minLongitude , double minLatitude , double maxLongitude , double maxLatitude ) { Set < String > ids = new HashSet <> ( ) ; forCellsIn ( minLongitude , minLatitude , maxLongitude , maxLatitude , cell -> { if ( ids . isEmpty ( ) ) { ids . addAll ( cell . getContainingIds ( ) ) ; } else { ids . retainAll ( cell . getContainingIds ( ) ) ; } } ) ; return ids ; }

Identify which countries are guaranteed to contain the given bounding box fully.
The given bounding box may wrap around the 180th longitude, i.e minLongitude = 170 and
maxLongitude = -170.

@param minLongitude minimum longitude of geo position (-180...180)
@param minLatitude minimum latitude of geo position (-90...90)
@param maxLongitude maximum longitude of geo position (-180...180)
@param maxLatitude maximum latitude of geo position (-90...90)

@return the ids of the countries the given bounding box is guaranteed to be contained in,
not in any particular order

Identify which countries are guaranteed to contain the given bounding box fully . The given bounding box may wrap around the 180th longitude i . e minLongitude = 170 and maxLongitude = - 170 .


public Set<String> getIntersectingIds(
			double minLongitude, double minLatitude, double maxLongitude, double maxLatitude)
	{
		Set<String> ids = new HashSet<>();
		forCellsIn(minLongitude, minLatitude, maxLongitude, maxLatitude, cell ->
		{
			ids.addAll(cell.getAllIds());
		});
		return ids;
	}

public Set < String > getIntersectingIds ( double minLongitude , double minLatitude , double maxLongitude , double maxLatitude ) { Set < String > ids = new HashSet <> ( ) ; forCellsIn ( minLongitude , minLatitude , maxLongitude , maxLatitude , cell -> { ids . addAll ( cell . getAllIds ( ) ) ; } ) ; return ids ; }

Identify which countries intersect with the given bounding box. The given bounding box may
wrap around the 180th longitude, i.e minLongitude = 170 and maxLongitude = -170.

@param minLongitude minimum longitude of geo position (-180...180)
@param minLatitude minimum latitude of geo position (-90...90)
@param maxLongitude maximum longitude of geo position (-180...180)
@param maxLatitude maximum latitude of geo position (-90...90)

@return the ids of the countries the given bounding box intersects with, not in any
particular order

Identify which countries intersect with the given bounding box . The given bounding box may wrap around the 180th longitude i . e minLongitude = 170 and maxLongitude = - 170 .


public String uri(HttpMethod method, T target, Object... params) {
        MethodlessRouter<T> router = (method == null) ? anyMethodRouter : routers.get(method);

        // Fallback to anyMethodRouter if no router is found for the method
        if (router == null) {
            router = anyMethodRouter;
        }

        String ret = router.uri(target, params);
        if (ret != null) {
            return ret;
        }

        // Fallback to anyMethodRouter if the router was not anyMethodRouter and no path is found
        return (router != anyMethodRouter) ? anyMethodRouter.uri(target, params) : null;
    }

Given a target and params, this method tries to do the reverse routing
and returns the URI.

Placeholders in the path pattern will be filled with the params.
The params can be a map of {@code placeholder name -> value}
or ordered values.

If a param doesn't have a corresponding placeholder, it will be put
to the query part of the result URI.

@return {@code null} if there's no match

Given a target and params this method tries to do the reverse routing and returns the URI .


public OrderlessRouter<T> addRoute(String pathPattern, T target) {
        PathPattern p = new PathPattern(pathPattern);
        if (routes.containsKey(p)) {
            return this;
        }

        routes.put(p, target);
        addReverseRoute(target, p);
        return this;
    }

public OrderlessRouter < T > addRoute ( String pathPattern , T target ) { PathPattern p = new PathPattern ( pathPattern ) ; if ( routes . containsKey ( p ) ) { return this ; } routes . put ( p , target ) ; addReverseRoute ( target , p ) ; return this ; }

This method does nothing if the path pattern has already been added.
A path pattern can only point to one target.

This method does nothing if the path pattern has already been added . A path pattern can only point to one target .


public int size() {
        return first.routes().size() + other.routes().size() + last.routes().size();
    }

public int size ( ) { return first . routes ( ) . size ( ) + other . routes ( ) . size ( ) + last . routes ( ) . size ( ) ; }

Returns the number of routes in this router.

Returns the number of routes in this router .


public MethodlessRouter<T> addRouteFirst(String pathPattern, T target) {
        first.addRoute(pathPattern, target);
        return this;
    }

public MethodlessRouter < T > addRouteFirst ( String pathPattern , T target ) { first . addRoute ( pathPattern , target ) ; return this ; }

Adds route to the "first" section.

<p>A path pattern can only point to one target. This method does nothing if the pattern
has already been added.


public MethodlessRouter<T> addRoute(String pathPattern, T target) {
        other.addRoute(pathPattern, target);
        return this;
    }

public MethodlessRouter < T > addRoute ( String pathPattern , T target ) { other . addRoute ( pathPattern , target ) ; return this ; }

Adds route to the "other" section.

<p>A path pattern can only point to one target. This method does nothing if the pattern
has already been added.


public MethodlessRouter<T> addRouteLast(String pathPattern, T target) {
        last.addRoute(pathPattern, target);
        return this;
    }

public MethodlessRouter < T > addRouteLast ( String pathPattern , T target ) { last . addRoute ( pathPattern , target ) ; return this ; }

Adds route to the "last" section.

<p>A path pattern can only point to one target. This method does nothing if the pattern
has already been added.


public boolean anyMatched(String[] requestPathTokens) {
        return first.anyMatched(requestPathTokens) ||
                other.anyMatched(requestPathTokens) ||
                last.anyMatched(requestPathTokens);
    }

public boolean anyMatched ( String [ ] requestPathTokens ) { return first . anyMatched ( requestPathTokens ) || other . anyMatched ( requestPathTokens ) || last . anyMatched ( requestPathTokens ) ; }


private Criterion smartEqual(String property, Object value) {
        if (value == null) {
            return Restrictions.isNull(property);
        }
        else {
            return Restrictions.eq(property, value);
        }
    }

private Criterion smartEqual ( String property , Object value ) { if ( value == null ) { return Restrictions . isNull ( property ) ; } else { return Restrictions . eq ( property , value ) ; } }

There are two different Criterion for if a property is null or checking equality. This is a
convience method to return the one based on if value is null or not.

There are two different Criterion for if a property is null or checking equality . This is a convience method to return the one based on if value is null or not .


protected String getStoreFileName(String owner, String name) {
        final StringBuilder fileNameBuff = new StringBuilder();

        fileNameBuff.append(owner != null ? "_" + owner : "null");
        fileNameBuff.append("_");
        fileNameBuff.append(name != null ? "_" + name : "null");
        fileNameBuff.append(".bms.xml");

        return fileNameBuff.toString();
    }

protected String getStoreFileName ( String owner , String name ) { final StringBuilder fileNameBuff = new StringBuilder ( ) ; fileNameBuff . append ( owner != null ? "_" + owner : "null" ) ; fileNameBuff . append ( "_" ) ; fileNameBuff . append ( name != null ? "_" + name : "null" ) ; fileNameBuff . append ( ".bms.xml" ) ; return fileNameBuff . toString ( ) ; }

Generates the file name String for an owner and book name.

@param owner The owner of the bookmark set.
@param name The name of the bookmark set.
@return The file name for the owner and name.

Generates the file name String for an owner and book name .


protected int compareFolders(final Entry e1, final Entry e2) {
        final boolean f1 = e1 instanceof Folder;
        final boolean f2 = e2 instanceof Folder;

        if (f1 && !f2) {
            return -1;
        }
        else if (!f1 && f2) {
            return 1;
        }
        else {
            return 0;
        }
    }

protected int compareFolders ( final Entry e1 , final Entry e2 ) { final boolean f1 = e1 instanceof Folder ; final boolean f2 = e2 instanceof Folder ; if ( f1 && ! f2 ) { return - 1 ; } else if ( ! f1 && f2 ) { return 1 ; } else { return 0 ; } }

Folders are always greater than non-Folders, if they are both Folders
or both not Folders they are equal.

Folders are always greater than non - Folders if they are both Folders or both not Folders they are equal .


protected int compareEntries(final Entry e1, final Entry e2) {
        return new CompareToBuilder()
            .append(e1.getName(), e2.getName())
            .append(e1.getNote(), e2.getNote())
            .append(e1.getCreated(), e2.getCreated())
            .append(e1.getModified(), e2.getModified())
            .toComparison();
    }

protected int compareEntries ( final Entry e1 , final Entry e2 ) { return new CompareToBuilder ( ) . append ( e1 . getName ( ) , e2 . getName ( ) ) . append ( e1 . getNote ( ) , e2 . getNote ( ) ) . append ( e1 . getCreated ( ) , e2 . getCreated ( ) ) . append ( e1 . getModified ( ) , e2 . getModified ( ) ) . toComparison ( ) ; }

Compairs the entries by name, note, created and modified properties in that
order.

Compairs the entries by name note created and modified properties in that order .


protected int compareBookmarks(final Entry e1, final Entry e2) {
        if (e1 instanceof Bookmark && e2 instanceof Bookmark) {
            final Bookmark b1 = (Bookmark)e1;
            final Bookmark b2 = (Bookmark)e2;

            return new CompareToBuilder()
                .append(b1.getUrl(), b2.getUrl())
                .append(b1.isNewWindow(), b2.isNewWindow())
                .toComparison();
        }
        else {
            return 0;
        }
    }

protected int compareBookmarks ( final Entry e1 , final Entry e2 ) { if ( e1 instanceof Bookmark && e2 instanceof Bookmark ) { final Bookmark b1 = ( Bookmark ) e1 ; final Bookmark b2 = ( Bookmark ) e2 ; return new CompareToBuilder ( ) . append ( b1 . getUrl ( ) , b2 . getUrl ( ) ) . append ( b1 . isNewWindow ( ) , b2 . isNewWindow ( ) ) . toComparison ( ) ; } else { return 0 ; } }

If both classes are not Bookmarks they are equal. If they are both
bookmarks they are compared by url then newWindow properties.

If both classes are not Bookmarks they are equal . If they are both bookmarks they are compared by url then newWindow properties .


public void setServletClassLastModifiedTime(long lastModified) {
        if (this.servletClassLastModifiedTime < lastModified) {
            synchronized (this) {
                if (this.servletClassLastModifiedTime < lastModified) {
                    this.servletClassLastModifiedTime = lastModified;
                    reload = true;
                }
            }
        }
    }

public void setServletClassLastModifiedTime ( long lastModified ) { if ( this . servletClassLastModifiedTime < lastModified ) { synchronized ( this ) { if ( this . servletClassLastModifiedTime < lastModified ) { this . servletClassLastModifiedTime = lastModified ; reload = true ; } } } }

Sets the last-modified time of the servlet class file associated with
this JspServletWrapper.

@param lastModified Last-modified time of servlet class

Sets the last - modified time of the servlet class file associated with this JspServletWrapper .


public java.util.List<String> getDependants() {
	try {
	    Object target;
	    if (isTagFile) {
                if (reload) {
                    tagHandlerClass = ctxt.load();
                }
		target = tagHandlerClass.newInstance();
	    } else {
		target = getServlet();
	    }
	    if (target != null && target instanceof JspSourceDependent) {
                return ((JspSourceDependent) target).getDependants();
	    }
	} catch (Throwable ex) {
	}
	return null;
    }

public java . util . List < String > getDependants ( ) { try { Object target ; if ( isTagFile ) { if ( reload ) { tagHandlerClass = ctxt . load ( ) ; } target = tagHandlerClass . newInstance ( ) ; } else { target = getServlet ( ) ; } if ( target != null && target instanceof JspSourceDependent ) { return ( ( JspSourceDependent ) target ) . getDependants ( ) ; } } catch ( Throwable ex ) { } return null ; }

Get a list of files that the current page has source dependency on.

Get a list of files that the current page has source dependency on .


public Class findClass(String className) throws ClassNotFoundException {

        // If the class file is in memory, use it
        byte[] cdata = this.bytecodes.get(className);

        String path = className.replace('.', '/') + ".class";
        if (cdata == null) {
            // If the bytecode preprocessor is not enabled, use super.findClass
   	    // as usual.
/* XXX
            if (!PreprocessorUtil.isPreprocessorEnabled()) {
                return super.findClass(className);
            }
*/

            // read class data from file
            cdata = loadClassDataFromFile(path);
            if (cdata == null) {
                throw new ClassNotFoundException(className);
            }
        }

        // Preprocess the loaded byte code
/* XXX
        if (PreprocessorUtil.isPreprocessorEnabled()) {
            cdata = PreprocessorUtil.processClass(path, cdata);
        }
*/

        Class clazz = null;
        if (securityManager != null) {
            ProtectionDomain pd
                    = new ProtectionDomain(codeSource, permissionCollection);
            clazz = defineClass(className, cdata, 0, cdata.length, pd);
        } else {
            clazz = defineClass(className, cdata, 0, cdata.length);
        }
        return clazz;
    }


public static String[] parseAuthorization ( final HttpServletRequest request )
    {
        final String auth = request.getHeader ( "Authorization" );
        logger.debug ( "Auth header: {}", auth );

        if ( auth == null || auth.isEmpty () )
        {
            return null;
        }

        final String[] toks = auth.split ( "\\s" );
        if ( toks.length < 2 )
        {
            return null;
        }

        if ( !"Basic".equalsIgnoreCase ( toks[0] ) )
        {
            return null;
        }

        final byte[] authData = Base64.getDecoder ().decode ( toks[1] );
        final String authStr = StandardCharsets.ISO_8859_1.decode ( ByteBuffer.wrap ( authData ) ).toString ();

        logger.debug ( "Auth String: {}", authStr );

        final String[] authToks = authStr.split ( ":", 2 );

        logger.debug ( "Auth tokens: {}", new Object[] { authToks } );

        if ( authToks.length != 2 )
        {
            return null;
        }

        return authToks;
    }

public
static
String
[
]
parseAuthorization
(
final
HttpServletRequest
request
)
{
final
String
auth
=
request
.
getHeader
(
"Authorization"
)
;
logger
.
debug
(
"Auth header: {}"
,
auth
)
;
if
(
auth
==
||
auth
.
isEmpty
(
)
)
{
return
;
}
final
String
[
]
toks
=
auth
.
split
(
"\\s"
)
;
if
(
toks
.
length
<
2
)
{
return
;
}
if
(
!
"Basic"
.
equalsIgnoreCase
(
toks
[
0
]
)
)
{
return
;
}
final
byte
[
]
authData
=
Base64
.
getDecoder
(
)
.
decode
(
toks
[
1
]
)
;
final
String
authStr
=
StandardCharsets
.
ISO_8859_1
.
decode
(
ByteBuffer
.
wrap
(
authData
)
)
.
toString
(
)
;
logger
.
debug
(
"Auth String: {}"
,
authStr
)
;
final
String
[
]
authToks
=
authStr
.
split
(
":"
,
2
)
;
logger
.
debug
(
"Auth tokens: {}"
,
new
Object
[
]
{
authToks
}
)
;
if
(
authToks
.
length
!=
2
)
{
return
;
}
return
authToks
;
}

Parse the basic authentication header

@param request
the request to fetch the header from
@return either null if no valid header entry was found, or a
string array with exactly two entries (username, password)


public static ProtectedFunctionMapper getInstance() {
        ProtectedFunctionMapper funcMapper;
	if (SecurityUtil.isPackageProtectionEnabled()) {
	    funcMapper = AccessController.doPrivileged(
		new PrivilegedAction<ProtectedFunctionMapper>() {
		public ProtectedFunctionMapper run() {
		    return new ProtectedFunctionMapper();
		}
	    } );
	} else {
	    funcMapper = new ProtectedFunctionMapper();
	}
	funcMapper.fnmap = new java.util.HashMap<String, Method>();
	return funcMapper;
    }

public static ProtectedFunctionMapper getInstance ( ) { ProtectedFunctionMapper funcMapper ; if ( SecurityUtil . isPackageProtectionEnabled ( ) ) { funcMapper = AccessController . doPrivileged ( new PrivilegedAction < ProtectedFunctionMapper > ( ) { public ProtectedFunctionMapper run ( ) { return new ProtectedFunctionMapper ( ) ; } } ) ; } else { funcMapper = new ProtectedFunctionMapper ( ) ; } funcMapper . fnmap = new java . util . HashMap < String , Method > ( ) ; return funcMapper ; }

Generated Servlet and Tag Handler implementations call this
method to retrieve an instance of the ProtectedFunctionMapper.
This is necessary since generated code does not have access to
create instances of classes in this package.

@return A new protected function mapper.

Generated Servlet and Tag Handler implementations call this method to retrieve an instance of the ProtectedFunctionMapper . This is necessary since generated code does not have access to create instances of classes in this package .


public void mapFunction(String fnQName, final Class<?> c,
			    final String methodName, final Class<?>[] args )
    {
	java.lang.reflect.Method method;
        if (SecurityUtil.isPackageProtectionEnabled()){
            try{
                method = AccessController.doPrivileged(
                new PrivilegedExceptionAction<Method>(){
                    public Method run() throws Exception{
                        return c.getDeclaredMethod(methodName, args);
                    }
                });
            } catch (PrivilegedActionException ex){
                throw new RuntimeException(
                    "Invalid function mapping - no such method: "
		    + ex.getException().getMessage());
            }
        } else {
             try {
                method = c.getDeclaredMethod(methodName, args);
            } catch( NoSuchMethodException e ) {
                throw new RuntimeException(
                    "Invalid function mapping - no such method: "
		    + e.getMessage());
            }
        }

	this.fnmap.put(fnQName, method );
    }

Stores a mapping from the given EL function prefix and name to
the given Java method.

@param fnQName The EL function qualified name (including prefix)
@param c The class containing the Java method
@param methodName The name of the Java method
@param args The arguments of the Java method
@throws RuntimeException if no method with the given signature
could be found.

Stores a mapping from the given EL function prefix and name to the given Java method .


public static ProtectedFunctionMapper getMapForFunction(
		String fnQName, final Class<?> c,
                final String methodName, final Class<?>[] args )
    {
        java.lang.reflect.Method method;
        ProtectedFunctionMapper funcMapper;
        if (SecurityUtil.isPackageProtectionEnabled()){
            funcMapper = AccessController.doPrivileged(
                new PrivilegedAction<ProtectedFunctionMapper>(){
                public ProtectedFunctionMapper run() {
                    return new ProtectedFunctionMapper();
                }
            });

            try{
                method = AccessController.doPrivileged(
                    new PrivilegedExceptionAction<Method>(){
                    public Method run() throws Exception{
                        return c.getDeclaredMethod(methodName, args);
                    }
                });
            } catch (PrivilegedActionException ex){
                throw new RuntimeException(
                    "Invalid function mapping - no such method: "
                    + ex.getException().getMessage());
            }
        } else {
	    funcMapper = new ProtectedFunctionMapper();
             try {
                method = c.getDeclaredMethod(methodName, args);
            } catch( NoSuchMethodException e ) {
                throw new RuntimeException(
                    "Invalid function mapping - no such method: "
                    + e.getMessage());
            }
        }
        funcMapper.theMethod = method;
	return funcMapper;
    }

Creates an instance for this class, and stores the Method for
the given EL function prefix and name. This method is used for
the case when there is only one function in the EL expression.

@param fnQName The EL function qualified name (including prefix)
@param c The class containing the Java method
@param methodName The name of the Java method
@param args The arguments of the Java method
@throws RuntimeException if no method with the given signature
could be found.

Creates an instance for this class and stores the Method for the given EL function prefix and name . This method is used for the case when there is only one function in the EL expression .


public Method resolveFunction(String prefix, String localName) {
        if (this.fnmap != null) {
            return this.fnmap.get(prefix + ":" + localName);
        }
	return theMethod;
    }

public Method resolveFunction ( String prefix , String localName ) { if ( this . fnmap != null ) { return this . fnmap . get ( prefix + ":" + localName ) ; } return theMethod ; }

Resolves the specified local name and prefix into a Java.lang.Method.
Returns null if the prefix and local name are not found.

@param prefix the prefix of the function
@param localName the short name of the function
@return the result of the method mapping.  Null means no entry found.

Resolves the specified local name and prefix into a Java . lang . Method . Returns null if the prefix and local name are not found .


public void setValues(char[] ch, int offset, int length) {
        this.ch = ch;
        this.offset = offset;
        this.length = length;
    }

public void setValues ( char [ ] ch , int offset , int length ) { this . ch = ch ; this . offset = offset ; this . length = length ; }

Initializes the contents of the XMLString structure with the
specified values.

@param ch     The character array.
@param offset The offset into the character array.
@param length The length of characters from the offset.

Initializes the contents of the XMLString structure with the specified values .


public Object resolveVariable (String pName)
            throws javax.servlet.jsp.el.ELException {

        ELContext elContext = pageContext.getELContext();
        ELResolver elResolver = elContext.getELResolver();
        try {
            return elResolver.getValue(elContext, null, pName);
        } catch (javax.el.ELException ex) {
            throw new javax.servlet.jsp.el.ELException();
        }
    }

public Object resolveVariable ( String pName ) throws javax . servlet . jsp . el . ELException { ELContext elContext = pageContext . getELContext ( ) ; ELResolver elResolver = elContext . getELResolver ( ) ; try { return elResolver . getValue ( elContext , null , pName ) ; } catch ( javax . el . ELException ex ) { throw new javax . servlet . jsp . el . ELException ( ) ; } }

Resolves the specified variable within the given context.
Returns null if the variable is not found.

Resolves the specified variable within the given context . Returns null if the variable is not found .


public Node.Nodes parse(String inFileName)
	        throws FileNotFoundException, JasperException, IOException {
	// If we're parsing a packaged tag file or a resource included by it
	// (using an include directive), ctxt.getTagFileJar() returns the
	// JAR file from which to read the tag file or included resource,
	// respectively.
        isTagFile = ctxt.isTagFile();
        directiveOnly = false;
        return doParse(inFileName, null, ctxt.getTagFileJarUrl());
    }

Parses a JSP page or tag file. This is invoked by the compiler.

@param inFileName The path to the JSP page or tag file to be parsed.

Parses a JSP page or tag file . This is invoked by the compiler .


public Node.Nodes parse(String inFileName, Node parent,
			    URL jarFileUrl)
	        throws FileNotFoundException, JasperException, IOException {
        // For files that are statically included, isTagfile and directiveOnly
        // remain unchanged.
        return doParse(inFileName, parent, jarFileUrl);
    }

Processes an include directive with the given path.

@param inFileName The path to the resource to be included.
@param parent The parent node of the include directive.
@param jarFile The JAR file from which to read the included resource,
or null of the included resource is to be read from the filesystem

Processes an include directive with the given path .


public Node.Nodes parseTagFileDirectives(String inFileName)
	        throws FileNotFoundException, JasperException, IOException {
        boolean isTagFileSave = isTagFile;
        boolean directiveOnlySave = directiveOnly;
        isTagFile = true;
        directiveOnly = true;
        Node.Nodes page = doParse(inFileName, null,
                             (URL) ctxt.getTagFileJarUrls().get(inFileName));
        directiveOnly = directiveOnlySave;
        isTagFile = isTagFileSave;
        return page;
    }

public Node . Nodes parseTagFileDirectives ( String inFileName ) throws FileNotFoundException , JasperException , IOException { boolean isTagFileSave = isTagFile ; boolean directiveOnlySave = directiveOnly ; isTagFile = true ; directiveOnly = true ; Node . Nodes page = doParse ( inFileName , null , ( URL ) ctxt . getTagFileJarUrls ( ) . get ( inFileName ) ) ; directiveOnly = directiveOnlySave ; isTagFile = isTagFileSave ; return page ; }

Extracts tag file directive information from the tag file with the
given name.

This is invoked by the compiler

@param inFileName The name of the tag file to be parsed.

Extracts tag file directive information from the tag file with the given name .


private Node.Nodes doParse(String inFileName,
                               Node parent,
                               URL jarFileUrl)
	        throws FileNotFoundException, JasperException, IOException {

	Node.Nodes parsedPage = null;
	isEncodingSpecifiedInProlog = false;
	isDefaultPageEncoding = false;
        hasBom = false;

	JarFile jarFile = getJarFile(jarFileUrl);
	String absFileName = resolveFileName(inFileName);
	String jspConfigPageEnc = getJspConfigPageEncoding(absFileName);

	// Figure out what type of JSP document and encoding type we are
	// dealing with
	determineSyntaxAndEncoding(absFileName, jarFile, jspConfigPageEnc);

	if (parent != null) {
	    // Included resource, add to dependent list
	    compiler.getPageInfo().addDependant(absFileName);
	}

        comparePageEncodings(jspConfigPageEnc);

	// Dispatch to the appropriate parser
	if (isXml) {
	    // JSP document (XML syntax)
            // InputStream for jspx page is created and properly closed in
            // JspDocumentParser.
            parsedPage = JspDocumentParser.parse(this, absFileName,
                                                 jarFile, parent,
                                                 isTagFile, directiveOnly,
                                                 sourceEnc,
                                                 jspConfigPageEnc,
                                                 isEncodingSpecifiedInProlog);
	} else {
	    // Standard syntax
	    InputStreamReader inStreamReader = null;
	    try {
		inStreamReader = JspUtil.getReader(absFileName, sourceEnc,
						   jarFile, ctxt, err);
		JspReader jspReader = new JspReader(ctxt, absFileName,
						    sourceEnc, inStreamReader,
						    err);
                parsedPage = Parser.parse(this, absFileName, jspReader, parent,
                                          isTagFile, directiveOnly, jarFileUrl,
					  sourceEnc, jspConfigPageEnc,
					  isDefaultPageEncoding, hasBom);
            } finally {
		if (inStreamReader != null) {
		    try {
			inStreamReader.close();
		    } catch (Exception any) {
		    }
		}
	    }
	}

	if (jarFile != null) {
	    try {
		jarFile.close();
	    } catch (Throwable t) {}
	}

	baseDirStack.pop();

	return parsedPage;
    }

Parses the JSP page or tag file with the given path name.

@param inFileName The name of the JSP page or tag file to be parsed.
@param parent The parent node (non-null when processing an include
directive)
@param isTagFile true if file to be parsed is tag file, and false if it
is a regular JSP page
@param directivesOnly true if the file to be parsed is a tag file and
we are only interested in the directives needed for constructing a
TagFileInfo.
@param jarFile The JAR file from which to read the JSP page or tag file,
or null if the JSP page or tag file is to be read from the filesystem

Parses the JSP page or tag file with the given path name .


public Compiler createCompiler(boolean jspcMode) throws JasperException {
        if (jspCompiler != null ) {
            return jspCompiler;
        }

        jspCompiler = new Compiler(this, jsw, jspcMode);
        return jspCompiler;
    }

public Compiler createCompiler ( boolean jspcMode ) throws JasperException { if ( jspCompiler != null ) { return jspCompiler ; } jspCompiler = new Compiler ( this , jsw , jspcMode ) ; return jspCompiler ; }


public java.io.InputStream getResourceAsStream(String res)
           throws JasperException {
        return context.getResourceAsStream(canonicalURI(res));
    }

public java . io . InputStream getResourceAsStream ( String res ) throws JasperException { return context . getResourceAsStream ( canonicalURI ( res ) ) ; }

Gets a resource as a stream, relative to the meanings of this
context's implementation.
@return a null if the resource cannot be found or represented
as an InputStream.

Gets a resource as a stream relative to the meanings of this context s implementation .


private Optional<Instant> calcLastMod ()
    {
        Instant globalLastMod = null;

        for ( final ChannelInformation ci : this.channelService.list () )
        {
            final Optional<Instant> lastMod = ofNullable ( ci.getState ().getModificationTimestamp () );

            if ( globalLastMod == null || lastMod.get ().isAfter ( globalLastMod ) )
            {
                globalLastMod = lastMod.get ();
            }
        }
        return Optional.ofNullable ( globalLastMod );
    }

private Optional < Instant > calcLastMod ( ) { Instant globalLastMod = null ; for ( final ChannelInformation ci : this . channelService . list ( ) ) { final Optional < Instant > lastMod = ofNullable ( ci . getState ( ) . getModificationTimestamp ( ) ) ; if ( globalLastMod == null || lastMod . get ( ) . isAfter ( globalLastMod ) ) { globalLastMod = lastMod . get ( ) ; } } return Optional . ofNullable ( globalLastMod ) ; }

Find the last modification timestamp of all channels

@return the latest modification timestamp of all channels


ArrayList basicFindClassLoaders() {
		Class[] stack = contextFinder.getClassContext();
		ArrayList result = new ArrayList(1);
		ClassLoader previousLoader = null;
		for (int i = 1; i < stack.length; i++) {
			ClassLoader tmp = stack[i].getClassLoader();
			if (checkClass(stack[i]) && tmp != null && tmp != this) {
				if (checkClassLoader(tmp)) {
					if (previousLoader != tmp) {
						result.add(tmp);
						previousLoader = tmp;
					}
				}
				// stop at the framework classloader or the first bundle classloader
				if (Activator.getBundle(stack[i]) != null)
					break;
			}
		}
		return result;
	}

We assume that the bootclassloader never uses the context classloader to find classes in itself.

We assume that the bootclassloader never uses the context classloader to find classes in itself .


private boolean checkClassLoader(ClassLoader classloader) {
		if (classloader == null || classloader == getParent())
			return false;
		for (ClassLoader parent = classloader.getParent(); parent != null; parent = parent.getParent())
			if (parent == this)
				return false;
		return true;
	}

private boolean checkClassLoader ( ClassLoader classloader ) { if ( classloader == null || classloader == getParent ( ) ) return false ; for ( ClassLoader parent = classloader . getParent ( ) ; parent != null ; parent = parent . getParent ( ) ) if ( parent == this ) return false ; return true ; }

not be used as a delegate, otherwise we endup in endless recursion.

not be used as a delegate otherwise we endup in endless recursion .


private boolean startLoading(String name) {
		Set classesAndResources = (Set) cycleDetector.get();
		if (classesAndResources != null && classesAndResources.contains(name))
			return false;

		if (classesAndResources == null) {
			classesAndResources = new HashSet(3);
			cycleDetector.set(classesAndResources);
		}
		classesAndResources.add(name);
		return true;
	}

private boolean startLoading ( String name ) { Set classesAndResources = ( Set ) cycleDetector . get ( ) ; if ( classesAndResources != null && classesAndResources . contains ( name ) ) return false ; if ( classesAndResources == null ) { classesAndResources = new HashSet ( 3 ) ; cycleDetector . set ( classesAndResources ) ; } classesAndResources . add ( name ) ; return true ; }

False is returned when a cycle is being detected


private static byte[] readStreamHeader(InputStream in) throws IOException {
        byte[] streamHeader = new byte[DecoderUtil.STREAM_HEADER_SIZE];
        new DataInputStream(in).readFully(streamHeader);
        return streamHeader;
    }

private static byte [ ] readStreamHeader ( InputStream in ) throws IOException { byte [ ] streamHeader = new byte [ DecoderUtil . STREAM_HEADER_SIZE ] ; new DataInputStream ( in ) . readFully ( streamHeader ) ; return streamHeader ; }

Reads the Stream Header into a buffer.
This is a helper function for the constructors.

Reads the Stream Header into a buffer . This is a helper function for the constructors .


public static <T> PaginationResult<T> paginate ( final Integer startPage, final int pageSize, final List<T> fullDataSet )
    {
        return paginate ( startPage, pageSize, ( start, length ) -> {

            final int len = fullDataSet.size ();
            if ( start > len )
            {
                return Collections.emptyList ();
            }

            return fullDataSet.subList ( start, Math.min ( start + length, len ) );
        } );
    }

public static < T > PaginationResult < T > paginate ( final Integer startPage , final int pageSize , final List < T > fullDataSet ) { return paginate ( startPage , pageSize , ( start , length ) -> { final int len = fullDataSet . size ( ) ; if ( start > len ) { return Collections . emptyList ( ) ; } return fullDataSet . subList ( start , Math . min ( start + length , len ) ) ; } ) ; }

Paginate from a full data set

@param startPage
the start page
@param pageSize
the size of a single page
@param fullDataSet
the full data set
@return a subset of the full data set, containing the items which match
the page window


public static MetaKey fromString ( final String string )
    {
        final int idx = string.indexOf ( ':' );
        if ( idx < 1 )
        {
            // -1: none at all, 0: empty namespace
            return null;
        }

        if ( idx + 1 >= string.length () )
        {
            // empty key segment
            return null;
        }

        return new MetaKey ( string.substring ( 0, idx ), string.substring ( idx + 1 ), true );
    }

public
static
MetaKey
fromString
(
final
String
string
)
{
final
int
idx
=
string
.
indexOf
(
'
'
)
;
if
(
idx
<
1
)
{
// -1: none at all, 0: empty namespace
return
;
}
if
(
idx
+
1
>=
string
.
length
(
)
)
{
// empty key segment
return
;
}
return
new
MetaKey
(
string
.
substring
(
0
,
idx
)
,
string
.
substring
(
idx
+
1
)
,
true
)
;
}

Convert a string to a MetaKey if possible

@param string
the string to convert
@return the new MetaKey instance or null if the format was
invalid


private void fillRequirements () throws IOException
    {
        this.requirements.add ( new Dependency ( "rpmlib(CompressedFileNames)", "3.0.4-1", RpmDependencyFlags.LESS, RpmDependencyFlags.EQUAL, RpmDependencyFlags.RPMLIB ) );

        if ( !this.options.getFileDigestAlgorithm ().equals ( DigestAlgorithm.MD5 ) )
        {
            this.requirements.add ( new Dependency ( "rpmlib(FileDigests)", "4.6.0-1", RpmDependencyFlags.LESS, RpmDependencyFlags.EQUAL, RpmDependencyFlags.RPMLIB ) );
        }

        this.requirements.add ( new Dependency ( "rpmlib(PayloadFilesHavePrefix)", "4.0-1", RpmDependencyFlags.LESS, RpmDependencyFlags.EQUAL, RpmDependencyFlags.RPMLIB ) );
        this.options.getPayloadCoding ().createProvider ().fillRequirements ( this.requirements::add );
    }

private void fillRequirements ( ) throws IOException { this . requirements . add ( new Dependency ( "rpmlib(CompressedFileNames)" , "3.0.4-1" , RpmDependencyFlags . LESS , RpmDependencyFlags . EQUAL , RpmDependencyFlags . RPMLIB ) ) ; if ( ! this . options . getFileDigestAlgorithm ( ) . equals ( DigestAlgorithm . MD5 ) ) { this . requirements . add ( new Dependency ( "rpmlib(FileDigests)" , "4.6.0-1" , RpmDependencyFlags . LESS , RpmDependencyFlags . EQUAL , RpmDependencyFlags . RPMLIB ) ) ; } this . requirements . add ( new Dependency ( "rpmlib(PayloadFilesHavePrefix)" , "4.0-1" , RpmDependencyFlags . LESS , RpmDependencyFlags . EQUAL , RpmDependencyFlags . RPMLIB ) ) ; this . options . getPayloadCoding ( ) . createProvider ( ) . fillRequirements ( this . requirements :: add ) ; }

Fill extra requirements the RPM file itself may have

@throws IOException


public TagFileInfo getTagFile(String shortName) {

	TagFileInfo tagFile = super.getTagFile(shortName);
	if (tagFile == null) {
	    String path = tagFileMap.get(shortName);
	    if (path == null) {
		return null;
	    }

	    TagInfo tagInfo = null;
	    try {
		tagInfo = TagFileProcessor.parseTagFileDirectives(pc,
								  shortName,
								  path,
								  this);
	    } catch (JasperException je) {
		throw new RuntimeException(je.toString());
	    }

	    tagFile = new TagFileInfo(shortName, path, tagInfo);
	    vec.add(tagFile);

            this.tagFiles = vec.toArray(new TagFileInfo[vec.size()]);
	}

	return tagFile;
    }

public TagFileInfo getTagFile ( String shortName ) { TagFileInfo tagFile = super . getTagFile ( shortName ) ; if ( tagFile == null ) { String path = tagFileMap . get ( shortName ) ; if ( path == null ) { return null ; } TagInfo tagInfo = null ; try { tagInfo = TagFileProcessor . parseTagFileDirectives ( pc , shortName , path , this ) ; } catch ( JasperException je ) { throw new RuntimeException ( je . toString ( ) ) ; } tagFile = new TagFileInfo ( shortName , path , tagInfo ) ; vec . add ( tagFile ) ; this . tagFiles = vec . toArray ( new TagFileInfo [ vec . size ( ) ] ) ; } return tagFile ; }

Checks to see if the given tag name maps to a tag file path,
and if so, parses the corresponding tag file.

@return The TagFileInfo corresponding to the given tag name, or null if
the given tag name is not implemented as a tag file

Checks to see if the given tag name maps to a tag file path and if so parses the corresponding tag file .


private void parseImplicitTld(JspCompilationContext ctxt, String path)
            throws JasperException {

        InputStream is = null;
        TreeNode tld = null;

        try {
            URL uri = ctxt.getResource(path);
            if (uri == null) {
                // no implicit.tld
                return;
            }

            is = uri.openStream();
            /* SJSAS 6384538
            tld = new ParserUtils().parseXMLDocument(IMPLICIT_TLD, is);
            */
            // START SJSAS 6384538
            tld = new ParserUtils().parseXMLDocument(
                IMPLICIT_TLD, is, ctxt.getOptions().isValidationEnabled());
            // END SJSAS 6384538
        } catch (Exception ex) {
            throw new JasperException(ex);
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (Throwable t) {}
            }
        }

        this.jspversion = tld.findAttribute("version");

        Iterator list = tld.findChildren();
        while (list.hasNext()) {
            TreeNode element = (TreeNode) list.next();
            String tname = element.getName();
            if ("tlibversion".equals(tname)
                    || "tlib-version".equals(tname)) {
                this.tlibversion = element.getBody();
            } else if ("jspversion".equals(tname)
                    || "jsp-version".equals(tname)) {
                this.jspversion = element.getBody();
            } else if (!"shortname".equals(tname)
                    && !"short-name".equals(tname)) {
                err.jspError("jsp.error.implicitTld.additionalElements",
                             path, tname);
            }
        }

        // JSP version in implicit.tld must be 2.0 or greater
        Double jspVersionDouble = Double.valueOf(this.jspversion);
        if (Double.compare(jspVersionDouble, Constants.JSP_VERSION_2_0) < 0) {
            err.jspError("jsp.error.implicitTld.jspVersion", path,
                         this.jspversion);
        }
    }

Parses the JSP version and tlib-version from the implicit.tld at the
given path.

Parses the JSP version and tlib - version from the implicit . tld at the given path .


public String getChecksum ( final String fileName, final String algorithm )
    {
        if ( !this.digests.contains ( algorithm ) )
        {
            return null;
        }

        final String result = this.checksums.get ( fileName + ":" + algorithm );

        if ( result == null )
        {
            throw new IllegalStateException ( String.format ( "Stream '%s' not closed.", fileName ) );
        }

        return result;
    }

public
String
getChecksum
(
final
String
fileName
,
final
String
algorithm
)
{
if
(
!
this
.
digests
.
contains
(
algorithm
)
)
{
return
;
}
final
String
result
=
this
.
checksums
.
get
(
fileName
+
":"
+
algorithm
)
;
if
(
result
==
)
{
throw
new
IllegalStateException
(
String
.
format
(
"Stream '%s' not closed."
,
fileName
)
)
;
}
return
result
;
}

Get the digest of a closed file

@param fileName
the file name to get the digest for
@param algorithm
the digest algorithm
@return the digest or null if the digest was not requested.
The digest will be lower case hex encoded.
@throws IllegalStateException
If the file is still open or was never opened


public long getSize ( final String fileName )
    {
        final Long result = this.sizes.get ( fileName );

        if ( result == null )
        {
            throw new IllegalStateException ( String.format ( "Stream '%s' not closed or was not added", fileName ) );
        }

        return result;
    }

Get the size of a closed file

@param fileName
the file name to get the size for
@return the size
@throws IllegalStateException
If the file is still open or was never opened


private static void validateChannelName ( final String name, final ValidationContext ctx )
    {
        if ( name == null || name.isEmpty () )
        {
            return;
        }

        final Matcher m = ChannelService.NAME_PATTERN.matcher ( name );
        if ( !m.matches () )
        {
            ctx.error ( "names", String.format ( "The channel name '%s' must match the pattern '%s'", name, ChannelService.NAME_PATTERN.pattern () ) );
        }
    }

Validate the name of the channel

@param name
the channel name to test
@param ctx
the validation context


public void seekToBlock(int blockNumber) throws IOException {
        if (in == null)
            throw new XZIOException("Stream closed");

        if (blockNumber < 0 || blockNumber >= blockCount)
            throw new XZIOException("Invalid XZ Block number: " + blockNumber);

        // This is a bit silly implementation. Here we locate the uncompressed
        // offset of the specified Block, then when doing the actual seek in
        // seek(), we need to find the Block number based on seekPos.
        seekPos = getBlockPos(blockNumber);
        seekNeeded = true;
    }

Seeks to the beginning of the given XZ Block.

@throws      XZIOException
if blockNumber < 0 or
blockNumber >= getBlockCount(),
or if stream has been closed

@since 1.3

Seeks to the beginning of the given XZ Block .


private void locateBlockByPos(BlockInfo info, long pos) {
        if (pos < 0 || pos >= uncompressedSize)
            throw new IndexOutOfBoundsException(
                    "Invalid uncompressed position: " + pos);

        // Locate the Stream that contains the target position.
        IndexDecoder index;
        for (int i = 0; ; ++i) {
            index = streams.get(i);
            if (index.hasUncompressedOffset(pos))
                break;
        }

        // Locate the Block from the Stream that contains the target position.
        index.locateBlock(info, pos);

        assert (info.compressedOffset & 3) == 0;
        assert info.uncompressedSize > 0;
        assert pos >= info.uncompressedOffset;
        assert pos < info.uncompressedOffset + info.uncompressedSize;
    }

Locates the Block that contains the given uncompressed position.

Locates the Block that contains the given uncompressed position .