How to Create following String Dynamically - java

I am doing project using Lucen library in here I need to build query dynamically using Json object. so in here I use jettison library. as an example my json like this
{"OR":{"OR": {"fildKey1": "value1","fildKey2": "value2","fildKeyabc": "valueabc"},"AND": {"AND": {"fildKey3": "value3","OR": {"fildKey4": "value4","fildKey5": "value5"}},"fildKeyw": "valuew"}}}
using above json I need to create following query
(( fildKey1 : value1 OR fildKey2 : value2 OR fildKeyabc : valueabc )OR(( fildKey3 : value3 AND( fildKey4 : value4 OR fildKey5 : value5 ))AND fildKeyw : valuew ))
but I can't get the above query.my result is like this
(( fildKey1 : value1 OR fildKey2 : value2 OR fildKeyabc : valueabc )OR(( fildKey3 : value3 AND( fildKey4 : value4 OR fildKey5 : value5 )AND)AND fildKeyw : valuew )OR)
I need to remove above extra 2 operators this is my code
public class JettisionCls {
static Stack s = new Stack();
String operater = null;
static String res = "";
int bracket_counter = 0;
public void getKeyAndValue(JSONObject json_obj) throws JSONException{
Iterator<String> iter = json_obj.keys();
while (iter.hasNext()) {
String obj = iter.next();
if(obj.toLowerCase().equals("and") || obj.toLowerCase().equals("or")){
//System.out.print(obj);
operater = obj;
}
JSONObject temp = null;
try {
temp = new JSONObject(json_obj.get(obj).toString());
} catch (JSONException e) {
e.getStackTrace();
}
if (temp != null) {
//System.out.print("(");
res = res +"(";
bracket_counter=bracket_counter+1;
s.push(operater);
getKeyAndValue(temp);
//System.out.print(")");
res = res +")";
bracket_counter=bracket_counter-1;
if((s.size()) != 0 && bracket_counter != 0){
//System.out.print(s.peek());
s.pop();
res = res +s.peek();
}
else{
s.pop();
}
}
else{
if(iter.hasNext()){
res = res+" "+obj + " : " + json_obj.get(obj) + " " + operater; }
else{
res = res+" "+obj + " : " + json_obj.get(obj)+" ";
}
}
}
}
my main method look like this
String multiLevelQuery = "{\"OR\":{\"OR\": {\"fildKey1\": \"value1\",\"fildKey2\": \"value2\",\"fildKeyabc\": \"valueabc\"},\"AND\": {\"AND\": {\"fildKey3\": \"value3\",\"OR\": {\"fildKey4\": \"value4\",\"fildKey5\": \"value5\"}},\"fildKeyw\": \"valuew\"}}}";
JSONObject jobj = new JSONObject(multiLevelQuery);
JettisionCls obj = new JettisionCls();
obj.getKeyAndValue(jobj);
System.out.println(JettisionCls.res);
if anyone can please help me.

I think you can do this using string replacement.
public void createQry(String s){
String temp = s;
if(temp.contains(")OR)")){
temp = temp.replace(")OR)", "))");
}
if(s.contains(")AND)")){
temp = temp.replace(")AND)", "))");
}
System.out.println(temp);
}

Hmm, this is an interesting problem. But instead of brute force, I would have gone with something more elegant like recursion. The pushing, popping and concatinating will be done by recursion for you. In your code, I can see a lot of places where it can break. Even if you fix this issue, there is a chance that it will fail for another condition.
A sample algorithm with recursion would be
public String generateQuery(JSONObject json_obj) {
if(single_json_obj)
return generated_query_for_single_condition;
//else complex json with inner children
else
return generateQuery(innerJSONObject)
}
}

Related

Convert QueryString to Json using JAVA

