I have a field called phone number which has values such as 0833888999 that I want to format as following 0833 888 999.
The answer that Rachana offered blew is true for few countries but not all countries.
Therefore,
I am using this Google library to format contact numbers from different countries; however, the problem is that after persisting the contact numbers in database I can not search for them on database, for example the library would format contact numbers of different countries in different format, for example add space or "-" between them that makes hibernate unable to find them.
+18182223333 >>> +1 818-222-3333
+441135558888 >>> +44 113 555 8888
Hibernate
.add(Restrictions.ilike("user.phone","+18182223333");
Try this
<s:property value="getText('{0,number,0### ### ###}',{phone})"/>
Where,phone=0833888999
Hope this will help you also see Using Struts2 Tags to Formatting Numbers
you will get clear idea about number formatting
I think you should keep the raw phone number (e.g. 0833888999) in the database and it's the View responsibility to format it accordingly.
You can have a separate table "country_phone_format" holding a country_id and a phone_format and you could fetch the phone_format as a #ManyToOne entity so that you have both the raw data and the format to properly display it into the View.
The PhoneFormat could be easily cached with the second level cache, as they should be rarely modified.
Just as Vlad mentions, you should keep the raw phone number (e.g. 0833888999) in the database (or save it with the country and area code if you prefer) and leave th responsibility to format it accordingly to the View.
You can use Type Conversion to convert to/from the format you desire - and take advantage of the google library you mention. Something like the following can get you started (abbreviated just to get the gist of it):
public class MyConverter extends StrutsTypeConverter {
public Object convertFromString(Map context, String[] values, Class toClass) {
String phoneNr = values[0]
MyPhoneObject phone = googleLibrary.doYourMagic(phoneNr);
return phone;
}
public String convertToString(Map context, Object o) {
googleLibrary.parseString( ((MyPhoneObject)o).rawPhoneNr() );
}
}
Don't forget to register the converter in xwork-conversion.properties
my.PhoneObject=path.to.MyConverter
Related
I have implemented a custom bridge which maps all the dynamic fields with related types. Types can be of FieldType.STRING or FieldType.DOUBLE or FieldType.BOOLEAN based on the value.
When I looked on the mapping on my elastic search schema, all the string fields are mapped with type TEXT where I expect it to be a keyword so that I can do a wildcard serach.
Here is my problem I want to filter "AAA-VALUE" for dynamically mapped field 'attribute.dynamic-field-1'
I have an indexed value as "AAA-VALUE" for dynamically mapped field 'attribute.dynamic-field-1'
If I want to do a keyword search, I faced error like 'Field bridge is not found' then I resolved the error by ignoring the bridge using ignoreFieldBridge and the error is gone.
Then again I tried to do a search with value as "AAA-VALUE" and the result is empty (no data found). Here I created the query using a keyword() query.
Then again I tried to do a phrase query then it got worked but the problem is how I can do a wild card search like '-VALUE'.
Regarding code, I followed similar implementation as given here https://github.com/hibernate/hibernate-search/blob/master/legacy/engine/src/test/java/org/hibernate/search/test/bridge/MultiFieldMapBridge.java
Only the type differs in my implementation, where the type can be a string or boolean or double.
My hibernate search version - hibernate-search.version and hibernate-search-elasticsearch = 5.11.3.Final
It got to work after doing below changes.
This how I added the fields before
public class MultiFieldMapClassBridge implements MetadataProvidingFieldBridge {
;
;
;
luceneOptions.addFieldToDocument( fieldPrefix + "." + key, value, document );
}
But the fields should be added as below.
public class MultiFieldMapClassBridge implements MetadataProvidingFieldBridge {
;
;
org.apache.lucene.document.Field field = new org.apache.lucene.document.StringField(fieldPrefix + "." + key, value, luceneOptions.getStore());
document.add(field);
}
I written the wild card query as below
queryBuilder.keyword().wildcard().onField(prefixedPath).ignoreFieldBridge().matching(String.format("*%s*", matchingString.toLowerCase(Locale.getDefault()))).createQuery();
I realised this after reading this doc where the class bridges have to add the field as StringField.
https://docs.jboss.org/hibernate/search/5.5/reference/en-US/html_single/#example-class-bridge
I am trying to read a smart card and i have been able to get some data from the smart card. The issue i am facing now is how to get the CardHolder name from the smart card.
i have
if(emv_is_tag_present(0x5F20) >=0){
tagDataLength = emv_get_tag_data(0x5F20, tagData, tagData.length);
if(debug)Log.d(APP_TAG, "Carder "+ tagDataLength);
appState.trans.setuserName(StringUtil.toString(AppUtil.removeTailF(ByteUtil.bcdToAscii(tagData,0, tagDataLength))));
}
I do not really know the format to use in getting this field from the card while trying to use 5F20 Cardholder Name Indicates cardholder name according to ISO 7813 Card ans 2-26 '70' or '77' 2 26 primitive which i got from here
This is the output i am getting 3030303030333830D160222101..but, whenever i try to convert that into a String...it gives back 00000380Ñ`"! which is not really the name of the Cardholder.
Reading through the document (which link is posted there), i am not sure if i am using the correct format in getting my data. cos, in the document, i have ans 2-26. I do not really understand what it means.
Tag 5F20 - CARD HOLDER NAME, if CARD returning the value of this tag, value will be hex string - Hex value of ASCII characters , what you need to do is to convert value to string and you will get the value personalized in the card.
in the document, i have ans 2-26. I do not really understand what it means.
sometimes we avoid to personalize card holder name inside the card and then we personalize " /" - space followed by / = 2 char. It is the minimum value for tag 5F20 defined in different EMV specification. Max value is 26 therefore 2-26 used for Tag 5F20.
Hope this information will help you..
I am designing a RESTful API.
One service should offer query functionality for multiple key-value pairs. For example, the client can query with one HTTP GET request for different products and the associated quantity.
The client wants to query product 1 with the amount 44 AND product 2 with the amount 55.
I actually don't want my URI to look like this:
/produkt?productId1=1&productquantity1=44&productId2=2&productquantity2=55
because I don't know how many products are queried.
Or like this:
/produkt?product=1,44&product=2,55
because how can the client know that before the comma there is the productId and after the comma the quantity.
Does anyone have other solutions? Or is it not RESTful to offer the possibility to query multiple products with one request? Is it better to offer the possibility to query just one product with the associated quantity and if the client wants to query more products, they should send more requests?
Here is one idea to pass a parameter:
/products?productDetail=[{"key":"key0","value":"key1"},{"key":"key2","value":"key2"},{"key":"key3","value":"key3"}]
where
[{"key":"key0","value":"key1"},{"key":"key2","value":"key2"},{"key":"key3","value":"key3"}]
is a JSON representation of the List<kv> class
class kv {
String key;
String value;
public kv(String key, String value) {
super();
this.key = key;
this.value = value;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
so you can easily convert query parameter productDetail in to List<kv> using
new Gson().fromJson(productDetail,kv.class);
than you can easily iterate all elements.
Another suggestion is, if you don't know how many products are queried then use a POST request for this.
I would expand upon your second suggestion a little by adding explicit names for the parts of your product, and using semicolons in place of commas to separate product attributes, since the order does not matter*.
/products?id=1;qty=44&qty=55;id=2
Note how id and qty are switched around for the second product, because the order of attributes does not matter.
* There is a convention to use commas when the order is important, and semicolons when the order is not important.
The most idiomatic HTTP GET way I can think to do it:
/produkt?productId=1&productquantity=44&productId=2&productquantity=55
I ran into a similar situation recently where Clients needed to be able to search by "Product Attributes" which are defined arbitrarily for each Product. Clients also needed to be able to create these links easily and pass them around via email, etc. I didn't want to create a custom query string because I didn't want to create a custom parser and it adds an extra step where the Client could make a mistake. And I didn't want to pass json as it relied on the Client to generate that JSON in some cases.
While the HTTP Spec doesn't take a hard stance on multiple values per parameter, every example I can find indicates that order is preserved. Java example:
String[] productIds = this.request.getParameterValues("productId");
String[] productQuantities = this.request.getParameterValues("productquantity");
productIds[0]; // 1
productQuantities[0]; // 44
productIds[1]; // 2
productQuantities[1]; // 55
I'll leave error and index range checking as an exercise for the reader.
Hy,
Hbase allows a column family to have different qualifiers in different rows. In my case a column family has the following specification
abc[cnt] # where cnt is an integer that can be any positive integer
what I want to achieve is to get all the data from a different column family, only if the value of the described qualifier (in a different column family) matches.
for narrowing the Scan down I just add those two families I need for the query. but that is as far as I could get for now.
I already achieved the same behaviour with a SingleColumnValueFilter, but then the qualifier was known in advance. but for this one the qualifier can be abc1, abc2 ... there would be too many options, thus too many SingleColumnValueFilter's.
Then I tried using the ValueFilter, but this filter only returns those columns that match the value, thus the wrong column family.
Can you think of any way to achieve my goal, querying for a value within a dynamically created qualifier in a column family and returning the contents of the column family and another column family (as specified when creating the Scan)? preferably only querying once.
Thanks in advance for any input.
UPDATE: (for clarification as discussed in the comments)
in a more graphical way, a row may have the following:
colfam1:aaa
colfam1:aab
colfam1:aac
colfam2:abc1
colfam2:abc2
whereas I want to get all of the family colfam1 if any value of colfam2 has e.g. the value x, with regard to the fact that colfam2:abc[cnt] is dynamically created with cnt being any positive integer
I see two approaches for this: client-side filtering or server-side filtering.
Client-side filtering is more straightforward. The Scan adds only the two families "colfam1" and "colfam2". Then, for each Result you get from scanner.next(), you must filter according to the qualifiers in "colfam2".
byte[] queryValue = Bytes.toBytes("x");
Scan scan = new Scan();
scan.addFamily(Bytes.toBytes("colfam1");
scan.addFamily(Bytes.toBytes("colfam2");
ResultScanner scanner = myTable.getScanner(scan);
Result res;
while((res = scanner.next()) != null) {
NavigableMap<byte[],byte[]> colfam2 = res.getFamilyMap(Bytes.toBytes("colfam2"));
boolean foundQueryValue = false;
SearchForQueryValue: while(!colfam2.isEmpty()) {
Entry<byte[], byte[]> cell = colfam2.pollFirstEntry();
if( Bytes.equals(cell.getValue(), queryValue) ) {
foundQueryValue = true;
break SearchForQueryValue;
}
}
if(foundQueryValue) {
NavigableMap<byte[],byte[]> colfam1 = res.getFamilyMap(Bytes.toBytes("colfam1"));
LinkedList<KeyValue> listKV = new LinkedList<KeyValue>();
while(!colfam1.isEmpty()) {
Entry<byte[], byte[]> cell = colfam1.pollFirstEntry();
listKV.add(new KeyValue(res.getRow(), Bytes.toBytes("colfam1"), cell.getKey(), cell.getValue());
}
Result filteredResult = new Result(listKV);
}
}
(This code was not tested)
And then finally filteredResult is what you want. This approach is not elegant and might also give you performance issues if you have a lot of data in those families. If "colfam1" has a lot of data, you don't want to transfer it to the client if it will end up not being used if value "x" is not in a qualifier of "colfam2".
Server-side filtering. This requires you to implement your own Filter class. I believe you cannot use the provided filter types to do this. Implementing your own Filter takes some work, you also need to compile it as a .jar and make it available to all RegionServers. But then, it helps you to avoid sending loads of data of "colfam1" in vain.
It is too much work for me to show you how to custom implement a Filter, so I recommend reading a good book (HBase: The Definitive Guide for example). However, the Filter code will look pretty much like the client-side filtering I showed you, so that's half of the work done.
I have this entity - I'm trying to determine the type of its properties - in Google App Engine's internal data-types PREFERRED (as opposed to Java data types).
The below code is obviously simplified. In reality I do not know the entity's properties or anything else about it.
final DatastoreService dss = DatastoreServiceFactory.getDatastoreService();
final Query query = new Query("Person");
final PreparedQuery pq = dss.prepare(query);
for (Entity entity : pq.asIterable())
{
final Object property = entity.getProperty("some_property");
// Here I want to determine which data type 'property' represents - GAE-wise.
}
In App Engine's Java code I've found some hints:
DataTypeTranslator
DataTypeTranslator.typeMap (internal private member)
Property.Meaning.GD_PHONENUMBER
I'm unable to link those together into what I need - some sort of reflection.
I wish I was able to do something like this:
entity.getPropertyType("some_property");
Does anyone know better?
DataTypeTranslator source code here
Edit #1: <<
INGORE this one. It's me who put these postfixes (I was confused by the doc).
Here's more important info I've found.
I'm getting it in Eclipse' tool-tip mini-window when I point over an entity (one which I just fetched from the Datastore).
The Datastore seems to send it (this payload) as raw text which is nice, maybe I'll have to parse it (but, how do I get it from code LOL).
Pay attention to the types in here, it's written plain simple.
Here it is:
<Entity [Bird(9)]:
Int64Type:44rmna4kc2g23i9brlupps74ir#Int64Type = 1234567890
String:igt7qvk9p89nc3gjqn9s3jq69c = 7tns1l48vpttq5ff47i3jlq3f9
PhoneNumber:auih50aecl574ud23v9h4rfvt1#PhoneNumberType = 03-6491234
Date:k1qstkn9np0mpb6fp41cj6i3am = Wed Jul 20 23:03:13 UTC 2011
>
For example, property named String:igt7qvk9p89nc3gjqn9s3jq69c has the value of 7tns1l48vpttq5ff47i3jlq3f9 and it doesn't tell its type. Also property Date:k1qstkn9np0mpb6fp41cj6i3am.
Property named Int64Type:44rmna4kc2g23i9brlupps74ir has the value of "1234567890" and here it strictly mentions that the data type is of "Int64Type".
I'm searching for it too.
It's a bit of a hack, but at least my output includes the type (without needing a secret decoder ring). But my code is slightly different:
Query allusersentityquery = new Query();
allusersentityquery.setAncestor(userKey);
for (final Entity entity : datastore.prepare(allusersentityquery).asIterable()) {
Map<String, Object> properties = entity.getProperties();
String[] propertyNames = properties.keySet().toArray(
new String[properties.size()]);
for(final String propertyName : propertyNames) {
// propertyNames string contains
// "com.google.appengine.api.datastore.PostalAddress" if it is a Postal Address
}
}
There seems to be no documents about determining the Property Types here.