A very strange porblem. I'm tring to update contacts name by this rule:
- if a contact's name start with "bit" + space ("bit ") so -> update the contact's name to name.substring(4, name.length()), and that means that the contact name will update without the "bit ".
when I use name.substring from number that lower them 4 (I think until the space in contact's name) its working perfectly. When I use from the 4 character onwards the contact's name multiply. For exmaple, when i use name = name.substring(4, name.length()) while name equal to "bit Lili" its update to:
Lili Lili.
private void updateContact(String name) {
ContentResolver cr = getContentResolver();
String where = ContactsContract.Data.DISPLAY_NAME + " = ?";
String[] params = new String[] {name};
Cursor phoneCur = managedQuery(ContactsContract.Data.CONTENT_URI,null,where,params,null);
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
if ((null == phoneCur)) {//createContact(name, phone);
Toast.makeText(this, "no contact with this name", Toast.LENGTH_SHORT).show();
return;} else {ops.add(ContentProviderOperation.newUpdate(android.provider.ContactsContract.Data.CONTENT_URI)
.withSelection(where, params)
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name.substring(4,name.length()))
.build());
}
phoneCur.close();
try {cr.applyBatch(ContactsContract.AUTHORITY, ops);}
catch (RemoteException e) {e.printStackTrace();}
catch (OperationApplicationException e) {e.printStackTrace();}}
Thanks!
Not a certain answer but it suppose to work the issue you have is with the
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME //This specific part has a problem with the new update function
,name.substring(4,name.length()))
So my fix proposal is to change it to family name and given name change these as you need based on your question you want to remove the given name so it's a fix for that
public static boolean updateContactName(#NonNull Context context, #NonNull String name) {
if (name.length() < 4) return true;
String givenNameKey = ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME;
String familyNameKey = ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME;
String changedName = name.substring(4, name.length());
ArrayList<ContentProviderOperation> ops = new ArrayList<>();
String where = ContactsContract.Data.DISPLAY_NAME + " = ?";
String[] params = new String[]{name};
ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
.withSelection(where, params)
.withValue(givenNameKey, changedName)
.withValue(familyNameKey, "")
.build());
try {
context.getContentResolver()
.applyBatch(ContactsContract.AUTHORITY, ops);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
Related
I have a categorized Notes view, let say the first categorized column is TypeOfVehicle the second categorized column is Model and the third categorized column is Manufacturer.
I would like to collect only the values for the first category and return it as json object:
I am facing two problems:
- I can not read the value for the category, the column values are emptry and when I try to access the underlying document it is null
the script won't hop over to the category/sibling on the same level.
can someone explain me what am I doing wrong here?
private Object getFirstCategory() {
JsonJavaObject json = new JsonJavaObject();
try{
String server = null;
String filepath = null;
server = props.getProperty("server");
filepath = props.getProperty("filename");
Database db;
db = utils.getSession().getDatabase(server, filepath);
if (db.isOpen()) {
View vw = db.getView("transport");
if (null != vw) {
vw.setAutoUpdate(false);
ViewNavigator nav;
nav = vw.createViewNav();
JsonJavaArray arr = new JsonJavaArray();
Integer count = 0;
ViewEntry tmpentry;
ViewEntry entry = nav.getFirst();
while (null != entry) {
Vector<?> columnValues = entry.getColumnValues();
if(entry.isCategory()){
System.out.println("entry notesid = " + entry.getNoteID());
Document doc = entry.getDocument();
if(null != doc){
if (doc.hasItem("TypeOfVehicle ")){
System.out.println("category has not " + "TypeOfVehicle ");
}
else{
System.out.println("category IS " + doc.getItemValueString("TypeOfVehicle "));
}
} else{
System.out.println("doc is null");
}
JsonJavaObject row = new JsonJavaObject();
JsonJavaObject jo = new JsonJavaObject();
String TypeOfVehicle = String.valueOf(columnValues.get(0));
if (null != TypeOfVehicle ) {
if (!TypeOfVehicle .equals("")){
jo.put("TypeOfVehicle ", TypeOfVehicle );
} else{
jo.put("TypeOfVehicle ", "Not categorized");
}
} else {
jo.put("TypeOfVehicle ", "Not categorized");
}
row.put("request", jo);
arr.put(count, row);
count++;
tmpentry = nav.getNextSibling(entry);
entry.recycle();
entry = tmpentry;
} else{
//tmpentry = nav.getNextCategory();
//entry.recycle();
//entry = tmpentry;
}
}
json.put("data", arr);
vw.setAutoUpdate(true);
vw.recycle();
}
}
} catch (Exception e) {
OpenLogUtil.logErrorEx(e, JSFUtil.getXSPContext().getUrl().toString(), Level.SEVERE, null);
}
return json;
}
What you're doing wrong is trying to treat any single view entry as both a category and a document. A single view entry can only be one of a category, a document, or a total.
If you have an entry for which isCategory() returns true, then for the same entry:
isDocument() will return false.
getDocument() will return null.
getNoteID() will return an empty string.
If the only thing you need is top-level categories, then get the first entry from the navigator and iterate over entries using nav.getNextSibling(entry) as you're already doing, but:
Don't try to get documents, note ids, or fields.
Use entry.getColumnValues().get(0) to get the value of the first column for each category.
If the view contains any uncategorised documents, it's possible that entry.getColumnValues().get(0) might throw an exception, so you should also check that entry.getColumnValues().size() is at least 1 before trying to get a value.
If you need any extra data beyond just top-level categories, then note that subcategories and documents are children of their parent categories.
If an entry has a subcategory, nav.getChild(entry) will get the first subcategory of that entry.
If an entry has no subcategories, but is a category which contains documents, nav.getChild(entry) will get the first document in that category.
i have a huge problem with duplicated contacts.
After sorting array with:
Collections.sort(mAllContacts);
I'm reading contacts with :
ContentResolver cr = mContext.getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,
null, null, null, null);
if ((cur != null ? cur.getCount() : 0) > 0) {
while (cur != null && cur.moveToNext()) {
String id = cur.getString(
cur.getColumnIndex(ContactsContract.Contacts._ID));
String name = cur.getString(cur.getColumnIndex(
ContactsContract.Contacts.DISPLAY_NAME));
if (cur.getInt(cur.getColumnIndex(
ContactsContract.Contacts.HAS_PHONE_NUMBER)) > 0) {
Cursor pCur = cr.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
new String[]{id}, null);
while (pCur.moveToNext()) {
String phoneNo = pCur.getString(pCur.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.NUMBER));
contacts = new AllContacts(name, phoneNo);
mAllContacts.add(contacts);
}
pCur.close();
}
}
}
if (cur != null) {
cur.close();
}
With this way, all contact are retrieved to a list (Local storage, Sim, Gmail etc).
I have no problem to remove duplicated contact by name like this:
for (int i = 0; i < mAllContacts.size() - 1; i++) {
if (mAllContacts.get(i).getmContactName().equals(mAllContacts.get(i + 1).getmContactName())) {
Log.d("duplicatedArray", "setAdapter: " + mAllContacts.get(i).getmContactName());
mAllContacts.remove(i+1);
}
}
but it's not a good practice because some times different contacts may have same name,
so i can remove duplicated contact with same method but use:
mAllContacts.get(i + 1).getmPhoneNumber()
And here is the problems comes:
For some reason , the phone number have different format while reading from gmail, local storage , sim.
For ex.
Gmail phone number : +972-54-333-55-88
Local storage phone number : +972-543335588
Sim : +972543335588
How can i solve my problem to remove duplicated values.
And yes , i need to read contact from all places where they appear (gmail, local storage , sim)
Apply regex to change the same phone numbers to a common format e.g.
class Main {
public static void main(String args[]) {
String p1 = "+972-54-333-55-88";
String p2 = "+972-543335588";
String p3 = "+972543335588";
String p4 = "+97(2543)335588";
String p5 = "+97 2543 335588";
String regex = "[^0-9+]";
System.out.println(p1.replaceAll(regex, ""));
System.out.println(p2.replaceAll(regex, ""));
System.out.println(p3.replaceAll(regex, ""));
System.out.println(p4.replaceAll(regex, ""));
System.out.println(p5.replaceAll(regex, ""));
}
}
Output:
+972543335588
+972543335588
+972543335588
+972543335588
+972543335588
Normalize
I think you should normalize these phone numbers before you store them.
So for example all of these:
Gmail phone number : +972-54-333-55-88
Local storage phone number : +972-543335588
Sim : +97254335588
Could just be stored as 97254335588 You can parse these numbers by removing all space, hyphens, and plus signs.
HashSet
It would also be easier to store these in a HashSet so you don't even need to worry about removing duplicates.
I need to get the ID of room by its name from JSONObject.
I uploaded Json file here: https://gitlab.com/JaroslavVond/json/blob/master/Json
So I know the name of the room (Kitchen1) and I need to write some function in Java that will return me the ID of the room (in this case "1").
Any ideas how to do that?
So far I have something like this:
private static String GetIdRoom(String room) {
String id = "";
JSONObject myResponse = SendHTTP("/groups", "GET", "");
try {
// some code to get ID of room
} catch (Exception ex) {
System.out.println("error - " + ex);
}
return null ;
}
Iterator<?> ids = myResponse.keys();
while( ids.hasNext() ) {
id = (String) ids.next();
if(myResponse.getJSONObject(id).getString("name").equals(room)){
return id;
}
}
Problem
I want to see if user "john" is in group "Calltaker". I can't seem to get the syntax right on my search filter to check for a specific user in a specific group. I can list all users in a group to verify the desired user is there.
Questions
What is the right syntax for a ldap search filter to determine if a specific user is in a specific group(in Tivoli Access Manager)?
What should I check on the returned LDAPEntry object given by that search string to see that the user is, or isn't, in the group?
Info
john is defined in "cn=users,dc=ldap,dc=net"
Calltaker is defined in "cn=groups,dc=ldap,dc=net"
I'm querying against TAM's ldap, from java
Using the searchfilter to be "cn=Calltaker" I can print out the search results such that calling nextEntry.toString contains the list of users. See Example 1 below
Here's a few searchfilters I've tried that don't work (aka searchResults.next() throws an error):
(&(objectclass=groupOfUniqueName)(uniquemember=uid="+ username + ",cn=groups,dc=ldap,dc=net))
(&(objectclass=groupOfUniqueName)(uniquemember=uid="+ username + ",cn=users,dc=ldap,dc=net))
(uniquemember=uid="+ username + ",cn=users,dc=ldap,dc=net)
Example 1) only search group, using searchFilter="cn=Calltaker", verify it contains users:
System.out.println(nextEntry.toString()); //added newlines for readability
nextEntry:
LDAPEntry:
cn=Calltaker,cn=groups,dc=ldap,dc=net;
LDAPAttributeSet:
LDAPAttribute: {type='objectclass', values='groupOfUniqueNames','top'}
LDAPAttribute: {type='uniquemember',
values=
'uid=placeholder,cn=users,dc=ldap,dc=net',
'secAuthority=default',
'uid=john,cn=users,dc=ldap,dc=net',
'uid=sally,cn=users,dc=ldap,dc=net', ....etc
Code:
public boolean isUserInGroup(username){
boolean userInGroup = false;
String loginDN = "uid=" + admin_username + "," + "cn=users,dc=ldap,dc=net";
String searchBase = "cn=groups,dc=ldap,dc=net";
int searchScope = LDAPConnection.SCOPE_SUB;
searchFilter = "(&(objectclass=ePerson)(uniquemember=uid="+ username + ",cn=users,dc=ldap,dc=net))";
//Connect
LDAPConnection lc = connect(hosts);
lc.bind(LDAPConnection.LDAP_V3, loginDN, admin_password.getBytes("UTF8"));
lc.getAuthenticationDN();
LDAPSearchResults searchResults = lc.search(searchBase,
searchScope,
searchFilter,
null, // return all attributes
false); // return attrs and values
while (searchResults.hasMore()) {
LDAPEntry nextEntry = null;
try {
nextEntry = searchResults.next();
} catch (LDAPException e) {
// Exception is thrown, go for next entry
if (e.getResultCode() == LDAPException.LDAP_TIMEOUT || e.getResultCode() == LDAPException.CONNECT_ERROR)
break;
else
continue;
}
//TODO some check to verify nextEntry shows the user in the group
userInGroup = true;
LDAPAttributeSet attributeSet = nextEntry.getAttributeSet();
Iterator<LDAPAttribute> allAttributes = attributeSet.iterator();
while (allAttributes.hasNext()) {
LDAPAttribute attribute = (LDAPAttribute) allAttributes.next();
String attributeName = attribute.getName();
System.out.println("found attribute '" + attributeName + "' with value '" + attribute.getStringValue() + "'");
}
}
lc.disconnect();
return userInGroup;
}
** EDIT **
Implemented answer from EJP, changed searchBase to include group
Code that works:
private static final String admin_username = "foo";
private static final String[] hosts = new String[]{"foohost.net"};
public boolean isUserInGroup(String username, String group){
boolean userInGroup = false;
String loginDN = "uid=" + admin_username + "," + "cn=users,dc=ldap,dc=net";
String searchBase = "cn=" + group + "," + "cn=groups,dc=ldap,dc=net";
int searchScope = LDAPConnection.SCOPE_SUB;
searchFilter = "(&(objectclass=groupOfUniqueNames)(uniquemember=uid="+ username + ",cn=users,dc=ldap,dc=net))";
//Connect
LDAPConnection lc = connect(hosts);
lc.bind(LDAPConnection.LDAP_V3, loginDN, admin_password.getBytes("UTF8"));
lc.getAuthenticationDN();
LDAPSearchResults searchResults = lc.search(searchBase,
searchScope,
searchFilter,
null, // return all attributes
false); // return attrs and values
while (searchResults.hasMore()) {
LDAPEntry nextEntry = null;
try {
nextEntry = searchResults.next();
} catch (LDAPException e) {
// Exception is thrown, go for next entry
if (e.getResultCode() == LDAPException.LDAP_TIMEOUT || e.getResultCode() == LDAPException.CONNECT_ERROR)
break;
else
continue;
}
//A result was found, therefore the user is in the group
userInGroup = true;
}
lc.disconnect();
return userInGroup;
}
What is the right syntax for a ldap search filter to determine if a specific user is in a specific group(in Tivoli Access Manager)?
Either of the filters you used, but the objectClass to search on is groupofUniqueNames (plural).
What should I check on the returned LDAPEntry object given by that search string to see that the user is, or isn't, in the group?
Nothing. He will be, otherwise the group won't be returned in the search. All you need to do is check that the search result is non-empty.
Here's a few searchfilters I've tried that don't work (aka searchResults.next() throws an error):
Throws what error?
(&(objectclass=groupOfUniqueName)(uniquemember=uid="+ username + ",cn=groups,dc=ldap,dc=net))
Nothing wrong with this except for groupOfUniqueName. You should use search filter arguments like {0} rather than building them into the search string.
(&(objectclass=groupOfUniqueName)(uniquemember=uid="+ username + ",cn=users,dc=ldap,dc=net))
This one will search the cn=users subtree for a group. It won't work unless you have groups under cn=users, which doesn't seem likely.
(uniquemember=uid="+ username + ",cn=users,dc=ldap,dc=net)
This will select non-groups. You don't want that: you need the objectClass part.
The green is the lore
and the yellow is the displayname
http://puu.sh/k2iI7/62619f9536.jpg
I'm trying to seperate them in there rightful places for some odd reason there both appearing in both of the places.
items.java
public ItemStack applyLore(ItemStack stack, String name, String lore1){
ItemMeta meta = stack.getItemMeta();
meta.setDisplayName(name.replaceAll("&([0-9a-f])", "\u00A7$1"));
ArrayList<String> lore = new ArrayList<String>();
lore.add(lore1.replaceAll("&([0-9a-f])", "\u00A7$1"));
meta.setLore(lore);
stack.setItemMeta(meta);
return stack;
}
// p.getInventory().addItem(new ItemStack(Integer.parseInt(s), 1));
public void giveItemfromConfig(Player p)
{
String name ="name:";
String lore ="lore:";
for ( String s : plugin.file.getFile().getStringList(plugin.file.path) ) {
try {
s.split(" ");
if ( s.contains(name) || s.contains(lore) )
{
String namelength = s.substring(name.length());
String lorelength = s.substring(lore.length());
p.getInventory().addItem(applyLore(new ItemStack(Integer.parseInt(s.split(" ")[0])),
namelength.replace("_", " ").replace("ame:", "").replace("e:", "").replace("lor", "").replace("ore", ""),
lorelength.replace("_", " ").replace("lor:", "").replace("e:", "").replace("am", "").replace("lor", "").replace("ore", "")));
p.sendMessage("debug");
} else {
///nope.exe
p.getInventory().addItem(new ItemStack(Integer.parseInt(s)));
}
} catch(Exception e)
{
e.printStackTrace();
Bukkit.getConsoleSender().sendMessage(ChatColor.AQUA + "Error in Config, Your id must be a integer ERROR:" + e);
}
}
}
config.yml
ChestPopulater:
items:
- 276 name:cookie
First thing is the problem is because of "Integer.parseInt(s)".
I dont know why you added this one as we dont have full source code or idea what you are trying to do with String "s" so that you will get result.
If you are doing it to get "276" , I will suggest you to do following :
String s2 = s.replaceAll("[A-Za-z]","").replace(":","").trim();
Integer i = Integer.parseInt(s2);