protected PropertyDescriptor[] lookupAnnotatedProperties(final Class type) {
		PropertyDescriptor[] properties = annotatedProperties.get(type);

		if (properties != null) {
			return properties;
		}

		ClassDescriptor cd = ClassIntrospector.get().lookup(type);
		PropertyDescriptor[] allProperties = cd.getAllPropertyDescriptors();

		List<PropertyDescriptor> list = new ArrayList<>();

		for (PropertyDescriptor propertyDescriptor : allProperties) {

			Annotation ann = null;

			if (propertyDescriptor.getFieldDescriptor() != null) {
				ann = propertyDescriptor.getFieldDescriptor().getField().getAnnotation(annotations);
			}
			if (ann == null && propertyDescriptor.getWriteMethodDescriptor() != null) {
				ann = propertyDescriptor.getWriteMethodDescriptor().getMethod().getAnnotation(annotations);
			}
			if (ann == null && propertyDescriptor.getReadMethodDescriptor() != null) {
				ann = propertyDescriptor.getReadMethodDescriptor().getMethod().getAnnotation(annotations);
			}

			if (ann != null) {
				list.add(propertyDescriptor);
			}
		}

		if (list.isEmpty()) {
			properties = EMPTY;
		} else {
			properties = list.toArray(new PropertyDescriptor[0]);
		}

		annotatedProperties.put(type, properties);

		return properties;
	}

protected PropertyDescriptor [ ] lookupAnnotatedProperties ( final Class type ) { PropertyDescriptor [ ] properties = annotatedProperties . get ( type ) ; if ( properties != null ) { return properties ; } ClassDescriptor cd = ClassIntrospector . get ( ) . lookup ( type ) ; PropertyDescriptor [ ] allProperties = cd . getAllPropertyDescriptors ( ) ; List < PropertyDescriptor > list = new ArrayList <> ( ) ; for ( PropertyDescriptor propertyDescriptor : allProperties ) { Annotation ann = null ; if ( propertyDescriptor . getFieldDescriptor ( ) != null ) { ann = propertyDescriptor . getFieldDescriptor ( ) . getField ( ) . getAnnotation ( annotations ) ; } if ( ann == null && propertyDescriptor . getWriteMethodDescriptor ( ) != null ) { ann = propertyDescriptor . getWriteMethodDescriptor ( ) . getMethod ( ) . getAnnotation ( annotations ) ; } if ( ann == null && propertyDescriptor . getReadMethodDescriptor ( ) != null ) { ann = propertyDescriptor . getReadMethodDescriptor ( ) . getMethod ( ) . getAnnotation ( annotations ) ; } if ( ann != null ) { list . add ( propertyDescriptor ) ; } } if ( list . isEmpty ( ) ) { properties = EMPTY ; } else { properties = list . toArray ( new PropertyDescriptor [ 0 ] ) ; } annotatedProperties . put ( type , properties ) ; return properties ; }

Lookups for annotated properties. Caches all annotated properties on the first
action class scan.

Lookups for annotated properties . Caches all annotated properties on the first action class scan .


public DbServer detectDatabaseAndConfigureDbOom(
			final ConnectionProvider cp,
			final DbOomConfig dbOomConfig) {

		cp.init();

		final Connection connection = cp.getConnection();

		final DbServer dbServer = detectDatabase(connection);

		cp.closeConnection(connection);

		dbServer.accept(dbOomConfig);

		return dbServer;
	}

public DbServer detectDatabaseAndConfigureDbOom ( final ConnectionProvider cp , final DbOomConfig dbOomConfig ) { cp . init ( ) ; final Connection connection = cp . getConnection ( ) ; final DbServer dbServer = detectDatabase ( connection ) ; cp . closeConnection ( connection ) ; dbServer . accept ( dbOomConfig ) ; return dbServer ; }

Detects database and configure DbOom engine.

Detects database and configure DbOom engine .


@Override
	public void close() throws IOException {
		if (closed) {
			return;
		}
		if (gzipstream != null) {
			flushToGZip();
			gzipstream.close();
			gzipstream = null;
		} else {
			if (bufferCount > 0) {
				output.write(buffer, 0, bufferCount);
				bufferCount = 0;
			}
		}
		output.close();
		closed = true;
	}

@ Override public void close ( ) throws IOException { if ( closed ) { return ; } if ( gzipstream != null ) { flushToGZip ( ) ; gzipstream . close ( ) ; gzipstream = null ; } else { if ( bufferCount > 0 ) { output . write ( buffer , 0 , bufferCount ) ; bufferCount = 0 ; } } output . close ( ) ; closed = true ; }

Closes this output stream, causing any buffered data to be flushed and any
further output data to throw an IOException.

Closes this output stream causing any buffered data to be flushed and any further output data to throw an IOException .


@Override
	public void write(final int b) throws IOException {

		if (closed) {
			throw new IOException("Cannot write to a closed output stream");
		}
		if (bufferCount >= buffer.length) {
			flushToGZip();
		}
		buffer[bufferCount++] = (byte) b;
	}

Writes the specified byte to our output stream.

Writes the specified byte to our output stream .


@Override
	public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
			throws IOException, ServletException {

		HttpServletRequest httpRequest = (HttpServletRequest) request;
		HttpServletResponse httpResponse = (HttpServletResponse) response;

		if (isRequestedSessionIdFromURL(httpRequest)) {
			HttpSession session = httpRequest.getSession(false);

			if (session != null) {
				session.invalidate();		// clear session if session id in URL
			}
		}

		// wrap response to remove URL encoding
		HttpServletResponseWrapper wrappedResponse = new HttpServletResponseWrapper(httpResponse) {
			@Override
			public String encodeRedirectUrl(final String url) {
				return url;
			}

			@Override
			public String encodeRedirectURL(final String url) {
				return url;
			}

			@Override
			public String encodeUrl(final String url) {
				return url;
			}

			@Override
			public String encodeURL(final String url) {
				return url;
			}
		};

		chain.doFilter(request, wrappedResponse);
	}

@
Override
public
void
doFilter
(
final
ServletRequest
request
,
final
ServletResponse
response
,
final
FilterChain
chain
)
throws
IOException
,
ServletException
{
HttpServletRequest
httpRequest
=
(
HttpServletRequest
)
request
;
HttpServletResponse
httpResponse
=
(
HttpServletResponse
)
response
;
if
(
isRequestedSessionIdFromURL
(
httpRequest
)
)
{
HttpSession
session
=
httpRequest
.
getSession
(
false
)
;
if
(
session
!=
)
{
session
.
invalidate
(
)
;
// clear session if session id in URL
}
}
// wrap response to remove URL encoding
HttpServletResponseWrapper
wrappedResponse
=
new
HttpServletResponseWrapper
(
httpResponse
)
{
@
Override
public
String
encodeRedirectUrl
(
final
String
url
)
{
return
url
;
}
@
Override
public
String
encodeRedirectURL
(
final
String
url
)
{
return
url
;
}
@
Override
public
String
encodeUrl
(
final
String
url
)
{
return
url
;
}
@
Override
public
String
encodeURL
(
final
String
url
)
{
return
url
;
}
}
;
chain
.
doFilter
(
request
,
wrappedResponse
)
;
}

Filters requests to remove URL-based session identifiers.

Filters requests to remove URL - based session identifiers .


public String getEncodedName() {
		if (name == null) {
			return null;
		}
		try {
			return MimeUtility.encodeText(name);
		} catch (final UnsupportedEncodingException ueex) {
			throw new MailException(ueex);
		}
	}

public String getEncodedName ( ) { if ( name == null ) { return null ; } try { return MimeUtility . encodeText ( name ) ; } catch ( final UnsupportedEncodingException ueex ) { throw new MailException ( ueex ) ; } }

Returns encoded attachment name.

@return encoded attachment name. Value may be {@code null}.


public byte[] toByteArray() {
		final FastByteArrayOutputStream out;
		if (size != -1) {
			out = new FastByteArrayOutputStream(size);
		} else {
			out = new FastByteArrayOutputStream();
		}
		writeToStream(out);
		return out.toByteArray();
	}

public byte [ ] toByteArray ( ) { final FastByteArrayOutputStream out ; if ( size != - 1 ) { out = new FastByteArrayOutputStream ( size ) ; } else { out = new FastByteArrayOutputStream ( ) ; } writeToStream ( out ) ; return out . toByteArray ( ) ; }

Returns byte content of the attachment.

@return byte array with content of the attachment.

Returns byte content of the attachment .


public void writeToFile(final File destination) {
		InputStream input = null;
		final OutputStream output;
		try {
			input = getDataSource().getInputStream();
			output = new FileOutputStream(destination);

			StreamUtil.copy(input, output);
		}
		catch (final IOException ioex) {
			throw new MailException(ioex);
		}
		finally {
			StreamUtil.close(input);
		}
	}

public void writeToFile ( final File destination ) { InputStream input = null ; final OutputStream output ; try { input = getDataSource ( ) . getInputStream ( ) ; output = new FileOutputStream ( destination ) ; StreamUtil . copy ( input , output ) ; } catch ( final IOException ioex ) { throw new MailException ( ioex ) ; } finally { StreamUtil . close ( input ) ; } }

Saves attachment to a file.

@param destination The destination file to be written.


public void writeToStream(final OutputStream out) {
		InputStream input = null;
		try {
			input = getDataSource().getInputStream();

			StreamUtil.copy(input, out);
		}
		catch (final IOException ioex) {
			throw new MailException(ioex);
		}
		finally {
			StreamUtil.close(input);
		}
	}

public void writeToStream ( final OutputStream out ) { InputStream input = null ; try { input = getDataSource ( ) . getInputStream ( ) ; StreamUtil . copy ( input , out ) ; } catch ( final IOException ioex ) { throw new MailException ( ioex ) ; } finally { StreamUtil . close ( input ) ; } }

Saves attachment to the output stream.

@param out OutputStream where attachment should be copied to.


protected static String appendArgument(final String desc, final String type) {
		int ndx = desc.indexOf(')');
		return desc.substring(0, ndx) + type + desc.substring(ndx);
	}

protected static String appendArgument ( final String desc , final String type ) { int ndx = desc . indexOf ( ' ' ) ; return desc . substring ( 0 , ndx ) + type + desc . substring ( ndx ) ; }

Appends argument to the existing description.

Appends argument to the existing description .


protected static String prependArgument(final String desc, final String type) {
		int ndx = desc.indexOf('(');
		ndx++;
		return desc.substring(0, ndx) + type + desc.substring(ndx);
	}

protected static String prependArgument ( final String desc , final String type ) { int ndx = desc . indexOf ( ' ' ) ; ndx ++ ; return desc . substring ( 0 , ndx ) + type + desc . substring ( ndx ) ; }

Prepends argument to the existing description.

Prepends argument to the existing description .


protected static String changeReturnType(final String desc, final String type) {
		int ndx = desc.indexOf(')');
		return desc.substring(0, ndx + 1) + type;
	}

protected static String changeReturnType ( final String desc , final String type ) { int ndx = desc . indexOf ( ' ' ) ; return desc . substring ( 0 , ndx + 1 ) + type ; }


@Override
	public void text(final CharSequence text) {
		if (!strip) {
			super.text(text);
			return;
		}

		int textLength = text.length();

		char[] dest = new char[textLength];

		int ndx = 0;
		boolean regularChar = true;
		for (int i = 0; i < textLength; i++) {
			char c = text.charAt(i);

			if (CharUtil.isWhitespace(c)) {
				if (regularChar) {
					regularChar = false;
					c = ' ';
				} else {
					continue;
				}
			} else {
				regularChar = true;
			}

			dest[ndx] = c;
			ndx++;
		}

		if (regularChar || (ndx != 1)) {
			super.text(CharBuffer.wrap(dest, 0, ndx));
			strippedCharsCount += textLength - ndx;
		} else {
			strippedCharsCount += textLength;
		}
	}

@ Override public void text ( final CharSequence text ) { if ( ! strip ) { super . text ( text ) ; return ; } int textLength = text . length ( ) ; char [ ] dest = new char [ textLength ] ; int ndx = 0 ; boolean regularChar = true ; for ( int i = 0 ; i < textLength ; i ++ ) { char c = text . charAt ( i ) ; if ( CharUtil . isWhitespace ( c ) ) { if ( regularChar ) { regularChar = false ; c = ' ' ; } else { continue ; } } else { regularChar = true ; } dest [ ndx ] = c ; ndx ++ ; } if ( regularChar || ( ndx != 1 ) ) { super . text ( CharBuffer . wrap ( dest , 0 , ndx ) ) ; strippedCharsCount += textLength - ndx ; } else { strippedCharsCount += textLength ; } }


public <T> void register(final Class<T> type, final TypeConverter<T> typeConverter) {
		converters.put(type, typeConverter);
	}

public < T > void register ( final Class < T > type , final TypeConverter < T > typeConverter ) { converters . put ( type , typeConverter ) ; }

Registers a converter for specified type.
User must register converter for all super-classes as well.

@param type		class that converter is for
@param typeConverter	converter for provided class

Registers a converter for specified type . User must register converter for all super - classes as well .


public <T> TypeConverter<T> lookup(final Class<T> type) {
		return converters.get(type);
	}

