I have run into an interesting problem which I'm pretty sure is the fault of HashMap. Consider the following debug code (AMap is a HashMap, key is a value passed to this method)
System.out.println("getBValues - Given: " + key);
System.out.println("getBValues - Contains Key: " + AMap.containsKey(key));
System.out.println("getBValues - Value: " + AMap.get(key));
for(Map.Entry<A,HashSet<B>> entry : AMap.entrySet()) {
System.out.println("getBValues(key) - Equal: " + (key.equals(entry.getKey())));
System.out.println("getBValues(key) - HashCode Equal: "+(key.hashCode() == entry.getKey().hashCode()));
System.out.println("getBValues(key) - Key: " + entry.getKey());
System.out.println("getBValues(key) - Value: " + entry.getValue());
}
Now in this Map I insert a single key (Channel) and value. Later I try and get the value back with get() and run this debug code which in my case gives this output:
getBValues - Given: Channel(...)
getBValues - Contains Key: false <--- Doesnt contain key?!
getBValues - Value: null <--- Null (bad)
getBValues(key) - Equal: true <--- Given key and AMap key is equal
getBValues(key) - HashCode Equal: true
getBValues(key) - Key: Channel(Same...)
getBValues(key) - Value: [] <--- Not null (This is the expected result)
As you can see, fetching the key from the HashMap directly doesn't work but looping through I get the exact same key, meaning its there it just can't be found with get(). My question is what would cause this? How can get() not find a key that exists?
I would provide an some example code of this but I can't seem to reproduce this independently.
Any suggestions on what might be causing this?
I'll bet you didn't override equals and hashCode properly in your key Channel class. That would explain it.
Joshua Bloch tells you how to do it correctly in his "Effective Java" Chapter 3.
http://java.sun.com/developer/Books/effectivejava/Chapter3.pdf
From what I can see, we still haven't ruled out if it has to do with immutability.
If you do:
aMap.put(key, value);
key.setFieldIncludedInHashCodeAndEquals(25);
then you would get the result from above.
To rule this out, either show us more of your code or, in the for loop in your example above, add
System.out.println(aMap.get(entry.getKey()));
Also, use a debugger. That way, you can see if your object is in the correct bucket.
Related
I'm currently populating a List from a .audit file and extracting out two pieces of information into a Map. Here is what the file looks like:
type : REGISTRY_SETTING
description : "1.9.56 Network security: Do not store LAN Manager hash value on next password change: Enabled"
info : "This control defines whether the LAN Manager (LM) hash value for the new password is stored when the password is changed."
solution : "Make sure 'Do not store LAN Manager hash value on next password change' is Enabled."
reference : "PCI-DSS|8.4,800-53|AC-3,800-53|SC-5,800-53|CM-7,800-53|CM-6,CCE|CCE-8937-5"
see_also : "https://benchmarks.cisecurity.org/tools2/windows/CIS_Microsoft_Windows_7_Benchmark_v1.2.0.pdf"
value_type : POLICY_DWORD
reg_key : "HKLM\System\CurrentControlSet\Control\Lsa"
reg_item : "NoLMHash"
value_data : 1
type : REGISTRY_SETTING
description : "1.13.3 Notify antivirus programs when opening attachments: Enabled"
info : "This control defines whether antivirus program to be notified when opening attachments."
solution : "Make sure 'Notify antivirus programs when opening attachments' is Enabled."
reference : "800-53|SI-3,PCI-DSS|5.1.1,CCE|CCE-10076-8,PCI-DSS|5.1"
see_also : "https://benchmarks.cisecurity.org/tools2/windows/CIS_Microsoft_Windows_7_Benchmark_v1.2.0.pdf"
value_type : POLICY_DWORD
reg_key : "HKU\Software\Microsoft\Windows\CurrentVersion\Policies\Attachments"
reg_item : "ScanWithAntiVirus"
value_data : 3
reg_ignore_hku_users : "S-1-5-18,S-1-5-19,S-1-5-20"
I need the Map to be in a <description,value_data> format, regardless of whether anything comes after value_data Eg:
Key: "1.9.56 Network security: Do not store LAN Manager hash value on next password changed."
Value: 1
Here is my current code for populating the Map with it's key values:
String descriptionString = Pattern.quote("description") + "(.*?)" + Pattern.quote("info");
Pattern descriptionPattern = Pattern.compile(descriptionString);
Matcher descriptionMatcher = descriptionPattern.matcher(auditContentList.get(i));
while(descriptionMatcher.find())
{
System.out.println("Key found ");
customItemMap.put(descriptionMatcher.group(1),"");
}
Problem is I cant use two regexes simultaneously to populate the same index of the Map at any given time. Is there any better way to do this?
for your sample data, maybe you should try this :
description.*?"(.*?)"[\s\S]*?value_data.*?(\d+)
i've test it [here]
In my model class, I have overridden the toString() method and the contents of the toString method is given below.
getQueryName() + " -" + (getCriticalities().isEmpty() ? "" : " <b>Criticalities:</b> " + getCriticalities())
+ (getCompletions().isEmpty() ? "" : " <b>Completions:</b> " + getCompletions()) + (getPriorities().isEmpty() ? "" : " <b>Priorities:</b> " + getPriorities())
+ (getUrgencies().isEmpty() ? "" : " <b>Urgencies:</b> " + getUrgencies())
+ (getHistorical().isEmpty() || getHistorical().equals("None") ? "" : " <b>Historical:</b> " + getHistorical())
+ (getPlannerGroups().isEmpty() ? "" : " <b>Planner Groups:</b> " + getPlannerGroups())
+ (getWorkOrderNumbers().isEmpty() ? "" : " <b>Work Order Number:</b> " + getWorkOrderNumbers())
+ (getWorkCenters().isEmpty() ? "" : " <b>Work Centers:</b> " + getWorkCenters());
I have to change words like criticalities, completions in the language that the user has selected. I already have property files for languages. But as it is an entity class, I am unsure of how to change it.
I think you have 2 options:
Return language keys instead of literals in toString method, and then use bundle.getString(object.toString())
Or asign the key to a variable and then use bundle.getString(variable) inside the toString method.
I am afraid you are running into "separation of concerns" problem.
In an ideal world, it is a view that is responsible for I18n, i.e. resolving translations. Is there any specific reason why your model should be language aware?
Personally, I don't think so. You should keep your models as language-independent as possible and format all the numbers, as well as translate all the messages in your views.
One thing to note here: if things like Criticalities needs translation and there are not too many items, it usually makes sense to use enums rather than strings (using strings in programming logic is considered bad practice, by the way).
If you have to use a specific object, it may make sense to add a specific identifier that you can later use to resolve the translations (in ResourceBundle look-ups). Sometimes you can use object values, but this will decrease the translation quality, as translators needs context (and the easiest way to provide context is bring it in a translation key).
I'd like to know how they did it in the edit page of the datastore viewer and any help would be much appreciate. Seems pretty simple but can't figure it out. Here's a screenshot to show exactly what I mean.
The Key class has a kind and (name or id), and also a parent, which will be null or another key.
Starting from the key for an entity, you can print the kind and the id, then look for the parent, print its kind and id, then look for its parent, print the kind and id, etc.
See https://developers.google.com/appengine/docs/java/javadoc/com/google/appengine/api/datastore/Key
The string encoded Key does indeed contain the kind and id of itself and all its ancestors. There is no problem with looping server-side on the parent field until it is null (it's basically a string + objects manipulation, no query to the datastore is involved), to create the breadcrumb.
I don't know if it has been done client-side in JS, but it should be possible as it is basically a base64 encoding. See function Encode() in https://github.com/golang/appengine/blob/master/datastore/key.go for the algorithm.
This online tool decodes and encode keys : http://datastore-key.appspot.com . It also works as a service with JSON output. The Go code server-side does not issue datastore queries.
The Java answer is probably this:
https://cloud.google.com/appengine/docs/java/javadoc/com/google/appengine/api/datastore/KeyFactory#stringToKey(java.lang.String)
This gives you a Key from an encoded representation, which you can then query for kind, namespace, id, parent and appId, which allows similar processing than in the python answer mentioned in a comment above.
As an example, the following code fragment remaps a key that has one parent and comes originally from another GAE application:
String key = "sflkjsadfliasjflkhsa"; // replace this by a real key
// a not very elegant way to get the current app id
String appId = KeyFactory.createKey("dummy", 1).getAppId();
// here, the key is converted from an encoded String to a key object
Key keyObj = KeyFactory.stringToKey(key);
String oldAppId = keyObj.getAppId();
// if the app id is different, we have to convert the key
if (!appId.equals(oldAppId)) {
// creeate a new key with parent having the correct app id
Key parentKey = keyObj.getParent();
Key newParentKey = KeyFactory.createKey(parentKey.getKind(), parentKey.getId());
Key newKeyObj = KeyFactory.createKey(newParentKey, keyObj.getKind(), keyObj.getId());
// convert the key back to a String replacing the original one
String newKey = KeyFactory.keyToString(newKeyObj);
// replace this by a call to your logger
Log.warn(getClass(), "remapped key: appId: " + oldAppId + " -> " + appId + " oldKey: " + key + " -> " + newKey);
key = newKey;
}
JDK 1.7.0
XMLUnit 1.3
When comparing this control XML string:
String controlXml = "" +
"<client>" +
" <name>Hello World</name>" +
"</client>";
With this test XML string:
String testXml = "" +
"<client>" +
" <name>Hello World</name>" +
"</client>";
XMLUNIT returns false and I was expecting it to return true (no differences).
Here is my usage:
XMLUnit.setIgnoreComments(true);
XMLUnit.setIgnoreWhitespace(true);
Diff diff = new Diff(controlXml,testXml);
boolean result = diff.similar(); //result is false
I also get the following error in the console window:
[Fatal Error] :1:103: The entity "nbsp" was referenced, but not declared.
I'm not sure what to do here.
I looked into it and I got some info about EntityResolver using Google but it's all very confusing.
I need the entity to be treated as plain text. Logically, as plain text, they are equal.
I tried toggling with the following options:
XMLUnit.setExpandEntityReferences(false); //tried true, false
XMLUnit.setIgnoreDiffBetweenTextAndCDATA(false); //tried true, false
Nothing worked.
Please help, I'm totally lost. Thanks!
It appears that there's a difference between character entities ( ) and numerical entities ( ).
XMLUnit has no problems with numerical entities as opposed to character entities.
I'm thinking that a simple character-entity-to-numerical-entity procedure should be sufficient to resolve my problem.
I have not added anything to my Database yet, thus the following query should return a result of 0 by my reckoning.
Query query = pm.newQuery(Password.class);
query.setFilter("password == :passwordParam");
query.setResult("count(password)");
query.setResultClass(Integer.class);
Integer result = (Integer)query.execute(password);
System.out.println("Result: [" + result + "]");
It returns null
Neither the javadocs, nor the result docs, say anything about this method being able to return null. My guess is that I did something wrong.
http://db.apache.org/jdo/api20/apidocs/javax/jdo/Query.html#execute%28%29
http://www.datanucleus.org/products/accessplatform_2_2/jdo/jdoql_result.html
When I tried your code with DataNucleus I experienced a similar problem at first.
The bycode enhancer was not running. Once I enabled it the count became 0 has expected.
Perhaps you're having a similar problem.