Log function call on new line in Java and C# - java

I have a logging function in CSharp and Java that I use in walking the stack. How do I make each log print to a new line only. Below are my Java and CSharp Functions.
public static void LogFunctionCall(String parameters){
Object trace = Thread.currentThread().getStackTrace()[3];
android.util.Log.i("##################" + trace.toString()+ "", parameters );
}
the java version is this
public static void LogFunctionCall(string parameters,
[System.Runtime.CompilerServices.CallerMemberName] string methodName = "",
[System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "",
[System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
{
var stackFrame = new StackFrame(1);
var callerMethod = stackFrame.GetMethod();
var className = callerMethod.DeclaringType;
System.Diagnostics.Trace.WriteLine("CCCCCCCCCCCCCCCC" + " " + className + " " + methodName + " " + sourceLineNumber + " " + parameters + "\n");
}
I code on a windows machine.
Please where exactly do I need to place the new line character. I tried this
public static void LogFunctionCall(String parameters){
Object trace = Thread.currentThread().getStackTrace()[3];
android.util.Log.i("##################" + trace.toString()+ "", parameters + "\n" );
}
but I still saw some of the logs being clumped up on a single line.

Instead of \n, try \r\n (carriage return and newline). Some text editors will display differently, so the newline may be in there, but whatever app you're using to read the logs might not be displaying it correctly.

You could also try
System.lineSeparator();
I've seen instances where the /n won't work but the lineSep does.

Also, because it hasn't been mentioned, Environment.NewLine will give you the new line character that is configured for the current environment.

Related

Convert HOCON string into Java object

One of my webservice return below Java string:
[
{
id=5d93532e77490b00013d8862,
app=null,
manufacturer=pearsonEducation,
bookUid=bookIsbn,
model=2019,
firmware=[1.0],
bookName=devotional,
accountLinking=mandatory
}
]
I have the equivalent Java object for the above string. I would like to typecast or convert the above java string into Java Object.
I couldn't type-cast it since it's a String, not an object. So, I was trying to convert the Java string to JSON string then I can write that string into Java object but no luck getting invalid character "=" exception.
Can you change the web service to return JSON?
That's not possible. They are not changing their contracts. It would be super easy if they returned JSON.
The format your web-service returns has it's own name HOCON. (You can read more about it here)
You do not need your custom parser. Do not try to reinvent the wheel.
Use an existing one instead.
Add this maven dependency to your project:
<dependency>
<groupId>com.typesafe</groupId>
<artifactId>config</artifactId>
<version>1.3.0</version>
</dependency>
Then parse the response as follows:
Config config = ConfigFactory.parseString(text);
String id = config.getString("id");
Long model = config.getLong("model");
There is also an option to parse the whole string into a POJO:
MyResponsePojo response = ConfigBeanFactory.create(config, MyResponsePojo.class);
Unfortunately this parser does not allow null values. So you'll need to handle exceptions of type com.typesafe.config.ConfigException.Null.
Another option is to convert the HOCON string into JSON:
String hoconString = "...";
String jsonString = ConfigFactory.parseString(hoconString)
.root()
.render(ConfigRenderOptions.concise());
Then you can use any JSON-to-POJO mapper.
Well, this is definitely not the best answer to be given here, but it is possible, at least…
Manipulate the String in small steps like this in order to get a Map<String, String> which can be processed. See this example, it's very basic:
public static void main(String[] args) {
String data = "[\r\n"
+ " {\r\n"
+ " id=5d93532e77490b00013d8862, \r\n"
+ " app=null,\r\n"
+ " manufacturer=pearsonEducation, \r\n"
+ " bookUid=bookIsbn, \r\n"
+ " model=2019,\r\n"
+ " firmware=[1.0], \r\n"
+ " bookName=devotional, \r\n"
+ " accountLinking=mandatory\r\n"
+ " }\r\n"
+ "]";
// manipulate the String in order to have
String[] splitData = data
// no leading and trailing [ ] - cut the first and last char
.substring(1, data.length() - 1)
// no linebreaks
.replace("\n", "")
// no windows linebreaks
.replace("\r", "")
// no opening curly brackets
.replace("{", "")
// and no closing curly brackets.
.replace("}", "")
// Then split it by comma
.split(",");
// create a map to store the keys and values
Map<String, String> dataMap = new HashMap<>();
// iterate the key-value pairs connected with '='
for (String s : splitData) {
// split them by the equality symbol
String[] keyVal = s.trim().split("=");
// then take the key
String key = keyVal[0];
// and the value
String val = keyVal[1];
// and store them in the map ——> could be done directly, of course
dataMap.put(key, val);
}
// print the map content
dataMap.forEach((key, value) -> System.out.println(key + " ——> " + value));
}
Please note that I just copied your example String which may have caused the line breaks and I think it is not smart to just replace() all square brackets because the value firmware seems to include those as content.
In my opinion, we split the parse process in two step.
Format the output data to JSON.
Parse text by JSON utils.
In this demo code, i choose regex as format method, and fastjson as JSON tool. you can choose jackson or gson. Furthermore, I remove the [ ], you can put it back, then parse it into array.
import com.alibaba.fastjson.JSON;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class SerializedObject {
private String id;
private String app;
static Pattern compile = Pattern.compile("([a-zA-Z0-9.]+)");
public static void main(String[] args) {
String str =
" {\n" +
" id=5d93532e77490b00013d8862, \n" +
" app=null,\n" +
" manufacturer=pearsonEducation, \n" +
" bookUid=bookIsbn, \n" +
" model=2019,\n" +
" firmware=[1.0], \n" +
" bookName=devotional, \n" +
" accountLinking=mandatory\n" +
" }\n";
String s1 = str.replaceAll("=", ":");
StringBuffer sb = new StringBuffer();
Matcher matcher = compile.matcher(s1);
while (matcher.find()) {
matcher.appendReplacement(sb, "\"" + matcher.group(1) + "\"");
}
matcher.appendTail(sb);
System.out.println(sb.toString());
SerializedObject serializedObject = JSON.parseObject(sb.toString(), SerializedObject.class);
System.out.println(serializedObject);
}
}

Why won't "\t" create a tab?

I want the "Module Code = " and "Result = " to be separated by a tab but whenever I run the code below it literally just outputs
"Module Code = Biology\tResult = 40.0"
public String toString()
{
return "Module Code = " + moduleCode + "\t" + "Result = " + result;
}
The problem is that you're viewing the value of the produced string in the BlueJ window. That window is good for debugging purposes, but it won't exhibit the same behavior that a proper output device would, especially with respect to characters such as newline, tabulation, etc. Those characters will still appear with their escape sequences, just like you typed them in your source code.
In other words, your toString() method is fine and it works as intended. If you want to see its results formatted properly, don't view them using BlueJ -- print them somewhere else. The console is a good choice:
System.out.println(module.toString());
Why won't “\t” create a new line?
well, that is because “\t” is a tabulation not a new line “\n”
if you need a new line try instead
return "Module Code = " + moduleCode + "\n" + "Result = " + result;

Crawling a URL in order to extract all the other URLs in that page

I am trying to crawl URLs in order to extract other URLs inside of each URL. To do such, I read the HTML code of the page, read each line of each, match it with a pattern and then extract the needed part as shown below:
public class SimpleCrawler {
static String pattern="https://www\\.([^&]+)\\.(?:com|net|org|)/([^&]+)";
static Pattern UrlPattern = Pattern.compile (pattern);
static Matcher UrlMatcher;
public static void main(String[] args) {
try {
URL url = new URL("https://stackoverflow.com/");
BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
while((String line = br.readLine())!=null){
UrlMatcher= UrlPattern.matcher(line);
if(UrlMatcher.find())
{
String extractedPath = UrlMatcher.group(1);
String extractedPath2 = UrlMatcher.group(2);
System.out.println("http://www."+extractedPath+".com"+extractedPath2);
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
However, there some issue with it which I would like to address them:
How is it possible to make either http and www or even both of them, optional? I have encountered many cases that there are links without either or both parts, so the regex will not match them.
According to my code, I make two groups, one between http until the domain extension and the second is whatever comes after it. This, however, causes two sub-problems:
2.1 Since it is HTML codes, the rest of the HTML tags that may come after the URL will be extracted to.
2.2 In the System.out.println("http://www."+extractedPath+".com"+extractedPath2); I cannot make sure if it shows right URL (regardless of previous issues) because I do not know which domain extension it is matched with.
Last but not least, I wonder how to match both http and https as well?
How about:
try {
boolean foundMatch = subjectString.matches(
"(?imx)^\n" +
"(# Scheme\n" +
" [a-z][a-z0-9+\\-.]*:\n" +
" (# Authority & path\n" +
" //\n" +
" ([a-z0-9\\-._~%!$&'()*+,;=]+#)? # User\n" +
" ([a-z0-9\\-._~%]+ # Named host\n" +
" |\\[[a-f0-9:.]+\\] # IPv6 host\n" +
" |\\[v[a-f0-9][a-z0-9\\-._~%!$&'()*+,;=:]+\\]) # IPvFuture host\n" +
" (:[0-9]+)? # Port\n" +
" (/[a-z0-9\\-._~%!$&'()*+,;=:#]+)*/? # Path\n" +
" |# Path without authority\n" +
" (/?[a-z0-9\\-._~%!$&'()*+,;=:#]+(/[a-z0-9\\-._~%!$&'()*+,;=:#]+)*/?)?\n" +
" )\n" +
"|# Relative URL (no scheme or authority)\n" +
" ([a-z0-9\\-._~%!$&'()*+,;=#]+(/[a-z0-9\\-._~%!$&'()*+,;=:#]+)*/? # Relative path\n" +
" |(/[a-z0-9\\-._~%!$&'()*+,;=:#]+)+/?) # Absolute path\n" +
")\n" +
"# Query\n" +
"(\\?[a-z0-9\\-._~%!$&'()*+,;=:#/?]*)?\n" +
"# Fragment\n" +
"(\\#[a-z0-9\\-._~%!$&'()*+,;=:#/?]*)?\n" +
"$");
} catch (PatternSyntaxException ex) {
// Syntax error in the regular expression
}
With one library. I used HtmlCleaner. It does the job.
you can find it at:
http://htmlcleaner.sourceforge.net/javause.php
another example (not tested) with jsoup:
http://jsoup.org/cookbook/extracting-data/example-list-links
rather readable.
You can enhance it, choose < A > tags or others, HREF, etc...
or be more precise with case (HreF, HRef, ...): for exercise
import org.htmlcleaner.*;
public static Vector<String> HTML2URLS(String _source)
{
Vector<String> result=new Vector<String>();
HtmlCleaner cleaner = new HtmlCleaner();
// Principal Node
TagNode node = cleaner.clean(_source);
// All nodes
TagNode[] myNodes =node.getAllElements(true);
int s=myNodes.length;
for (int pos=0;pos<s;pos++)
{
TagNode tn=myNodes[pos];
// all attributes
Map<String,String> mss=tn.getAttributes();
// Name of tag
String name=tn.getName();
// Is there href ?
String href="";
if (mss.containsKey("href")) href=mss.get("href");
if (mss.containsKey("HREF")) href=mss.get("HREF");
if (name.equals("a")) result.add(href);
if (name.equals("A")) result.add(href);
}
return result;
}

How to remove commas at the end of any string

I have Strings "a,b,c,d,,,,, ", ",,,,a,,,,"
I want these strings to be converted into "a,b,c,d" and ",,,,a" respectively.
I am writing a regular expression for this. My java code looks like this
public class TestRegx{
public static void main(String[] arg){
String text = ",,,a,,,";
System.out.println("Before " +text);
text = text.replaceAll("[^a-zA-Z0-9]","");
System.out.println("After " +text);
}}
But this is removing all the commas here.
How can write this to achieve as given above?
Use :
text.replaceAll(",*$", "")
As mentioned by #Jonny in comments, can also use:-
text.replaceAll(",+$", "")
Your first example had a space at the end, so it needs to match [, ]. When using the same regular expression multiple times, it's better to compile it up front, and it only needs to replace once, and only if at least one character will be removed (+).
Simple version:
text = text.replaceFirst("[, ]+$", "");
Full code to test both inputs:
String[] texts = { "a,b,c,d,,,,, ", ",,,,a,,,," };
Pattern p = Pattern.compile("[, ]+$");
for (String text : texts) {
String text2 = p.matcher(text).replaceFirst("");
System.out.println("Before \"" + text + "\"");
System.out.println("After \"" + text2 + "\"");
}
Output
Before "a,b,c,d,,,,, "
After "a,b,c,d"
Before ",,,,a,,,,"
After ",,,,a"

Split a string in Java

I have a function that accepts a message in String form. The message looks like this : "HTTP/1.1 GET /1/ \n"
I have been using the java.String.split method to break down the string into three smaller substrings, version, command, and number. Then I reconstruct the oringal string from the substrings and output it.
However, when I run teh function the program results in ArrayIndex out of bounds : 1, but still functions properly. But when I run the program step by step in the debugger (netbeans) the program does not result in the ArrayIndex out of bounds nonesense and functions as normal
Any suggestions?
Sam
String output = "";
String[] tokens = clientMessage.split(" ");
String version = tokens[0];
String command = tokens[1];
String potNum = tokens[2];
output = version + " " + command + " " + potNum;
EDIT yes, the program is multithreaded, the clientMsessage string contains "HTTP/1.1 GET /1/ \n" all the time, the value fo clientMessage never changes. The clientMessage is a string sent from a client program and then processed on the server and the output is snet back tot eh client but I keep getting the array errors
I suggest you print out/log your inputs. I suspect you are doing something differently when you debug your program. Its possible this works the first time you call it but when its called again, it fails.
Add before the split.
System.out.println("clientMessage >" + clientMessage +"<");
If your output looks like
clientMessage >HTCPCP/1.0 PROPFIND /1/<
clientMessage >HTCPCP/1.0 PROPFIND /1/<
clientMessage ><
It appears you have an empty request message. I imagine this means the client will not be sending more requests and you have to handle this differently.
ArrayIndexOutOfBounds arises when you are accessing index of an array which does not have any values means in your case tokens[1] does not exists. When debugging are you using same string as input??
Sorry this is not an answer but just an additional question to find what is actually wrong and comments are too small to put that much code. The following works for me, so one of your asumptions is wrong:
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
String clientMessage = "HTTP/1.1 GET /1/ \n";
String[] tokens = clientMessage.split(" ");
String version = tokens[0];
String command = tokens[1];
String potNum = tokens[2];
System.err.println(version + " " + command + " " + potNum);
}
}
It runs OK on my side. I would have to guess that sometimes clientMessage is a value that does not contain enough spaces to be seperated in 3 parts.
Perhaps there is more to the code than you are including here. I put your code in a class as follows and it compiles and runs without error. Is there something missing?
public class Andrew {
public static void main(String args[]) {
String output = "";
String clientMessage = "HTTP/1.1 GET /1/ \n";
String[] tokens = clientMessage.split(" ");
String version = tokens[0];
String command = tokens[1];
String potNum = tokens[2];
output = version + " " + command + " " + potNum;
System.out.println(output);
}
}

Categories