I want to convert "id=1&location=india" querystring to {"id":"1","location":"india"} json format using java.
I am using spring version 4.0.3.
Well this is not a direct way, but this is the first though came to my mind.
Convert the queryString to Hashtable using HttpUtils , then marshall it into JSON.
https://tomcat.apache.org/tomcat-7.0-doc/servletapi/javax/servlet/http/HttpUtils.html
Update:
HttpUtils produces Hashtable.
I think you can write a converter like this
public class ConvertToJson {
public static void main(String[] args) {
String a = "id=1&location=india";
System.out.println(convert(a));
}
private static String convert(String a) {
String res = "{\"";
for (int i = 0; i < a.length(); i++) {
if (a.charAt(i) == '=') {
res += "\"" + ":" + "\"";
} else if (a.charAt(i) == '&') {
res += "\"" + "," + "\"";
} else {
res += a.charAt(i);
}
}
res += "\"" + "}";
return res;
}
}
it can do the job for you
try this..
try
{
String query="id=1&location=india";
String queryArray[]=query.split("&");
String id[]=queryArray[0].split("=");
String location[]=queryArray[1].split("=");
JSONObject jsonObject=new JSONObject();
jsonObject.put(id[0],id[1]);
jsonObject.put(location[0],location[1]);
Log.i("Stackoverflow",jsonObject.toString());
}
catch (JSONException e)
{
e.printStackTrace();
Log.i("Stackoverflow",e.getMessage());
}

Get the json path of a value with jackson

I'm trying to retrieve the json path of a value from a json string with jackson. As I couldn't find any function inside jackson giving me this result, I wanted to create my own function.
So I made this function :
public static String getJsonPath(Map.Entry<String, JsonNode> jsonNode, String valueSearched) {
String res = "";
String key = jsonNode.getKey();
JsonNode value = jsonNode.getValue();
if (value.isValueNode() && value.equals(valueSearched)) { // Here the value change to a ValueNode and the key weirdly equals to "".
return res + key;
} else {
if (value.isContainerNode()) {
if (value.isObject()) {
Iterator<Map.Entry<String, JsonNode>> elements = value.fields();
while (elements.hasNext()) {
Map.Entry<String, JsonNode> element = elements.next();
res += "." + element.getKey() + generateJsonPathArgumentFromJson(element, valueSearched);
}
} else {
int i = 0;
ArrayNode arrayNode = (ArrayNode) jsonNode;
Iterator<Map.Entry<String,JsonNode>> elements = arrayNode.fields();
while (elements.hasNext()) {
Map.Entry<String, JsonNode> element = elements.next();
i++;
res += "(" + i + ")" + generateJsonPathArgumentFromJson(element, valueSearched);
}
}
}
}
return "";
}
Why the key gets equal to "" after the first if ? Or there's a better way to construct a json path for a specific value ?
Just get the solutions :
protected static String generateJsonPathArgumentFromJson(JsonNode jsonNode, String valueSearched) {
if (jsonNode.isValueNode() && !jsonNode.asText().equals(valueSearched)) {
return null;
} else {
if (jsonNode.isContainerNode()) {
if (jsonNode.isObject()) {
Iterator<Map.Entry<String, JsonNode>> elements = jsonNode.fields();
while (elements.hasNext()) {
Map.Entry<String, JsonNode> element = elements.next();
String res = generateJsonPathArgumentFromJson(element.getValue(), valueSearched);
if (res != null) {
return "." + element.getKey() + res;
}
}
} else {
int i = 0;
Iterator<JsonNode> elements = jsonNode.elements();
while (elements.hasNext()) {
JsonNode element = elements.next();
String res = generateJsonPathArgumentFromJson(element, valueSearched);
if (res != null) {
return "(" + i + ")" + res;
}
i++;
}
}
}
}
return "";
}
I'm sure there's better way to do, but at least it works :)

incompatible types, expected hashmap found String

