views:

402

answers:

4

Is there any reserve words for JSON as a KEY?

my Json structure is

dimObject{String:String}
finalObject(String:dimObject}

Line1# JSONObject dimObject=new JSONObject()
Line2# dimObject.put("class",["A","B","c"]);
Line3# dimObject.put("name",["sam"]);
Line4# System.out.print("dimObject#"+dimObject.toString());
Line5# JSONObject finalObject=new new JSONObect();
Line6# finalObject("supplier",dimObject);
Line7# System.out.print("finalObject#"+finalObject.toString());

OUTPUT:

dimObject#{"class":["A","B","c"],"name":["sam"]}
finalObject#{"supplier":{"name":["sam"]}}

So the problem is why my json is behaving in a weird manner.
I have not defined "class" as variable name, it's just a Key.

Problem is ,if an argument is given like,"class" is a key or reserve word then how i successfully inserted in Line#2,and if its insert able in dimObject then why its not insert able in finalObject.

Please help me solving this mystery

EXACT CODE::

public JSONObject getRequiredAttributesWithValues() {
        List<UserConstraint> constraintList = new ArrayList<UserConstraint>();
        Map<String, FactTableOptimizingInfo> factTableMap = MappingInfo.INSTANCE.
                getFactTableUserNameToFactTableOptimizingInfoMap();
        Map<String, DimensionTableInfo> dimTableMap = MappingInfo.INSTANCE.getDimTableRealNameToObjectMap();
        JSONObject requiredAttributes = getRequiredAttributes();
        JSONObject finalObject = new JSONObject();
        for (Object dimName : requiredAttributes.keySet()) {
            JSONObject dimObject = new JSONObject();
            JSONArray colNames = requiredAttributes.getJSONArray((String) dimName);
            for (Object colName : colNames) {
                List<String> columnList = new ArrayList<String>();
                String dimensionName = (String) dimName;
                String columnName = (String) colName;
                constraintList = new ArrayList<UserConstraint>();
                for (FilterDataStructure filter : this.info.getGlobalFilterList()) {
                    if (filter.getDimName().equals(dimensionName)) {
                        if (filter.getColumnName().equals(columnName)) {
                            AtomicConstraint.ConstraintType type;
                            try {
                                Integer.parseInt(filter.getValue());
                                type = AtomicConstraint.ConstraintType.INTEGER_TYPE;
                            } catch (NumberFormatException e) {
                                type = AtomicConstraint.ConstraintType.STRING_TYPE;
                            }
                            UserConstraint constraint = new UserAtomicConstraint(dimensionName, columnName, 
                                                        AtomicConstraint.getStringToOperator(filter.getOperator()),
                                                        filter.getValue(), type, factTableMap, dimTableMap);
                            constraintList.add(constraint);
                        }
                    }
                }

                columnList.add(columnName);
                List<UserDimensionInfoToBuildQuery> dimList = new ArrayList<UserDimensionInfoToBuildQuery>();
                UserTableAndColInfo groupByInfo = new UserTableAndColInfo(dimensionName, columnName);
                ArrayList<UserTableAndColInfo> groupByInfoList = new ArrayList<UserTableAndColInfo>();
                groupByInfoList.add(groupByInfo);

                UserDimensionInfoToBuildQuery dim = new UserDimensionInfoToBuildQuery(dimensionName, columnList);
                dimList.add(dim);
                UserInfoToBuildQuery.Builder queryBuilder = new UserInfoToBuildQuery.Builder(dimList).
                        groupBy(groupByInfoList);
                if (constraintList != null && !(constraintList.isEmpty())) {
                    if (constraintList.size() > 1) {
                        queryBuilder = queryBuilder.constraints(new UserComplexConstraint(constraintList,
                                ComplexConstraint.Joiner.AND));
                    } else {
                        queryBuilder = queryBuilder.constraints(constraintList.get(0));
                    }
                }
                List<Object> result = (List<Object>) DataAccessor.getData(queryBuilder.build());
                if (result == null) {
                    continue;
                }
                JSONArray valueArray = new JSONArray();

                for (Object row : result) {
                    List<Object> splitRow = (List<Object>) row;
                    valueArray.add(splitRow.get(0).toString());
                }
                dimObject.put(colName, valueArray);
            }
            finalObject.put(dimName, dimObject);
        }
        return finalObject;
    }
}
+3  A: 

As to follow up with your observation, JSON follows JavaScript (or ECMAScript, as it should be called) reserved words and class is one of them.

EDIT:

While dabbling with javascript, it seems you can use reserve words within quotation marks, I have tested it as follows:

myObj = {"class" : "Analysis of Algorithms"}; // <--works
myObj = { class  : "Analysis of Algorithms"}; //  <--works
myObj = { class  : "class"}; // <--works
myObj = {"class" :  class }; // <--does not work.

As well it is interesting, I am still puzzled by the problem. With JSON I am using all my techniques with javascript, so I cannot produce the same results as you can.

I found the source file for JSONObject.java at this website