public < T > TypeConverter < T > lookup ( final Class < T > type ) { return converters . get ( type ) ; }

Retrieves converter for provided type. Only registered types are matched,
therefore subclasses must be also registered.

@return founded converter or null

Retrieves converter for provided type . Only registered types are matched therefore subclasses must be also registered .


public List<Node> select(final String query) {
		Collection<List<CssSelector>> selectorsCollection = CSSelly.parse(query);
		return select(selectorsCollection);
	}

public List < Node > select ( final String query ) { Collection < List < CssSelector >> selectorsCollection = CSSelly . parse ( query ) ; return select ( selectorsCollection ) ; }

Selects nodes using CSS3 selector query.

Selects nodes using CSS3 selector query .


public List<Node> select(final Collection<List<CssSelector>> selectorsCollection) {
		List<Node> results = new ArrayList<>();
		for (List<CssSelector> selectors : selectorsCollection) {
			processSelectors(results, selectors);
		}
		return results;
	}

public List < Node > select ( final Collection < List < CssSelector > > selectorsCollection ) { List < Node > results = new ArrayList <> ( ) ; for ( List < CssSelector > selectors : selectorsCollection ) { processSelectors ( results , selectors ) ; } return results ; }

Selected nodes using pre-parsed CSS selectors. Take in consideration
collection type for results grouping order.

Selected nodes using pre - parsed CSS selectors . Take in consideration collection type for results grouping order .


protected void processSelectors(final List<Node> results, final List<CssSelector> selectors) {
		List<Node> selectedNodes = select(rootNode, selectors);

		for (Node selectedNode : selectedNodes) {
			if (!results.contains(selectedNode)) {
				results.add(selectedNode);
			}
		}
	}

protected void processSelectors ( final List < Node > results , final List < CssSelector > selectors ) { List < Node > selectedNodes = select ( rootNode , selectors ) ; for ( Node selectedNode : selectedNodes ) { if ( ! results . contains ( selectedNode ) ) { results . add ( selectedNode ) ; } } }

Process selectors and keep adding results.

Process selectors and keep adding results .


public Node selectFirst(final String query) {
		List<Node> selectedNodes = select(query);
		if (selectedNodes.isEmpty()) {
			return null;
		}
		return selectedNodes.get(0);
	}

public Node selectFirst ( final String query ) { List < Node > selectedNodes = select ( query ) ; if ( selectedNodes . isEmpty ( ) ) { return null ; } return selectedNodes . get ( 0 ) ; }

Selects nodes using CSS3 selector query and returns the very first one.

Selects nodes using CSS3 selector query and returns the very first one .


protected void walkDescendantsIteratively(final LinkedList<Node> nodes, final CssSelector cssSelector, final List<Node> result) {
		while (!nodes.isEmpty()) {
			Node node = nodes.removeFirst();
			selectAndAdd(node, cssSelector, result);

			// append children in walking order to be processed right after this node
			int childCount = node.getChildNodesCount();
			for (int i = childCount - 1; i >= 0; i--) {
				nodes.addFirst(node.getChild(i));
			}
		}
	}

Walks over the child notes, maintaining the tree order and not using recursion.

Walks over the child notes maintaining the tree order and not using recursion .


protected void walk(final Node rootNode, final CssSelector cssSelector, final List<Node> result) {

		// previous combinator determines the behavior
		CssSelector previousCssSelector = cssSelector.getPrevCssSelector();

		Combinator combinator = previousCssSelector != null ?
				previousCssSelector.getCombinator() :
				Combinator.DESCENDANT;

		switch (combinator) {
			case DESCENDANT:
				LinkedList<Node> nodes = new LinkedList<>();
				int childCount = rootNode.getChildNodesCount();
				for (int i = 0; i < childCount; i++) {
					nodes.add(rootNode.getChild(i));
					// recursive
//					selectAndAdd(node, cssSelector, result);
//					walk(node, cssSelector, result);
				}
				walkDescendantsIteratively(nodes, cssSelector, result);
				break;
			case CHILD:
				childCount = rootNode.getChildNodesCount();
				for (int i = 0; i < childCount; i++) {
					Node node = rootNode.getChild(i);
					selectAndAdd(node, cssSelector, result);
				}
				break;
			case ADJACENT_SIBLING:
				Node node = rootNode.getNextSiblingElement();
				if (node != null) {
					selectAndAdd(node, cssSelector, result);
				}
				break;
			case GENERAL_SIBLING:
				node = rootNode;
				while (true) {
					node = node.getNextSiblingElement();
					if (node == null) {
						break;
					}
					selectAndAdd(node, cssSelector, result);
				}
				break;
		}	}

Finds nodes in the tree that matches single selector.

Finds nodes in the tree that matches single selector .


protected void selectAndAdd(final Node node, final CssSelector cssSelector, final List<Node> result) {
		// ignore all nodes that are not elements
		if (node.getNodeType() != Node.NodeType.ELEMENT) {
			return;
		}
		boolean matched = cssSelector.accept(node);
		if (matched) {
			// check for duplicates
			if (result.contains(node)) {
				return;
			}
			// no duplicate found, add it to the results
			result.add(node);
		}
	}

Selects single node for single selector and appends it to the results.

Selects single node for single selector and appends it to the results .


protected boolean filter(final List<Node> currentResults, final Node node, final CssSelector cssSelector, final int index) {
		return cssSelector.accept(currentResults, node, index);
	}

protected boolean filter ( final List < Node > currentResults , final Node node , final CssSelector cssSelector , final int index ) { return cssSelector . accept ( currentResults , node , index ) ; }


private static char [] zzUnpackCMap(final String packed) {
    char [] map = new char[0x110000];
    int i = 0;  /* index in packed string  */
    int j = 0;  /* index in unpacked array */
    while (i < 128) {
      int  count = packed.charAt(i++);
      char value = packed.charAt(i++);
      do map[j++] = value; while (--count > 0);
    }
    return map;
  }

private
static
char
[
]
zzUnpackCMap
(
final
String
packed
)
{
char
[
]
map
=
new
char
[
0x110000
]
;
int
i
=
0
;
/* index in packed string  */
int
j
=
0
;
/* index in unpacked array */
while
(
i
<
128
)
{
int
count
=
packed
.
charAt
(
i
++
)
;
char
value
=
packed
.
charAt
(
i
++
)
;
do
map
[
j
++
]
=
value
;
while
(
count
>
0
)
;
}
return
map
;
}

Unpacks the compressed character translation table.

@param packed   the packed character translation table
@return         the unpacked character translation table

Unpacks the compressed character translation table .


private boolean zzRefill() {
    if (zzBuffer == null) {
      zzBuffer = zzChars;
      zzEndRead += zzChars.length;
      return false;
    }
    return true;
  }

private boolean zzRefill ( ) { if ( zzBuffer == null ) { zzBuffer = zzChars ; zzEndRead += zzChars . length ; return false ; } return true ; }

Refills the input buffer.

@return      false, iff there was new input.


protected <T> PageData<T> page(String sql, final Map params, final int page, final int pageSize, final String sortColumnName, final boolean ascending, final Class[] target) {
		if (sortColumnName != null) {
			sql = buildOrderSql(sql, sortColumnName, ascending);
		}

		int from = (page - 1) * pageSize;

		String pageSql = buildPageSql(sql, from, pageSize);
		DbSqlBuilder dbsql = sql(pageSql);

		DbOomQuery query = query(dbsql);
		query.setMaxRows(pageSize);
		query.setFetchSize(pageSize);
		query.setMap(params);

		List<T> list = query.list(pageSize, target);
		query.close();

		String countSql = buildCountSql(sql);
		dbsql = sql(countSql);
		query = query(dbsql);
		query.setMap(params);
		long count = query.executeCount();
		query.close();

		return new PageData<>(page, (int) count, pageSize, list);
	}

protected < T > PageData < T > page ( String sql , final Map params , final int page , final int pageSize , final String sortColumnName , final boolean ascending , final Class [ ] target ) { if ( sortColumnName != null ) { sql = buildOrderSql ( sql , sortColumnName , ascending ) ; } int from = ( page - 1 ) * pageSize ; String pageSql = buildPageSql ( sql , from , pageSize ) ; DbSqlBuilder dbsql = sql ( pageSql ) ; DbOomQuery query = query ( dbsql ) ; query . setMaxRows ( pageSize ) ; query . setFetchSize ( pageSize ) ; query . setMap ( params ) ; List < T > list = query . list ( pageSize , target ) ; query . close ( ) ; String countSql = buildCountSql ( sql ) ; dbsql = sql ( countSql ) ; query = query ( dbsql ) ; query . setMap ( params ) ; long count = query . executeCount ( ) ; query . close ( ) ; return new PageData <> ( page , ( int ) count , pageSize , list ) ; }

Pages given page.

@param sql sql query that lists all items
@param params map of SQL parameters
@param page current page to show
@param pageSize number of items to show
@param sortColumnName name of sorting column, null for no sorting
@param ascending true for ascending order
@param target db entities for mapping (sa usual in DbOom)


protected String removeSelect(String sql) {
		int ndx = StringUtil.indexOfIgnoreCase(sql, "select");
		if (ndx != -1) {
			sql = sql.substring(ndx + 6);	// select.length()
		}
		return sql;
	}

protected
String
removeSelect
(
String
sql
)
{
int
ndx
=
StringUtil
.
indexOfIgnoreCase
(
sql
,
"select"
)
;
if
(
ndx
!=
1
)
{
sql
=
sql
.
substring
(
ndx
+
6
)
;
// select.length()
}
return
sql
;
}

Removes the first 'select' from the sql query.

Removes the first select from the sql query .


protected String removeToFrom(String sql) {
		int from = 0;
		int fromCount = 1;
		int selectCount = 0;
		int lastNdx = 0;
		while (true) {
			int ndx = StringUtil.indexOfIgnoreCase(sql, "from", from);
			if (ndx == -1) {
				break;
			}

			// count selects in left part
			String left = sql.substring(lastNdx, ndx);
			selectCount += StringUtil.countIgnoreCase(left, "select");

			if (fromCount >= selectCount) {
				sql = sql.substring(ndx);
				break;
			}

			// find next 'from'
			lastNdx = ndx;
			from = ndx + 4;
			fromCount++;
		}
		return sql;
	}

protected
String
removeToFrom
(
String
sql
)
{
int
from
=
0
;
int
fromCount
=
1
;
int
selectCount
=
0
;
int
lastNdx
=
0
;
while
(
true
)
{
int
ndx
=
StringUtil
.
indexOfIgnoreCase
(
sql
,
"from"
,
from
)
;
if
(
ndx
==
1
)
{
break
;
}
// count selects in left part
String
left
=
sql
.
substring
(
lastNdx
,
ndx
)
;
selectCount
+=
StringUtil
.
countIgnoreCase
(
left
,
"select"
)
;
if
(
fromCount
>=
selectCount
)
{
sql
=
sql
.
substring
(
ndx
)
;
break
;
}
// find next 'from'
lastNdx
=
ndx
;
from
=
ndx
+
4
;
fromCount
++
;
}
return
sql
;
}

Removes the first part of the sql up to the relevant 'from'.
Tries to detect sub-queries in the 'select' part.

Removes the first part of the sql up to the relevant from . Tries to detect sub - queries in the select part .


protected String removeLastOrderBy(String sql) {
		int ndx = StringUtil.lastIndexOfIgnoreCase(sql, "order by");
		if (ndx != -1) {
			int ndx2 = sql.lastIndexOf(sql, ')');
			if (ndx > ndx2) {
				sql = sql.substring(0, ndx);
			}
		}
		return sql;
	}

protected
String
removeLastOrderBy
(
String
sql
)
{
int
ndx
=
StringUtil
.
lastIndexOfIgnoreCase
(
sql
,
"order by"
)
;
if
(
ndx
!=
1
)
{
int
ndx2
=
sql
.
lastIndexOf
(
sql
,
'
'
)
;
if
(
ndx
>
ndx2
)
{
sql
=
sql
.
substring
(
0
,
ndx
)
;
}
}
return
sql
;
}

Removes everything from last "order by".


public static String decode(final String html) {

		int ndx = html.indexOf('&');
		if (ndx == -1) {
			return html;
		}

		StringBuilder result = new StringBuilder(html.length());

		int lastIndex = 0;
		int len = html.length();
mainloop:
		while (ndx != -1) {
			result.append(html.substring(lastIndex, ndx));

			lastIndex = ndx;
			while (html.charAt(lastIndex) != ';') {
				lastIndex++;
				if (lastIndex == len) {
					lastIndex = ndx;
					break mainloop;
				}
			}

			if (html.charAt(ndx + 1) == '#') {
				// decimal/hex
				char c = html.charAt(ndx + 2);
				int radix;
				if ((c == 'x') || (c == 'X')) {
					radix = 16;
					ndx += 3;
				} else {
					radix = 10;
					ndx += 2;
				}

				String number = html.substring(ndx, lastIndex);
				int i = Integer.parseInt(number, radix);
				result.append((char) i);
				lastIndex++;
			} else {
				// token
				String encodeToken = html.substring(ndx + 1, lastIndex);

				char[] replacement = ENTITY_MAP.get(encodeToken);
				if (replacement == null) {
					result.append('&');
					lastIndex = ndx + 1;
				} else {
					result.append(replacement);
					lastIndex++;
				}
			}
			ndx = html.indexOf('&', lastIndex);
		}
		result.append(html.substring(lastIndex));
		return result.toString();
	}

