@@ -16,16 +16,13 @@ import org.readium.r2.shared.publication.encryption.encryption
16
16
import org.readium.r2.shared.publication.flatten
17
17
import org.readium.r2.shared.publication.protection.ContentProtection
18
18
import org.readium.r2.shared.publication.services.contentProtectionServiceFactory
19
- import org.readium.r2.shared.resource.ArchiveFactory
20
19
import org.readium.r2.shared.resource.Resource
21
- import org.readium.r2.shared.resource.ResourceFactory
22
20
import org.readium.r2.shared.resource.TransformingContainer
21
+ import org.readium.r2.shared.util.AbsoluteUrl
23
22
import org.readium.r2.shared.util.ThrowableError
24
23
import org.readium.r2.shared.util.Try
25
- import org.readium.r2.shared.util.Url
26
24
import org.readium.r2.shared.util.flatMap
27
25
import org.readium.r2.shared.util.getOrElse
28
- import org.readium.r2.shared.util.toFile
29
26
30
27
internal class LcpContentProtection (
31
28
private val lcpService : LcpService ,
@@ -46,7 +43,7 @@ internal class LcpContentProtection(
46
43
credentials : String? ,
47
44
allowUserInteraction : Boolean ,
48
45
sender : Any?
49
- ): Try <ContentProtection .Asset , Publication .OpeningException > {
46
+ ): Try <ContentProtection .Asset , Publication .OpenError > {
50
47
return when (asset) {
51
48
is Asset .Container -> openPublication(asset, credentials, allowUserInteraction, sender)
52
49
is Asset .Resource -> openLicense(asset, credentials, allowUserInteraction, sender)
@@ -58,7 +55,7 @@ internal class LcpContentProtection(
58
55
credentials : String? ,
59
56
allowUserInteraction : Boolean ,
60
57
sender : Any?
61
- ): Try <ContentProtection .Asset , Publication .OpeningException > {
58
+ ): Try <ContentProtection .Asset , Publication .OpenError > {
62
59
val license = retrieveLicense(asset, credentials, allowUserInteraction, sender)
63
60
return createResultAsset(asset, license)
64
61
}
@@ -73,27 +70,13 @@ internal class LcpContentProtection(
73
70
?.let { LcpPassphraseAuthentication (it, fallback = this .authentication) }
74
71
? : this .authentication
75
72
76
- val file = (asset as ? Asset .Resource )?.resource?.source?.toFile()
77
- ? : (asset as ? Asset .Container )?.container?.source?.toFile()
78
-
79
- return file
80
- // This is less restrictive with regard to network availability.
81
- ?.let {
82
- lcpService.retrieveLicense(
83
- it,
84
- asset.mediaType,
85
- authentication,
86
- allowUserInteraction,
87
- sender
88
- )
89
- }
90
- ? : lcpService.retrieveLicense(asset, authentication, allowUserInteraction, sender)
73
+ return lcpService.retrieveLicense(asset, authentication, allowUserInteraction, sender)
91
74
}
92
75
93
76
private fun createResultAsset (
94
77
asset : Asset .Container ,
95
78
license : Try <LcpLicense , LcpException >
96
- ): Try <ContentProtection .Asset , Publication .OpeningException > {
79
+ ): Try <ContentProtection .Asset , Publication .OpenError > {
97
80
val serviceFactory = LcpContentProtectionService
98
81
.createFactory(license.getOrNull(), license.failureOrNull())
99
82
@@ -107,7 +90,9 @@ internal class LcpContentProtection(
107
90
onCreatePublication = {
108
91
decryptor.encryptionData = (manifest.readingOrder + manifest.resources + manifest.links)
109
92
.flatten()
110
- .mapNotNull { it.properties.encryption?.let { enc -> it.href to enc } }
93
+ .mapNotNull {
94
+ it.properties.encryption?.let { enc -> it.url() to enc }
95
+ }
111
96
.toMap()
112
97
113
98
servicesBuilder.contentProtectionServiceFactory = serviceFactory
@@ -122,7 +107,7 @@ internal class LcpContentProtection(
122
107
credentials : String? ,
123
108
allowUserInteraction : Boolean ,
124
109
sender : Any?
125
- ): Try <ContentProtection .Asset , Publication .OpeningException > {
110
+ ): Try <ContentProtection .Asset , Publication .OpenError > {
126
111
val license = retrieveLicense(licenseAsset, credentials, allowUserInteraction, sender)
127
112
128
113
val licenseDoc = license.getOrNull()?.license
@@ -132,9 +117,7 @@ internal class LcpContentProtection(
132
117
LicenseDocument (it)
133
118
} catch (e: Exception ) {
134
119
return Try .failure(
135
- Publication .OpeningException .ParsingFailed (
136
- ThrowableError (e)
137
- )
120
+ Publication .OpenError .InvalidAsset (cause = ThrowableError (e))
138
121
)
139
122
}
140
123
}
@@ -145,55 +128,64 @@ internal class LcpContentProtection(
145
128
}
146
129
147
130
val link = checkNotNull(licenseDoc.link(LicenseDocument .Rel .Publication ))
148
- val url = Url (link.url.toString() )
131
+ val url = (link.url() as ? AbsoluteUrl )
149
132
? : return Try .failure(
150
- Publication .OpeningException . ParsingFailed (
151
- ThrowableError (
133
+ Publication .OpenError . InvalidAsset (
134
+ cause = ThrowableError (
152
135
LcpException .Parsing .Url (rel = LicenseDocument .Rel .Publication .value)
153
136
)
154
137
)
155
138
)
156
139
157
- return assetRetriever.retrieve(
158
- url,
159
- mediaType = link.mediaType,
160
- assetType = AssetType .Archive
161
- )
162
- .mapFailure { Publication .OpeningException .ParsingFailed (it) }
163
- .flatMap { createResultAsset(it as Asset .Container , license) }
164
- }
165
-
166
- private fun ResourceFactory.Error.wrap (): Publication .OpeningException =
167
- when (this ) {
168
- is ResourceFactory .Error .NotAResource ->
169
- Publication .OpeningException .NotFound ()
170
- is ResourceFactory .Error .Forbidden ->
171
- Publication .OpeningException .Forbidden ()
172
- is ResourceFactory .Error .SchemeNotSupported ->
173
- Publication .OpeningException .UnsupportedAsset ()
174
- }
140
+ val asset =
141
+ if (link.mediaType != null ) {
142
+ assetRetriever.retrieve(
143
+ url,
144
+ mediaType = link.mediaType,
145
+ assetType = AssetType .Archive
146
+ )
147
+ .map { it as Asset .Container }
148
+ .mapFailure { it.wrap() }
149
+ } else {
150
+ (assetRetriever.retrieve(url) as ? Asset .Container )
151
+ ?.let { Try .success(it) }
152
+ ? : Try .failure(Publication .OpenError .UnsupportedAsset ())
153
+ }
175
154
176
- private fun ArchiveFactory.Error.wrap (): Publication .OpeningException =
177
- when (this ) {
178
- is ArchiveFactory .Error .FormatNotSupported ->
179
- Publication .OpeningException .UnsupportedAsset ()
180
- is ArchiveFactory .Error .PasswordsNotSupported ->
181
- Publication .OpeningException .UnsupportedAsset ()
182
- is ArchiveFactory .Error .ResourceReading ->
183
- resourceException.wrap()
184
- }
155
+ return asset.flatMap { createResultAsset(it, license) }
156
+ }
185
157
186
- private fun Resource.Exception.wrap (): Publication .OpeningException =
158
+ private fun Resource.Exception.wrap (): Publication .OpenError =
187
159
when (this ) {
188
160
is Resource .Exception .Forbidden ->
189
- Publication .OpeningException .Forbidden (ThrowableError (this ))
161
+ Publication .OpenError .Forbidden (ThrowableError (this ))
190
162
is Resource .Exception .NotFound ->
191
- Publication .OpeningException .NotFound (ThrowableError (this ))
163
+ Publication .OpenError .NotFound (ThrowableError (this ))
192
164
Resource .Exception .Offline , is Resource .Exception .Unavailable ->
193
- Publication .OpeningException .Unavailable (ThrowableError (this ))
165
+ Publication .OpenError .Unavailable (ThrowableError (this ))
194
166
is Resource .Exception .Other , is Resource .Exception .BadRequest ->
195
- Publication .OpeningException . Unexpected (this )
167
+ Publication .OpenError . Unknown (this )
196
168
is Resource .Exception .OutOfMemory ->
197
- Publication .OpeningException .OutOfMemory (ThrowableError (this ))
169
+ Publication .OpenError .OutOfMemory (ThrowableError (this ))
170
+ }
171
+
172
+ private fun AssetRetriever.Error.wrap (): Publication .OpenError =
173
+ when (this ) {
174
+ is AssetRetriever .Error .ArchiveFormatNotSupported ->
175
+ Publication .OpenError .UnsupportedAsset (this )
176
+ is AssetRetriever .Error .Forbidden ->
177
+ Publication .OpenError .Forbidden (this )
178
+ is AssetRetriever .Error .InvalidAsset ->
179
+ Publication .OpenError .InvalidAsset (this )
180
+ is AssetRetriever .Error .NotFound ->
181
+ Publication .OpenError .NotFound (this )
182
+ is AssetRetriever .Error .OutOfMemory ->
183
+ Publication .OpenError .OutOfMemory (this )
184
+ is AssetRetriever .Error .SchemeNotSupported ->
185
+ Publication .OpenError .UnsupportedAsset (this )
186
+ is AssetRetriever .Error .Unavailable ->
187
+ Publication .OpenError .Unavailable (this )
188
+ is AssetRetriever .Error .Unknown ->
189
+ Publication .OpenError .Unknown (this )
198
190
}
199
191
}
0 commit comments