Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Switch to GitLab Next
Sign in / Register
Toggle navigation
vcard4android
Project overview
Project overview
Details
Activity
Releases
Cycle Analytics
Insights
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Locked Files
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Security & Compliance
Security & Compliance
Dependency List
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Jobs
Commits
Open sidebar
bitfire web engineering
vcard4android
Commits
3f5c2d96
Commit
3f5c2d96
authored
Jun 25, 2017
by
Ricki Hirner
🐑
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Rewrite to Kotlin
parent
5a203f07
Pipeline
#9310173
passed with stage
in 9 minutes and 51 seconds
Changes
26
Pipelines
1
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
2532 additions
and
2853 deletions
+2532
-2853
build.gradle
build.gradle
+11
-10
src/androidTest/java/at/bitfire/vcard4android/AndroidAddressBookTest.java
...java/at/bitfire/vcard4android/AndroidAddressBookTest.java
+4
-2
src/androidTest/java/at/bitfire/vcard4android/AndroidContactTest.java
...est/java/at/bitfire/vcard4android/AndroidContactTest.java
+39
-37
src/androidTest/java/at/bitfire/vcard4android/AndroidGroupTest.java
...dTest/java/at/bitfire/vcard4android/AndroidGroupTest.java
+13
-10
src/androidTest/java/at/bitfire/vcard4android/impl/TestAddressBook.kt
...est/java/at/bitfire/vcard4android/impl/TestAddressBook.kt
+41
-0
src/main/java/at/bitfire/vcard4android/AndroidAddressBook.java
...ain/java/at/bitfire/vcard4android/AndroidAddressBook.java
+0
-133
src/main/java/at/bitfire/vcard4android/AndroidAddressBook.kt
src/main/java/at/bitfire/vcard4android/AndroidAddressBook.kt
+126
-0
src/main/java/at/bitfire/vcard4android/AndroidContact.java
src/main/java/at/bitfire/vcard4android/AndroidContact.java
+0
-1448
src/main/java/at/bitfire/vcard4android/AndroidContact.kt
src/main/java/at/bitfire/vcard4android/AndroidContact.kt
+1260
-0
src/main/java/at/bitfire/vcard4android/AndroidContactFactory.java
.../java/at/bitfire/vcard4android/AndroidContactFactory.java
+0
-27
src/main/java/at/bitfire/vcard4android/AndroidContactFactory.kt
...in/java/at/bitfire/vcard4android/AndroidContactFactory.kt
+16
-0
src/main/java/at/bitfire/vcard4android/AndroidGroup.java
src/main/java/at/bitfire/vcard4android/AndroidGroup.java
+0
-192
src/main/java/at/bitfire/vcard4android/AndroidGroup.kt
src/main/java/at/bitfire/vcard4android/AndroidGroup.kt
+182
-0
src/main/java/at/bitfire/vcard4android/AndroidGroupFactory.kt
...main/java/at/bitfire/vcard4android/AndroidGroupFactory.kt
+7
-4
src/main/java/at/bitfire/vcard4android/BatchOperation.java
src/main/java/at/bitfire/vcard4android/BatchOperation.java
+0
-160
src/main/java/at/bitfire/vcard4android/BatchOperation.kt
src/main/java/at/bitfire/vcard4android/BatchOperation.kt
+129
-0
src/main/java/at/bitfire/vcard4android/CachedGroupMembership.kt
...in/java/at/bitfire/vcard4android/CachedGroupMembership.kt
+21
-0
src/main/java/at/bitfire/vcard4android/Constants.kt
src/main/java/at/bitfire/vcard4android/Constants.kt
+6
-5
src/main/java/at/bitfire/vcard4android/Contact.java
src/main/java/at/bitfire/vcard4android/Contact.java
+0
-654
src/main/java/at/bitfire/vcard4android/Contact.kt
src/main/java/at/bitfire/vcard4android/Contact.kt
+524
-0
src/main/java/at/bitfire/vcard4android/ContactsStorageException.kt
...java/at/bitfire/vcard4android/ContactsStorageException.kt
+2
-12
src/main/java/at/bitfire/vcard4android/GroupMethod.kt
src/main/java/at/bitfire/vcard4android/GroupMethod.kt
+3
-2
src/main/java/at/bitfire/vcard4android/LabeledProperty.java
src/main/java/at/bitfire/vcard4android/LabeledProperty.java
+0
-32
src/main/java/at/bitfire/vcard4android/LabeledProperty.kt
src/main/java/at/bitfire/vcard4android/LabeledProperty.kt
+22
-0
src/test/java/at/bitfire/vcard4android/ContactTest.java
src/test/java/at/bitfire/vcard4android/ContactTest.java
+124
-124
src/test/java/at/bitfire/vcard4android/EzVCardTest.java
src/test/java/at/bitfire/vcard4android/EzVCardTest.java
+2
-1
No files found.
build.gradle
View file @
3f5c2d96
buildscript
{
ext
.
kotlin_version
=
'1.1.3'
repositories
{
jcenter
()
}
dependencies
{
classpath
'com.android.tools.build:gradle:2.3.1'
classpath
"org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects
{
repositories
{
jcenter
()
maven
{
url
'http://oss.sonatype.org/content/repositories/snapshots'
}
}
repositories
{
jcenter
()
}
apply
plugin:
'com.android.library'
apply
plugin:
'kotlin-android'
android
{
compileSdkVersion
26
...
...
@@ -50,9 +48,10 @@ android {
}
dependencies
{
compile
'org.apache.commons:commons-lang3:3.5'
compile
"org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
compile
'org.apache.commons:commons-text:1.1'
compile
'commons-io:commons-io:2.5'
provided
'org.projectlombok:lombok:1.16.16'
// ez-vcard to parse/generate VCards
compile
(
'com.googlecode.ez-vcard:ez-vcard:0.10.2'
)
{
...
...
@@ -66,8 +65,10 @@ dependencies {
androidTestCompile
'com.android.support.test:runner:+'
androidTestCompile
'com.android.support.test:rules:+'
androidTestCompile
'junit:junit:4.12'
androidTestCompile
'org.projectlombok:lombok:1.16.16'
testCompile
'junit:junit:4.12'
testCompile
'org.projectlombok:lombok:1.16.16'
}
// grant permissions for unit tests
...
...
src/androidTest/java/at/bitfire/vcard4android/AndroidAddressBookTest.java
View file @
3f5c2d96
...
...
@@ -21,6 +21,8 @@ import org.junit.Test;
import
java.util.Arrays
;
import
at.bitfire.vcard4android.impl.TestAddressBook
;
import
static
android
.
support
.
test
.
InstrumentationRegistry
.
getContext
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertFalse
;
...
...
@@ -47,7 +49,7 @@ public class AndroidAddressBookTest {
@Test
public
void
testSettings
()
throws
ContactsStorageException
{
AndroidAddressBook
addressBook
=
new
AndroidAddressBook
(
testAccount
,
provider
,
AndroidGroupFactory
.
INSTANCE
,
AndroidContactFactory
.
INSTANCE
);
AndroidAddressBook
addressBook
=
new
TestAddressBook
(
testAccount
,
provider
);
ContentValues
values
=
new
ContentValues
();
values
.
put
(
ContactsContract
.
Settings
.
SHOULD_SYNC
,
false
);
...
...
@@ -68,7 +70,7 @@ public class AndroidAddressBookTest {
@Test
public
void
testSyncState
()
throws
ContactsStorageException
{
AndroidAddressBook
addressBook
=
new
AndroidAddressBook
(
testAccount
,
provider
,
AndroidGroupFactory
.
INSTANCE
,
AndroidContactFactory
.
INSTANCE
);
AndroidAddressBook
addressBook
=
new
TestAddressBook
(
testAccount
,
provider
);
addressBook
.
setSyncState
(
new
byte
[
0
]);
assertEquals
(
0
,
addressBook
.
getSyncState
().
length
);
...
...
src/androidTest/java/at/bitfire/vcard4android/AndroidContactTest.java
View file @
3f5c2d96
...
...
@@ -26,7 +26,9 @@ import java.io.IOException;
import
java.nio.charset.Charset
;
import
java.sql.Date
;
import
java.util.Arrays
;
import
java.util.List
;
import
at.bitfire.vcard4android.impl.TestAddressBook
;
import
ezvcard.VCardVersion
;
import
ezvcard.property.Address
;
import
ezvcard.property.Birthday
;
...
...
@@ -52,7 +54,7 @@ public class AndroidContactTest {
provider
=
getContext
().
getContentResolver
().
acquireContentProviderClient
(
ContactsContract
.
AUTHORITY
);
assertNotNull
(
provider
);
addressBook
=
new
AndroidAddressBook
(
testAccount
,
provider
,
AndroidGroupFactory
.
INSTANCE
,
AndroidContactFactory
.
INSTANCE
);
addressBook
=
new
TestAddressBook
(
testAccount
,
provider
);
}
@After
...
...
@@ -64,30 +66,30 @@ public class AndroidContactTest {
@Test
public
void
testAddAndReadContact
()
throws
ContactsStorageException
,
FileNotFoundException
{
Contact
vcard
=
new
Contact
();
vcard
.
displayName
=
"Mya Contact"
;
vcard
.
prefix
=
"Magª"
;
vcard
.
givenName
=
"Mya"
;
vcard
.
familyName
=
"Contact"
;
vcard
.
s
uffix
=
"BSc"
;
vcard
.
phoneticGivenName
=
"Först"
;
vcard
.
phoneticMiddleName
=
"Mittelerde"
;
vcard
.
phoneticFamilyName
=
"Fämilie"
;
vcard
.
birthDay
=
new
Birthday
(
Date
.
valueOf
(
"1980-04-16"
));
vcard
.
setDisplayName
(
"Mya Contact"
)
;
vcard
.
setPrefix
(
"Magª"
)
;
vcard
.
setGivenName
(
"Mya"
)
;
vcard
.
setFamilyName
(
"Contact"
)
;
vcard
.
s
etSuffix
(
"BSc"
)
;
vcard
.
setPhoneticGivenName
(
"Först"
)
;
vcard
.
setPhoneticMiddleName
(
"Mittelerde"
)
;
vcard
.
setPhoneticFamilyName
(
"Fämilie"
)
;
vcard
.
setBirthDay
(
new
Birthday
(
Date
.
valueOf
(
"1980-04-16"
)
));
AndroidContact
contact
=
new
AndroidContact
(
addressBook
,
vcard
,
null
,
null
);
contact
.
create
();
@Cleanup
(
"delete"
)
AndroidContact
contact2
=
new
AndroidContact
(
addressBook
,
contact
.
id
,
null
,
null
);
@Cleanup
(
"delete"
)
AndroidContact
contact2
=
new
AndroidContact
(
addressBook
,
contact
.
getId
()
,
null
,
null
);
Contact
vcard2
=
contact2
.
getContact
();
assertEquals
(
vcard
.
displayName
,
vcard2
.
displayName
);
assertEquals
(
vcard
.
prefix
,
vcard2
.
prefix
);
assertEquals
(
vcard
.
g
ivenName
,
vcard2
.
givenName
);
assertEquals
(
vcard
.
familyName
,
vcard2
.
familyName
);
assertEquals
(
vcard
.
suffix
,
vcard2
.
suffix
);
assertEquals
(
vcard
.
phoneticGivenName
,
vcard2
.
phoneticGivenName
);
assertEquals
(
vcard
.
phoneticMiddleName
,
vcard2
.
phoneticMiddleName
);
assertEquals
(
vcard
.
phoneticFamilyName
,
vcard2
.
phoneticFamilyName
);
assertEquals
(
vcard
.
birthDay
,
vcard2
.
birthDay
);
assertEquals
(
vcard
.
getDisplayName
(),
vcard2
.
getDisplayName
()
);
assertEquals
(
vcard
.
getPrefix
(),
vcard2
.
getPrefix
()
);
assertEquals
(
vcard
.
g
etGivenName
(),
vcard2
.
getGivenName
()
);
assertEquals
(
vcard
.
getFamilyName
(),
vcard2
.
getFamilyName
()
);
assertEquals
(
vcard
.
getSuffix
(),
vcard2
.
getSuffix
()
);
assertEquals
(
vcard
.
getPhoneticGivenName
(),
vcard2
.
getPhoneticGivenName
()
);
assertEquals
(
vcard
.
getPhoneticMiddleName
(),
vcard2
.
getPhoneticMiddleName
()
);
assertEquals
(
vcard
.
getPhoneticFamilyName
(),
vcard2
.
getPhoneticFamilyName
()
);
assertEquals
(
vcard
.
getBirthDay
(),
vcard2
.
getBirthDay
()
);
}
@Test
...
...
@@ -99,37 +101,37 @@ public class AndroidContactTest {
"TEL;CELL=;PREF=:+12345\r\n"
+
"EMAIL;PREF=invalid:test@example.com\r\n"
+
"END:VCARD\r\n"
;
Contact
[]
contacts
=
Contact
.
fromStream
(
IOUtils
.
toInputStream
(
vCard
,
charset
),
charset
,
null
);
List
<
Contact
>
contacts
=
Contact
.
fromStream
(
IOUtils
.
toInputStream
(
vCard
,
charset
),
charset
,
null
);
AndroidContact
dbContact
=
new
AndroidContact
(
addressBook
,
contacts
[
0
]
,
null
,
null
);
AndroidContact
dbContact
=
new
AndroidContact
(
addressBook
,
contacts
.
get
(
0
)
,
null
,
null
);
dbContact
.
create
();
@Cleanup
(
"delete"
)
AndroidContact
dbContact2
=
new
AndroidContact
(
addressBook
,
dbContact
.
id
,
null
,
null
);
@Cleanup
(
"delete"
)
AndroidContact
dbContact2
=
new
AndroidContact
(
addressBook
,
dbContact
.
getId
()
,
null
,
null
);
Contact
contact2
=
dbContact2
.
getContact
();
assertEquals
(
"Test"
,
contact2
.
displayName
);
assertEquals
(
"+12345"
,
contact2
.
phoneNumbers
.
get
(
0
).
property
.
getText
());
assertEquals
(
"test@example.com"
,
contact2
.
emails
.
get
(
0
).
property
.
getValue
());
assertEquals
(
"Test"
,
contact2
.
getDisplayName
()
);
assertEquals
(
"+12345"
,
contact2
.
getPhoneNumbers
().
get
(
0
).
getProperty
()
.
getText
());
assertEquals
(
"test@example.com"
,
contact2
.
getEmails
().
get
(
0
).
getProperty
()
.
getValue
());
}
@Test
public
void
testLargeTransactionManyRows
()
throws
ContactsStorageException
,
FileNotFoundException
{
Contact
vcard
=
new
Contact
();
vcard
.
displayName
=
"Large Transaction (many rows)"
;
vcard
.
setDisplayName
(
"Large Transaction (many rows)"
)
;
for
(
int
i
=
0
;
i
<
4000
;
i
++)
vcard
.
emails
.
add
(
new
LabeledProperty
<
Email
>(
new
Email
(
"test"
+
i
+
"@example.com"
)));
vcard
.
getEmails
()
.
add
(
new
LabeledProperty
<
Email
>(
new
Email
(
"test"
+
i
+
"@example.com"
)));
AndroidContact
contact
=
new
AndroidContact
(
addressBook
,
vcard
,
null
,
null
);
contact
.
create
();
@Cleanup
(
"delete"
)
AndroidContact
contact2
=
new
AndroidContact
(
addressBook
,
contact
.
id
,
null
,
null
);
@Cleanup
(
"delete"
)
AndroidContact
contact2
=
new
AndroidContact
(
addressBook
,
contact
.
getId
()
,
null
,
null
);
Contact
vcard2
=
contact2
.
getContact
();
assertEquals
(
4000
,
vcard2
.
emails
.
size
());
assertEquals
(
4000
,
vcard2
.
getEmails
()
.
size
());
}
@Test
(
expected
=
ContactsStorageException
.
class
)
public
void
testLargeTransactionSingleRow
()
throws
ContactsStorageException
{
Contact
vcard
=
new
Contact
();
vcard
.
displayName
=
"Large Transaction (one row which is too large)"
;
vcard
.
setDisplayName
(
"Large Transaction (one row which is too large)"
)
;
// 1 MB eTag ... have fun
char
data
[]
=
new
char
[
1024
*
1024
];
...
...
@@ -146,7 +148,7 @@ public class AndroidContactTest {
address
.
setLabel
(
"My \"Label\"\nLine 2"
);
address
.
setStreetAddress
(
"Street \"Address\""
);
Contact
contact
=
new
Contact
();
contact
.
addresses
.
add
(
new
LabeledProperty
<>(
address
));
contact
.
getAddresses
()
.
add
(
new
LabeledProperty
<>(
address
));
/* label-param = "LABEL=" param-value
* param-values must not contain DQUOTE and should be encoded as defined in RFC 6868
...
...
@@ -171,16 +173,16 @@ public class AndroidContactTest {
@Test
public
void
testBirthdayWithoutYear
()
throws
ContactsStorageException
,
FileNotFoundException
{
Contact
vcard
=
new
Contact
();
vcard
.
displayName
=
"Mya Contact"
;
vcard
.
birthDay
=
new
Birthday
(
PartialDate
.
parse
(
"-04-16"
));
vcard
.
setDisplayName
(
"Mya Contact"
)
;
vcard
.
setBirthDay
(
new
Birthday
(
PartialDate
.
parse
(
"-04-16"
)
));
AndroidContact
contact
=
new
AndroidContact
(
addressBook
,
vcard
,
null
,
null
);
contact
.
create
();
@Cleanup
(
"delete"
)
AndroidContact
contact2
=
new
AndroidContact
(
addressBook
,
contact
.
id
,
null
,
null
);
@Cleanup
(
"delete"
)
AndroidContact
contact2
=
new
AndroidContact
(
addressBook
,
contact
.
getId
()
,
null
,
null
);
Contact
vcard2
=
contact2
.
getContact
();
assertEquals
(
vcard
.
displayName
,
vcard2
.
displayName
);
assertEquals
(
vcard
.
birthDay
,
vcard2
.
birthDay
);
assertEquals
(
vcard
.
getDisplayName
(),
vcard2
.
getDisplayName
()
);
assertEquals
(
vcard
.
getBirthDay
(),
vcard2
.
getBirthDay
()
);
}
...
...
src/androidTest/java/at/bitfire/vcard4android/AndroidGroupTest.java
View file @
3f5c2d96
...
...
@@ -19,6 +19,9 @@ import org.junit.Before;
import
org.junit.Test
;
import
java.io.FileNotFoundException
;
import
java.util.List
;
import
at.bitfire.vcard4android.impl.TestAddressBook
;
import
static
android
.
support
.
test
.
InstrumentationRegistry
.
getContext
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
...
...
@@ -37,7 +40,7 @@ public class AndroidGroupTest {
provider
=
getContext
().
getContentResolver
().
acquireContentProviderClient
(
ContactsContract
.
AUTHORITY
);
assertNotNull
(
provider
);
addressBook
=
new
AndroidAddressBook
(
testAccount
,
provider
,
AndroidGroupFactory
.
INSTANCE
,
AndroidContactFactory
.
INSTANCE
);
addressBook
=
new
TestAddressBook
(
testAccount
,
provider
);
}
@After
...
...
@@ -49,24 +52,24 @@ public class AndroidGroupTest {
@Test
public
void
testCreateReadDeleteGroup
()
throws
FileNotFoundException
,
ContactsStorageException
{
Contact
contact
=
new
Contact
();
contact
.
displayName
=
"at.bitfire.vcard4android-AndroidGroupTest"
;
contact
.
note
=
"(test group)"
;
contact
.
setDisplayName
(
"at.bitfire.vcard4android-AndroidGroupTest"
)
;
contact
.
setNote
(
"(test group)"
)
;
// ensure we start without this group
assertEquals
(
0
,
addressBook
.
queryGroups
(
ContactsContract
.
Groups
.
TITLE
+
"=?"
,
new
String
[]
{
contact
.
displayName
}).
length
);
assertEquals
(
0
,
addressBook
.
queryGroups
(
ContactsContract
.
Groups
.
TITLE
+
"=?"
,
new
String
[]
{
contact
.
getDisplayName
()
}).
size
()
);
// create group
AndroidGroup
group
=
new
AndroidGroup
(
addressBook
,
contact
,
null
,
null
);
group
.
create
();
AndroidGroup
[]
groups
=
addressBook
.
queryGroups
(
ContactsContract
.
Groups
.
TITLE
+
"=?"
,
new
String
[]
{
contact
.
displayName
}
);
assertEquals
(
1
,
groups
.
length
);
Contact
contact2
=
groups
[
0
]
.
getContact
();
assertEquals
(
contact
.
displayName
,
contact2
.
displayName
);
assertEquals
(
contact
.
note
,
contact2
.
note
);
List
<
AndroidGroup
>
groups
=
addressBook
.
queryGroups
(
ContactsContract
.
Groups
.
TITLE
+
"=?"
,
new
String
[]
{
contact
.
getDisplayName
()
}
);
assertEquals
(
1
,
groups
.
size
()
);
Contact
contact2
=
groups
.
get
(
0
)
.
getContact
();
assertEquals
(
contact
.
getDisplayName
(),
contact2
.
getDisplayName
()
);
assertEquals
(
contact
.
getNote
(),
contact2
.
getNote
()
);
// delete group
group
.
delete
();
assertEquals
(
0
,
addressBook
.
queryGroups
(
ContactsContract
.
Groups
.
TITLE
+
"=?"
,
new
String
[]
{
contact
.
displayName
}).
length
);
assertEquals
(
0
,
addressBook
.
queryGroups
(
ContactsContract
.
Groups
.
TITLE
+
"=?"
,
new
String
[]
{
contact
.
getDisplayName
()
}).
size
()
);
}
}
src/androidTest/java/at/bitfire/vcard4android/impl/TestAddressBook.kt
0 → 100644
View file @
3f5c2d96
/*
* Copyright © Ricki Hirner (bitfire web engineering).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*/
package
at.bitfire.vcard4android.impl
import
android.accounts.Account
import
android.content.ContentProviderClient
import
at.bitfire.vcard4android.*
class
TestAddressBook
(
account
:
Account
,
provider
:
ContentProviderClient
):
AndroidAddressBook
<
AndroidContact
,
AndroidGroup
>(
account
,
provider
,
ContactFactory
,
GroupFactory
)
{
object
ContactFactory
:
AndroidContactFactory
<
AndroidContact
>
{
override
fun
newInstance
(
addressBook
:
AndroidAddressBook
<
AndroidContact
,
AndroidGroup
>,
id
:
Long
,
fileName
:
String
?,
eTag
:
String
?)
=
AndroidContact
(
addressBook
,
id
,
fileName
,
eTag
)
override
fun
newInstance
(
addressBook
:
AndroidAddressBook
<
AndroidContact
,
AndroidGroup
>,
contact
:
Contact
,
fileName
:
String
?,
eTag
:
String
?):
AndroidContact
=
AndroidContact
(
addressBook
,
contact
,
fileName
,
eTag
)
}
object
GroupFactory
:
AndroidGroupFactory
<
AndroidGroup
>
{
override
fun
newInstance
(
addressBook
:
AndroidAddressBook
<
AndroidContact
,
AndroidGroup
>,
id
:
Long
,
fileName
:
String
?,
eTag
:
String
?)
=
AndroidGroup
(
addressBook
,
id
,
fileName
,
eTag
)
override
fun
newInstance
(
addressBook
:
AndroidAddressBook
<
AndroidContact
,
AndroidGroup
>,
contact
:
Contact
,
fileName
:
String
?,
eTag
:
String
?)
=
AndroidGroup
(
addressBook
,
contact
,
fileName
,
eTag
)
}
}
\ No newline at end of file
src/main/java/at/bitfire/vcard4android/AndroidAddressBook.java
deleted
100644 → 0
View file @
5a203f07
/*
* Copyright © 2013 – 2015 Ricki Hirner (bitfire web engineering).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*/
package
at
.
bitfire
.
vcard4android
;
import
android.accounts.Account
;
import
android.content.ContentProviderClient
;
import
android.content.ContentValues
;
import
android.database.Cursor
;
import
android.database.DatabaseUtils
;
import
android.net.Uri
;
import
android.os.RemoteException
;
import
android.provider.ContactsContract
;
import
android.provider.ContactsContract.Groups
;
import
android.provider.ContactsContract.RawContacts
;
import
java.io.FileNotFoundException
;
import
java.util.LinkedList
;
import
java.util.List
;
import
lombok.Cleanup
;
public
class
AndroidAddressBook
{
public
Account
account
;
final
public
ContentProviderClient
provider
;
final
AndroidGroupFactory
groupFactory
;
final
AndroidContactFactory
contactFactory
;
public
AndroidAddressBook
(
Account
account
,
ContentProviderClient
provider
,
AndroidGroupFactory
groupFactory
,
AndroidContactFactory
contactFactory
)
{
this
.
account
=
account
;
this
.
provider
=
provider
;
this
.
groupFactory
=
groupFactory
;
this
.
contactFactory
=
contactFactory
;
}
// account-specific address book settings
@SuppressWarnings
(
"Recycle"
)
public
ContentValues
getSettings
()
throws
ContactsStorageException
{
try
{
@Cleanup
Cursor
cursor
=
provider
.
query
(
syncAdapterURI
(
ContactsContract
.
Settings
.
CONTENT_URI
),
null
,
null
,
null
,
null
);
if
(
cursor
!=
null
&&
cursor
.
moveToNext
())
{
ContentValues
values
=
new
ContentValues
();
DatabaseUtils
.
cursorRowToContentValues
(
cursor
,
values
);
return
values
;
}
else
throw
new
FileNotFoundException
();
}
catch
(
FileNotFoundException
|
RemoteException
e
)
{
throw
new
ContactsStorageException
(
"Couldn't read contacts settings"
,
e
);
}
}
public
void
updateSettings
(
ContentValues
values
)
throws
ContactsStorageException
{
values
.
put
(
ContactsContract
.
Settings
.
ACCOUNT_NAME
,
account
.
name
);
values
.
put
(
ContactsContract
.
Settings
.
ACCOUNT_TYPE
,
account
.
type
);
try
{
provider
.
insert
(
syncAdapterURI
(
ContactsContract
.
Settings
.
CONTENT_URI
),
values
);
}
catch
(
RemoteException
e
)
{
throw
new
ContactsStorageException
(
"Couldn't write contacts settings"
,
e
);
}
}
// account-specific address book sync state
public
byte
[]
getSyncState
()
throws
ContactsStorageException
{
try
{
return
ContactsContract
.
SyncState
.
get
(
provider
,
account
);
}
catch
(
RemoteException
e
)
{
throw
new
ContactsStorageException
(
"Couldn't read contacts sync state"
,
e
);
}
}
public
void
setSyncState
(
byte
[]
data
)
throws
ContactsStorageException
{
try
{
ContactsContract
.
SyncState
.
set
(
provider
,
account
,
data
);
}
catch
(
RemoteException
e
)
{
throw
new
ContactsStorageException
(
"Couldn't write contacts sync state"
,
e
);
}
}
// groups
@SuppressWarnings
(
"Recycle"
)
protected
AndroidGroup
[]
queryGroups
(
String
where
,
String
[]
whereArgs
)
throws
ContactsStorageException
{
try
{
@Cleanup
Cursor
cursor
=
provider
.
query
(
syncAdapterURI
(
Groups
.
CONTENT_URI
),
new
String
[]
{
Groups
.
_ID
,
AndroidGroup
.
COLUMN_FILENAME
,
AndroidGroup
.
COLUMN_ETAG
},
where
,
whereArgs
,
null
);
List
<
AndroidGroup
>
groups
=
new
LinkedList
<>();
while
(
cursor
!=
null
&&
cursor
.
moveToNext
())
groups
.
add
(
groupFactory
.
newInstance
(
this
,
cursor
.
getLong
(
0
),
cursor
.
getString
(
1
),
cursor
.
getString
(
2
)));
return
groups
.
toArray
(
groupFactory
.
newArray
(
groups
.
size
()));
}
catch
(
RemoteException
e
)
{
throw
new
ContactsStorageException
(
"Couldn't query contact groups"
,
e
);
}
}
@SuppressWarnings
(
"Recycle"
)
protected
AndroidContact
[]
queryContacts
(
String
where
,
String
[]
whereArgs
)
throws
ContactsStorageException
{
try
{
@Cleanup
Cursor
cursor
=
provider
.
query
(
syncAdapterURI
(
RawContacts
.
CONTENT_URI
),
new
String
[]
{
RawContacts
.
_ID
,
AndroidContact
.
COLUMN_FILENAME
,
AndroidContact
.
COLUMN_ETAG
},
where
,
whereArgs
,
null
);
List
<
AndroidContact
>
contacts
=
new
LinkedList
<>();
while
(
cursor
!=
null
&&
cursor
.
moveToNext
())
contacts
.
add
(
contactFactory
.
newInstance
(
this
,
cursor
.
getLong
(
0
),
cursor
.
getString
(
1
),
cursor
.
getString
(
2
)));
return
contacts
.
toArray
(
contactFactory
.
newArray
(
contacts
.
size
()));
}
catch
(
RemoteException
e
)
{
throw
new
ContactsStorageException
(
"Couldn't query contacts"
,
e
);
}
}
// helpers
public
Uri
syncAdapterURI
(
Uri
uri
)
{
return
uri
.
buildUpon
()
.
appendQueryParameter
(
RawContacts
.
ACCOUNT_NAME
,
account
.
name
)
.
appendQueryParameter
(
RawContacts
.
ACCOUNT_TYPE
,
account
.
type
)
.
appendQueryParameter
(
ContactsContract
.
CALLER_IS_SYNCADAPTER
,
"true"
)
.
build
();
}
}
src/main/java/at/bitfire/vcard4android/AndroidAddressBook.kt
0 → 100644
View file @
3f5c2d96
/*
* Copyright © 2013 – 2015 Ricki Hirner (bitfire web engineering).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*/
package
at.bitfire.vcard4android
import
android.accounts.Account
import
android.annotation.SuppressLint
import
android.content.ContentProviderClient
import
android.content.ContentValues
import
android.database.DatabaseUtils
import
android.net.Uri
import
android.os.RemoteException
import
android.provider.ContactsContract
import
android.provider.ContactsContract.Groups
import
android.provider.ContactsContract.RawContacts
import
java.io.FileNotFoundException
import
java.util.*
open
class
AndroidAddressBook
<
out
T1
:
AndroidContact
,
out
T2
:
AndroidGroup
>(
var
account
:
Account
,
val
provider
:
ContentProviderClient
,
val
contactFactory
:
AndroidContactFactory
<
T1
>,
val
groupFactory
:
AndroidGroupFactory
<
T2
>
)
{
// account-specific address book settings
@Throws
(
ContactsStorageException
::
class
)
fun
getSettings
():
ContentValues
{
val
values
=
ContentValues
()
try
{
provider
.
query
(
syncAdapterURI
(
ContactsContract
.
Settings
.
CONTENT_URI
),
null
,
null
,
null
,
null
)
?.
use
{
cursor
->
if
(
cursor
.
moveToNext
())
DatabaseUtils
.
cursorRowToContentValues
(
cursor
,
values
)
else
throw
FileNotFoundException
()
}
}
catch
(
e
:
Exception
)
{
throw
ContactsStorageException
(
"Couldn't read address book settings"
,
e
)
}
return
values
}
@Throws
(
ContactsStorageException
::
class
)
fun
updateSettings
(
values
:
ContentValues
)
{
values
.
put
(
ContactsContract
.
Settings
.
ACCOUNT_NAME
,
account
.
name
)
values
.
put
(
ContactsContract
.
Settings
.
ACCOUNT_TYPE
,
account
.
type
)
try
{
provider
.
insert
(
syncAdapterURI
(
ContactsContract
.
Settings
.
CONTENT_URI
),
values
)
}
catch
(
e
:
RemoteException
)
{
throw
ContactsStorageException
(
"Couldn't write address book settings"
,
e
)
}
}
// account-specific address book sync state
@Throws
(
ContactsStorageException
::
class
)
fun
getSyncState
():
ByteArray
=
try
{
ContactsContract
.
SyncState
.
get
(
provider
,
account
)
}
catch
(
e
:
RemoteException
)
{
throw
ContactsStorageException
(
"Couldn't read address book sync state"
,
e
)
}
@Throws
(
ContactsStorageException
::
class
)
fun
setSyncState
(
data
:
ByteArray
)
{
try
{
ContactsContract
.
SyncState
.
set
(
provider
,
account
,
data
)
}
catch
(
e
:
RemoteException
)
{
throw
ContactsStorageException
(
"Couldn't write contacts sync state"
,
e
)
}
}
// groups
@SuppressLint
(
"Recycle"
)
@Throws
(
ContactsStorageException
::
class
)
protected
fun
queryContacts
(
where
:
String
?,
whereArgs
:
Array
<
String
>?):
List
<
T1
>
{
val
contacts
=
LinkedList
<
T1
>()
try
{
provider
.
query
(
syncAdapterURI
(
RawContacts
.
CONTENT_URI
),
arrayOf
(
RawContacts
.
_ID
,
AndroidContact
.
COLUMN_FILENAME
,
AndroidContact
.
COLUMN_ETAG
),
where
,
whereArgs
,
null
)
?.
let
{
cursor
->
while
(
cursor
.
moveToNext
())
contacts
+=
contactFactory
.
newInstance
(
this
,
cursor
.
getLong
(
0
),
cursor
.
getString
(
1
),
cursor
.
getString
(
2
))
}
}
catch
(
e
:
RemoteException
)
{
throw
ContactsStorageException
(
"Couldn't query contacts"
,
e
)
}
return
contacts
}
@SuppressLint
(
"Recycle"
)
@Throws
(
ContactsStorageException
::
class
)
protected
fun
queryGroups
(
where
:
String
?,
whereArgs
:
Array
<
String
>?):
List
<
T2
>
{
val
groups
=
LinkedList
<
T2
>()
try
{
provider
.
query
(
syncAdapterURI
(
Groups
.
CONTENT_URI
),
arrayOf
(
Groups
.
_ID
,
AndroidGroup
.
COLUMN_FILENAME
,
AndroidGroup
.
COLUMN_ETAG
),
where
,
whereArgs
,
null
)
?.
use
{
cursor
->
while
(
cursor
.
moveToNext
())
groups
+=
groupFactory
.
newInstance
(
this
,
cursor
.
getLong
(
0
),
cursor
.
getString
(
1
),
cursor
.
getString
(
2
))
}
}
catch
(
e
:
RemoteException
)
{
throw
ContactsStorageException
(
"Couldn't query contact groups"
,
e
)
}
return
groups
}
// helpers
fun
syncAdapterURI
(
uri
:
Uri
)
=
uri
.
buildUpon
()
.
appendQueryParameter
(
RawContacts
.
ACCOUNT_NAME
,
account
.
name
)
.
appendQueryParameter
(
RawContacts
.
ACCOUNT_TYPE
,
account
.
type
)
.
appendQueryParameter
(
ContactsContract
.
CALLER_IS_SYNCADAPTER
,
"true"
)
.
build
()
!!
}
src/main/java/at/bitfire/vcard4android/AndroidContact.java
deleted
100644 → 0
View file @
5a203f07
This diff is collapsed.
Click to expand it.
src/main/java/at/bitfire/vcard4android/AndroidContact.kt
0 → 100644
View file @
3f5c2d96
This diff is collapsed.
Click to expand it.
src/main/java/at/bitfire/vcard4android/AndroidContactFactory.java
deleted
100644 → 0
View file @
5a203f07
/*
* Copyright © 2013 – 2015 Ricki Hirner (bitfire web engineering).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*/
package
at
.
bitfire
.
vcard4android
;
public
class
AndroidContactFactory
{
public
static
final
AndroidContactFactory
INSTANCE
=
new
AndroidContactFactory
();
public
AndroidContact
newInstance
(
AndroidAddressBook
addressBook
,
long
id
,
String
fileName
,
String
eTag
)
{
return
new
AndroidContact
(
addressBook
,
id
,
fileName
,
eTag
);
}
public
AndroidContact
newInstance
(
AndroidAddressBook
addressBook
,
Contact
contact
,
String
fileName
,
String
eTag
)
{
return
new
AndroidContact
(
addressBook
,
contact
,
fileName
,
eTag
);
}
public
AndroidContact
[]
newArray
(
int
size
)
{
return
new
AndroidContact
[
size
];
}
}
src/main/java/at/bitfire/vcard4android/AndroidContactFactory.kt
0 → 100644
View file @
3f5c2d96
/*
* Copyright © 2013 – 2015 Ricki Hirner (bitfire web engineering).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*/
package
at.bitfire.vcard4android
interface
AndroidContactFactory
<
out
T
:
AndroidContact
>
{
fun
newInstance
(
addressBook
:
AndroidAddressBook
<
AndroidContact
,
AndroidGroup
>,
id
:
Long
,
fileName
:
String
?,
eTag
:
String
?):
T
fun
newInstance
(
addressBook
:
AndroidAddressBook
<
AndroidContact
,
AndroidGroup
>,
contact
:
Contact
,
fileName
:
String
?,
eTag
:
String
?):
T
}
src/main/java/at/bitfire/vcard4android/AndroidGroup.java
deleted
100644 → 0
View file @
5a203f07
/*
* Copyright © 2013 – 2015 Ricki Hirner (bitfire web engineering).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*/
package
at
.
bitfire
.
vcard4android
;
import
android.annotation.SuppressLint
;
import
android.content.ContentUris
;
import
android.content.ContentValues
;
import
android.database.Cursor
;
import
android.net.Uri
;
import
android.os.RemoteException
;
import
android.provider.ContactsContract
;
import
android.provider.ContactsContract.CommonDataKinds.GroupMembership
;
import
android.provider.ContactsContract.Groups
;
import
android.provider.ContactsContract.RawContacts
;
import
android.provider.ContactsContract.RawContacts.Data
;
import
org.apache.commons.lang3.StringUtils
;
import
java.io.FileNotFoundException
;
import
lombok.Cleanup
;
import
lombok.Getter
;
import
lombok.ToString
<