public
static
String
decode
(
final
String
html
)
{
int
ndx
=
html
.
indexOf
(
'
'
)
;
if
(
ndx
==
1
)
{
return
html
;
}
StringBuilder
result
=
new
StringBuilder
(
html
.
length
(
)
)
;
int
lastIndex
=
0
;
int
len
=
html
.
length
(
)
;
mainloop
:
while
(
ndx
!=
1
)
{
result
.
append
(
html
.
substring
(
lastIndex
,
ndx
)
)
;
lastIndex
=
ndx
;
while
(
html
.
charAt
(
lastIndex
)
!=
'
'
)
{
lastIndex
++
;
if
(
lastIndex
==
len
)
{
lastIndex
=
ndx
;
break
mainloop
;
}
}
if
(
html
.
charAt
(
ndx
+
1
)
==
'
'
)
{
// decimal/hex
char
c
=
html
.
charAt
(
ndx
+
2
)
;
int
radix
;
if
(
(
c
==
'
'
)
||
(
c
==
'
'
)
)
{
radix
=
16
;
ndx
+=
3
;
}
else
{
radix
=
10
;
ndx
+=
2
;
}
String
number
=
html
.
substring
(
ndx
,
lastIndex
)
;
int
i
=
Integer
.
parseInt
(
number
,
radix
)
;
result
.
append
(
(
char
)
i
)
;
lastIndex
++
;
}
else
{
// token
String
encodeToken
=
html
.
substring
(
ndx
+
1
,
lastIndex
)
;
char
[
]
replacement
=
ENTITY_MAP
.
get
(
encodeToken
)
;
if
(
replacement
==
)
{
result
.
append
(
'
'
)
;
lastIndex
=
ndx
+
1
;
}
else
{
result
.
append
(
replacement
)
;
lastIndex
++
;
}
}
ndx
=
html
.
indexOf
(
'
'
,
lastIndex
)
;
}
result
.
append
(
html
.
substring
(
lastIndex
)
)
;
return
result
.
toString
(
)
;
}

Decodes HTML text. Assumes that all character references are properly closed with semi-colon.

Decodes HTML text . Assumes that all character references are properly closed with semi - colon .


public static String detectName(final char[] input, int ndx) {
		final Ptr ptr = new Ptr();

		int firstIndex = 0;
		int lastIndex = ENTITY_NAMES.length - 1;
		int len = input.length;
		char[] lastName = null;

		final BinarySearchBase binarySearch = new BinarySearchBase() {
			@Override
			protected int compare(final int index) {
				char[] name = ENTITY_NAMES[index];

				if (ptr.offset >= name.length) {
					return -1;
				}

				return name[ptr.offset] - ptr.c;
			}
		};

		while (true) {
			ptr.c = input[ndx];

			if (!CharUtil.isAlphaOrDigit(ptr.c)) {
				return lastName != null ? new String(lastName) : null;
			}

			firstIndex = binarySearch.findFirst(firstIndex, lastIndex);
			if (firstIndex < 0) {
				return lastName != null ? new String(lastName) : null;
			}

			char[] element = ENTITY_NAMES[firstIndex];

			if (element.length == ptr.offset + 1) {
				// total match, remember position, continue for finding the longer name
				lastName = ENTITY_NAMES[firstIndex];
			}

			lastIndex = binarySearch.findLast(firstIndex, lastIndex);

			if (firstIndex == lastIndex) {
				// only one element found, check the rest
				for (int i = ptr.offset; i < element.length; i++) {
					if (element[i] != input[ndx]) {
						return lastName != null ? new String(lastName) : null;
					}
					ndx++;
				}
				return new String(element);
			}

			ptr.offset++;

			ndx++;
			if (ndx == len) {
				return lastName != null ? new String(lastName) : null;
			}
		}
	}

Detects the longest character reference name on given position in char array.

Detects the longest character reference name on given position in char array .


@Override
	protected String buildOrderSql(String sql, final String column, final boolean ascending) {
		sql += " order by " + column;
		if (!ascending) {
			sql += " desc";
		}
		return sql;
	}

@
Override
protected
String
buildOrderSql
(
String
sql
,
final
String
column
,
final
boolean
ascending
)
{
sql
+=
" order by "
+
column
;
if
(
!
ascending
)
{
sql
+=
" desc"
;
}
return
sql
;
}


@Override
	protected String buildPageSql(String sql, final int from, final int pageSize) {
		sql = removeSelect(sql);
		return "select LIMIT " + from + ' ' + pageSize + sql;
	}

@
Override
protected
String
buildPageSql
(
String
sql
,
final
int
from
,
final
int
pageSize
)
{
sql
=
removeSelect
(
sql
)
;
return
"select LIMIT "
+
from
+
'
'
+
pageSize
+
sql
;
}

Builds page sql using LIMIT keyword after the SELECT.

Builds page sql using LIMIT keyword after the SELECT .


private void resolveColumnsAndProperties(final Class type) {
		PropertyDescriptor[] allProperties = ClassIntrospector.get().lookup(type).getAllPropertyDescriptors();
		List<DbEntityColumnDescriptor> decList = new ArrayList<>(allProperties.length);
		int idcount = 0;

		HashSet<String> names = new HashSet<>(allProperties.length);

		for (PropertyDescriptor propertyDescriptor : allProperties) {

			DbEntityColumnDescriptor dec =
					DbMetaUtil.resolveColumnDescriptors(this, propertyDescriptor, isAnnotated, columnNamingStrategy);

			if (dec != null) {
				if (!names.add(dec.getColumnName())) {
					throw new DbOomException("Duplicate column name: " + dec.getColumnName());
				}

				decList.add(dec);

				if (dec.isId) {
					idcount++;
				}
			}
		}
		if (decList.isEmpty()) {
			throw new DbOomException("No column mappings in entity: " + type);
		}
		columnDescriptors = decList.toArray(new DbEntityColumnDescriptor[0]);
		Arrays.sort(columnDescriptors);

		// extract ids from sorted list
		if (idcount > 0) {
			idColumnDescriptors = new DbEntityColumnDescriptor[idcount];
			idcount = 0;
			for (DbEntityColumnDescriptor dec : columnDescriptors) {
				if (dec.isId) {
					idColumnDescriptors[idcount++] = dec;
				}
			}
		}
	}

private
void
resolveColumnsAndProperties
(
final
Class
type
)
{
PropertyDescriptor
[
]
allProperties
=
ClassIntrospector
.
get
(
)
.
lookup
(
type
)
.
getAllPropertyDescriptors
(
)
;
List
<
DbEntityColumnDescriptor
>
decList
=
new
ArrayList
<>
(
allProperties
.
length
)
;
int
idcount
=
0
;
HashSet
<
String
>
names
=
new
HashSet
<>
(
allProperties
.
length
)
;
for
(
PropertyDescriptor
propertyDescriptor
:
allProperties
)
{
DbEntityColumnDescriptor
dec
=
DbMetaUtil
.
resolveColumnDescriptors
(
this
,
propertyDescriptor
,
isAnnotated
,
columnNamingStrategy
)
;
if
(
dec
!=
)
{
if
(
!
names
.
add
(
dec
.
getColumnName
(
)
)
)
{
throw
new
DbOomException
(
"Duplicate column name: "
+
dec
.
getColumnName
(
)
)
;
}
decList
.
add
(
dec
)
;
if
(
dec
.
isId
)
{
idcount
++
;
}
}
}
if
(
decList
.
isEmpty
(
)
)
{
throw
new
DbOomException
(
"No column mappings in entity: "
+
type
)
;
}
columnDescriptors
=
decList
.
toArray
(
new
DbEntityColumnDescriptor
[
0
]
)
;
Arrays
.
sort
(
columnDescriptors
)
;
// extract ids from sorted list
if
(
idcount
>
0
)
{
idColumnDescriptors
=
new
DbEntityColumnDescriptor
[
idcount
]
;
idcount
=
0
;
for
(
DbEntityColumnDescriptor
dec
:
columnDescriptors
)
{
if
(
dec
.
isId
)
{
idColumnDescriptors
[
idcount
++
]
=
dec
;
}
}
}
}

Resolves list of all columns and properties.

Resolves list of all columns and properties .


public DbEntityColumnDescriptor findByColumnName(final String columnName) {
		if (columnName == null) {
			return null;
		}
		init();
		for (DbEntityColumnDescriptor columnDescriptor : columnDescriptors) {
			if (columnDescriptor.columnName.equalsIgnoreCase(columnName)) {
				return columnDescriptor;
			}
		}
		return null;
	}

public DbEntityColumnDescriptor findByColumnName ( final String columnName ) { if ( columnName == null ) { return null ; } init ( ) ; for ( DbEntityColumnDescriptor columnDescriptor : columnDescriptors ) { if ( columnDescriptor . columnName . equalsIgnoreCase ( columnName ) ) { return columnDescriptor ; } } return null ; }

Finds column descriptor by column name. Case is ignored.

Finds column descriptor by column name . Case is ignored .


public DbEntityColumnDescriptor findByPropertyName(final String propertyName) {
		if (propertyName == null) {
			return null;
		}
		init();
		for (DbEntityColumnDescriptor columnDescriptor : columnDescriptors) {
			if (columnDescriptor.propertyName.equals(propertyName)) {
				return columnDescriptor;
			}
		}
		return null;
	}

public DbEntityColumnDescriptor findByPropertyName ( final String propertyName ) { if ( propertyName == null ) { return null ; } init ( ) ; for ( DbEntityColumnDescriptor columnDescriptor : columnDescriptors ) { if ( columnDescriptor . propertyName . equals ( propertyName ) ) { return columnDescriptor ; } } return null ; }

Finds column descriptor by property name.

Finds column descriptor by property name .


public String getPropertyName(final String columnName) {
		DbEntityColumnDescriptor dec = findByColumnName(columnName);
		return dec == null ? null : dec.propertyName;
	}

public String getPropertyName ( final String columnName ) { DbEntityColumnDescriptor dec = findByColumnName ( columnName ) ; return dec == null ? null : dec . propertyName ; }

Returns property name for specified column name.

Returns property name for specified column name .


public String getColumnName(final String propertyName) {
		DbEntityColumnDescriptor dec = findByPropertyName(propertyName);
		return dec == null ? null : dec.columnName;
	}

public String getColumnName ( final String propertyName ) { DbEntityColumnDescriptor dec = findByPropertyName ( propertyName ) ; return dec == null ? null : dec . columnName ; }

Returns column name for specified property name..

Returns column name for specified property name ..


public Object getIdValue(final E object) {
		final String propertyName = getIdPropertyName();
		return BeanUtil.declared.getProperty(object, propertyName);
	}

public Object getIdValue ( final E object ) { final String propertyName = getIdPropertyName ( ) ; return BeanUtil . declared . getProperty ( object , propertyName ) ; }

Returns ID value for given entity instance.

Returns ID value for given entity instance .


public void setIdValue(final E object, final Object value) {
		final String propertyName = getIdPropertyName();
		BeanUtil.declared.setProperty(object, propertyName, value);
	}

public void setIdValue ( final E object , final Object value ) { final String propertyName = getIdPropertyName ( ) ; BeanUtil . declared . setProperty ( object , propertyName , value ) ; }


public String getKeyValue(final E object) {
		Object idValue = getIdValue(object);

		String idValueString = idValue == null ?  StringPool.NULL : idValue.toString();

		return type.getName().concat(StringPool.COLON).concat(idValueString);
	}

public String getKeyValue ( final E object ) { Object idValue = getIdValue ( object ) ; String idValueString = idValue == null ? StringPool . NULL : idValue . toString ( ) ; return type . getName ( ) . concat ( StringPool . COLON ) . concat ( idValueString ) ; }

Returns unique key for this entity. Returned key
is built from entity class and id value.

Returns unique key for this entity . Returned key is built from entity class and id value .


public StringBand append(String s) {
		if (s == null) {
			s = StringPool.NULL;
		}

		if (index >= array.length) {
			expandCapacity();
		}

		array[index++] = s;
		length += s.length();

		return this;
	}

public StringBand append ( String s ) { if ( s == null ) { s = StringPool . NULL ; } if ( index >= array . length ) { expandCapacity ( ) ; } array [ index ++ ] = s ; length += s . length ( ) ; return this ; }


public void setIndex(final int newIndex) {
		if (newIndex < 0) {
			throw new ArrayIndexOutOfBoundsException(newIndex);
		}

		if (newIndex > array.length) {
			String[] newArray = new String[newIndex];
			System.arraycopy(array, 0, newArray, 0, index);
			array = newArray;
		}

		if (newIndex > index) {
			for (int i = index; i < newIndex; i++) {
				array[i] = StringPool.EMPTY;
			}
		} else if (newIndex < index) {
			for (int i = newIndex; i < index; i++) {
				array[i] = null;
			}
		}

		index = newIndex;
		length = calculateLength();
	}

