Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get rid of Apache Commons #41

Merged
merged 19 commits into from
Jul 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@ agp = "8.5.1"
androidx-annotation = "1.8.0"
androidx-test-runner = "1.6.1"
androidx-rest-rules = "1.6.1"
# noinspection GradleDependency
commons-io = "2.6"
# noinspection GradleDependency
commons-text = "1.3"
desugar = "2.0.4"
dokka = "1.9.20"
ezvcard = "0.12.1"
Expand All @@ -17,8 +13,6 @@ junit = "4.13.2"
androidx-annotation = { module = "androidx.annotation:annotation", version.ref = "androidx-annotation" }
androidx-test-runner = { module = "androidx.test:runner", version.ref = "androidx-test-runner" }
androidx-test-rules = { module = "androidx.test:rules", version.ref = "androidx-rest-rules" }
commons-io = { module = "commons-io:commons-io", version.ref = "commons-io" }
commons-text = { module = "org.apache.commons:commons-text", version.ref = "commons-text" }
desugar = { module = "com.android.tools:desugar_jdk_libs", version.ref = "desugar" }
ezvcard = { module = "com.googlecode.ez-vcard:ez-vcard", version.ref = "ezvcard" }
kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" }
Expand Down
4 changes: 0 additions & 4 deletions lib/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,6 @@ dependencies {
coreLibraryDesugaring(libs.desugar)

implementation(libs.androidx.annotation)
@Suppress("RedundantSuppression")
implementation(libs.commons.io)
@Suppress("RedundantSuppression")
implementation(libs.commons.text)

// ez-vcard to parse/generate vCards
api(libs.ezvcard) { // requires Java 8
Expand Down
13 changes: 13 additions & 0 deletions lib/src/androidTest/java/at/bitfire/vcard4android/TestUtils.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package at.bitfire.vcard4android

object TestUtils {

/**
* Reads a resource from the classpath and returns it as a byte array.
* @param resource The resource to read. Note that it must start with a `/`.
* @throws NullPointerException If the resource doesn't exist.
*/
fun resourceToByteArray(resource: String): ByteArray =
this::class.java.getResourceAsStream(resource)!!.use { it.readBytes() }

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.rule.GrantPermissionRule
import at.bitfire.vcard4android.AndroidContact
import at.bitfire.vcard4android.Contact
import at.bitfire.vcard4android.TestUtils
import at.bitfire.vcard4android.impl.TestAddressBook
import org.apache.commons.io.IOUtils
import org.junit.Assert.*
import org.junit.BeforeClass
import org.junit.ClassRule
Expand Down Expand Up @@ -81,7 +81,7 @@ class PhotoBuilderTest {
val rawContactId = ContentUris.parseId(contactUri)

try {
val photo = IOUtils.resourceToByteArray("/large.jpg")
val photo = TestUtils.resourceToByteArray("/large.jpg")
val photoUri = PhotoBuilder.insertPhoto(provider, testAccount, rawContactId, photo)
assertNotNull(photoUri)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.rule.GrantPermissionRule
import at.bitfire.vcard4android.AndroidContact
import at.bitfire.vcard4android.Contact
import at.bitfire.vcard4android.TestUtils
import at.bitfire.vcard4android.impl.TestAddressBook
import org.apache.commons.io.IOUtils
import org.junit.Assert
import org.junit.Assert.*
import org.junit.BeforeClass
Expand Down Expand Up @@ -64,13 +64,13 @@ class PhotoHandlerTest {

@Test
fun testConvertToJpeg_Jpeg() {
val blob = IOUtils.resourceToByteArray("/small.jpg")
val blob = TestUtils.resourceToByteArray("/small.jpg")
assertArrayEquals(blob, PhotoHandler.convertToJpeg(blob, 75))
}

@Test
fun testConvertToJpeg_Png() {
val blob = IOUtils.resourceToByteArray("/small.png")
val blob = TestUtils.resourceToByteArray("/small.png")
assertFalse(Arrays.equals(blob, PhotoHandler.convertToJpeg(blob, 75)))
}

Expand All @@ -86,7 +86,7 @@ class PhotoHandlerTest {

@Test
fun testPhoto_Blob() {
val blob = IOUtils.resourceToByteArray("/small.jpg")
val blob = TestUtils.resourceToByteArray("/small.jpg")
val contact = Contact()
PhotoHandler(null).handle(ContentValues().apply {
put(Photo.PHOTO, blob)
Expand All @@ -98,7 +98,7 @@ class PhotoHandlerTest {
fun testPhoto_FileId() {
val contact = Contact().apply {
displayName = "Contact with photo"
photo = IOUtils.resourceToByteArray("/large.jpg")
photo = TestUtils.resourceToByteArray("/large.jpg")
}
val androidContact = AndroidContact(addressBook, contact, null, null)
val rawContactId = ContentUris.parseId(androidContact.add())
Expand Down
6 changes: 3 additions & 3 deletions lib/src/main/java/at/bitfire/vcard4android/AndroidContact.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@ import android.provider.ContactsContract.RawContacts.Data
import androidx.annotation.CallSuper
import at.bitfire.vcard4android.contactrow.ContactProcessor
import at.bitfire.vcard4android.contactrow.PhotoBuilder
import org.apache.commons.lang3.builder.ToStringBuilder
import java.io.FileNotFoundException

open class AndroidContact(
open val addressBook: AndroidAddressBook<out AndroidContact, out AndroidGroup>
open val addressBook: AndroidAddressBook<out AndroidContact, out AndroidGroup>
) {

companion object {
Expand Down Expand Up @@ -214,6 +213,7 @@ open class AndroidContact(

protected fun dataSyncURI() = addressBook.syncAdapterURI(ContactsContract.Data.CONTENT_URI)

override fun toString() = ToStringBuilder.reflectionToString(this)!!
override fun toString() =
"AndroidContact(id=$id, fileName=$fileName, eTag=$eTag, _contact=$_contact)"

}
6 changes: 3 additions & 3 deletions lib/src/main/java/at/bitfire/vcard4android/AndroidGroup.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,10 @@ import android.provider.ContactsContract.Groups
import android.provider.ContactsContract.RawContacts
import android.provider.ContactsContract.RawContacts.Data
import androidx.annotation.CallSuper
import org.apache.commons.lang3.builder.ToStringBuilder
import java.io.FileNotFoundException

open class AndroidGroup(
val addressBook: AndroidAddressBook<out AndroidContact, out AndroidGroup>
val addressBook: AndroidAddressBook<out AndroidContact, out AndroidGroup>
) {

companion object {
Expand Down Expand Up @@ -164,6 +163,7 @@ open class AndroidGroup(
return addressBook.syncAdapterURI(ContentUris.withAppendedId(Groups.CONTENT_URI, id))
}

override fun toString() = ToStringBuilder.reflectionToString(this)!!
override fun toString() =
"AndroidGroup(id=$id, fileName=$fileName, eTag=$eTag, _contact=$_contact)"

}
74 changes: 31 additions & 43 deletions lib/src/main/java/at/bitfire/vcard4android/Contact.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ import ezvcard.VCardVersion
import ezvcard.io.json.JCardReader
import ezvcard.io.text.VCardReader
import ezvcard.property.*
import org.apache.commons.lang3.builder.HashCodeBuilder
import org.apache.commons.lang3.builder.ReflectionToStringBuilder
import java.io.IOException
import java.io.OutputStream
import java.io.Reader
Expand All @@ -29,51 +27,50 @@ import java.util.*
*
* [Contact]s are written to and read from the Android storage by [AndroidContact].
*/
class Contact {

var uid: String? = null
var group = false
data class Contact(
var uid: String? = null,
var group: Boolean = false,

/** list of UIDs of group members without urn:uuid prefix (only meaningful if [group] is true) */
val members = mutableSetOf<String>()
val members: MutableSet<String> = mutableSetOf(),

var displayName: String? = null
var prefix: String? = null
var givenName: String? = null
var middleName: String? = null
var familyName: String? = null
var suffix: String? = null
var displayName: String? = null,
var prefix: String? = null,
var givenName: String? = null,
var middleName: String? = null,
var familyName: String? = null,
var suffix: String? = null,

var phoneticGivenName: String? = null
var phoneticMiddleName: String? = null
var phoneticFamilyName: String? = null
var phoneticGivenName: String? = null,
var phoneticMiddleName: String? = null,
var phoneticFamilyName: String? = null,

/** vCard NICKNAME – Android only supports one nickname **/
var nickName: LabeledProperty<Nickname>? = null
var nickName: LabeledProperty<Nickname>? = null,

var organization: Organization? = null
var jobTitle: String? = null // vCard TITLE
var jobDescription: String? = null // vCard ROLE
var organization: Organization? = null,
var jobTitle: String? = null, // vCard TITLE
var jobDescription: String? = null, // vCard ROLE

val phoneNumbers = LinkedList<LabeledProperty<Telephone>>()
val emails = LinkedList<LabeledProperty<Email>>()
val impps = LinkedList<LabeledProperty<Impp>>()
val addresses = LinkedList<LabeledProperty<Address>>()
val categories = LinkedList<String>()
val urls = LinkedList<LabeledProperty<Url>>()
val relations = LinkedList<Related>()
val phoneNumbers: LinkedList<LabeledProperty<Telephone>> = LinkedList(),
val emails: LinkedList<LabeledProperty<Email>> = LinkedList(),
val impps: LinkedList<LabeledProperty<Impp>> = LinkedList(),
val addresses: LinkedList<LabeledProperty<Address>> = LinkedList(),
val categories: LinkedList<String> = LinkedList(),
val urls: LinkedList<LabeledProperty<Url>> = LinkedList(),
val relations: LinkedList<Related> = LinkedList(),

var note: String? = null
var note: String? = null,

var anniversary: Anniversary? = null
var birthDay: Birthday? = null
val customDates = LinkedList<LabeledProperty<XAbDate>>()
var anniversary: Anniversary? = null,
var birthDay: Birthday? = null,
val customDates: LinkedList<LabeledProperty<XAbDate>> = LinkedList(),

var photo: ByteArray? = null
var photo: ByteArray? = null,

/** unknown properties in text vCard format */
var unknownProperties: String? = null

) {

companion object {
// productID (if set) will be used to generate a PRODID property.
Expand Down Expand Up @@ -143,22 +140,13 @@ class Contact {
/* unknownProperties */
)

override fun hashCode(): Int {
val builder = HashCodeBuilder(29, 3).append(compareFields())
return builder.toHashCode()
}

override fun equals(other: Any?) =
if (other is Contact)
compareFields().contentDeepEquals(other.compareFields())
else
false

override fun toString(): String {
val builder = ReflectionToStringBuilder(this)
builder.setExcludeFieldNames("photo")
return builder.toString()
}
override fun hashCode() = compareFields().contentHashCode()


interface Downloader {
Expand Down
30 changes: 15 additions & 15 deletions lib/src/main/java/at/bitfire/vcard4android/ContactReader.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@

package at.bitfire.vcard4android

import at.bitfire.vcard4android.Utils.trimToNull
import at.bitfire.vcard4android.property.*
import at.bitfire.vcard4android.property.CustomScribes.registerCustomScribes
import ezvcard.Ezvcard
import ezvcard.VCard
import ezvcard.parameter.RelatedType
import ezvcard.property.*
import ezvcard.util.PartialDate
import org.apache.commons.lang3.StringUtils
import java.net.URI
import java.net.URISyntaxException
import java.time.Instant
Expand Down Expand Up @@ -105,7 +105,7 @@ class ContactReader internal constructor(val vCard: VCard, val downloader: Conta
uriString
}

return StringUtils.trimToNull(uid)
return uid?.trimToNull()
}

}
Expand All @@ -131,20 +131,20 @@ class ContactReader internal constructor(val vCard: VCard, val downloader: Conta
uriToUid(prop.uri)?.let { c.members += it }

is FormattedName ->
c.displayName = StringUtils.trimToNull(prop.value)
ArnyminerZ marked this conversation as resolved.
Show resolved Hide resolved
c.displayName = prop.value?.trimToNull()
is StructuredName -> {
c.prefix = StringUtils.trimToNull(prop.prefixes.joinToString(" "))
c.givenName = StringUtils.trimToNull(prop.given)
c.middleName = StringUtils.trimToNull(prop.additionalNames.joinToString(" "))
c.familyName = StringUtils.trimToNull(prop.family)
c.suffix = StringUtils.trimToNull(prop.suffixes.joinToString(" "))
c.prefix = prop.prefixes.joinToString(" ").trimToNull()
c.givenName = prop.given?.trimToNull()
c.middleName = prop.additionalNames.joinToString(" ").trimToNull()
c.familyName = prop.family?.trimToNull()
c.suffix = prop.suffixes.joinToString(" ").trimToNull()
}
is XPhoneticFirstName ->
c.phoneticGivenName = StringUtils.trimToNull(prop.value)
c.phoneticGivenName = prop.value?.trimToNull()
is XPhoneticMiddleName ->
c.phoneticMiddleName = StringUtils.trimToNull(prop.value)
c.phoneticMiddleName = prop.value?.trimToNull()
is XPhoneticLastName ->
c.phoneticFamilyName = StringUtils.trimToNull(prop.value)
c.phoneticFamilyName = prop.value?.trimToNull()
is Nickname ->
c.nickName = LabeledProperty(prop, findAndRemoveLabel(prop.group))

Expand All @@ -154,9 +154,9 @@ class ContactReader internal constructor(val vCard: VCard, val downloader: Conta
is Organization ->
c.organization = prop
is Title ->
c.jobTitle = StringUtils.trimToNull(prop.value)
c.jobTitle = prop.value?.trimToNull()
is Role ->
c.jobDescription = StringUtils.trimToNull(prop.value)
c.jobDescription = prop.value?.trimToNull()

is Telephone ->
if (!prop.text.isNullOrBlank())
Expand Down Expand Up @@ -252,7 +252,7 @@ class ContactReader internal constructor(val vCard: VCard, val downloader: Conta
}

is Note -> {
StringUtils.trimToNull(prop.value)?.let { note ->
prop.value.trimToNull()?.let { note ->
if (c.note == null)
c.note = note
else
Expand Down Expand Up @@ -324,7 +324,7 @@ class ContactReader internal constructor(val vCard: VCard, val downloader: Conta
for (label in vCard.getProperties(XAbLabel::class.java)) {
if (label.group.equals(group, true)) {
vCard.removeProperty(label)
return StringUtils.trimToNull(label.value)
return label.value.trimToNull()
}
}

Expand Down
13 changes: 6 additions & 7 deletions lib/src/main/java/at/bitfire/vcard4android/ContactWriter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

package at.bitfire.vcard4android

import at.bitfire.vcard4android.Utils.capitalize
import at.bitfire.vcard4android.Utils.isEmpty
import at.bitfire.vcard4android.Utils.trimToNull
import at.bitfire.vcard4android.property.*
import at.bitfire.vcard4android.property.CustomScribes.registerCustomScribes
import ezvcard.Ezvcard
Expand All @@ -15,13 +17,8 @@ import ezvcard.io.text.VCardWriter
import ezvcard.parameter.ImageType
import ezvcard.parameter.RelatedType
import ezvcard.property.*
import org.apache.commons.lang3.StringUtils
import org.apache.commons.text.WordUtils
import java.io.OutputStream
import java.time.Instant
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.temporal.ChronoField
import java.util.*
import java.util.logging.Level

Expand Down Expand Up @@ -128,7 +125,7 @@ class ContactWriter private constructor(val contact: Contact, val version: VCard
// vCard 4 REQUIRES FN [RFC 6350 6.2.1 FN]
val fn =
// use display name, if available
StringUtils.trimToNull(contact.displayName) ?:
contact.displayName.trimToNull() ?:
// no display name, try organization
contact.organization?.values?.joinToString(" / ") ?:
// otherwise, try nickname
Expand Down Expand Up @@ -201,7 +198,9 @@ class ContactWriter private constructor(val contact: Contact, val version: VCard
if (relation.types.isEmpty())
name.addParameter("TYPE", "other")
else
label = relation.types.joinToString(", ") { type -> WordUtils.capitalize(type.value) }
label = relation.types.joinToString(", ") { type ->
type.value.capitalize()
}
}
}

Expand Down
Loading