I have a String of length 1000-1500 chars. I want to divide the same into paragraphs. What I am doing now is:
String tempDisplayText =
"this is the long...... string of length 1000-2000 chars";
String displayText = null;
if (tempDisplayText != null && tempDisplayText.length() > 400) {
int firstFullStopIndex = tempDisplayText.indexOf(". ", 350);
if (firstFullStopIndex > 0) {
displayText = "<p>"
+ tempDisplayText.substring(0, firstFullStopIndex)
+ ".</p><p>"
+ tempDisplayText.substring(firstFullStopIndex + 1)
+ "</p>";
feed.setDisplayText(displayText);
}
}
This code is working fine, but divides the whole string into 2 paragraphs only. But some time the next paragraph is too lengthy thus looses its readability. Is there any standard way to divide strings into paragraphs in Java?
I see no reason why you shouldn't repeat this for the remainder, i.e., the second paragraph. You can't split a sentence.
StringBuilder sb = new StringBuilder();
if (tempDisplayText != null) {
int firstFullStopIndex;
while( tempDisplayText.length() > 400
&&
(firstFullStopIndex = tempDisplayText.indexOf(". ", 350)) >= 0 ){
sb.append( "<p>" );
sb.append( tempDisplayText.substring(0, firstFullStopIndex) );
sb.append( ".</p>" );
tempDisplayText = tempDisplayText.substring(firstFullStopIndex + 1);
}
if( tempDisplayText.length() > 0 ){
sb.append( "<p>" ).append( tempDisplayText ).append( "</p>" );
}
tempDisplayText = sb.toString();
}
Related
I am displaying output in jsp page using scriplets.
I am getting output from database as follows:
out.println(a) ; //prints output Jan-2019 Feb-2019 March-2019 April-2019
out.println(b) ; //prints output 100100200300
I am trying to print the output in jsp page using html css as follows:
Month Price
Jan-2019 100
Feb-2019 100
March-2019 200
April-2019 300
I searched a lot in google still didn't find any solution also tried with different regex code still its not resolved. Any help will be much appreciated.
Here is the code. It was intentionally made more "verbose" so as to facilitate more use of Regular Expressions with your data feed.
String a = "Jan-2019 Feb-2019 March-2019 April-2019";
String b = "100100200300";
Pattern P1 = Pattern.compile("(\\w{3,})-(\\d{4})");
Pattern P2 = Pattern.compile("[1-9]+0+");
Vector<Integer> years = new Vector<>();
Vector<String> months = new Vector<>();
Vector<Integer> prices = new Vector<>();
Matcher m = P1.matcher(a);
while (m.find())
{
months.add(m.group(1));
years.add(new Integer(m.group(2)));
}
m = P2.matcher(b);
while (m.find()) prices.add(new Integer(m.group()));
// Useful for debugging, to make sure these are "parallel arrays"
// Parallel Arrays are almost *always* useful when regular-expressions & parsing is "happening."
System.out.println( "years.size():\t" + years.size() + '\n' +
"months.size():\t" + months.size() + '\n' +
"prices.size():\t" + prices.size() + "\n\n" );
int len = years.size();
for (int i=0; i < len; i++)
System.out.println( months.elementAt(i) + " " +
years.elementAt(i) + ":\t" +
prices.elementAt(i) );
System.exit(0);
Here is the output:
years.size(): 4
months.size(): 4
prices.size(): 4
Jan 2019: 100
Feb 2019: 100
March 2019: 200
April 2019: 300
For splitting a do this:
String[] months = a.split(" ");
For splitting b do this:
ArrayList<String> prices = new ArrayList<String>();
boolean isZero = false;
String tmpPrice = "";
for (int i = 0; i < b.length(); i++) {
if (i + 1 >= b.length()) {
tmpPrice = tmpPrice + b.charAt(i);
prices.add(tmpPrice);
} else if (isZero && b.charAt(i) != '0') {
prices.add(tmpPrice);
tmpPrice = "" + b.charAt(i);
isZero = false;
} else if (b.charAt(i) == '0') {
isZero = true;
tmpPrice = tmpPrice + b.charAt(i);
} else if (b.charAt(i) != '0') {
isZero = false;
tmpPrice = tmpPrice + b.charAt(i);
}
}
I have an XML file shown below:
<Envelope>
<Body>
<user1>
<userId>userName</userId>
<password>password</password>
<creditCard>
<creditCardNumber>12345678901234</creditCardNumber>
<cvv>123</cvv>
</creditCard>
</user1>
<user2>
<userId>userName</userId>
<password>password</password>
<creditCard>
<creditCardNumber>12345678901234</creditCardNumber>
<cvv>123</cvv>
</creditCard>
</user2>
</Body>
</Envelope>
I have a java code used to log the xml transactions on to some server for future reference. This java code has methods to mask some characters or whole value of tag before logging as the credit card details are not to be disclosed.
Here are the methods:
public static String mask( String input, String[] tags, String maskPattern, String namespacePattern)
throws Throwable
{
StringBuffer sb = new StringBuffer( input );
encodedXML = false;
if (sb.indexOf( ">" ) > 0) {
// XML is encoded
gt = ">";
lt = "<";
encodedXML = true;
// modify patterns for encoded xml
maskPattern = "(>)" + alphaNumericStuff + "+(<)/";
if (sb.indexOf( """ ) >= 0) {
// There is a mix of double quotes and " in this xml
namespacePattern = mixedEncodingAlphaNumericStuff + "*";
}
}
for (int i = 0; i < tags.length; i++) {
// do a quick check to see if the tag is in the string to reduce excessive string creation
if (sb.indexOf( tags[i] ) < 0) {
continue;
} else {
sb = maskElementValue( sb, tags[i],maskPattern, namespacePattern );
}
}
return sb.toString();
}
private static StringBuffer maskElementValue( StringBuffer sb, String tag, String maskPattern,String namespacePattern)
{
// Pattern p = Pattern.compile( tag + maskPattern ); doesn't take namespace into account
Pattern p = Pattern.compile( tag + namespacePattern + maskPattern );
Matcher m = p.matcher( sb.toString() );
StringBuffer tempSB = new StringBuffer();
String namespaceStr = "";
while (m.find()) {
namespaceStr = m.group().substring( tag.length(), m.group().indexOf( gt ) );
// Added full masking for username and password including last 4 characters
if (tag.equalsIgnoreCase( "username" ) || tag.equalsIgnoreCase( "password" )) {
m.appendReplacement( tempSB, tag + namespaceStr + gt + xOut( new StringBuffer( m.group().substring( tag.length() + namespaceStr.length() + gt.length() ) ), true ) );
} else {
m.appendReplacement( tempSB, tag + namespaceStr + gt + xOut( new StringBuffer( m.group().substring( tag.length() + namespaceStr.length() + gt.length() ) ), false ) );
}
}
m.appendTail( tempSB );
return tempSB;
}
private static String xOut( StringBuffer sb, boolean maskAll )
{
int dataSize = sb.toString().trim().length() - 1 - lt.length();
if (!maskAll && dataSize > 4) {
if (sb.indexOf( "<" ) > 0 || sb.indexOf( "<" ) > 0) {
StringBuffer tempmaskSB = new StringBuffer( sb.substring( 0, sb.indexOf( "<" ) ) );
dataSize = tempmaskSB.length();
}
// Don't mask last 4 digit
for (int i = 0; i < dataSize - 4; i++) {
sb.setCharAt( i, 'X' );
}
} else {
if (sb.indexOf( "<" ) > 0 || sb.indexOf( "<" ) > 0) {
StringBuffer tempmaskSB = new StringBuffer( sb.substring( 0, sb.indexOf( "<" ) ) );
dataSize = tempmaskSB.length();
}
// Mask all
for (int i = 0; i < dataSize; i++) {
sb.setCharAt( i, 'X' );
}
}
return sb.toString();
}
I am passing the xml as string to the method and an array of tags that are to be masked. If it is username and password they should be masked completely and other tags in the array should be masked except the last 4 characters.
Now the problem is that masking is not happening for some of the transactions. when we have done a load testing, 12 out of 18000 transactions are not masked the protected data.
In some cases, user1 details are getting masked but user2 details are not masked in the same transaction.
Could any one help me in understanding why this is happening? Has anybody faced such issue before?
Thanks in advance.
Not sure if this is helpful. But i would do the masking part with jsoup
Example:
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.parser.Parser;
import org.jsoup.select.Elements;
public class Mask {
static String xml = "<Envelope>\n" +
"<Body>\n" +
" <user1>\n" +
" <userId>userName</userId>\n" +
" <password>password</password>\n" +
" <creditCard>\n" +
" <creditCardNumber>12345678901234</creditCardNumber>\n" +
" <cvv>123</cvv>\n" +
" </creditCard>\n" +
" </user1>\n" +
" <user2>\n" +
" <userId>userName</userId>\n" +
" <password>password</password>\n" +
" <creditCard>\n" +
" <creditCardNumber>12345678901234</creditCardNumber>\n" +
" <cvv>123</cvv>\n" +
" </creditCard>\n" +
" </user2>\n" +
"</Body>\n" +
"</Envelope>";
public static void main (String[]args){
Document doc = Jsoup.parse(xml, "", Parser.xmlParser());
Elements toMaskCompletely = doc.select("userId,password");
Elements toMaskPartially = doc.select("creditCardNumber");
for(Element ele : toMaskCompletely){
ele.text("XXXXX");
}
for(Element ele : toMaskPartially){
ele.text("XXXXXXXX"+ele.text().substring(ele.text().length()-4));
}
System.out.println(doc.toString());
}
}
I am building a tag reader for inventory purpose. Using the for loop to iterate through the tags to count/total the ids. I get an error on my return line "tagsFound cannot be resolved into a variable". How do i use the variable inside the for loop and then access it outside the loop?
public String[] getTags(AlienClass1Reader reader)throws AlienReaderException{
int coneCount = 0;
int drumCount = 0;
// Open a connection to the reader
reader.open();
// Ask the reader to read tags and print them
Tag tagList[] = reader.getTagList();
if (tagList == null) {
System.out.println("No Tags Found");
} else {
System.out.println("Tag(s) found: " + tagList.length);
for (int i=0; i<tagList.length; i++) {
Tag tag = tagList[i];
System.out.println("ID:" + tag.getTagID() +
", Discovered:" + tag.getDiscoverTime() +
", Last Seen:" + tag.getRenewTime() +
", Antenna:" + tag.getAntenna() +
", Reads:" + tag.getRenewCount()
);
//tagFound[i]= "" + tag.getTagID();
String phrase = tag.getTagID();
tagFound[i] = phrase;
String delims = "[ ]+";
String[] tokens = phrase.split(delims);
if (tokens[0].equals("0CCE") && tokens[3].equals("1001")){drumCount++;}
if (tokens[0].equals("0CCE") && tokens[3].equals("1004")){coneCount++;}
String[] tagsFound;
tagsFound[i] = tag.getTagID();
}
System.out.println("Cones= " + coneCount);
System.out.println("Drums= " + drumCount);
// Close the connection
reader.close();
return tagsFound;
}
}
public String[] getTags(AlienClass1Reader reader)throws AlienReaderException{
int coneCount = 0;
int drumCount = 0;
// Open a connection to the reader
reader.open();
// Ask the reader to read tags and print them
Tag tagList[] = reader.getTagList();
if (tagList == null) {
System.out.println("No Tags Found");
} else {
System.out.println("Tag(s) found: " + tagList.length);
String[] tagsFound = new String[tagList.length];
for (int i=0; i<tagList.length; i++) {
tagsFound = "";
Tag tag = tagList[i];
System.out.println("ID:" + tag.getTagID() +
", Discovered:" + tag.getDiscoverTime() +
", Last Seen:" + tag.getRenewTime() +
", Antenna:" + tag.getAntenna() +
", Reads:" + tag.getRenewCount()
);
//tagFound[i]= "" + tag.getTagID();
String phrase = tag.getTagID();
tagFound[i] = phrase;
String delims = "[ ]+";
String[] tokens = phrase.split(delims);
if (tokens[0].equals("0CCE") && tokens[3].equals("1001")){drumCount++;}
if (tokens[0].equals("0CCE") && tokens[3].equals("1004")){coneCount++;}
tagsFound[i] = tag.getTagID();
}
System.out.println("Cones= " + coneCount);
System.out.println("Drums= " + drumCount);
// Close the connection
reader.close();
return tagsFound;
}
}
the returned array will have empty strings in the positions where the tag does not satisfy the criteria.
I am trying to build a string recursively but it isn't quite working
my code looks like this
public void UpdatePrintList(ArrayList<Node> closedList, ArrayList<Node> openList)
{
if(count <= iterations)
{
String line1 = "";
for(int i = 0; i < closedList.size(); i++)
{
if(i > 0)
{
line1 = line1 + "-";
}
line1 = line1 + closedList.get(i).GetMovement();
}
line1 = line1 + " " + closedList.get(closedList.size()-1).GetG() + " " + closedList.get(closedList.size()-1).GetHeuristic() + " " + closedList.get(closedList.size()-1).GetF();
printList.add(line1);
//*****************************************************************
String line2 = "OPEN ";
for(int i = 0; i < openList.size(); i++)
{
line2 = FindEarlierNode(openList.get(i), line2);
}
System.out.println(line2);
}
count++;
}
private String FindEarlierNode(Node varNode, String varString)
{
if(varNode.OpenedBy() == null)
{
varString += varNode.GetMovement() + "-";
}
else
{
FindEarlierNode(varNode.OpenedBy(), varString);
}
varString = varString + varNode.GetMovement() + "-";
return varString;
}
The strange thing is that I know that this if statement
if(varNode.OpenedBy() == null)
{
varString += varNode.GetMovement() + "-";
}
runs correctly, so the function does reach the earliest node. But it doesnt add to the string. The code runs but returns nothing. GetMovement just returns a one or two character string. The output should look like this:
OPEN S-R S-RD S-D
But instead it looks like this:
OPEN D-DL-L-
Can anyone help?
Managed to work it out. This gives me my desired output:
private String FindEarlierNode(Node varNode, String varString)
{
if(varNode.OpenedBy() != null)
{
varString = varString + varNode.GetMovement() + "-";
return FindEarlierNode(varNode.OpenedBy(), varString);
}
return varString += varNode.GetMovement() + " ";
}
thanks everyone.
I inherited a Play 1.2.4 application which has just been security audited. It seems some methods are unsafe so I need to change them to use prepared statements.
One of the methods in question is this:
public static void surveys(int startIndex, int endIndex, boolean isAscending, String orderBy, String searchField,
String searchText, String filter) {
NdgUser currentUser = NdgUser.find("byUserName", session.get("ndgUser")).first();
NdgUser currentUserAdmin = NdgUser.find("byUserName", currentUser.userAdmin).first();
List<Survey> surveys = null;
String query;
if (filter != null && filter.length() > 0) {
query = getQuery2Filters( "available" , String.valueOf( SurveyStatusConsts.getStatusFlag( filter ) ),
"ndg_user_id", String.valueOf(currentUserAdmin.getId()), false,
searchField, searchText, null, isAscending );//sorting is not needed now
}
else {
query = getQuery( "ndg_user_id" , String.valueOf(currentUserAdmin.getId()), false,
searchField, searchText, null, isAscending );//sorting is not needed now
}
long totalItems = 0;
totalItems = Survey.count( query );
if ( orderBy != null && orderBy.equals( "resultCollection" ) ) {
surveys = Survey.find( query ).fetch();
Collections.sort( surveys, new SurveyNdgResultCollectionComapator() );
if ( !isAscending ) {
Collections.reverse( surveys );
}
int subListEndIndex = surveys.size() <= endIndex ? surveys.size() : endIndex;
surveys = surveys.subList( startIndex, subListEndIndex );
} else {
if (filter != null && filter.length() > 0) {
query = getQuery2Filters( "available", String.valueOf( SurveyStatusConsts.getStatusFlag( filter ) ),
"ndg_user_id", String.valueOf(currentUserAdmin.getId()), false,
searchField, searchText, orderBy, isAscending );
}
else {
query = getQuery( "ndg_user_id", String.valueOf(currentUserAdmin.getId()), false,
searchField, searchText, orderBy, isAscending );
}
surveys = Survey.find( query ).from( startIndex ).fetch( endIndex - startIndex );
}
serializeSurveys(surveys, startIndex, totalItems);
}
which makes use of another couple of methods to actually build the query
private static String getQuery(String filterName, String filterValue, boolean isFilterString, String searchField,
String searchText, String orderBy, boolean isAscending ) {
StringBuilder query = new StringBuilder();
String statusQuery = "";
String searchQuery = "";
String sortingQuery = "";
if ( filterName != null && filterName.length() > 0
&& filterValue != null && filterValue.length() > 0 ) {
statusQuery = filterName + "=" + ( isFilterString ? ("'" + filterValue + "'") : filterValue );
}
if ( searchField != null && searchText != null && searchText.length() > 0 ) {
if(searchField.equals("dateSent")) {
searchQuery = "DATE_FORMAT(" + searchField + ", '%d/%m/%Y')" + " like '%" + searchText + "%'";
}
else {
searchQuery = searchField + " like '%" + searchText + "%'";
}
}
if ( orderBy != null && orderBy.length()> 0 ) {
sortingQuery = "order by " + orderBy + ( isAscending ? " asc" : " desc" );
}
query.append( statusQuery )
.append( ( statusQuery.length() > 0 && searchQuery.length() > 0 ) ? " and " : ' ' )
.append( searchQuery )
.append( ' ' )
.append( sortingQuery );
return query.toString();
}
and
private static String getQuery2Filters(String filterName, String filterValue, String filterName2,
String filterValue2, boolean isFilterString, String searchField,
String searchText, String orderBy, boolean isAscending ) {
StringBuilder query = new StringBuilder();
String statusQuery = "";
String searchQuery = "";
String sortingQuery = "";
if ( filterName != null && filterName.length() > 0
&& filterValue != null && filterValue.length() > 0 ) {
statusQuery = filterName + "=" + ( isFilterString ? ("'" + filterValue + "'") : filterValue );
}
if ( filterName2 != null && filterName2.length() > 0
&& filterValue2 != null && filterValue2.length() > 0 ) {
statusQuery += " and " + filterName2 + "="
+ ( isFilterString ? ("'" + filterValue2 + "'") : filterValue2 );
}
if ( searchField != null && searchText != null && searchText.length() > 0 ) {
searchQuery = searchField + " like '%" + searchText + "%'";
}
if ( orderBy != null && orderBy.length()> 0 ) {
sortingQuery = "order by " + orderBy + ( isAscending ? " asc" : " desc" );
}
query.append( statusQuery )
.append( ( statusQuery.length() > 0 && searchQuery.length() > 0 ) ? " and " : ' ' )
.append( searchQuery )
.append( ' ' )
.append( sortingQuery );
return query.toString();
}
I believe it is these auxiliary methods I need to change for basic string concatenation to something using parameters but I am a bit lost as to how actually do that. I am not very familar with either Java or Hibernate/JPA so some pointers gratefully received