public void setIndex ( final int newIndex ) { if ( newIndex < 0 ) { throw new ArrayIndexOutOfBoundsException ( newIndex ) ; } if ( newIndex > array . length ) { String [ ] newArray = new String [ newIndex ] ; System . arraycopy ( array , 0 , newArray , 0 , index ) ; array = newArray ; } if ( newIndex > index ) { for ( int i = index ; i < newIndex ; i ++ ) { array [ i ] = StringPool . EMPTY ; } } else if ( newIndex < index ) { for ( int i = newIndex ; i < index ; i ++ ) { array [ i ] = null ; } } index = newIndex ; length = calculateLength ( ) ; }


protected void expandCapacity() {
		String[] newArray = new String[array.length << 1];
		System.arraycopy(array, 0, newArray, 0, index);
		array = newArray;
	}

protected void expandCapacity ( ) { String [ ] newArray = new String [ array . length << 1 ] ; System . arraycopy ( array , 0 , newArray , 0 , index ) ; array = newArray ; }

Expands internal string array by multiplying its size by 2.

Expands internal string array by multiplying its size by 2 .


protected int calculateLength() {
		int len = 0;
		for (int i = 0; i < index; i++) {
			len += array[i].length();
		}
		return len;
	}

protected int calculateLength ( ) { int len = 0 ; for ( int i = 0 ; i < index ; i ++ ) { len += array [ i ] . length ( ) ; } return len ; }


protected String createMixingMessage(final BeanDefinition targetBeanDefinition, final BeanDefinition refBeanDefinition) {
		return "Scopes mixing detected: " +
				refBeanDefinition.name + "@" + refBeanDefinition.scope.getClass().getSimpleName() + " -> " +
				targetBeanDefinition.name + "@" + targetBeanDefinition.scope.getClass().getSimpleName();
	}

protected
String
createMixingMessage
(
final
BeanDefinition
targetBeanDefinition
,
final
BeanDefinition
refBeanDefinition
)
{
return
"Scopes mixing detected: "
+
refBeanDefinition
.
name
+
"@"
+
refBeanDefinition
.
scope
.
getClass
(
)
.
getSimpleName
(
)
+
" -> "
+
targetBeanDefinition
.
name
+
"@"
+
targetBeanDefinition
.
scope
.
getClass
(
)
.
getSimpleName
(
)
;
}


protected Object createScopedProxyBean(final PetiteContainer petiteContainer, final BeanDefinition refBeanDefinition) {

		Class beanType = refBeanDefinition.type;

		Class proxyClass = proxyClasses.get(beanType);

		if (proxyClass == null) {
			// create proxy class only once

			if (refBeanDefinition instanceof ProxettaBeanDefinition) {
				// special case, double proxy!

				ProxettaBeanDefinition pbd =
					(ProxettaBeanDefinition) refBeanDefinition;

				ProxyProxetta proxetta = Proxetta.proxyProxetta().withAspects(ArraysUtil.insert(pbd.proxyAspects, aspect, 0));

				proxetta.setClassNameSuffix("$ScopedProxy");
				proxetta.setVariableClassName(true);

				ProxyProxettaFactory builder = proxetta.proxy().setTarget(pbd.originalTarget);

				proxyClass = builder.define();

				proxyClasses.put(beanType, proxyClass);
			}
			else {
				ProxyProxetta proxetta = Proxetta.proxyProxetta().withAspect(aspect);

				proxetta.setClassNameSuffix("$ScopedProxy");
				proxetta.setVariableClassName(true);

				ProxyProxettaFactory builder = proxetta.proxy().setTarget(beanType);

				proxyClass = builder.define();

				proxyClasses.put(beanType, proxyClass);
			}
		}

		Object proxy;

		try {
			proxy = ClassUtil.newInstance(proxyClass);

			Field field = proxyClass.getField("$__petiteContainer$0");

			field.set(proxy, petiteContainer);

			field = proxyClass.getField("$__name$0");

			field.set(proxy, refBeanDefinition.name);
		} catch (Exception ex) {
			throw new PetiteException(ex);
		}

		return proxy;
	}

protected
Object
createScopedProxyBean
(
final
PetiteContainer
petiteContainer
,
final
BeanDefinition
refBeanDefinition
)
{
Class
beanType
=
refBeanDefinition
.
type
;
Class
proxyClass
=
proxyClasses
.
get
(
beanType
)
;
if
(
proxyClass
==
)
{
// create proxy class only once
if
(
refBeanDefinition
instanceof
ProxettaBeanDefinition
)
{
// special case, double proxy!
ProxettaBeanDefinition
pbd
=
(
ProxettaBeanDefinition
)
refBeanDefinition
;
ProxyProxetta
proxetta
=
Proxetta
.
proxyProxetta
(
)
.
withAspects
(
ArraysUtil
.
insert
(
pbd
.
proxyAspects
,
aspect
,
0
)
)
;
proxetta
.
setClassNameSuffix
(
"$ScopedProxy"
)
;
proxetta
.
setVariableClassName
(
true
)
;
ProxyProxettaFactory
builder
=
proxetta
.
proxy
(
)
.
setTarget
(
pbd
.
originalTarget
)
;
proxyClass
=
builder
.
define
(
)
;
proxyClasses
.
put
(
beanType
,
proxyClass
)
;
}
else
{
ProxyProxetta
proxetta
=
Proxetta
.
proxyProxetta
(
)
.
withAspect
(
aspect
)
;
proxetta
.
setClassNameSuffix
(
"$ScopedProxy"
)
;
proxetta
.
setVariableClassName
(
true
)
;
ProxyProxettaFactory
builder
=
proxetta
.
proxy
(
)
.
setTarget
(
beanType
)
;
proxyClass
=
builder
.
define
(
)
;
proxyClasses
.
put
(
beanType
,
proxyClass
)
;
}
}
Object
proxy
;
try
{
proxy
=
ClassUtil
.
newInstance
(
proxyClass
)
;
Field
field
=
proxyClass
.
getField
(
"$__petiteContainer$0"
)
;
field
.
set
(
proxy
,
petiteContainer
)
;
field
=
proxyClass
.
getField
(
"$__name$0"
)
;
field
.
set
(
proxy
,
refBeanDefinition
.
name
)
;
}
catch
(
Exception
ex
)
{
throw
new
PetiteException
(
ex
)
;
}
return
proxy
;
}

Creates scoped proxy bean for given bean definition.

Creates scoped proxy bean for given bean definition .


protected void loopBody() throws JspException {
		JspFragment body = getJspBody();
		if (body == null) {
			return;
		}

		LoopIterator loopIterator = new LoopIterator(start, end, step, modulus);
		if (status != null) {
			getJspContext().setAttribute(status, loopIterator);
		}
		while (loopIterator.next()) {
			TagUtil.invokeBody(body);
		}
		if (status != null) {
			getJspContext().removeAttribute(status);
		}
	}

protected void loopBody ( ) throws JspException { JspFragment body = getJspBody ( ) ; if ( body == null ) { return ; } LoopIterator loopIterator = new LoopIterator ( start , end , step , modulus ) ; if ( status != null ) { getJspContext ( ) . setAttribute ( status , loopIterator ) ; } while ( loopIterator . next ( ) ) { TagUtil . invokeBody ( body ) ; } if ( status != null ) { getJspContext ( ) . removeAttribute ( status ) ; } }


protected void init() {
		File[] filesArray = dir.listFiles();

		filesCount = 0;

		if (filesArray != null) {
			filesCount = filesArray.length;

			for (File file : filesArray) {
				if (!acceptFile(file)) {
					continue;
				}

				map.put(file, new MutableLong(file.lastModified()));
			}
		}
	}

protected void init ( ) { File [ ] filesArray = dir . listFiles ( ) ; filesCount = 0 ; if ( filesArray != null ) { filesCount = filesArray . length ; for ( File file : filesArray ) { if ( ! acceptFile ( file ) ) { continue ; } map . put ( file , new MutableLong ( file . lastModified ( ) ) ) ; } } }

Initializes dir watcher by reading all files
from watched folder.

Initializes dir watcher by reading all files from watched folder .


protected boolean acceptFile(final File file) {
		if (!file.isFile()) {
			return false;			// ignore non-files
		}

		String fileName = file.getName();

		if (ignoreDotFiles) {
			if (fileName.startsWith(StringPool.DOT)) {
				return false;        // ignore hidden files
			}
		}

		if (patterns == null) {
			return true;
		}

		return Wildcard.matchOne(fileName, patterns) != -1;
	}

protected
boolean
acceptFile
(
final
File
file
)
{
if
(
!
file
.
isFile
(
)
)
{
return
false
;
// ignore non-files
}
String
fileName
=
file
.
getName
(
)
;
if
(
ignoreDotFiles
)
{
if
(
fileName
.
startsWith
(
StringPool
.
DOT
)
)
{
return
false
;
// ignore hidden files
}
}
if
(
patterns
==
)
{
return
true
;
}
return
Wildcard
.
matchOne
(
fileName
,
patterns
)
!=
1
;
}

Accepts if a file is going to be watched.

Accepts if a file is going to be watched .


public DirWatcher useWatchFile(final String name) {
		watchFile = new File(dir, name);

		if (!watchFile.isFile() || !watchFile.exists()) {
			try {
				FileUtil.touch(watchFile);
			} catch (IOException ioex) {
				throw new DirWatcherException("Invalid watch file: " + name, ioex);
			}
		}

		watchFileLastAccessTime = watchFile.lastModified();

		return this;
	}

public
DirWatcher
useWatchFile
(
final
String
name
)
{
watchFile
=
new
File
(
dir
,
name
)
;
if
(
!
watchFile
.
isFile
(
)
||
!
watchFile
.
exists
(
)
)
{
try
{
FileUtil
.
touch
(
watchFile
)
;
}
catch
(
IOException
ioex
)
{
throw
new
DirWatcherException
(
"Invalid watch file: "
+
name
,
ioex
)
;
}
}
watchFileLastAccessTime
=
watchFile
.
lastModified
(
)
;
return
this
;
}


public void start(final long pollingInterval) {
		if (timer == null) {
			if (!startBlank) {
				init();
			}
			timer = new Timer(true);
			timer.schedule(new WatchTask(), 0, pollingInterval);
		}
	}

public void start ( final long pollingInterval ) { if ( timer == null ) { if ( ! startBlank ) { init ( ) ; } timer = new Timer ( true ) ; timer . schedule ( new WatchTask ( ) , 0 , pollingInterval ) ; } }


protected void onChange(final DirWatcherEvent.Type type, final File file) {
		listeners.accept(new DirWatcherEvent(type, file));
	}

protected void onChange ( final DirWatcherEvent . Type type , final File file ) { listeners . accept ( new DirWatcherEvent ( type , file ) ) ; }


public void add(final Enumeration<T> enumeration) {
		if (allEnumerations.contains(enumeration)) {
			throw new IllegalArgumentException("Duplicate enumeration");
		}
		allEnumerations.add(enumeration);
	}

public
void
add
(
final
Enumeration
<
T
>
enumeration
)
{
if
(
allEnumerations
.
contains
(
enumeration
)
)
{
throw
new
IllegalArgumentException
(
"Duplicate enumeration"
)
;
}
allEnumerations
.
add
(
enumeration
)
;
}


int computeFieldInfoSize() {
    // The access_flags, name_index, descriptor_index and attributes_count fields use 8 bytes.
    int size = 8;
    // For ease of reference, we use here the same attribute order as in Section 4.7 of the JVMS.
    if (constantValueIndex != 0) {
      // ConstantValue attributes always use 8 bytes.
      symbolTable.addConstantUtf8(Constants.CONSTANT_VALUE);
      size += 8;
    }
    // Before Java 1.5, synthetic fields are represented with a Synthetic attribute.
    if ((accessFlags & Opcodes.ACC_SYNTHETIC) != 0
        && symbolTable.getMajorVersion() < Opcodes.V1_5) {
      // Synthetic attributes always use 6 bytes.
      symbolTable.addConstantUtf8(Constants.SYNTHETIC);
      size += 6;
    }
    if (signatureIndex != 0) {
      // Signature attributes always use 8 bytes.
      symbolTable.addConstantUtf8(Constants.SIGNATURE);
      size += 8;
    }
    // ACC_DEPRECATED is ASM specific, the ClassFile format uses a Deprecated attribute instead.
    if ((accessFlags & Opcodes.ACC_DEPRECATED) != 0) {
      // Deprecated attributes always use 6 bytes.
      symbolTable.addConstantUtf8(Constants.DEPRECATED);
      size += 6;
    }
    if (lastRuntimeVisibleAnnotation != null) {
      size +=
          lastRuntimeVisibleAnnotation.computeAnnotationsSize(
              Constants.RUNTIME_VISIBLE_ANNOTATIONS);
    }
    if (lastRuntimeInvisibleAnnotation != null) {
      size +=
          lastRuntimeInvisibleAnnotation.computeAnnotationsSize(
              Constants.RUNTIME_INVISIBLE_ANNOTATIONS);
    }
    if (lastRuntimeVisibleTypeAnnotation != null) {
      size +=
          lastRuntimeVisibleTypeAnnotation.computeAnnotationsSize(
              Constants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS);
    }
    if (lastRuntimeInvisibleTypeAnnotation != null) {
      size +=
          lastRuntimeInvisibleTypeAnnotation.computeAnnotationsSize(
              Constants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS);
    }
    if (firstAttribute != null) {
      size += firstAttribute.computeAttributesSize(symbolTable);
    }
    return size;
  }