Anthony Forloney
but the problem is,how i was bale to insert the word in LINE#2??
Sam Rudolph
I would hate to leave this question off with *well, it could have been a glitch* remark, but have you tried to simulate the data and get the same results each time? It gets inserted into `dimObject` but then not `finalObject`? Or this happened once, you haven't tried it again?
Anthony Forloney
ya...I used debugger for several times(hours),and was monitoring each and every line very closely
Sam Rudolph
@Anthony Forloney:: Thnax for the answer,will be looking frwd to your answer
Sam Rudolph
@Anthony Forloney::wel YOUR fourth case is looking interesting,I guess my answer lies come where inside the case#4..would like to see your more comments to find out the exact reason..
Sam Rudolph
Your case would be different, since your *value* is *["A", "B", "c"]* which is not a keyword, mine was. But, the keyword works when put with quotes. I looked at the `put` method inside of **JSONObject.java** you might have a problem where it interprets the value of the string being passed in, it might not interpret it as *"class"* in javascript, but rather *class* but thats my wild guess, I must admit, I am stumped.
Anthony Forloney
I can't see anything in JSONObject.java that would treat `"class"` as anything other than a string, or indeed any other reason for it to fail... though the `catch (Exception e) { return null; }` is worrying, I can't see it failing and still producing this result.
bobince
@bobince, It doesn't make any sense to me, maybe somehow from Java to JavaScript, something gets lost in translation.
Anthony Forloney
Well there's no JavaScript element to the problem if your `finalObject.toString()` is not including the `class` property! (JSON strings are deliberately quoted to avoid reserved words; you can still have trouble with key names that are also JS Object properties like `toString` in IE, but that's not at issue here.)
bobince
@bobince:yeah i also went through the JSONObject.java,was not able to find any reason to treat"class" as anything other than a string,
Sam Rudolph
@bobince: "static void testValidity(Object o)" is proper in this case
Sam Rudolph
IS the problem Lies some where near this Constructor:::: public JSONObject() { this.map = new HashMap(); }
Sam Rudolph
+2  A: 

Edit: In your example, you're writing code in Java. I don't know what Java implementation of JSON you're using, but it's probably not strict. It's not meant to be a JavaScript interpreter or engine, so it's not preventing you from doing something you shouldn't do. That's why you can add the "class" key like you did -- the Java side is going to let you do that even though it's wrong. It's not checking to make sure you're not using keywords as identifiers. When that JSON gets interpreted by a web browser after it's left the Java world, you will have problems, because now that "class" word has a special meaning.

class is a reserved word. You should avoid using it as a variable name. See here for a list of reserved words.

Chrome's JavaScript console let me use it as an identifier. IE8 behaves differently. I can't use it in dot notation but I can use it with bracket notation. See a.class and a['class'] in the following.

>>var class = "1"
  "Expected identifier"
>>var a = "1"
undefined
>>a
"1"
>>class
  "Syntax error"
>>var a = {}
undefined
>>a["foo"] = "1"
"1"
>>a["class"] = "2"
"2"
>>a.class
  "Expected identifier"
>>a.foo
"1"
>>a['foo']
"1"
>>a['class']
"2"

The point is, don't use reserved words as identifiers. You probably won't get the results you expect.

Jonathon
ya i got your point and agree with that also,but the problem is why my output was inconsistent?
Sam Rudolph
Because you're using a keyword as an identifier.
Jonathon
@Jon::Ya i agree with your point,the thing that making unsettled is how it succeeded at Line#2(am not bothered as why it failed at line#7) ,I take your point that its a key word and i should not have used this word
Sam Rudolph
I've edited my answer to try to explain that, now.
Jonathon
still unclear for result at line#2
Sam Rudolph
There are NO reserved words in JSON cause unlike JavaScript, JSON REQUIRES the keys to be quoted. See the spec.
Tomas
@Tomas no quarrel there, but I wonder if a browser's or library's implementation or translation of JSON as JavaScript objects will uncover problems like the question author experienced?
Jonathon
+1  A: 

the reason JSON uses { "double quotes":"around key/vals" } is for this exact reason - to escape reserved words.

that said, if you are getting valid JSON, there should be no problems, as any reserved words will be escaped by the "double quotes"...

I noticed you have a missing quote in this line:

finalObject#{"supplier:{"name":["sam"]}}

should be "supplier". is there anyway you could change that? or is it being auto generated?

Dan Beam
@Dan:hey sorry that was a typing error,I have corrected that.
Sam Rudolph
why the downvote...? "Is there any reserve words for JSON as a KEY?" - the answer is no.
Dan Beam
-1 as it was not answer of the question,and your above comment is very small answer of the question,you have not talked about the mysterious behavior of the JSON
Sam Rudolph
it escapes reserved words by using `"double quotes"`, there's really not much more to it than that...
Dan Beam
+1 as most others seem to miss the important point that there is no such thing as a reserved word in JSON.
Tomas
+1  A: 

I don't think that your minimal example correctly replicates the problem that you are experiencing.

Using the json java library from json.org, I ran this Java code:

public static void main(String[] args) throws JSONException {
    JSONObject dimObject=new JSONObject();
    dimObject.put("class",new JSONArray(new String[] {"A","B","c"}));
    dimObject.put("name", "sam");
    System.out.println("dimObject#"+dimObject.toString());
    JSONObject finalObject=new JSONObject();
    finalObject.put("supplier",dimObject);
    System.out.println("finalObject#"+finalObject.toString());
}

and the output was as expected:

dimObject#{"name":"sam","class":["A","B","c"]}
finalObject#{"supplier":{"name":"sam","class":["A","B","c"]}}
Yoni