java parsing of complex string? - java
I am getting a string response from server like this..
[
Anchor{anchorName='&loreal_lip_balm',
clientName='loreal india',
anchorPrice=10,
campaigns=[
Campaign{
campaignId='loreal_camp1',
question='How to Turn Your Melted Lipstick into a Tinted Lip Balm',
startDate=2015-08-04,
endDate=2015-08-04,
imageURL='null',
regionCountry='ALL',
rewardInfo='null',
campaignPrice=20,
options=null
}
]},
Anchor{
anchorName='&loreal_total_repair_5',
clientName='loreal india',
anchorPrice=125,
campaigns=[
Campaign{
campaignId='loreal_camp2',
question='Is it a good
product to buy?',
startDate=2015-08-04,
endDate=2015-08-04,
imageURL='null',
regionCountry='ALL',
rewardInfo='null',
campaignPrice=20,
options=null
}
]
}
].
can anybody tell me how to parse this.It is not a json response.
I used hand coded parsers for simple languages where I felt that using http://www.antlr.org/ or https://javacc.java.net to be a bit heavy. I used the same structure for parsing JSON, CSS a simple template. Modified it to parse your response. See whether it helps.
package snippet;
import java.io.IOException;
import java.io.PushbackReader;
import java.io.Reader;
import java.io.StringReader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import snippet.RecursiveDescentParser.Token.TokenType;
public class RecursiveDescentParser {
// #formatter:off
final static String text = "" +
"[" +
" Anchor{anchorName='&loreal_lip_balm'," +
" clientName='loreal india'," +
"" +
" anchorPrice=10," +
" campaigns=[" +
" Campaign{" +
" campaignId='loreal_camp1'," +
"" +
" question='How to Turn Your Melted Lipstick into a Tinted Lip Balm'," +
"" +
" startDate=2015-08-04," +
" endDate=2015-08-04," +
" imageURL='null'," +
"" +
" regionCountry='ALL'," +
" rewardInfo='null'," +
" campaignPrice=20," +
"" +
" options=null" +
" }" +
" ]}," +
" Anchor{" +
"" +
" anchorName='&loreal_total_repair_5'," +
" clientName='loreal india'," +
" anchorPrice=125," +
"" +
" campaigns=[" +
" Campaign{" +
" campaignId='loreal_camp2'," +
" question='Is it a good" +
" product to buy?'," +
" startDate=2015-08-04," +
" endDate=2015-08-04," +
"" +
" imageURL='null'," +
" regionCountry='ALL'," +
" rewardInfo='null'," +
"" +
" campaignPrice=20," +
" options=null" +
" }" +
" ]" +
" }" +
" ]" +
"";
// #formatter:on
static class Token {
enum TokenType {
OPEN_BRACKET, CLOSE_BRACKET, OPEN_BRACE, CLOSE_BRACE, STRING, NAME, COMMA, EQUALS, INTEGER, DATE, EOF, NULL;
}
private String text;
private TokenType type;
public Token(TokenType type) {
this(type, null);
}
public Token(TokenType type, String text) {
this.type = type;
this.text = text;
}
public TokenType getType() {
return type;
}
public String getText() {
return text;
}
#Override public String toString() {
return "Token [text=" + text + ", type=" + type + "]";
}
}
static class TokenReader {
private PushbackReader reader;
public TokenReader(Reader reader) {
this.reader = new PushbackReader(reader);
}
public Token nextToken() throws IOException {
Token t = nextTokenx();
System.out.println("Got: " + t);
return t;
}
public Token nextTokenx() throws IOException {
int c;
while ((c = reader.read()) != -1 && Character.isWhitespace((char) c))
;
if (c == -1)
return new Token(TokenType.EOF);
switch (c) {
case '[':
return new Token(TokenType.OPEN_BRACKET);
case ']':
return new Token(TokenType.CLOSE_BRACKET);
case '{':
return new Token(TokenType.OPEN_BRACE);
case '}':
return new Token(TokenType.CLOSE_BRACE);
case ',':
return new Token(TokenType.COMMA);
case '=':
return new Token(TokenType.EQUALS);
default:
if (Character.isDigit(c))
return readIntegerOrDate(c);
if (c == '\'')
return readString(c);
if (Character.isJavaIdentifierStart(c))
return readName(c);
throw new RuntimeException("Invalid character '" + ((char) c) + "' in input");
}
}
private Token readName(int c) throws IOException {
StringBuilder sb = new StringBuilder();
sb.append((char) c);
while ((c = reader.read()) != -1 && Character.isJavaIdentifierPart(c))
sb.append((char) c);
if (c != -1)
reader.unread(c);
if ("null".equals(sb.toString()))
return new Token(TokenType.NULL);
return new Token(TokenType.NAME, sb.toString());
}
private Token readString(int end) throws IOException {
StringBuilder sb = new StringBuilder();
int c;
while ((c = reader.read()) != -1 && c != end)
sb.append((char) c);
return new Token(TokenType.STRING, sb.toString());
}
private Token readIntegerOrDate(int c) throws IOException {
StringBuilder sb = new StringBuilder();
sb.append((char) c);
while ((c = reader.read()) != -1 && Character.isDigit((char) c))
sb.append((char) c);
if (c == '-') {
sb.append((char) c);
return readDate(sb);
}
if (c != -1)
reader.unread(c);
return new Token(TokenType.INTEGER, sb.toString());
}
private Token readDate(StringBuilder sb) throws IOException {
int c;
while ((c = reader.read()) != -1 && Character.isDigit((char) c))
sb.append((char) c);
if (c == -1)
throw new RuntimeException("EOF while reading date");
if (c != '-')
throw new RuntimeException("Invalid character '" + (char) c + "' while reading date");
sb.append((char) c);
while ((c = reader.read()) != -1 && Character.isDigit((char) c))
sb.append((char) c);
if (c != -1)
reader.unread(c);
return new Token(TokenType.DATE, sb.toString());
}
}
static class Lexer {
private TokenReader reader;
private Token current;
public Lexer(Reader reader) {
this.reader = new TokenReader(reader);
}
public Token expect(TokenType... tt) throws IOException {
if (current == null)
current = reader.nextToken();
for (TokenType tokenType : tt) {
if (current.getType() == tokenType) {
Token r = current;
current = null;
return r;
}
}
throw new RuntimeException("Expecting one of " + Arrays.asList(tt) + " but got " + current);
}
public Token expect1or0(TokenType... tt) throws IOException {
if (current == null)
current = reader.nextToken();
for (TokenType tokenType : tt) {
if (current.getType() == tokenType) {
Token r = current;
current = null;
return r;
}
}
return null;
}
}
public Object parse(String text) throws IOException {
return parse(new StringReader(text));
}
private Object parse(Reader reader) throws IOException {
Lexer lexer = new Lexer(reader);
return parse(lexer);
}
private Object parse(Lexer lexer) throws IOException {
Token t = lexer.expect1or0(TokenType.OPEN_BRACE, TokenType.OPEN_BRACKET, TokenType.EOF);
if (t == null || t.getType() == TokenType.EOF)
return null;
else if (t.getType() == TokenType.OPEN_BRACKET) {
return parseList(lexer);
} else {
return parseMap(null, lexer);
}
}
private List<Object> parseList(Lexer lexer) throws IOException {
ArrayList<Object> result = new ArrayList<Object>();
Token tName = lexer.expect1or0(TokenType.NAME);
while (tName != null) {
lexer.expect(TokenType.OPEN_BRACE);
result.add(parseMap(tName.getText(), lexer));
if (lexer.expect1or0(TokenType.COMMA) != null)
tName = lexer.expect(TokenType.NAME);
else
tName = null;
}
lexer.expect(TokenType.CLOSE_BRACKET);
return result;
}
private Object parseMap(String oname, Lexer lexer) throws IOException {
Map<String, Object> result = new HashMap<String, Object>();
if (oname != null)
result.put("objectName", oname);
Token tName = lexer.expect1or0(TokenType.NAME);
while (tName != null) {
String name = tName.getText();
lexer.expect(TokenType.EQUALS);
Token next = lexer.expect(TokenType.STRING, TokenType.DATE, TokenType.INTEGER, TokenType.OPEN_BRACKET,
TokenType.OPEN_BRACE, TokenType.NULL);
TokenType tt = next.getType();
if (tt == TokenType.STRING) {
result.put(name, next.getText());
} else if (tt == TokenType.DATE) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
result.put(name, sdf.parse(next.getText()));
} catch (ParseException e) {
return new RuntimeException(e);
}
} else if (tt == TokenType.INTEGER) {
result.put(name, Integer.valueOf(next.getText()));
} else if (tt == TokenType.OPEN_BRACKET) {
result.put(name, parseList(lexer));
} else if (tt == TokenType.OPEN_BRACE) {
result.put(name, parseMap(null, lexer));
} else {
result.put(name, null);
}
if (lexer.expect1or0(TokenType.COMMA) != null)
tName = lexer.expect(TokenType.NAME);
else
tName = null;
}
lexer.expect(TokenType.CLOSE_BRACE);
return result;
}
public static void main(String[] args) throws IOException {
RecursiveDescentParser parser = new RecursiveDescentParser();
Object o = parser.parse(text);
System.out.println(o);
}
}
Here is my suggestion.
I assume as you said that your input from the server is String.
I have build a little method that return the value of the required key.
public String valueFinder(String data, String key){
int keyValueStart = data.indexOf(key) + key.length() + 1;
String keyValueRaw = data.substring(keyValueStart, data.length());
int keyValueEnd = keyValueRaw.indexOf(",");
String keyValue = keyValueRaw.substring(0, keyValueEnd);
String value = keyValue.replaceAll("^\'|\'$", "");
return value;
}
So if you pass the String data generated by the server to the method and the ask for the required key for example for "clientName" it will return loreal india, if you pass/look-for "anchorName" it will return &loreal_lip_balm.
Now you have the concept, you are welcome to change/modify/customize it as you wish to fetch more detailed information in your campaigns or other scenarios.
It is possible to further develop the method to return single key value, a set of keys and values, convert keys and values to JSON or Array, and just name it.
All this can be done on the same concept.
There is a tool called ANTLR which is useful to read data like this.
Related
get the values of the attribute userparameters from active directory
I need to get the values of the userparameters attribute. I use this code to connect to ldap, and with filters get the information I need. The problem is that userparameters contains values of several types, and you can not get them in the usual way, otherwise you will see this: {userparameters=userParameters: PCtxCfgPresent????CtxCfgFlags1????CtxShadow????.CtxMaxDisconnectionTime????CtxMaxIdleTime????*CtxMinEncryptionLevel? In this question in c #, the solution to my problem is described, IADsTSUserEx saves considerable time and makes the code less. Is there a similar solution on java? After much searching, I did not find anything. Thank you.
I finally managed to get my piece of Java code running to fulfill this need. It's a direct port from this Powershell script : https://gist.github.com/HarmJ0y/08ee1824aa555598cff5efa4c5c96cf0 import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; import java.security.Security; import java.util.Hashtable; import javax.naming.Context; import javax.naming.NamingEnumeration; import javax.naming.directory.Attribute; import javax.naming.directory.SearchControls; import javax.naming.directory.SearchResult; import javax.naming.ldap.Control; import javax.naming.ldap.InitialLdapContext; import javax.naming.ldap.PagedResultsControl; import javax.naming.ldap.PagedResultsResponseControl; public class LDAP { public static void main(String[] args) { Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider()); InitialLdapContext ldapContext = null; Hashtable ldapEnv = new Hashtable(11); ldapEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); ldapEnv.put(Context.PROVIDER_URL, "ldaps://HOST:636"); ldapEnv.put(Context.SECURITY_AUTHENTICATION, "simple"); ldapEnv.put(Context.SECURITY_PROTOCOL, "ssl"); ldapEnv.put(Context.SECURITY_PRINCIPAL, "ADMIN"); ldapEnv.put(Context.SECURITY_CREDENTIALS, "PASSWORD"); ldapEnv.put("java.naming.ldap.attributes.binary", "objectGUID"); byte[] cookie = null; String baseName = "BASENAME"; try { ldapContext = new InitialLdapContext(ldapEnv, new Control[] { new PagedResultsControl(1, Control.NONCRITICAL) }); SearchControls ctls = new SearchControls(); ctls.setSearchScope(SearchControls.SUBTREE_SCOPE); ctls.setCountLimit(1); String[] attrs = new String[] { "objectGUID", "cn", "userParameters" }; ctls.setReturningAttributes(attrs); NamingEnumeration<SearchResult> e = ldapContext.search(baseName, "(&(objectclass=user)(cn=USERCN))", ctls); if (e.hasMore()) { SearchResult sr = e.next(); Attribute attr = sr.getAttributes().get("cn"); if (attr.get() != null) { NamingEnumeration<?> neAttr = attr.getAll(); while (neAttr.hasMoreElements()) { String val = neAttr.next().toString(); System.out.println(val); } } attr = sr.getAttributes().get("userParameters"); if (attr.get() != null) { NamingEnumeration<?> neAttr = attr.getAll(); while (neAttr.hasMoreElements()) { String v = neAttr.next().toString(); System.out.println("-------------"); byte[] val = v.getBytes(StandardCharsets.UTF_16LE); ByteBuffer buffer = ByteBuffer.wrap(val); buffer.order(ByteOrder.LITTLE_ENDIAN); buffer.position(96); char signature = buffer.getChar(); System.out.println("Signature : " + signature); if (signature == 'P') { int nbAttrs = (int) buffer.getChar(); System.out.println("nbAttrs : " + nbAttrs); for (int i = 0; i < nbAttrs; i++) { System.out.println("\n---- Attribute " + i + " ----"); int nameLength = (int) buffer.getChar(); System.out.println("nameLength : " + nameLength); int valueLength = (int) buffer.getChar(); System.out.println("valueLength : " + valueLength); int type = (int) buffer.getChar(); System.out.println("type : " + type); byte[] attrNameTab = new byte[nameLength]; buffer.get(attrNameTab); String attrName = new String(attrNameTab, StandardCharsets.UTF_16LE); System.out.println("attrName : " + attrName); byte[] attrValue = new byte[valueLength]; buffer.get(attrValue); if (attrName.matches("CtxCfgPresent|CtxCfgFlags1|CtxCallBack|CtxKeyboardLayout|CtxMinEncryptionLevel|CtxNWLogonServer|CtxMaxConnectionTime|CtxMaxDisconnectionTime|CtxMaxIdleTime|CtxShadow")) { String valueStr = ""; for (byte b : attrValue) { valueStr += (char) b; } Integer valueInt = Integer.parseUnsignedInt(valueStr, 16); System.out.println("attrValue : " + valueInt); if (attrName.matches("CtxShadow")) { switch (valueInt) { case 0x0: System.out.println(" -> Disable"); break; case 0x1000000: System.out.println(" -> EnableInputNotify"); break; case 0x2000000: System.out.println(" -> EnableInputNoNotify"); break; case 0x3000000: System.out.println(" -> EnableNoInputNotify"); break; case 0x4000000: System.out.println(" -> EnableNoInputNoNotify"); break; } } else if (attrName.matches("CtxCfgFlags1")) { // this field is represented as a bitmask for (CtxCfgFlagsBitValues en : CtxCfgFlagsBitValues.values()) { if (en.isBit(valueInt)) { System.out.println(" -> " + en.name()); } } } else if (attrName.matches("CtxMaxConnectionTime|CtxMaxDisconnectionTime|CtxMaxIdleTime")) { for (CtxCfgFlagsTimeValues en : CtxCfgFlagsTimeValues.values()) { if (en.getValue() == valueInt.intValue()) { System.out.println(" -> " + en.name()); } } } } else if (attrName.matches("CtxWFHomeDirDrive.*|CtxWFHomeDir.*|CtxWFHomeDrive.*|CtxInitialProgram.*|CtxWFProfilePath.*|CtxWorkDirectory.*|CtxCallbackNumber.*")) { String str = new String(attrValue, StandardCharsets.US_ASCII); String valueStr = convertHexToString(str); valueStr = valueStr.substring(0, valueStr.length() - 1); if (attrName.matches(".*W$")) { // handle wide strings valueStr = new String(new String(valueStr.getBytes(), StandardCharsets.US_ASCII).getBytes(),StandardCharsets.UTF_16LE); valueStr = valueStr.substring(0, valueStr.length() - 1); } System.out.println("attrValue : " + valueStr); } } } } } Control[] controls = ldapContext.getResponseControls(); if (controls != null) { for (int i = 0; i < controls.length; i++) { if (controls[i] instanceof PagedResultsResponseControl) { PagedResultsResponseControl prrc = (PagedResultsResponseControl) controls[i]; cookie = prrc.getCookie(); } else { // Handle other response controls (if any) } } } ldapContext.setRequestControls(new Control[] { new PagedResultsControl(1, cookie, Control.CRITICAL) }); } while (cookie != null); } catch (Exception e) { e.printStackTrace(); } finally { if (ldapContext != null) { try { ldapContext.close(); } catch (Exception e1) { } } } } public static String convertHexToString(String hex) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < hex.length() - 1; i += 2) { // grab the hex in pairs String output = hex.substring(i, (i + 2)); // convert hex to decimal int decimal = Integer.parseInt(output, 16); // convert the decimal to character sb.append((char) decimal); } return sb.toString(); } private static enum CtxCfgFlagsBitValues { INHERITCALLBACK(0x08000000), INHERITCALLBACKNUMBER(0x04000000), INHERITSHADOW(0x02000000), INHERITMAXSESSIONTIME(0x01000000), INHERITMAXDISCONNECTIONTIME(0x00800000), INHERITMAXIDLETIME(0x00400000), INHERITAUTOCLIENT(0x00200000), INHERITSECURITY(0x00100000), PROMPTFORPASSWORD(0x00080000), RESETBROKEN(0x00040000), RECONNECTSAME(0x00020000), LOGONDISABLED(0x00010000), AUTOCLIENTDRIVES(0x00008000), AUTOCLIENTLPTS(0x00004000), FORCECLIENTLPTDEF(0x00002000), DISABLEENCRYPTION(0x00001000), HOMEDIRECTORYMAPROOT(0x00000800), USEDEFAULTGINA(0x00000400), DISABLECPM(0x00000200), DISABLECDM(0x00000100), DISABLECCM(0x00000080), DISABLELPT(0x00000040), DISABLECLIP(0x00000020), DISABLEEXE(0x00000010), WALLPAPERDISABLED(0x00000008), DISABLECAM(0x00000004); private int mask; CtxCfgFlagsBitValues(int mask) { this.mask = mask; } public boolean isBit(int val) { return ((val & mask) == mask); } } private static enum CtxCfgFlagsTimeValues { ONE_MINUTE(1625948160), FIVE_MINUTES(-527236096), TEN_MINUTES(-1071183616), FIFTEEN_MINUTES(-1598354176), THIRTY_MINUTES(1081547520), ONE_HOUR(-2131872256), TWO_HOURS(14511360), THREE_HOURS(-2134137856), ONE_DAY(6039045), TWO_DAYS(12078090); private int value; CtxCfgFlagsTimeValues(int value) { this.value = value; } public int getValue() { return value; } } }
Java Syntax Checker using java.util.stack
I have an assignment with regards to making a Java syntax checker. It is using java.util.stack, and what it's supposed to do is read from a file that's provided and then check for syntax errors. How it is supposed to do this is by adding a 'token' to the stack that has the character, line number, position in the line, whether it's unmatched or unexpected and the line itself. The code for the function is as follows: public static boolean check(String Filename, boolean ConsoleOutput) throws FileNotFoundException { mFileName = Filename; mConsoleOutput = ConsoleOutput; File mFile = new File("src/Kurien/tests/" + mFileName); Scanner FileReader = new Scanner(mFile); if(ConsoleOutput) { System.out.println("Processing " + "'" + mFileName + "'" + "\n" + "----------------------"); } while (FileReader.hasNextLine()) { mLineNumber++; mLine = FileReader.nextLine(); for (int counter = 0; counter < mLine.length(); counter++) { mCharacter = mLine.charAt(counter); if (mCharacter == '(') { mStack.push(new Token(mCharacter, mLineNumber, counter, ErrorDetail.Unmatched, mLine)); } else if (mCharacter == '{') { mStack.push(new Token(mCharacter, mLineNumber, counter, ErrorDetail.Unmatched, mLine)); } else if (mCharacter == ')') { if (mStack.isEmpty()) { Error = true; mStack.push(new Token(mCharacter, mLineNumber, counter, ErrorDetail.Unexpected, mLine)); } else if (mStack.peek().equals('(')) { mStack.pop(); } else { Error = true; mStack.push(new Token(mCharacter, mLineNumber, counter, ErrorDetail.Unexpected, mLine)); } } else if (mCharacter == '}') { if (mStack.isEmpty()) { Error = true; mStack.push(new Token(mCharacter, mLineNumber, counter, ErrorDetail.Unexpected, mLine)); } else if (mStack.peek().equals('{')) { mStack.pop(); } else { Error = true; mStack.push(new Token(mCharacter, mLineNumber, counter, ErrorDetail.Unexpected,mLine)); } } } } if(!Error) { System.out.println("[SUCCESS]"); } else { while(mStack.iterator().hasNext()) { Token Temp = (Token)mStack.iterator().next(); if(Temp.mDetail == ErrorDetail.Unexpected) { System.out.println("[ERROR] " + Temp.mDetail.toString() + " closing token in file '" + mFileName + "'" + " line#" + Temp.mLineNumber); System.out.println(mLine); System.out.println(Spaces(Temp.mLine.length() - Temp.mPosition) + "^"); } else if(Temp.mDetail == ErrorDetail.Unmatched) { System.out.println("[ERROR] + " + Temp.mDetail + "token in file '" + mFileName + "'" + "line#" + Temp.mLineNumber); System.out.println(mLine); System.out.println(Spaces(Temp.mLine.length() - Temp.mPosition) + "^"); } } } return Error; } private static class Token { char mCharacter; int mLineNumber; int mPosition; ErrorDetail mDetail; String mLine; Token(char Character, int LineNumber, int Position, ErrorDetail Detail, String Line) { mCharacter = Character; mLineNumber = LineNumber; mPosition = Position; mDetail = Detail; mLine = Line; } } } Now, the expected output for the first test case is as follows: [ERROR] Unexpected closing token in file 'test1.txt' line#7: } ^ However all I get is the following: [ERROR] + Unmatchedtoken in file 'test1.txt'line#1 I know the formatting could be fine tuned, however there is clearly another problem here that I just can't quite put my finger on.
Android SQLite cursor returns 33 results, but debug only outputs 17
Hi folks I've got a strange cade. I'm trying to debug the SQLite DB in an app. If I do a query SELECT * from table I get 33 results, but if I iterate over the cursor it ends at result #17. Here's my debug class (the method in question is public static void WriteToFile(Cursor cursor, String query , String tables, String uri)) : package com.s2u.android.ps; import java.io.File; import java.io.FileWriter; import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.List; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.os.Environment; import android.util.Log; import com.s2u.android.ps.BO.App; import com.s2u.android.ps.BO.AppMember; import com.s2u.android.ps.datamodel.DatabaseManager; import com.s2u.android.ps.networkApis.AndroidLog; import com.s2u.android.ps.networkApis.AppConfig; public class DebugToFile { private static String TAG = "DebugToFile"; private static File path = new File(Environment.getExternalStorageDirectory() + "/ps_debug"); public static void WriteToFile(String lines , String tag) { WriteToFile(lines , tag , "txt"); } public static void WriteToFile(String lines , String tag , String ext) { if (!Validate("WriteToFile(String lines)")) return; File file = new File(path, tag + "_" + GetDateStampTens() + "." + ext); try { FileWriter fw = new FileWriter(file.getAbsolutePath() , true); PrintWriter pw = new PrintWriter(fw); pw.println(GetDateStamp() + " - " + lines); pw.println(); pw.flush(); pw.close(); //Log.e(TAG, "WriteToFile(String lines) - " + file.toString()); } catch (Exception e) { Log.e(TAG, "WriteToFile(String lines) failed!", e); } } public static void WriteToFileAppMember(ArrayList<AppMember> appMembers , String tag) { if (!Validate("WriteToFile(AppMember)")) return; File file = new File(path, tag + "_" + GetDateStampTens() + ".csv"); try { FileWriter fw = new FileWriter(file.getAbsolutePath() , true); PrintWriter pw = new PrintWriter(fw); pw.println(GetDateStamp() + " - " + "AppMembers"); boolean doOnce = true; for(com.s2u.android.ps.BO.AppMember appMember : appMembers) { if (doOnce) { doOnce = false; pw.println(appMember.getCsvLabels()); } pw.println(appMember.getCsvString()); } pw.println(); pw.flush(); pw.close(); //Log.e(TAG, "WriteToFile(String lines) - " + file.toString()); } catch (Exception e) { Log.e(TAG, "WriteToFile(String lines) failed!", e); } } public static void WriteToFileAppMember(List<AppMember> appMembers , String tag) { if (!Validate("WriteToFile(AppMember)")) return; File file = new File(path, tag + "_" + GetDateStampTens() + ".csv"); try { FileWriter fw = new FileWriter(file.getAbsolutePath() , true); PrintWriter pw = new PrintWriter(fw); pw.println(GetDateStamp() + " - " + "AppMembers"); boolean doOnce = true; for(com.s2u.android.ps.BO.AppMember appMember : appMembers) { if (doOnce) { doOnce = false; pw.println(appMember.getCsvLabels()); } pw.println(appMember.getCsvString()); } pw.println(); pw.flush(); pw.close(); //Log.e(TAG, "WriteToFile(String lines) - " + file.toString()); } catch (Exception e) { Log.e(TAG, "WriteToFile(String lines) failed!", e); } } public static void WriteToFileApps(List<App> apps , String tag) { if (!Validate("WriteToFile(AppMember)")) return; File file = new File(path, tag + "_" + GetDateStampTens() + ".csv"); try { FileWriter fw = new FileWriter(file.getAbsolutePath() , true); PrintWriter pw = new PrintWriter(fw); pw.println(GetDateStamp() + " - " + "App objects"); boolean doOnce = true; for(com.s2u.android.ps.BO.App app : apps) { if (doOnce) { doOnce = false; pw.println(app.getCsvLabels()); } pw.println(app.getCsvString()); } pw.println(); pw.flush(); pw.close(); //Log.e(TAG, "WriteToFile(String lines) - " + file.toString()); } catch (Exception e) { Log.e(TAG, "WriteToFile(String lines) failed!", e); } } public static void WriteToFile(Cursor cursor, String query , String tables, String uri) { if (!Validate("WriteToFile(cursor)")) return; File file = new File(path, uri + "_" + GetDateStampTens() + ".csv"); try { FileWriter fw = new FileWriter(file.getAbsolutePath(), true); PrintWriter pw = new PrintWriter(fw); int resultCount = cursor.getCount(); pw.println("time: " + GetDateStamp()); pw.println("tables: " + tables); pw.println("query: " + query); pw.println("result count: " + Integer.toString(resultCount)); int row = 0; String labels = "row,"; int startPosition = cursor.getPosition(); cursor.moveToPosition(-1); while (cursor.moveToNext()) { int colCount = cursor.getColumnCount(); row++; if (row >= resultCount) { pw.println("Error! rows >= cursor count -- at row : " + Integer.toString(row) ); break; } StringBuilder line = new StringBuilder(512); if (colCount <= 0) pw.println("Empty row?"); for(int i = 0; i < colCount; i++) { if (row == 1) { labels += cursor.getColumnName(i) + "[" + GetCursorFieldTypeString(cursor, i) + "]"; if (i < colCount - 1) labels += ","; } if (i == 0) line.append(Integer.toString(row) + ","); line.append(GetCursorString(cursor, i)); if (i < colCount - 1) { line.append(","); } } if (row == 1) pw.println(labels); pw.println(line.toString()); cursor.moveToNext(); if (row > 100) { pw.println("max rows output - stopped at row: " + Integer.toString(row)); break; } } pw.println("END"); pw.println(); pw.flush(); pw.close(); //Log.e(TAG, "WriteToFile(cursor) - " + file.toString()); cursor.moveToPosition(startPosition); } catch (Exception e) { Log.e(TAG, "WriteToFile(cursor) failed!", e); } } private static boolean Validate(String methodName) { if (!AppConfig.isTestBuild()) { Log.i(TAG, methodName + " - this is not a test build!"); return false; } if (!isExternalStorageWritable()) { AndroidLog.e(TAG, methodName + " - external storage not accessible"); return false; } if (!path.exists()) { path.mkdir(); if (!path.exists()) { AndroidLog.e(TAG, methodName + " - directory doesn't exist and couldn't create it: " + path.toString()); return false; } } return true; } private static String GetDateStamp() { Calendar c = Calendar.getInstance(); SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd-kk:mm:ss.SSS"); String date = df.format(c.getTime()); return date; } private static String GetDateStampTens() { String date = GetDateStamp(); date = date.substring(0,date.length() - 1) + "0"; return date; } private static boolean isExternalStorageWritable() { String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state)) { return true; } return false; } private static String GetCursorString(Cursor cursor, Integer i) { String result = "undefined"; switch(cursor.getType(i)) { case Cursor.FIELD_TYPE_NULL: result = "NULL"; break; case Cursor.FIELD_TYPE_BLOB: result = "BLOB length: " + Integer.toString(cursor.getBlob(i).length); break; case Cursor.FIELD_TYPE_FLOAT: result = Float.toString(cursor.getFloat(i)); break; case Cursor.FIELD_TYPE_INTEGER: result = Integer.toString(cursor.getInt(i)); break; case Cursor.FIELD_TYPE_STRING: result = cursor.getString(i); break; default: result = "undefined cursor value type(" + Integer.toString(cursor.getType(i)) + ") -- try getString: " + cursor.getString(i); } result.replace("", " "); return result; } private static String GetCursorFieldTypeString(Cursor cursor, Integer i) { String result = "UNK"; switch(cursor.getType(i)) { case Cursor.FIELD_TYPE_NULL: result = "NULL"; break; case Cursor.FIELD_TYPE_BLOB: result = "BLOB"; break; case Cursor.FIELD_TYPE_FLOAT: result = "F"; break; case Cursor.FIELD_TYPE_INTEGER: result = "INT"; break; case Cursor.FIELD_TYPE_STRING: result = "STR"; break; default: result = "UNK(" + Integer.toString(cursor.getType(i)) + ") "; } return result; } public static String AppListTypeToString(int appListType) { if (appListType == 0) return "kAppListMain"; else if (appListType == 1) return "kAppListProfile"; else if (appListType == 2) return "kAppListPromoted"; return "unknown list type int: " + Integer.toString(appListType); } public static void DumpDatabaseToFiles(DatabaseManager db) { SQLiteDatabase readableDb = db.getReadableDatabase(); DumpDatabaseToFiles(readableDb); } public static void DumpDatabaseToFiles(SQLiteDatabase db) { if (!Validate("DumpDatabaseToFiles")) return; Cursor c = db.rawQuery("SELECT name FROM sqlite_master WHERE type='table'", null); if (c.getCount() <= 0) { WriteToFile("table name count: " + Integer.toString(c.getCount()) , "dbdump_err"); c.close(); return; } //AndroidLog.i(TAG , "DumpDB table count: " + Integer.toString(c.getCount())); List<String> tableNames = new ArrayList<String>(); if (c.moveToFirst()) { while(!c.isAfterLast()) { tableNames.add(c.getString(c.getColumnIndex("name"))); c.moveToNext(); } } c.close(); for (int i = 0; i < tableNames.size(); i++) { String table = tableNames.get(i); c = db.rawQuery("SELECT * FROM " + table + " LIMIT 100 ", null); WriteToFile(c, "all" , table, table); c.close(); } } } The output csv file is: tables: app - from AppDAO.bulkInsertApp query: SELECT * FROM app result count: 33 row,_id[INT],packageName[STR],appName[STR],iconUrl1[STR],iconUrl2[NULL],publisher[STR],publisherEmail[NULL],price[INT],currency[STR],version[STR],category[STR],releaseDate[NULL],updatedOn[NULL],hasTried[INT],promo_url[NULL],promoParam[NULL],promoValueKey[NULL] 1,8192,com.shared2you.android.powerslyde,Powerslyde,https://lh5.ggpht.com/1qigt9Zz7oh5kTFiIS9ukJljVTm7W-Ur34XzcaQhFjc9GlMzATJ-ATRwYB6gxQhscHEU=w300,NULL,Shared2you, Inc.,NULL,0,, 1.08 ,Lifestyle,NULL,NULL,1,NULL,NULL,NULL 2,8219,com.android.providers.downloads.ui,com.android.providers.downloads.ui,NULL,NULL,NULL,NULL,NULL,,NULL,NULL,NULL,NULL,1,NULL,NULL,NULL 3,8225,com.google.android.apps.maps,Maps,https://lh3.ggpht.com/JW-F0fkeBHpKyh8lDcyQ7CveTRynYGByVBH9hUqnJxw4x64ORhoFJISdOWhekULemw0=w300,NULL,Google Inc.,NULL,0,, Varies with devic,Travel & Local,NULL,NULL,1,NULL,NULL,NULL 4,8231,com.android.vending,com.android.vending,NULL,NULL,NULL,NULL,NULL,,NULL,NULL,NULL,NULL,1,NULL,NULL,NULL 5,8246,com.google.android.apps.magazines,Google Play Newsstand,https://lh5.ggpht.com/rowOPaiODov-bNG7rnD6awPZwLnOc7Vzab-29GpfvB6jfE8DhOR42owBqAmLUXj-W2sI=w300,NULL,Google Inc.,NULL,0,, 3.1.0 ,News & Magazines,NULL,NULL,1,NULL,NULL,NULL 6,8248,com.google.android.gm,Gmail,https://lh4.ggpht.com/Ebn-CW55BnkwG7ng5nuGpijVpJeabTa-uPijd4keKbHpedz29SvDj3EZkfr20ZZzznE=w300,NULL,Google Inc.,NULL,0,, Varies with devic,Communication,NULL,NULL,1,NULL,NULL,NULL 7,8250,com.google.android.music,Google Play Music,https://lh6.ggpht.com/5opWBg-m6yFcjWzJz1LlT05YIf2Alyiy9YtpQm1f6U42LXWmCvB54M1zEkV9-hCaoTc=w300,NULL,Google Inc.,NULL,0,, Varies with devic,Music & Audio,NULL,NULL,1,NULL,NULL,NULL 8,8253,com.google.android.videos,Google Play Movies & TV,https://lh5.ggpht.com/fFPQTALNNU4xflvbazvbwPL5o4X3a_CqYHUWIh4FXmfU78aSSuP1OMkGXhXouxXzWPov=w300,NULL,Google Inc.,NULL,0,, Varies with devic,Media & Video,NULL,NULL,1,NULL,NULL,NULL 9,8312,com.android.chrome,Chrome Browser - Google,https://lh6.ggpht.com/lum4KYB0TtgvR-8vRMUZ_JhRnMQ4YqBIR0yjspc4ETsM9iJ8-4YHZ0s0HO9i0ez_=w300,NULL,Google Inc.,NULL,0,, Varies with devic,Communication,NULL,NULL,1,NULL,NULL,NULL 10,8316,com.google.android.calendar,Google Calendar,https://lh5.ggpht.com/qgUPYBPSTb61cPrijI9YXV3BEy00t5bhoBugDpEXTdEsQEv9B9-j8_ZDs_ClQzPbskc=w300,NULL,Google Inc.,NULL,0,, 201308023 ,Productivity,NULL,NULL,1,NULL,NULL,NULL 11,8433,com.estrongs.android.pop,ES File Explorer File Manager,https://lh5.ggpht.com/P31CiAbF5UMC1wbJxv2sPT4tSLLqfqUZPp8N0ATEaA0ZeMxXv_NjVDiswVKjeUUSS2w=w300,NULL,ES APP Group,NULL,0,, Varies with devic,Productivity,NULL,NULL,1,NULL,NULL,NULL 12,8867,com.devhd.feedly,Feedly,https://lh4.ggpht.com/rkouDgWbT3WNztDRa5QvnN8SatDK3zeHHwOMHZbiu2Vlf3-9hLlmH89W9gJpGEtxo3U=w300,NULL,Feedly Team,NULL,0,, 18.1.2 ,News & Magazines,NULL,NULL,1,NULL,NULL,NULL 13,8917,com.google.android.email,com.google.android.email,NULL,NULL,NULL,NULL,NULL,,NULL,NULL,NULL,NULL,1,NULL,NULL,NULL 14,12113,com.google.android.play.games,Google Play Games,https://lh5.ggpht.com/tkg8ndU21RjzO5WSz7JRpYJ35P-oDTm0md2sNwvVoBtQ0kE_ORHhorrzQWcjVTevxP8_=w300,NULL,Google Inc.,NULL,0,, 1.1.04 ,Entertainment,NULL,NULL,1,NULL,NULL,NULL 15,87853,com.google.android.apps.docs.editors.sheets,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,NULL,NULL,NULL 16,87862,com.google.android.apps.photos,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,NULL,NULL,NULL 17,87867,com.umfersolutions.eatthiszombies,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,NULL,NULL,NULL END Thanks!
You are advancing the cursor position two times, one in while (cursor.moveToNext()) and the other one at the end of the loop in pw.println(line.toString()); cursor.moveToNext(); Thats why you always will get half of the results, since at the end you move it one position, and then at then when checking the while condition it will advance again, so its reading position 0, then position 2, then 4...and so on...
Duplicate cursor.moveToNext() in the loop: while (cursor.moveToNext()) { ... pw.println(line.toString()); cursor.moveToNext(); ... }
Null pointer exception when comparing two Strings
I keep getting a Null Pointer Esception when comparing two Strings. I know both of the Strings aren't null so I am not sure what is going on. public void search() { while (!openList.isEmpty()) { currState = openList.removeFirst(); if (currState.equals(goal)) { //this line produces NullPointerException solution = true; printSolution(currState); break; Goal is a String that I read in from a file. Openlist is a linked list. the string start is: 120345678 and goal is: 012345678 public class BFS { public String start; public String goal; public String startFinal; LinkedList<String> openList; Map<String, Integer> levelDepth; Map<String, String> stateHistory; int nodes = 0; int limit = 100; int unique = -1; int newValue; int a; public String currState; boolean solution = false; public BFS() { openList = new LinkedList<String>(); levelDepth = new HashMap<String, Integer>(); stateHistory = new HashMap<String, String>(); this.start = start; this.goal = goal; addToOpenList(start, null);// add root } public void loadStartState(String filename) throws IOException { BufferedReader reader = new BufferedReader(new FileReader(filename)); try { StringBuilder sb = new StringBuilder(); String line = reader.readLine(); StringBuilder currentLine = new StringBuilder(); while (line != null) { currentLine.delete(0, currentLine.capacity()); currentLine.append(line); currentLine.deleteCharAt(1); currentLine.deleteCharAt(2); sb.append(currentLine.toString()); sb.append("\n"); line = reader.readLine(); } start = sb.toString(); System.out.println(start); } finally { reader.close(); } } public void loadGoalState(String filename)throws IOException{ BufferedReader reader = new BufferedReader(new FileReader(filename)); try { StringBuilder sb = new StringBuilder(); String line = reader.readLine(); StringBuilder currentLine = new StringBuilder(); while (line != null) { currentLine.delete(0, currentLine.capacity()); currentLine.append(line); currentLine.deleteCharAt(1); currentLine.deleteCharAt(2); sb.append(currentLine.toString()); sb.append("\n"); line = reader.readLine(); } goal = sb.toString(); System.out.println(goal); } finally { reader.close(); } } public void search() { while (!openList.isEmpty()) { currState = openList.removeFirst(); if (currState != null && currState.equals(goal)) { solution = true; printSolution(currState); break; } else { a = currState.indexOf("0"); // left while (a != 0 && a != 3 && a != 6) { String nextState = currState.substring(0, a - 1) + "0" + currState.charAt(a - 1) + currState.substring(a + 1); addToOpenList(nextState, currState); nodes++; break; } // up while (a != 0 && a != 1 && a != 2) { String nextState = currState.substring(0, a - 3) + "0" + currState.substring(a - 2, a) + currState.charAt(a - 3) + currState.substring(a + 1); addToOpenList(nextState, currState); nodes++; break; } // right while (a != 2 && a != 5 && a != 8) { String nextState = currState.substring(0, a) + currState.charAt(a + 1) + "0" + currState.substring(a + 2) + currState.substring(a + 1); addToOpenList(nextState, currState); nodes++; break; } // down while (a != 6 && a != 7 && a != 8) { String nextState = currState.substring(0, a) + currState.substring(a + 3, a + 4) + currState.substring(a + 1, a + 3) + "0" + currState.substring(a + 4); addToOpenList(nextState, currState); nodes++; break; } } } } private void addToOpenList(String newState, String oldState) { if (!levelDepth.containsKey(newState)) { newValue = oldState == null ? 0 : levelDepth.get(oldState) + 1; unique++; levelDepth.put(newState, newValue); openList.add(newState); stateHistory.put(newState, oldState); } }
Solution Try this, remove invocation of addToOpenList(start, null) before loading value of goal and start. Old stuff Here is null addToOpenList(start, null); String currState = openList.removeFirst(); currState == null Additional information public BFS() { this.start = start; // Variable 'start' is assigned to itself this.goal = goal; // Variable 'goal' is assigned to itself addToOpenList(start, null); // start is null } Even my IntelliJ see this :) Method invocation currState.indexOf("0") at line 115 may produce java.lang.NullPointerException 115: a = currState.indexOf("0");
Perhaps you could try something like: public void search(){ currState = openList.removeFirst(); while(currState != null){ if(currState.equals(goal)){ solution = true; printSolution(currState); break; } currState = openList.removeFirst(); } }
JPA wrapper to convert unchecked exceptions into checked exceptions?
Before I wander off and re-create the wheel, does anyone know of a JPA wrapper that turns the unchecked exceptions JPA throws into checked exceptions? Not looking for an argument about why I should not want checked exceptions, I do want them :-)
You can do 99% of rolling your own using the code below. It will leave you with two compile errors due to the members of a Collection needing to be encapsulated, but it does take you past the point where it is no longer worth automating. package so; import javax.persistence.*; import java.io.File; import java.io.FileWriter; import java.lang.reflect.*; public class CheckedPersistenceMaker { static final String PACKAGE = "stackoverflow.javax.persistence"; static final String PACKAGE_DIR = PACKAGE.replace('.', '/'); static Class<?>[] CLASSES = new Class<?>[] { Cache.class, EntityManager.class, EntityManagerFactory.class, EntityTransaction.class, Parameter.class, PersistenceUnitUtil.class, PersistenceUtil.class, Persistence.class, Query.class, Tuple.class, TupleElement.class, TypedQuery.class }; private static String getName(Class<?> c) { String name = c.getName(); for(Class<?> p:CLASSES) { if (p.equals(c)) return PACKAGE + ".Checked" + name.substring(name.lastIndexOf('.') + 1); } return c.getName(); } static void generateWrapper(Class<?> c) throws Exception { String name = c.getName(); TypeVariable<?>[] genType = c.getTypeParameters(); String varNames = ""; if (genType != null && genType.length != 0) { StringBuilder b = new StringBuilder(); b.append("<"); for(int i = 0;i < genType.length;i++) { if (i > 0) b.append(","); b.append(genType[i].getName()); } b.append(">"); varNames = b.toString(); } name = "Checked" + name.substring(name.lastIndexOf('.') + 1); File javaFile = new File(PACKAGE_DIR + "/" + name + ".java"); javaFile.getParentFile().mkdirs(); FileWriter w = new FileWriter(javaFile); w.write("package " + PACKAGE + ";\n"); w.write("public class " + name + varNames + " {\n"); w.write(" private final " + c.getName() + varNames + " wrapped;\n\n "); w.write(name + "(" + c.getName() + varNames + " original) {\nwrapped=original;\n}\n\n"); w.write(" public " + c.getName() + varNames + " getOriginal() { return wrapped; }\n\n"); Method[] ms = c.getDeclaredMethods(); for(Method m:ms) { if (!Modifier.isPublic(m.getModifiers())) continue; w.write(" "); String s = m.toGenericString(); s = s.replace(" abstract ", " "); s = s.replace(c.getName() + ".", ""); String q = s.substring(0, s.indexOf('(')); if (q.indexOf('<',10) != -1) q = q.substring(0, q.indexOf('<',10)); boolean needsTranslate = false; for(Class<?> cc:CLASSES) { String ccn = cc.getName(); if (q.indexOf(ccn) != -1) needsTranslate = true; String ccc = ccn.replace(cc.getPackage().getName() + ".", PACKAGE + ".Checked"); s = s.replace(ccn, ccc); } int pc = 0; int p = s.indexOf('('); if (s.charAt(p + 1) != ')') { StringBuilder b = new StringBuilder(s); int g = 0; char ch; do { ch = b.charAt(p); switch (ch) { case '<': { g++; break; } case '>': { g--; break; } case ',': case ')': { if (g == 0) { String pa = " p" + pc; b.insert(p, pa); pc++; p += pa.length(); } break; } } p++; } while( ch != ')' ); s = b.toString(); } w.write(s); w.write(" throws CheckedPersistenceException"); Class<?>[] excs = m.getExceptionTypes(); for(Class<?> e:excs) { w.write(", " + e.getName()); } w.write(" {\n try {\n "); Class<?> ret = m.getReturnType(); if (!ret.equals(Void.TYPE)) { w.write("return "); if (needsTranslate) { String retName = ret.getName(); retName = retName.replace(c.getPackage().getName() + ".", PACKAGE + ".Checked"); w.write("new " + retName + "("); } } if (Modifier.isStatic(m.getModifiers())) { w.write(c.getName() + "." + m.getName() + "("); } else { w.write("wrapped." + m.getName() + "("); } Class<?> paramTypes[] = m.getParameterTypes(); for(int i = 0;i < pc;i++) { if (i > 0) w.write(','); boolean isChecked = false; for(int j=0;j<CLASSES.length;j++) { if( CLASSES[j].equals(paramTypes[i]) ) isChecked=true; } w.write("p" + i); if(isChecked) w.write(".getOriginal()"); } w.write(')'); if (needsTranslate) w.write(')'); w.write(";\n } catch ( javax.persistence.PersistenceException e ) { throw new CheckedPersistenceException(e); }\n }\n\n"); } w.write("}\n"); w.close(); } public static void main(String[] args) throws Exception { for(Class<?> c:CLASSES) { generateWrapper(c); } } }