Returns the size of the field_info JVMS structure generated by this FieldWriter. Also adds the
names of the attributes of this field in the constant pool.

@return the size in bytes of the field_info JVMS structure.

Returns the size of the field_info JVMS structure generated by this FieldWriter . Also adds the names of the attributes of this field in the constant pool .


void putFieldInfo(final ByteVector output) {
    boolean useSyntheticAttribute = symbolTable.getMajorVersion() < Opcodes.V1_5;
    // Put the access_flags, name_index and descriptor_index fields.
    int mask = useSyntheticAttribute ? Opcodes.ACC_SYNTHETIC : 0;
    output.putShort(accessFlags & ~mask).putShort(nameIndex).putShort(descriptorIndex);
    // Compute and put the attributes_count field.
    // For ease of reference, we use here the same attribute order as in Section 4.7 of the JVMS.
    int attributesCount = 0;
    if (constantValueIndex != 0) {
      ++attributesCount;
    }
    if ((accessFlags & Opcodes.ACC_SYNTHETIC) != 0 && useSyntheticAttribute) {
      ++attributesCount;
    }
    if (signatureIndex != 0) {
      ++attributesCount;
    }
    if ((accessFlags & Opcodes.ACC_DEPRECATED) != 0) {
      ++attributesCount;
    }
    if (lastRuntimeVisibleAnnotation != null) {
      ++attributesCount;
    }
    if (lastRuntimeInvisibleAnnotation != null) {
      ++attributesCount;
    }
    if (lastRuntimeVisibleTypeAnnotation != null) {
      ++attributesCount;
    }
    if (lastRuntimeInvisibleTypeAnnotation != null) {
      ++attributesCount;
    }
    if (firstAttribute != null) {
      attributesCount += firstAttribute.getAttributeCount();
    }
    output.putShort(attributesCount);
    // Put the field_info attributes.
    // For ease of reference, we use here the same attribute order as in Section 4.7 of the JVMS.
    if (constantValueIndex != 0) {
      output
          .putShort(symbolTable.addConstantUtf8(Constants.CONSTANT_VALUE))
          .putInt(2)
          .putShort(constantValueIndex);
    }
    if ((accessFlags & Opcodes.ACC_SYNTHETIC) != 0 && useSyntheticAttribute) {
      output.putShort(symbolTable.addConstantUtf8(Constants.SYNTHETIC)).putInt(0);
    }
    if (signatureIndex != 0) {
      output
          .putShort(symbolTable.addConstantUtf8(Constants.SIGNATURE))
          .putInt(2)
          .putShort(signatureIndex);
    }
    if ((accessFlags & Opcodes.ACC_DEPRECATED) != 0) {
      output.putShort(symbolTable.addConstantUtf8(Constants.DEPRECATED)).putInt(0);
    }
    if (lastRuntimeVisibleAnnotation != null) {
      lastRuntimeVisibleAnnotation.putAnnotations(
          symbolTable.addConstantUtf8(Constants.RUNTIME_VISIBLE_ANNOTATIONS), output);
    }
    if (lastRuntimeInvisibleAnnotation != null) {
      lastRuntimeInvisibleAnnotation.putAnnotations(
          symbolTable.addConstantUtf8(Constants.RUNTIME_INVISIBLE_ANNOTATIONS), output);
    }
    if (lastRuntimeVisibleTypeAnnotation != null) {
      lastRuntimeVisibleTypeAnnotation.putAnnotations(
          symbolTable.addConstantUtf8(Constants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS), output);
    }
    if (lastRuntimeInvisibleTypeAnnotation != null) {
      lastRuntimeInvisibleTypeAnnotation.putAnnotations(
          symbolTable.addConstantUtf8(Constants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS), output);
    }
    if (firstAttribute != null) {
      firstAttribute.putAttributes(symbolTable, output);
    }
  }

Puts the content of the field_info JVMS structure generated by this FieldWriter into the given
ByteVector.

@param output where the field_info structure must be put.

Puts the content of the field_info JVMS structure generated by this FieldWriter into the given ByteVector .


public static Target ofValue(final Object value, final ScopeData scopeData) {
		return new Target(value, null, scopeData, null, VALUE_INSTANCE_CREATOR);
	}

public static Target ofValue ( final Object value , final ScopeData scopeData ) { return new Target ( value , null , scopeData , null , VALUE_INSTANCE_CREATOR ) ; }

Creates a common target over a value, with known scope data.

Creates a common target over a value with known scope data .


public void writeValue(final InjectionPoint injectionPoint, final Object propertyValue, final boolean silent) {
		writeValue(injectionPoint.targetName(), propertyValue, silent);
	}

public void writeValue ( final InjectionPoint injectionPoint , final Object propertyValue , final boolean silent ) { writeValue ( injectionPoint . targetName ( ) , propertyValue , silent ) ; }

Writes value to this target. Depending on a flag, writing the value can be
completely silent, when no exception is thrown and with top performances.
Otherwise, an exception is thrown on a failure.

Writes value to this target . Depending on a flag writing the value can be completely silent when no exception is thrown and with top performances . Otherwise an exception is thrown on a failure .


public void decorate(final Writer writer, final char[] pageContent, final char[] decoraContent) throws IOException {
		DecoraTag[] decoraTags = parseDecorator(decoraContent);

		parsePage(pageContent, decoraTags);

		writeDecoratedPage(writer, decoraContent, pageContent, decoraTags);
	}

public void decorate ( final Writer writer , final char [ ] pageContent , final char [ ] decoraContent ) throws IOException { DecoraTag [ ] decoraTags = parseDecorator ( decoraContent ) ; parsePage ( pageContent , decoraTags ) ; writeDecoratedPage ( writer , decoraContent , pageContent , decoraTags ) ; }

Decorates page content with decorator template and outputs the result.

Decorates page content with decorator template and outputs the result .


protected void parsePage(final char[] pageContent, final DecoraTag[] decoraTags) {
		LagartoParser lagartoParser = new LagartoParser(pageContent);
		PageRegionExtractor writer = new PageRegionExtractor(decoraTags);
		lagartoParser.parse(writer);
	}

protected void parsePage ( final char [ ] pageContent , final DecoraTag [ ] decoraTags ) { LagartoParser lagartoParser = new LagartoParser ( pageContent ) ; PageRegionExtractor writer = new PageRegionExtractor ( decoraTags ) ; lagartoParser . parse ( writer ) ; }

Parses target page and extracts Decora regions for replacements.

Parses target page and extracts Decora regions for replacements .


protected void writeDecoratedPage(final Writer out, final char[] decoratorContent, final char[] pageContent, final DecoraTag[] decoraTags) throws IOException {
		int ndx = 0;

		for (DecoraTag decoraTag : decoraTags) {
			// [1] just copy content before the Decora tag
			int decoratorLen = decoraTag.getStartIndex() - ndx;
			if (decoratorLen <= 0) {
				continue;
			}
			out.write(decoratorContent, ndx, decoratorLen);

			ndx = decoraTag.getEndIndex();

			// [2] now write region at the place of Decora tag
			int regionLen = decoraTag.getRegionLength();

			if (regionLen == 0) {
				if (decoraTag.hasDefaultValue()) {
					out.write(decoratorContent, decoraTag.getDefaultValueStart(), decoraTag.getDefaultValueLength());
				}
			} else {
				writeRegion(out, pageContent, decoraTag, decoraTags);
			}

		}

		// write remaining content
		out.write(decoratorContent, ndx, decoratorContent.length - ndx);
	}


protected void writeRegion(final Writer out, final char[] pageContent, final DecoraTag decoraTag, final DecoraTag[] decoraTags) throws IOException {
		int regionStart = decoraTag.getRegionStart();
		int regionLen = decoraTag.getRegionLength();
		int regionEnd = regionStart + regionLen;

		for (DecoraTag innerDecoraTag : decoraTags) {
			if (decoraTag == innerDecoraTag) {
				continue;
			}

			if (decoraTag.isRegionUndefined()) {
				continue;
			}

			if (innerDecoraTag.isInsideOtherTagRegion(decoraTag)) {
				// write everything from region start to the inner Decora tag
				out.write(pageContent, regionStart, innerDecoraTag.getRegionTagStart() - regionStart);

				regionStart = innerDecoraTag.getRegionTagEnd();
			}
		}

		// write remaining content of the region
		out.write(pageContent, regionStart, regionEnd - regionStart);
	}

Writes region to output, but extracts all inner regions.

Writes region to output but extracts all inner regions .


public void start() throws IOException {
		serverSocket = new ServerSocket(listenPort, socketBacklog);
		serverSocket.setReuseAddress(true);
		executorService = Executors.newFixedThreadPool(threadPoolSize);

		running = true;
		while (running) {
			Socket socket = serverSocket.accept();
			socket.setKeepAlive(false);
			executorService.execute(onSocketConnection(socket));
		}
		executorService.shutdown();
	}

public void start ( ) throws IOException { serverSocket = new ServerSocket ( listenPort , socketBacklog ) ; serverSocket . setReuseAddress ( true ) ; executorService = Executors . newFixedThreadPool ( threadPoolSize ) ; running = true ; while ( running ) { Socket socket = serverSocket . accept ( ) ; socket . setKeepAlive ( false ) ; executorService . execute ( onSocketConnection ( socket ) ) ; } executorService . shutdown ( ) ; }

Starts HTTP tunnel. Method ends when the tunnel is stopped.

Starts HTTP tunnel . Method ends when the tunnel is stopped .


public static ProcessResult run(final Process process) throws InterruptedException {
		final ByteArrayOutputStream baos = new ByteArrayOutputStream();

		final StreamGobbler outputGobbler = new StreamGobbler(process.getInputStream(), baos, OUTPUT_PREFIX);
		final StreamGobbler errorGobbler = new StreamGobbler(process.getErrorStream(), baos, ERROR_PREFIX);

		outputGobbler.start();
		errorGobbler.start();

		final int result = process.waitFor();

		outputGobbler.waitFor();
		errorGobbler.waitFor();

		return new ProcessResult(result, baos.toString());
	}

public static ProcessResult run ( final Process process ) throws InterruptedException { final ByteArrayOutputStream baos = new ByteArrayOutputStream ( ) ; final StreamGobbler outputGobbler = new StreamGobbler ( process . getInputStream ( ) , baos , OUTPUT_PREFIX ) ; final StreamGobbler errorGobbler = new StreamGobbler ( process . getErrorStream ( ) , baos , ERROR_PREFIX ) ; outputGobbler . start ( ) ; errorGobbler . start ( ) ; final int result = process . waitFor ( ) ; outputGobbler . waitFor ( ) ; errorGobbler . waitFor ( ) ; return new ProcessResult ( result , baos . toString ( ) ) ; }

Executes a process and returns the process output and exit code.

Executes a process and returns the process output and exit code .


@Override
	protected IMAPSSLStore getStore(final Session session) {
		SimpleAuthenticator simpleAuthenticator = (SimpleAuthenticator) authenticator;

		final URLName url;

		if (simpleAuthenticator == null) {
			url = new URLName(
				PROTOCOL_IMAP,
				host, port,
				StringPool.EMPTY, null, null);
		}
		else {
			final PasswordAuthentication pa = simpleAuthenticator.getPasswordAuthentication();
			url = new URLName(
				PROTOCOL_IMAP,
				host, port,
				StringPool.EMPTY,
				pa.getUserName(), pa.getPassword());
		}

		return new IMAPSSLStore(session, url);
	}

@ Override protected IMAPSSLStore getStore ( final Session session ) { SimpleAuthenticator simpleAuthenticator = ( SimpleAuthenticator ) authenticator ; final URLName url ; if ( simpleAuthenticator == null ) { url = new URLName ( PROTOCOL_IMAP , host , port , StringPool . EMPTY , null , null ) ; } else { final PasswordAuthentication pa = simpleAuthenticator . getPasswordAuthentication ( ) ; url = new URLName ( PROTOCOL_IMAP , host , port , StringPool . EMPTY , pa . getUserName ( ) , pa . getPassword ( ) ) ; } return new IMAPSSLStore ( session , url ) ; }

Returns email store.

@param session {@link Session}
@return {@link com.sun.mail.imap.IMAPSSLStore}


public ServletOutputStream createOutputStream() throws IOException {
		GzipResponseStream gzstream = new GzipResponseStream(origResponse);
		gzstream.setBuffer(threshold);
		return gzstream;
	}

public ServletOutputStream createOutputStream ( ) throws IOException { GzipResponseStream gzstream = new GzipResponseStream ( origResponse ) ; gzstream . setBuffer ( threshold ) ; return gzstream ; }

Creates and returns a ServletOutputStream to write the content associated
with this Response.

Creates and returns a ServletOutputStream to write the content associated with this Response .


@Override
	public void init(final TemplateData templateData) {
		super.init(templateData);
		if (hint != null) {
			templateData.incrementHintsCount();
		}
	}