public class Readparam
{
private static String method_name;
public static HashMap<String, Vector<String>> getParameters(String file_name)
{
HashMap temp_map = new HashMap();
String current_dir = System.getProperty("user.dir");
File new_file = new File(current_dir + "\\parameters\\" + file_name);
StringTokenizer stringtok = null;
StringBuffer temp_contents = new StringBuffer();
BufferedReader input = null;
try
{
input = new BufferedReader(new FileReader(new_file));
String current_line = null;
while (((current_line = input.readLine()) != null) && (current_line.length() > 0))
{
stringtok = new StringTokenizer(current_line, "(");
method_name = stringtok.nextToken();
String parsed_parameters = current_line.subSequence(current_line.indexOf("(") + 1, current_line.indexOf(")")).toString();
StringTokenizer paramtok = new StringTokenizer(parsed_parameters, ",");
String[] parsed_string = parsed_parameters.split(", ");
String parsing = method_name + "(";
for (int i = 0; i < parsed_string.length; i++)
{
String[] temp_parse = parsed_string[i].split(" ");
if (i < parsed_string.length - 1)
parsing = parsing + temp_parse[0] + ", ";
else {
parsing = parsing + temp_parse[0];
}
}
parsing = parsing + ")";
Vector temp_vector = new Vector();
for (String s : parsed_string) {
temp_vector.add(s);
}
temp_map.put(parsing, temp_vector);
}
}
catch (FileNotFoundException ex)
{
System.out.println("File not found: " + file_name);
String method_name = null;
return method_name;
}
any help on this is aprreciated
I have the last line "return method_name that does not compile
i recieve an error incompatible types, expected java.util.hashmap found java.lang.String
the last line return method_name does not compile
System.out.println("File not found: " + file_name);
HashMap<String, Vector<String>> method_name = null;
return method_name;
Since your method is of a certain type, you need to 'cast' the value that's being returned to that type.
If you are coding using Eclipse, you can just click on the little error icon, and it will offer to fix the error for you, and it will cast it for you. If you are not using Eclipse, you might consider it in the future. (NetBeans works in a similar manner)
Your method is declared to return HashMap<String, Vector<String>> (which is odd to start with - usually you'd use List rather than Vector if you're using the Java 2 collections). But then your only return statement is here:
String method_name = null;
return method_name;
That's clearly not returning a HashMap<String, Vector<String>>, is it? What do you expect that to do? You could just write
return null;
which would return a null reference as a HashMap<String, Vector<String>>. (Personally I'd just let the exception bubble up, but that's a different matter.)
(It also doesn't help that you haven't shown the end of your method, and that some of the indentation is decidedly odd.)

Remove stop words in Java --- Help needed

Im using a method to remove stop word defined in a file, that will rip off those words from the query string that i pass to this method... The code is working fine
Now what i need to do is ... If the query string contains just those stop words alone then it should not be ripped of..
eg : if the stopwords file has "is" "was" "and"
if the query is "I was a student" then the output should be " I a student"
but if the query is "and is " now i need the output the same as "and is".
Below is the method that i wrote to remove stop words.
public static String removeStopWords(String query) throws UnsupportedEncodingException
{
String []queryTerms = query.split("&");
String queryString="";
StringBuffer sb =new StringBuffer();
for (int i=0;i<queryTerms.length;i++){
if(queryTerms[i].startsWith("q=") && !queryTerms[i].startsWith("q.orig")){
queryString = queryTerms[i].replaceAll("q=","").trim().replace("+"," ").replaceAll("\\s+"," ").trim();
}
}
if(!queryString.equalsIgnoreCase("")) {
String [] tokens=queryString.split("\\s+");
List lStopWords=StopWordDataLoad.getlQueryStringStopword();
List<String> lTokens=new ArrayList<String>();
boolean noStopWord=false;
for(String s: tokens)
if(!lStopWords.contains(s)) {
if(sb.length()==0) sb.append(s);
else sb.append(" ").append(s);
} else noStopWord=true;
queryString=sb.toString().replaceAll("\\s+", " ");
if(queryString.equalsIgnoreCase("") || noStopWord ==false) return query;
}
else return query;
String fque="";
String finQue = "";
ArrayList<String> list = new ArrayList<String>();
for (int i=0;i<queryTerms.length;i++){
if(queryTerms[i].startsWith("q=") && !queryTerms[i].startsWith("q.orig")){
fque = "q="+URLEncoder.encode(queryString,PropertyLoader.getHttpEncoding());
list.add(fque);
} else if (!queryTerms[i].equalsIgnoreCase("")) list.add(queryTerms[i]);
}
ListIterator<String> iter = list.listIterator();
while(iter.hasNext()){
String str = iter.next();
finQue=finQue+"&"+str;
}
return finQue.trim();
}
Just change the last line to this:
String result = finQue.trim();
if (result.equals("")) {
return query;
} else {
return result;
}

Regex Issue With Multiple Groups

I'm trying to create a regex pattern to match the lines in the following format:
field[bii] = float4:.4f_degree // Galactic Latitude
field[class] = int2 (index) // Browse Object Classification
field[dec] = float8:.4f_degree (key) // Declination
field[name] = char20 (index) // Object Designation
field[dircos1] = float8 // 1st Directional Cosine
I came up with this pattern, which seemed to work, then suddenly seemed NOT to work:
field\[(.*)\] = (float|int|char)([0-9]|[1-9][0-9]).*(:(\.([0-9])))
Here is the code I'm trying to use (edit: provided full method instead of excerpt):
private static Map<String, String> createColumnMap(String filename) {
// create a linked hashmap mapping field names to their column types. Use LHM because I'm picky and
// would prefer to preserve the order
Map<String, String> columnMap = new LinkedHashMap<String, String>();
// define the regex patterns
Pattern columnNamePattern = Pattern.compile(columnNameRegexPattern);
try {
Scanner scanner = new Scanner(new FileInputStream(filename));
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if (line.indexOf("field[") != -1) {
// get the field name
Matcher fieldNameMatcher = columnNamePattern.matcher(line);
String fieldName = null;
if (fieldNameMatcher.find()) {
fieldName = fieldNameMatcher.group(1);
}
String columnName = null;
String columnType = null;
String columnPrecision = null;
String columnScale = null;
//Pattern columnTypePattern = Pattern.compile(".*(float|int|char)([0-9]|[1-9][0-9])");
Pattern columnTypePattern = Pattern.compile("field\\[(.*)\\] = (float|int|char).*([0-9]|[1-9][0-9]).*(:(\\.([0-9])))");
Matcher columnTypeMatcher = columnTypePattern.matcher(line);
System.out.println(columnTypeMatcher.lookingAt());
if (columnTypeMatcher.lookingAt()) {
System.out.println(fieldName + ": " + columnTypeMatcher.groupCount());
int count = columnTypeMatcher.groupCount();
if (count > 1) {
columnName = columnTypeMatcher.group(1);
columnType = columnTypeMatcher.group(2);
}
if (count > 2) {
columnScale = columnTypeMatcher.group(3);
}
if (count >= 6) {
columnPrecision = columnTypeMatcher.group(6);
}
}
int precision = Integer.parseInt(columnPrecision);
int scale = Integer.parseInt(columnScale);
if (columnType.equals("int")) {
if (precision <= 4) {
columnMap.put(fieldName, "INTEGER");
} else {
columnMap.put(fieldName, "BIGINT");
}
} else if (columnType.equals("float")) {
if (columnPrecision==null) {
columnMap.put(fieldName,"DECIMAL(8,4)");
} else {
columnMap.put(fieldName,"DECIMAL(" + columnPrecision + "," + columnScale + ")");
}
} else {
columnMap.put(fieldName,"VARCHAR("+columnPrecision+")");
}
}
if (line.indexOf("<DATA>") != -1) {
scanner.close();
break;
}
}
scanner.close();
} catch (FileNotFoundException e) {
}
return columnMap;
}
When I get the groupCount from the Matcher object, it says there are 6 groups. However, they aren't matching the text, so I could definitely use some help... can anyone assist?
It's not entirely clear to me what you're after but I came up with the following pattern and it accepts all of your input examples:
field\\[(.*)\\] = (float|int|char)([1-9][0-9]?)?(:\\.([0-9]))?
using this code:
String columnName = null;
String columnType = null;
String columnPrecision = null;
String columnScale = null;
// Pattern columnTypePattern =
// Pattern.compile(".*(float|int|char)([0-9]|[1-9][0-9])");
// field\[(.*)\] = (float|int|char)([0-9]|[1-9][0-9]).*(:(\.([0-9])))
Pattern columnTypePattern = Pattern
.compile("field\\[(.*)\\] = (float|int|char)([1-9][0-9]?)?(:\\.([0-9]))?");
Matcher columnTypeMatcher = columnTypePattern.matcher(line);
boolean match = columnTypeMatcher.lookingAt();
System.out.println("Match: " + match);
if (match) {
int count = columnTypeMatcher.groupCount();
if (count > 1) {
columnName = columnTypeMatcher.group(1);
columnType = columnTypeMatcher.group(2);
}
if (count > 2) {
columnScale = columnTypeMatcher.group(3);
}
if (count > 4) {
columnPrecision = columnTypeMatcher.group(5);
}
System.out.println("Name=" + columnName + "; Type=" + columnType + "; Scale=" + columnScale + "; Precision=" + columnPrecision);
}
I think the problem with your regex was it needed to make the scale and precision optional.
field\[(.*)\] = (float|int|char)([0-9]|[1-9][0-9]).*(:(\.([0-9])))
The .* is overly broad, and there is a lot of redundancy in ([0-9]|[1-9][0-9]), and I think the parenthetical group that starts with : and preceding .* should be optional.
After removing all the ambiguity, I get
field\[([^\]]*)\] = (float|int|char)(0|[1-9][0-9]+)(?:[^:]*(:(\.([0-9]+))))?

Categories

Resources