Skip to content

Commit 4d323a5

Browse files
committed
Parse catalogs and images.
1 parent 64d88c0 commit 4d323a5

File tree

8 files changed

+39313
-8
lines changed

8 files changed

+39313
-8
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package org.thepalaceproject.opds2.core
2+
3+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
4+
import com.fasterxml.jackson.annotation.JsonProperty
5+
6+
/**
7+
* The OPDS 2.0 catalog section.
8+
*/
9+
10+
@JsonIgnoreProperties(ignoreUnknown = true)
11+
data class O2Catalog(
12+
13+
/**
14+
* The catalog metadata.
15+
*/
16+
17+
@JsonProperty(
18+
value = "metadata",
19+
required = true
20+
)
21+
val metadata : O2Metadata,
22+
23+
/**
24+
* The set of catalog links.
25+
*/
26+
27+
@JsonProperty(
28+
value = "links"
29+
)
30+
val links : List<O2Link> = listOf(),
31+
32+
/**
33+
* The set of image links.
34+
*/
35+
36+
@JsonProperty(
37+
value = "images"
38+
)
39+
val images : List<O2Link> = listOf()
40+
) : O2Element()

org.thepalaceproject.opds2.core/src/main/kotlin/org/thepalaceproject/opds2/core/O2Feed.kt

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,20 @@ data class O2Feed @JsonCreator constructor(
3939
val links : List<O2Link> = listOf(),
4040

4141
/**
42-
* The feed links
42+
* The feed publications
4343
*/
4444

4545
@JsonProperty(
4646
value = "publications"
4747
)
48-
val publications : List<O2Publication> = listOf()
48+
val publications : List<O2Publication> = listOf(),
49+
50+
/**
51+
* The feed catalogs
52+
*/
53+
54+
@JsonProperty(
55+
value = "catalogs"
56+
)
57+
val catalogs : List<O2Catalog> = listOf()
4958
) : O2Element()

org.thepalaceproject.opds2.core/src/main/kotlin/org/thepalaceproject/opds2/core/O2LinkDeserializer.kt

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import com.fasterxml.jackson.databind.DeserializationContext
77
import com.fasterxml.jackson.databind.deser.std.StdDeserializer
88
import one.irradia.mime.api.MIMEType
99
import java.net.URI
10+
import java.net.URISyntaxException
11+
1012

1113
class O2LinkDeserializer : StdDeserializer<O2Link>(O2Link::class.java) {
1214

@@ -36,11 +38,48 @@ class O2LinkDeserializer : StdDeserializer<O2Link>(O2Link::class.java) {
3638
relation = raw.relation
3739
)
3840
} else {
39-
O2LinkBasic(
40-
href = URI.create(raw.href),
41-
type = raw.type,
42-
relation = raw.relation
43-
)
41+
val input = raw.href
42+
43+
try {
44+
return O2LinkBasic(
45+
href = URI(raw.href),
46+
type = raw.type,
47+
relation = raw.relation
48+
)
49+
} catch (_ : URISyntaxException) {
50+
val colon : Int =
51+
input.indexOf(':')
52+
if (colon <= 0) {
53+
throw URISyntaxException(input, "Missing scheme")
54+
}
55+
56+
val scheme =
57+
input.take(colon)
58+
val sspAndFrag =
59+
input.substring(colon + 1)
60+
val hash =
61+
sspAndFrag.indexOf('#')
62+
63+
val schemeSpecific =
64+
if (hash >= 0) {
65+
sspAndFrag.take(hash)
66+
} else {
67+
sspAndFrag
68+
}
69+
70+
val frag =
71+
if (hash >= 0) {
72+
sspAndFrag.substring(hash + 1)
73+
} else {
74+
null
75+
}
76+
77+
return O2LinkBasic(
78+
href = URI(scheme, schemeSpecific, frag),
79+
type = raw.type,
80+
relation = raw.relation
81+
)
82+
}
4483
}
4584
}
4685
}

org.thepalaceproject.opds2.core/src/main/kotlin/org/thepalaceproject/opds2/core/O2Module.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ object O2Module {
1616
.allowClass(Double::class.javaPrimitiveType)
1717
.allowClass(Int::class.javaPrimitiveType)
1818
.allowClass(MIMEType::class.java)
19+
.allowClass(O2Catalog::class.java)
1920
.allowClass(O2Feed::class.java)
2021
.allowClass(O2Link::class.java)
2122
.allowClass(O2LinkDeserializer.O2LinkRaw::class.java)
@@ -28,6 +29,7 @@ object O2Module {
2829
.allowClass(String::class.java)
2930
.allowClass(URI::class.java)
3031
.allowClassName("java.util.List<java.lang.String>")
32+
.allowClassName("java.util.List<org.thepalaceproject.opds2.core.O2Catalog>")
3133
.allowClassName("java.util.List<org.thepalaceproject.opds2.core.O2Link>")
3234
.allowClassName("java.util.List<org.thepalaceproject.opds2.core.O2NavigationLink>")
3335
.allowClassName("java.util.List<org.thepalaceproject.opds2.core.O2Publication>")

org.thepalaceproject.opds2.core/src/main/kotlin/org/thepalaceproject/opds2/core/O2Publication.kt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,14 @@ data class O2Publication @JsonCreator constructor(
2828
@JsonProperty(
2929
value = "links"
3030
)
31-
val links : List<O2Link> = listOf()
31+
val links : List<O2Link> = listOf(),
32+
33+
/**
34+
* The set of image links.
35+
*/
36+
37+
@JsonProperty(
38+
value = "images"
39+
)
40+
val images : List<O2Link> = listOf()
3241
) : O2Element()

org.thepalaceproject.opds2.tests/pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@
3434
<groupId>org.slf4j</groupId>
3535
<artifactId>slf4j-api</artifactId>
3636
</dependency>
37+
<dependency>
38+
<groupId>ch.qos.logback</groupId>
39+
<artifactId>logback-classic</artifactId>
40+
</dependency>
3741

3842
<dependency>
3943
<groupId>net.jqwik</groupId>

org.thepalaceproject.opds2.tests/src/main/kotlin/org/thepalaceproject/opds2/tests/O2FeedTest.kt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.thepalaceproject.opds2.tests
22

33
import com.fasterxml.jackson.databind.json.JsonMapper
4+
import org.junit.jupiter.api.Assertions.assertEquals
45
import org.junit.jupiter.api.BeforeEach
56
import org.junit.jupiter.api.Test
67
import org.junit.jupiter.api.io.TempDir
@@ -30,6 +31,23 @@ class O2FeedTest {
3031
this.resource("groups-20250821.json"),
3132
O2Feed::class.java
3233
)
34+
35+
assertEquals(0, feed.catalogs.size)
36+
assertEquals(14, feed.links.size)
37+
assertEquals(217, feed.publications.size)
38+
}
39+
40+
@Test
41+
fun testRegistry20250826() {
42+
val feed =
43+
this.mapper.readValue<O2Feed>(
44+
this.resource("registry-20250826.json"),
45+
O2Feed::class.java
46+
)
47+
48+
assertEquals(708, feed.catalogs.size)
49+
assertEquals(4, feed.links.size)
50+
assertEquals(0, feed.publications.size)
3351
}
3452

3553
private fun resource(

0 commit comments

Comments
 (0)