@ Override public void init ( final TemplateData templateData ) { super . init ( templateData ) ; if ( hint != null ) { templateData . incrementHintsCount ( ) ; } }


protected void appendAlias(final StringBuilder query, final DbEntityDescriptor ded, final DbEntityColumnDescriptor dec) {
		final ColumnAliasType columnAliasType = templateData.getColumnAliasType();

		if (columnAliasType == null || columnAliasType == ColumnAliasType.TABLE_REFERENCE) {
			final String tableName = ded.getTableName();
			final String columnName = dec.getColumnNameForQuery();
			templateData.registerColumnDataForTableRef(tableRef, tableName);
			query.append(tableRef).append(columnAliasSeparator).append(columnName);
		} else
		if (columnAliasType == ColumnAliasType.COLUMN_CODE) {
			final String tableName = ded.getTableName();
			final String columnName = dec.getColumnName();
			final String code = templateData.registerColumnDataForColumnCode(tableName, columnName);
			query.append(code);
		} else
		if (columnAliasType == ColumnAliasType.TABLE_NAME) {
			final String tableName = ded.getTableNameForQuery();
			final String columnName = dec.getColumnNameForQuery();
			query.append(tableName).append(columnAliasSeparator).append(columnName);
		}
	}

protected void appendAlias ( final StringBuilder query , final DbEntityDescriptor ded , final DbEntityColumnDescriptor dec ) { final ColumnAliasType columnAliasType = templateData . getColumnAliasType ( ) ; if ( columnAliasType == null || columnAliasType == ColumnAliasType . TABLE_REFERENCE ) { final String tableName = ded . getTableName ( ) ; final String columnName = dec . getColumnNameForQuery ( ) ; templateData . registerColumnDataForTableRef ( tableRef , tableName ) ; query . append ( tableRef ) . append ( columnAliasSeparator ) . append ( columnName ) ; } else if ( columnAliasType == ColumnAliasType . COLUMN_CODE ) { final String tableName = ded . getTableName ( ) ; final String columnName = dec . getColumnName ( ) ; final String code = templateData . registerColumnDataForColumnCode ( tableName , columnName ) ; query . append ( code ) ; } else if ( columnAliasType == ColumnAliasType . TABLE_NAME ) { final String tableName = ded . getTableNameForQuery ( ) ; final String columnName = dec . getColumnNameForQuery ( ) ; query . append ( tableName ) . append ( columnAliasSeparator ) . append ( columnName ) ; } }


protected void appendColumnName(final StringBuilder query, final DbEntityDescriptor ded, final DbEntityColumnDescriptor dec) {
		query.append(resolveTable(tableRef, ded)).append('.').append(dec.getColumnName());

		if (templateData.getColumnAliasType() != null) {     // create column aliases

			query.append(AS);

			switch (templateData.getColumnAliasType()) {
				case TABLE_NAME: {
					final String tableName = ded.getTableNameForQuery();
					query.append(tableName).append(columnAliasSeparator).append(dec.getColumnNameForQuery());
					break;
				}
				case TABLE_REFERENCE: {
					final String tableName = ded.getTableName();
					templateData.registerColumnDataForTableRef(tableRef, tableName);
					query.append(tableRef).append(columnAliasSeparator).append(dec.getColumnNameForQuery());
					break;
				}
				case COLUMN_CODE: {
					final String tableName = ded.getTableName();
					final String code = templateData.registerColumnDataForColumnCode(tableName, dec.getColumnName());
					query.append(code);
					break;
				}
			}
		}
	}

protected
void
appendColumnName
(
final
StringBuilder
query
,
final
DbEntityDescriptor
ded
,
final
DbEntityColumnDescriptor
dec
)
{
query
.
append
(
resolveTable
(
tableRef
,
ded
)
)
.
append
(
'
'
)
.
append
(
dec
.
getColumnName
(
)
)
;
if
(
templateData
.
getColumnAliasType
(
)
!=
)
{
// create column aliases
query
.
append
(
AS
)
;
switch
(
templateData
.
getColumnAliasType
(
)
)
{
case
TABLE_NAME
:
{
final
String
tableName
=
ded
.
getTableNameForQuery
(
)
;
query
.
append
(
tableName
)
.
append
(
columnAliasSeparator
)
.
append
(
dec
.
getColumnNameForQuery
(
)
)
;
break
;
}
case
TABLE_REFERENCE
:
{
final
String
tableName
=
ded
.
getTableName
(
)
;
templateData
.
registerColumnDataForTableRef
(
tableRef
,
tableName
)
;
query
.
append
(
tableRef
)
.
append
(
columnAliasSeparator
)
.
append
(
dec
.
getColumnNameForQuery
(
)
)
;
break
;
}
case
COLUMN_CODE
:
{
final
String
tableName
=
ded
.
getTableName
(
)
;
final
String
code
=
templateData
.
registerColumnDataForColumnCode
(
tableName
,
dec
.
getColumnName
(
)
)
;
query
.
append
(
code
)
;
break
;
}
}
}
}

Simply appends column name with optional table reference and alias.

Simply appends column name with optional table reference and alias .


protected void addRule(final D ruleDefinition, final boolean include) {
		if (rules == null) {
			rules = new ArrayList<>();
		}

		if (include) {
			includesCount++;
		} else {
			excludesCount++;
		}

		Rule<R> newRule = new Rule<>(makeRule(ruleDefinition), include);

		if (rules.contains(newRule)) {
			return;
		}

		rules.add(newRule);
	}

protected void addRule ( final D ruleDefinition , final boolean include ) { if ( rules == null ) { rules = new ArrayList <> ( ) ; } if ( include ) { includesCount ++ ; } else { excludesCount ++ ; } Rule < R > newRule = new Rule <> ( makeRule ( ruleDefinition ) , include ) ; if ( rules . contains ( newRule ) ) { return ; } rules . add ( newRule ) ; }

Adds a rule. Duplicates are not allowed and will be ignored.

Adds a rule . Duplicates are not allowed and will be ignored .


public boolean apply(final V value, final boolean blacklist, boolean flag) {
		if (rules == null) {
			return flag;
		}

		if (blacklist) {
			flag = processExcludes(value, flag);
			flag = processIncludes(value, flag);
		}
		else {
			flag = processIncludes(value, flag);
			flag = processExcludes(value, flag);
		}

		return flag;
	}

public boolean apply ( final V value , final boolean blacklist , boolean flag ) { if ( rules == null ) { return flag ; } if ( blacklist ) { flag = processExcludes ( value , flag ) ; flag = processIncludes ( value , flag ) ; } else { flag = processIncludes ( value , flag ) ; flag = processExcludes ( value , flag ) ; } return flag ; }

Applies rules on given flag. Flag is only changed if at least one rule
matched. Otherwise, the same value is returned. This way you can
chain several rules and have the rule engine change the flag
only when a rule is matched.

Applies rules on given flag . Flag is only changed if at least one rule matched . Otherwise the same value is returned . This way you can chain several rules and have the rule engine change the flag only when a rule is matched .


protected boolean processIncludes(final V value, boolean include) {
		if (includesCount > 0) {
			if (!include) {
				for (Rule<R> rule : rules) {
					if (!rule.include) {
						continue;
					}

					if (inExRuleMatcher.accept(value, rule.value, true)) {
						include = true;
						break;
					}
				}
			}
		}
		return include;
	}

protected boolean processIncludes ( final V value , boolean include ) { if ( includesCount > 0 ) { if ( ! include ) { for ( Rule < R > rule : rules ) { if ( ! rule . include ) { continue ; } if ( inExRuleMatcher . accept ( value , rule . value , true ) ) { include = true ; break ; } } } } return include ; }


protected boolean processExcludes(final V value, boolean include) {
		if (excludesCount > 0) {
			if (include) {
				for (Rule<R> rule : rules) {
					if (rule.include) {
						continue;
					}

					if (inExRuleMatcher.accept(value, rule.value, false)) {
						include = false;
						break;
					}
				}
			}
		}
		return include;
	}

protected boolean processExcludes ( final V value , boolean include ) { if ( excludesCount > 0 ) { if ( include ) { for ( Rule < R > rule : rules ) { if ( rule . include ) { continue ; } if ( inExRuleMatcher . accept ( value , rule . value , false ) ) { include = false ; break ; } } } } return include ; }


public String getPseudoClassName() {
		String name = getClass().getSimpleName().toLowerCase();
		name = name.replace('_', '-');
		return name;
	}

public String getPseudoClassName ( ) { String name = getClass ( ) . getSimpleName ( ) . toLowerCase ( ) ; name = name . replace ( ' ' , ' ' ) ; return name ; }

Returns pseudo-class name from simple class name.

Returns pseudo - class name from simple class name .


@Override
	public boolean addAll(final Collection<? extends E> c) {
		Iterator<? extends E> i = c.iterator();
		boolean changed = false;
		while (i.hasNext()) {
			boolean ret = add(i.next());
			if (!changed) {
				changed = ret;
			}
		}
		return changed;
	}

@ Override public boolean addAll ( final Collection < ? extends E > c ) { Iterator < ? extends E > i = c . iterator ( ) ; boolean changed = false ; while ( i . hasNext ( ) ) { boolean ret = add ( i . next ( ) ) ; if ( ! changed ) { changed = ret ; } } return changed ; }

Add all of the elements in the given collection to this list.

Add all of the elements in the given collection to this list .


protected int findInsertionPoint(final E o, int low, int high) {

		while (low <= high) {
			int mid = (low + high) >>> 1;
			int delta = compare(get(mid), o);

			if (delta > 0) {
				high = mid - 1;
			} else {
				low = mid + 1;
			}
		}

		return low;
	}

protected int findInsertionPoint ( final E o , int low , int high ) { while ( low <= high ) { int mid = ( low + high ) >>> 1 ; int delta = compare ( get ( mid ) , o ) ; if ( delta > 0 ) { high = mid - 1 ; } else { low = mid + 1 ; } } return low ; }

Conducts a binary search to find the index where Object
should be inserted.

Conducts a binary search to find the index where Object should be inserted .


public void bindAnnotationConfig(final Class<? extends Annotation> annotationType, final Class<? extends ActionConfig> actionConfigClass) {
		final ActionConfig actionConfig = registerNewActionConfiguration(actionConfigClass);

		actionConfigs.put(annotationType, actionConfig);

		for (final AnnotationParser annotationParser : annotationParsers) {
			if (annotationType.equals(annotationParser.getAnnotationType())) {
				// parser already exists
				return;
			}
		}
		annotationParsers = ArraysUtil.append(annotationParsers, new AnnotationParser(annotationType, Action.class));
	}

public
void
bindAnnotationConfig
(
final
Class
<
extends
Annotation
>
annotationType
,
final
Class
<
extends
ActionConfig
>
actionConfigClass
)
{
final
ActionConfig
actionConfig
=
registerNewActionConfiguration
(
actionConfigClass
)
;
actionConfigs
.
put
(
annotationType
,
actionConfig
)
;
for
(
final
AnnotationParser
annotationParser
:
annotationParsers
)
{
if
(
annotationType
.
equals
(
annotationParser
.
getAnnotationType
(
)
)
)
{
// parser already exists
return
;
}
}
annotationParsers
=
ArraysUtil
.
append
(
annotationParsers
,
new
AnnotationParser
(
annotationType
,
Action
.
class
)
)
;
}

Binds action annotation and the action config. This can overwrite the default annotation
configuration of an annotation.

Binds action annotation and the action config . This can overwrite the default annotation configuration of an annotation .


protected ActionConfig registerNewActionConfiguration(final Class<? extends ActionConfig> actionConfigClass) {
		final ActionConfig newActionConfig = createActionConfig(actionConfigClass);

		actionConfigs.put(actionConfigClass, newActionConfig);

		return newActionConfig;
	}

protected ActionConfig registerNewActionConfiguration ( final Class < ? extends ActionConfig > actionConfigClass ) { final ActionConfig newActionConfig = createActionConfig ( actionConfigClass ) ; actionConfigs . put ( actionConfigClass , newActionConfig ) ; return newActionConfig ; }

Registers action configuration for given type.

Registers action configuration for given type .


public ActionConfig lookup(final Class actionTypeOrAnnotationType) {
		final ActionConfig actionConfig = actionConfigs.get(actionTypeOrAnnotationType);

		if (actionConfig == null) {
			throw new MadvocException("ActionConfiguration not registered:" + actionTypeOrAnnotationType.getName());
		}
		return actionConfig;
	}

public
ActionConfig
lookup
(
final
Class
actionTypeOrAnnotationType
)
{
final
ActionConfig
actionConfig
=
actionConfigs
.
get
(
actionTypeOrAnnotationType
)
;
if
(
actionConfig
==
)
{
throw
new
MadvocException
(
"ActionConfiguration not registered:"
+
actionTypeOrAnnotationType
.
getName
(
)
)
;
}
return
actionConfig
;
}

Lookup for the action configuration. Typically, the input argument is either the action type or annotation type.

Lookup for the action configuration . Typically the input argument is either the action type or annotation type .


public <T extends ActionConfig> void with(final Class<T> actionConfigType, final Consumer<T> actionConfigConsumer) {
		final T actionConfig = (T) lookup(actionConfigType);
		actionConfigConsumer.accept(actionConfig);
	}

public < T extends ActionConfig > void with ( final Class < T > actionConfigType , final Consumer < T > actionConfigConsumer ) { final T actionConfig = ( T ) lookup ( actionConfigType ) ; actionConfigConsumer . accept ( actionConfig ) ; }

Fetch some action config and consumes it.

Fetch some action config and consumes it .


protected static void setupSystemMailProperties() {
		System.setProperty("mail.mime.encodefilename", Boolean.valueOf(Defaults.mailMimeEncodefilename).toString());
		System.setProperty("mail.mime.decodefilename", Boolean.valueOf(Defaults.mailMimeDecodefilename).toString());
	}

protected static void setupSystemMailProperties ( ) { System . setProperty ( "mail.mime.encodefilename" , Boolean . valueOf ( Defaults . mailMimeEncodefilename ) . toString ( ) ) ; System . setProperty ( "mail.mime.decodefilename" , Boolean . valueOf ( Defaults . mailMimeDecodefilename ) . toString ( ) ) ; }


public void validateWithin(final ValidationContext vctx, final Object value) {
		vtor.validate(vctx, value, name);
	}

public void validateWithin ( final ValidationContext vctx , final Object value ) { vtor . validate ( vctx , value , name ) ; }

Validates provided context and value withing this constraint content.

Validates provided context and value withing this constraint content .


protected Element findLastTable(final Node node) {
		Node tableNode = node;

		while (tableNode != null) {
			if (tableNode.getNodeType() == Node.NodeType.ELEMENT) {
				String tableNodeName = tableNode.getNodeName().toLowerCase();

				if (tableNodeName.equals("table")) {
					break;
				}
			}
			tableNode = tableNode.getParentNode();
		}

		return (Element) tableNode;
	}

protected Element findLastTable ( final Node node ) { Node tableNode = node ; while ( tableNode != null ) { if ( tableNode . getNodeType ( ) == Node . NodeType . ELEMENT ) { String tableNodeName = tableNode . getNodeName ( ) . toLowerCase ( ) ; if ( tableNodeName . equals ( "table" ) ) { break ; } } tableNode = tableNode . getParentNode ( ) ; } return ( Element ) tableNode ; }

Finds the last table in stack of open elements.

Finds the last table in stack of open elements .


protected void fixElements() {
		for (Element fosterElement : fosterElements) {
			// find parent table
			Element lastTable = findLastTable(fosterElement);
			Node fosterElementParent = fosterElement.getParentNode();

			// filter our foster element
			Node[] fosterChilds = fosterElement.getChildNodes();
			for (Node fosterChild : fosterChilds) {
				if (fosterChild.getNodeType() == Node.NodeType.ELEMENT) {
					if (isOneOfTableElements((Element) fosterChild)) {
						// move all child table elements outside
						// the foster element
						fosterChild.detachFromParent();
						fosterElementParent.insertBefore(fosterChild, fosterElement);
					}
				}
			}

			// finally, move foster element above the table
			fosterElement.detachFromParent();
			lastTable.getParentNode().insertBefore(fosterElement, lastTable);
		}
	}


protected Map<String, BeanData> registerSessionBeans(final HttpSession httpSession) {
	    SessionBeans sessionBeans = new SessionBeans();
		httpSession.setAttribute(SESSION_BEANS_NAME, sessionBeans);
		return sessionBeans.getBeanMap();
	}

protected Map < String , BeanData > registerSessionBeans ( final HttpSession httpSession ) { SessionBeans sessionBeans = new SessionBeans ( ) ; httpSession . setAttribute ( SESSION_BEANS_NAME , sessionBeans ) ; return sessionBeans . getBeanMap ( ) ; }

Registers new session destroy callback if not already registered.

Registers new session destroy callback if not already registered .


@SuppressWarnings("unchecked")
	protected Map<String, BeanData> getSessionMap(final HttpSession session) {
		SessionBeans sessionBeans = (SessionBeans) session.getAttribute(SESSION_BEANS_NAME);
		if (sessionBeans == null) {
			return null;
		}
		return sessionBeans.getBeanMap();
	}

@ SuppressWarnings ( "unchecked" ) protected Map < String , BeanData > getSessionMap ( final HttpSession session ) { SessionBeans sessionBeans = ( SessionBeans ) session . getAttribute ( SESSION_BEANS_NAME ) ; if ( sessionBeans == null ) { return null ; } return sessionBeans . getBeanMap ( ) ; }

Returns instance map from http session .


public void init(String name, final String superName, final String suffix, final String reqProxyClassName) {
		int lastSlash = name.lastIndexOf('/');
		this.targetPackage = lastSlash == -1 ? StringPool.EMPTY : name.substring(0, lastSlash).replace('/', '.');
		this.targetClassname = name.substring(lastSlash + 1);
		this.nextSupername = superName;
		this.superName = name;

		// create proxy name
		if (reqProxyClassName != null) {
			if (reqProxyClassName.startsWith(DOT)) {
				name = name.substring(0, lastSlash) + '/' + reqProxyClassName.substring(1);
			} else if (reqProxyClassName.endsWith(DOT)) {
				name = reqProxyClassName.replace('.', '/') + this.targetClassname;
			} else {
				name = reqProxyClassName.replace('.', '/');
			}
		}

		// add optional suffix
		if (suffix != null) {
			name += suffix;
		}
		this.thisReference = name;
		this.superReference = this.superName;
	}

public
void
init
(
String
name
,
final
String
superName
,
final
String
suffix
,
final
String
reqProxyClassName
)
{
int
lastSlash
=
name
.
lastIndexOf
(
'
'
)
;
this
.
targetPackage
=
lastSlash
==
1
StringPool
.
EMPTY
:
name
.
substring
(
0
,
lastSlash
)
.
replace
(
'
'
,
'
'
)
;
this
.
targetClassname
=
name
.
substring
(
lastSlash
+
1
)
;
this
.
nextSupername
=
superName
;
this
.
superName
=
name
;
// create proxy name
if
(
reqProxyClassName
!=
)
{
if
(
reqProxyClassName
.
startsWith
(
DOT
)
)
{
name
=
name
.
substring
(
0
,
lastSlash
)
+
'
'
+
reqProxyClassName
.
substring
(
1
)
;
}
else
if
(
reqProxyClassName
.
endsWith
(
DOT
)
)
{
name
=
reqProxyClassName
.
replace
(
'
'
,
'
'
)
+
this
.
targetClassname
;
}
else
{
name
=
reqProxyClassName
.
replace
(
'
'
,
'
'
)
;
}
}
// add optional suffix
if
(
suffix
!=
)
{
name
+=
suffix
;
}
this
.
thisReference
=
name
;
this
.
superReference
=
this
.
superName
;
}


void addAdviceInitMethod(final String name) {
		if (adviceInits == null) {
			adviceInits = new ArrayList<>();
		}
		adviceInits.add(name);
	}

void addAdviceInitMethod ( final String name ) { if ( adviceInits == null ) { adviceInits = new ArrayList <> ( ) ; } adviceInits . add ( name ) ; }


public void end() {
		if (newAction) {
			bundleId = bundlesManager.registerBundle(contextPath, actionPath, bundleId, bundleContentType, sources);
		}
	}

public void end ( ) { if ( newAction ) { bundleId = bundlesManager . registerBundle ( contextPath , actionPath , bundleId , bundleContentType , sources ) ; } }


protected void add(
			final String section, final String key,
			final StringBuilder value, final boolean trim, final Operator operator) {

		// ignore lines without : or =
		if (key == null) {
			return;
		}
		String fullKey = key;

		if (section != null) {
			if (fullKey.length() != 0) {
				fullKey = section + '.' + fullKey;
			} else {
				fullKey = section;
			}
		}
		String v = value.toString();

		if (trim) {
			if (valueTrimLeft && valueTrimRight) {
				v = v.trim();
			} else if (valueTrimLeft) {
				v = StringUtil.trimLeft(v);
			} else {
				v = StringUtil.trimRight(v);
			}
		}

		if (v.length() == 0 && skipEmptyProps) {
			return;
		}

		extractProfilesAndAdd(fullKey, v, operator);
	}

protected
void
add
(
final
String
section
,
final
String
key
,
final
StringBuilder
value
,
final
boolean
trim
,
final
Operator
operator
)
{
// ignore lines without : or =
if
(
key
==
)
{
return
;
}
String
fullKey
=
key
;
if
(
section
!=
)
{
if
(
fullKey
.
length
(
)
!=
0
)
{
fullKey
=
section
+
'
'
+
fullKey
;
}
else
{
fullKey
=
section
;
}
}
String
v
=
value
.
toString
(
)
;
if
(
trim
)
{
if
(
valueTrimLeft
&&
valueTrimRight
)
{
v
=
v
.
trim
(
)
;
}
else
if
(
valueTrimLeft
)
{
v
=
StringUtil
.
trimLeft
(
v
)
;
}
else
{
v
=
StringUtil
.
trimRight
(
v
)
;
}
}
if
(
v
.
length
(
)
==
0
&&
skipEmptyProps
)
{
return
;
}
extractProfilesAndAdd
(
fullKey
,
v
,
operator
)
;
}

Adds accumulated value to key and current section.

Adds accumulated value to key and current section .


protected void extractProfilesAndAdd(final String key, final String value, final Operator operator) {
		String fullKey = key;
		int ndx = fullKey.indexOf(PROFILE_LEFT);
		if (ndx == -1) {
			justAdd(fullKey, value, null, operator);
			return;
		}

		// extract profiles
		ArrayList<String> keyProfiles = new ArrayList<>();

		while (true) {
			ndx = fullKey.indexOf(PROFILE_LEFT);
			if (ndx == -1) {
				break;
			}

			final int len = fullKey.length();

			int ndx2 = fullKey.indexOf(PROFILE_RIGHT, ndx + 1);
			if (ndx2 == -1) {
				ndx2 = len;
			}

			// remember profile
			final String profile = fullKey.substring(ndx + 1, ndx2);
			keyProfiles.add(profile);

			// extract profile from key
			ndx2++;
			final String right = (ndx2 == len) ? StringPool.EMPTY : fullKey.substring(ndx2);
			fullKey = fullKey.substring(0, ndx) + right;
		}

		if (fullKey.startsWith(StringPool.DOT)) {
			// check for special case when only profile is defined in section
			fullKey = fullKey.substring(1);
		}

		// add value to extracted profiles
		justAdd(fullKey, value, keyProfiles, operator);
	}

Extracts profiles from the key name and adds key-value to them.

Extracts profiles from the key name and adds key - value to them .


protected void justAdd(final String key, final String value, final ArrayList<String> keyProfiles, final Operator operator) {
		if (operator == Operator.COPY) {
			HashMap<String,Object> target = new HashMap<>();

			String[] profiles = null;
			if (keyProfiles != null) {
				profiles = keyProfiles.toArray(new String[0]);
			}

			String[] sources = StringUtil.splitc(value, ',');
			for (String source : sources) {
				source = source.trim();

				// try to extract profile for parsing

				String[] lookupProfiles = profiles;
				String lookupProfilesString = null;

				int leftIndex = source.indexOf('<');
				if (leftIndex != -1) {
					int rightIndex = source.indexOf('>');

					lookupProfilesString = source.substring(leftIndex + 1, rightIndex);
					source = source.substring(0, leftIndex).concat(source.substring(rightIndex + 1));

					lookupProfiles = StringUtil.splitc(lookupProfilesString, ',');

					StringUtil.trimAll(lookupProfiles);
				}

				String[] wildcards = new String[] {source + ".*"};

				propsData.extract(target, lookupProfiles, wildcards, null);

				for (Map.Entry<String, Object> entry : target.entrySet()) {
					String entryKey = entry.getKey();
					String suffix = entryKey.substring(source.length());

					String newKey = key + suffix;

					String newValue = "${" + entryKey;
					if (lookupProfilesString != null) {
						newValue += "<" + lookupProfilesString + ">";
					}
					newValue += "}";

					if (profiles == null) {
						propsData.putBaseProperty(newKey, newValue, false);
					} else {
						for (final String p : profiles) {
							propsData.putProfileProperty(newKey, newValue, p, false);
						}
					}
				}
			}
			return;
		}

		boolean append = operator == Operator.QUICK_APPEND;
		if (keyProfiles == null) {
			propsData.putBaseProperty(key, value, append);
			return;
		}
		for (final String p : keyProfiles) {
			propsData.putProfileProperty(key, value, p, append);
		}

	}

protected
void
justAdd
(
final
String
key
,
final
String
value
,
final
ArrayList
<
String
>
keyProfiles
,
final
Operator
operator
)
{
if
(
operator
==
Operator
.
COPY
)
{
HashMap
<
String
,
Object
>
target
=
new
HashMap
<>
(
)
;
String
[
]
profiles
=
;
if
(
keyProfiles
!=
)
{
profiles
=
keyProfiles
.
toArray
(
new
String
[
0
]
)
;
}
String
[
]
sources
=
StringUtil
.
splitc
(
value
,
'
'
)
;
for
(
String
source
:
sources
)
{
source
=
source
.
trim
(
)
;
// try to extract profile for parsing
String
[
]
lookupProfiles
=
profiles
;
String
lookupProfilesString
=
;
int
leftIndex
=
source
.
indexOf
(
'
'
)
;
if
(
leftIndex
!=
1
)
{
int
rightIndex
=
source
.
indexOf
(
'
'
)
;
lookupProfilesString
=
source
.
substring
(
leftIndex
+
1
,
rightIndex
)
;
source
=
source
.
substring
(
0
,
leftIndex
)
.
concat
(
source
.
substring
(
rightIndex
+
1
)
)
;
lookupProfiles
=
StringUtil
.
splitc
(
lookupProfilesString
,
'
'
)
;
StringUtil
.
trimAll
(
lookupProfiles
)
;
}
String
[
]
wildcards
=
new
String
[
]
{
source
+
".*"
}
;
propsData
.
extract
(
target
,
lookupProfiles
,
wildcards
,
)
;
for
(
Map
.
Entry
<
String
,
Object
>
entry
:
target
.
entrySet
(
)
)
{
String
entryKey
=
entry
.
getKey
(
)
;
String
suffix
=
entryKey
.
substring
(
source
.
length
(
)
)
;
String
newKey
=
key
+
suffix
;
String
newValue
=
"${"
+
entryKey
;
if
(
lookupProfilesString
!=
)
{
newValue
+=
"<"
+
lookupProfilesString
+
">"
;
}
newValue
+=
"}"
;
if
(
profiles
==
)
{
propsData
.
putBaseProperty
(
newKey
,
newValue
,
false
)
;
}
else
{
for
(
final
String
p
:
profiles
)
{
propsData
.
putProfileProperty
(
newKey
,
newValue
,
p
,
false
)
;
}
}
}
}
return
;
}
boolean
append
=
operator
==
Operator
.
QUICK_APPEND
;
if
(
keyProfiles
==
)
{
propsData
.
putBaseProperty
(
key
,
value
,
append
)
;
return
;
}
for
(
final
String
p
:
keyProfiles
)
{
propsData
.
putProfileProperty
(
key
,
value
,
p
,
append
)
;
}
}


public static String typedesc2ClassName(final String desc) {
		String className = desc;
		switch (desc.charAt(0)) {
			case 'B':
			case 'C':
			case 'D':
			case 'F':
			case 'I':
			case 'J':
			case 'S':
			case 'Z':
			case 'V':
				if (desc.length() != 1) {
					throw new IllegalArgumentException(INVALID_BASE_TYPE + desc);
				}
				break;
			case 'L':
				className = className.substring(1, className.length() - 1); break;
			case '[':
				// uses less-known feature of class loaders for loading array types
				// using bytecode-like signatures.
				className = className.replace('/', '.');
				break;
			default: throw new IllegalArgumentException(INVALID_TYPE_DESCRIPTION + desc);
		}

		return className;
	}

Converts bytecode-like description to java class name that can be loaded
with a classloader. Uses less-known feature of class loaders for loading
array classes.

@see #typedescToSignature(String, jodd.mutable.MutableInteger)

Converts bytecode - like description to java class name that can be loaded with a classloader . Uses less - known feature of class loaders for loading array classes .


public static String typeref2Name(final String desc) {
		if (desc.charAt(0) != TYPE_REFERENCE) {
			throw new IllegalArgumentException(INVALID_TYPE_DESCRIPTION + desc);
		}
		String name = desc.substring(1, desc.length() - 1);
		return name.replace('/', '.');
	}

public static String typeref2Name ( final String desc ) { if ( desc . charAt ( 0 ) != TYPE_REFERENCE ) { throw new IllegalArgumentException ( INVALID_TYPE_DESCRIPTION + desc ) ; } String name = desc . substring ( 1 , desc . length ( ) - 1 ) ; return name . replace ( ' ' , ' ' ) ; }

Converts type reference to java - name .


public static String typedescToSignature(final String desc, final MutableInteger from) {
		int fromIndex = from.get();
		from.value++;	// default usage for most cases

		switch (desc.charAt(fromIndex)) {
			case 'B': return "byte";
			case 'C': return "char";
			case 'D': return "double";
			case 'F': return "float";
			case 'I': return "int";
			case 'J': return "long";
			case 'S': return "short";
			case 'Z': return "boolean";
			case 'V': return "void";

			case 'L':
				int index = desc.indexOf(';', fromIndex);
				if (index < 0) {
					throw new IllegalArgumentException(INVALID_TYPE_DESCRIPTION + desc);
				}
				from.set(index + 1);
				String str = desc.substring(fromIndex + 1, index);
				return str.replace('/', '.');

			case 'T':
				return desc.substring(from.value);

			case '[':
				StringBuilder brackets = new StringBuilder();
				int n = fromIndex;
				while (desc.charAt(n) == '[') {	// count opening brackets
					brackets.append("[]");
					n++;
				}
				from.value = n;
				String type = typedescToSignature(desc, from);	// the rest of the string denotes a `<field_type>'
				return type + brackets;

			default:
				if (from.value == 0) {
					throw new IllegalArgumentException(INVALID_TYPE_DESCRIPTION + desc);
				}
				// generics!
				return desc.substring(from.value);
		}
	}

Returns java-like signature of a bytecode-like description.
Only first description is parsed.

The field signature represents the value of an argument to a function or
the value of a variable. It is a series of bytes generated by the
following grammar:

{@code
<field_signature> ::= <field_type>
<field_type>      ::= <base_type>|<object_type>|<array_type>
<base_type>       ::= B|C|D|F|I|J|S|Z
<object_type>     ::= L<fullclassname>;
<array_type>      ::= [<field_type>

The meaning of the base types is as follows:
B byte signed byte
C char character
D double double precision IEEE float
F float single precision IEEE float
I int integer
J long long integer
L<fullclassname>; ... an object of the given class
S short signed short
Z boolean true or false
[<field sig> ... array
}

This method converts this string into a Java type declaration such as
String[].

Returns java - like signature of a bytecode - like description . Only first description is parsed .


public static String typeToTyperef(final Class type) {
		if (!type.isArray()) {
			if (!type.isPrimitive()) {
				return 'L' + typeToSignature(type) + ';';
			}
			if (type == int.class) {
				return "I";
			}
			if (type == long.class) {
				return "J";
			}
			if (type == boolean.class) {
				return "Z";
			}
			if (type == double.class) {
				return "D";
			}
			if (type == float.class) {
				return "F";
			}
			if (type == short.class) {
				return "S";
			}
			if (type == void.class) {
				return "V";
			}
			if (type == byte.class) {
				return "B";
			}
			if (type == char.class) {
				return "C";
			}
		}

		return type.getName();
	}

public static String typeToTyperef ( final Class type ) { if ( ! type . isArray ( ) ) { if ( ! type . isPrimitive ( ) ) { return ' ' + typeToSignature ( type ) + ' ' ; } if ( type == int . class ) { return "I" ; } if ( type == long . class ) { return "J" ; } if ( type == boolean . class ) { return "Z" ; } if ( type == double . class ) { return "D" ; } if ( type == float . class ) { return "F" ; } if ( type == short . class ) { return "S" ; } if ( type == void . class ) { return "V" ; } if ( type == byte . class ) { return "B" ; } if ( type == char . class ) { return "C" ; } } return type . getName ( ) ; }


public Consumers<T> addAll(final Consumer<T>... consumers) {
		Collections.addAll(consumerList, consumers);
		return this;
	}

public Consumers < T > addAll ( final Consumer < T > ... consumers ) { Collections . addAll ( consumerList , consumers ) ; return this ; }


@SuppressWarnings("unchecked")
	protected Collection<T> createCollection(final int length) {
		if (collectionType.isInterface()) {
			if (collectionType == List.class) {
				if (length > 0) {
					return new ArrayList<>(length);
				} else {
					return new ArrayList<>();
				}
			}

			if (collectionType == Set.class) {
				if (length > 0) {
					return new HashSet<>(length);
				} else {
					return new HashSet<>();
				}
			}

			throw new TypeConversionException("Unknown collection: " + collectionType.getName());
		}
		if (length > 0) {
			try {
				Constructor<Collection<T>> ctor = (Constructor<Collection<T>>) collectionType.getConstructor(int.class);
				return ctor.newInstance(Integer.valueOf(length));
			} catch (Exception ex) {
				// ignore exception
			}
		}

		try {
			return collectionType.getDeclaredConstructor().newInstance();
		} catch (Exception ex) {
			throw new TypeConversionException(ex);
		}
	}

@
SuppressWarnings
(
"unchecked"
)
protected
Collection
<
T
>
createCollection
(
final
int
length
)
{
if
(
collectionType
.
isInterface
(
)
)
{
if
(
collectionType
==
List
.
class
)
{
if
(
length
>
0
)
{
return
new
ArrayList
<>
(
length
)
;
}
else
{
return
new
ArrayList
<>
(
)
;
}
}
if
(
collectionType
==
Set
.
class
)
{
if
(
length
>
0
)
{
return
new
HashSet
<>
(
length
)
;
}
else
{
return
new
HashSet
<>
(
)
;
}
}
throw
new
TypeConversionException
(
"Unknown collection: "
+
collectionType
.
getName
(
)
)
;
}
if
(
length
>
0
)
{
try
{
Constructor
<
Collection
<
T
>>
ctor
=
(
Constructor
<
Collection
<
T
>
>
)
collectionType
.
getConstructor
(
int
.
class
)
;
return
ctor
.
newInstance
(
Integer
.
valueOf
(
length
)
)
;
}
catch
(
Exception
ex
)
{
// ignore exception
}
}
try
{
return
collectionType
.
getDeclaredConstructor
(
)
.
newInstance
(
)
;
}
catch
(
Exception
ex
)
{
throw
new
TypeConversionException
(
ex
)
;
}
}

Creates new collection of target component type.
Default implementation uses reflection to create
an collection of target type. Override it for better performances.

Creates new collection of target component type . Default implementation uses reflection to create an collection of target type . Override it for better performances .


protected Collection<T> convertToSingleElementCollection(final Object value) {
		Collection<T> collection = createCollection(0);

		//noinspection unchecked
		collection.add((T) value);

		return collection;
	}

protected
Collection
<
T
>
convertToSingleElementCollection
(
final
Object
value
)
{
Collection
<
T
>
collection
=
createCollection
(
0
)
;
//noinspection unchecked
collection
.
add
(
(
T
)
value
)
;
return
collection
;
}

Creates a collection with single element.

Creates a collection with single element .


protected Collection<T> convertValueToCollection(Object value) {
		if (value instanceof Iterable) {
			Iterable iterable = (Iterable) value;
			Collection<T> collection = createCollection(0);

			for (Object element : iterable) {
				collection.add(convertType(element));
			}
			return collection;
		}

		if (value instanceof CharSequence) {
			value = CsvUtil.toStringArray(value.toString());
		}

		Class type = value.getClass();

		if (type.isArray()) {
			// convert arrays
			Class componentType = type.getComponentType();

			if (componentType.isPrimitive()) {
				return convertPrimitiveArrayToCollection(value, componentType);
			} else {
				Object[] array = (Object[]) value;
				Collection<T> result = createCollection(array.length);
				for (Object a : array) {
					result.add(convertType(a));
				}
				return result;
			}
		}

		// everything else:
		return convertToSingleElementCollection(value);
	}

protected
Collection
<
T
>
convertValueToCollection
(
Object
value
)
{
if
(
value
instanceof
Iterable
)
{
Iterable
iterable
=
(
Iterable
)
value
;
Collection
<
T
>
collection
=
createCollection
(
0
)
;
for
(
Object
element
:
iterable
)
{
collection
.
add
(
convertType
(
element
)
)
;
}
return
collection
;
}
if
(
value
instanceof
CharSequence
)
{
value
=
CsvUtil
.
toStringArray
(
value
.
toString
(
)
)
;
}
Class
type
=
value
.
getClass
(
)
;
if
(
type
.
isArray
(
)
)
{
// convert arrays
Class
componentType
=
type
.
getComponentType
(
)
;
if
(
componentType
.
isPrimitive
(
)
)
{
return
convertPrimitiveArrayToCollection
(
value
,
componentType
)
;
}
else
{
Object
[
]
array
=
(
Object
[
]
)
value
;
Collection
<
T
>
result
=
createCollection
(
array
.
length
)
;
for
(
Object
a
:
array
)
{
result
.
add
(
convertType
(
a
)
)
;
}
return
result
;
}
}
// everything else:
return
convertToSingleElementCollection
(
value
)
;
}

Converts non-collection value to collection.

Converts non - collection value to collection .


protected Collection<T> convertCollectionToCollection(final Collection value) {
		Collection<T> collection = createCollection(value.size());

		for (Object v : value) {
			collection.add(convertType(v));
		}

		return collection;
	}

protected Collection < T > convertCollectionToCollection ( final Collection value ) { Collection < T > collection = createCollection ( value . size ( ) ) ; for ( Object v : value ) { collection . add ( convertType ( v ) ) ; } return collection ; }

Converts collection value to target collection.
Each element is converted to target component type.

Converts collection value to target collection . Each element is converted to target component type .