├── .gitignore
├── README.md
├── buildspec.yml
├── config
└── logback.xml
├── pom.xml
├── profiles
└── commonreleasetypes
│ ├── 13
│ ├── AudioAlbumMusicAndSpeech.xsl
│ ├── AudioAlbumMusicOnly.xsl
│ ├── AudioBook.xsl
│ ├── AudioSingle.xsl
│ ├── BusinessProfile.xsl
│ ├── DigitalBoxedSet.xsl
│ ├── DigitalClassicalAudioAlbum.xsl
│ ├── FilmBundle.xsl
│ ├── LongformVideo.xsl
│ ├── MidiRingtone.xsl
│ ├── MixedMediaBundle.xsl
│ ├── ReleaseProfileDeletedRules.xsl
│ ├── Ringtone.xsl
│ ├── SimpleVideoSingle.xsl
│ ├── SingleResourceRelease.xsl
│ ├── SingleResourceWithCoverArt.xsl
│ ├── TVSeries.xsl
│ ├── VideoAlbum.xsl
│ ├── VideoSingle.xsl
│ └── Wallpaper.xsl
│ ├── 14
│ ├── AudioAlbum.xsl
│ ├── AudioAlbumMusicOnly.xsl
│ ├── AudioBook.xsl
│ ├── AudioSingle.xsl
│ ├── BusinessProfile.xsl
│ ├── DigitalBoxedSet.xsl
│ ├── DigitalClassicalAudioAlbum.xsl
│ ├── FilmBundle.xsl
│ ├── LongformVideo.xsl
│ ├── MidiRingtone.xsl
│ ├── MixedMediaBundle.xsl
│ ├── Ringtone.xsl
│ ├── SimpleVideoSingle.xsl
│ ├── SingleResourceRelease.xsl
│ ├── SingleResourceReleaseWithCoverArt.xsl
│ ├── TVSeries.xsl
│ ├── VideoAlbum.xsl
│ └── VideoSingle.xsl
│ └── 21
│ ├── Audio.xsl
│ ├── BoxedSetVariant.xsl
│ ├── ClassicalVariant.xsl
│ ├── DjMix.xsl
│ ├── LongFormMusicalWorkVideo.xsl
│ ├── MixedMedia.xsl
│ ├── ReleaseProfileTrackReleaseRules.xsl
│ ├── Ringtone.xsl
│ ├── SimpleAudioSingle.xsl
│ ├── SimpleVideoSingle.xsl
│ ├── Video.xsl
│ └── release-notification-avs.sch.xsl
├── schema
├── ERN-2454 - MEAD XSD.zip
├── ddex.xsd
├── ddexC.xsd
├── ern
│ ├── 41
│ │ ├── avs4.xsd
│ │ └── release-notification.xsd
│ ├── 341
│ │ ├── ddex.xsd
│ │ ├── ddexC.xsd
│ │ ├── iso3166a2.xsd
│ │ ├── iso4217a.xsd
│ │ ├── iso639a2.xsd
│ │ └── release-notification.xsd
│ ├── 371
│ │ ├── avs_20161006.xsd
│ │ ├── ddex.xsd
│ │ ├── ddexC.xsd
│ │ ├── iso3166a2.xsd
│ │ ├── iso4217a.xsd
│ │ ├── iso639a2.xsd
│ │ └── release-notification.xsd
│ ├── 382
│ │ ├── avs_20161006.xsd
│ │ ├── ddex.xsd
│ │ ├── ddexC.xsd
│ │ ├── iso3166a2.xsd
│ │ ├── iso4217a.xsd
│ │ ├── iso639a2.xsd
│ │ └── release-notification.xsd
│ ├── 383
│ │ ├── avs383.xsd
│ │ └── release-notification.xsd
│ └── 411
│ │ ├── avs411.xsd
│ │ └── release-notification.xsd
├── iso3166a2.xsd
├── iso4217a.xsd
├── iso639a2.xsd
├── mead
│ └── 10
│ │ ├── avs3.xsd
│ │ └── media-enrichment-and-description.xsd
├── mlc
│ ├── 14
│ │ ├── mlc-avs.xsd
│ │ └── music-licensing-companies.xsd
│ └── 131
│ │ ├── avs_20161219.xsd
│ │ └── music-licensing-companies.xsd
├── release-notification.xsd
├── rin full
│ └── 11
│ │ ├── avs4.xsd
│ │ └── full-recording-information-notification.xsd
└── rin
│ └── 11
│ ├── avs4.xsd
│ └── full-recording-information-notification.xsd
└── src
└── main
├── assembly
└── bin.xml
├── java
└── net
│ └── ddex
│ └── ern
│ ├── config
│ ├── AppConfig.java
│ └── WebMvcConfig.java
│ ├── controller
│ └── ValidateController.java
│ ├── exception
│ ├── ErrorResponse.java
│ ├── ExceptionControllerAdvice.java
│ └── ValidatorException.java
│ ├── initializer
│ └── EmbeddedJetty.java
│ ├── schema
│ ├── Schema.java
│ ├── SchemaFactory.java
│ ├── SchemaValidator.java
│ ├── ThreeFourOneSchema.java
│ └── ThreeSevenOneSchema.java
│ ├── service
│ ├── SchemaService.java
│ └── SchematronService.java
│ ├── util
│ └── SchemaBuilder.java
│ └── vo
│ ├── ValidationResponse.java
│ └── ValidationResult.java
├── resources
├── application.properties
└── logback.xml
└── schematron
├── commonreleasetypes
├── 14
│ ├── NewReleaseMessage_BusinessProfile_14.sch
│ ├── NewReleaseMessage_ReleaseProfile_AudioAlbumMusicOnly_14.sch
│ ├── NewReleaseMessage_ReleaseProfile_AudioAlbum_14.sch
│ ├── NewReleaseMessage_ReleaseProfile_AudioBook_14.sch
│ ├── NewReleaseMessage_ReleaseProfile_AudioSingle_14.sch
│ ├── NewReleaseMessage_ReleaseProfile_DigitalBoxedSet_14.sch
│ ├── NewReleaseMessage_ReleaseProfile_DigitalClassicalAudioAlbum_14.sch
│ ├── NewReleaseMessage_ReleaseProfile_FilmBundle_14.sch
│ ├── NewReleaseMessage_ReleaseProfile_LongformVideo_14.sch
│ ├── NewReleaseMessage_ReleaseProfile_MidiRingtone_14.sch
│ ├── NewReleaseMessage_ReleaseProfile_MixedMediaBundle_14.sch
│ ├── NewReleaseMessage_ReleaseProfile_Ringtone_14.sch
│ ├── NewReleaseMessage_ReleaseProfile_SimpleVideoSingle_14.sch
│ ├── NewReleaseMessage_ReleaseProfile_SingleResourceReleaseWithCoverArt_14.sch
│ ├── NewReleaseMessage_ReleaseProfile_SingleResourceRelease_14.sch
│ ├── NewReleaseMessage_ReleaseProfile_TVSeries_14.sch
│ ├── NewReleaseMessage_ReleaseProfile_VideoAlbum_14.sch
│ └── NewReleaseMessage_ReleaseProfile_VideoSingle_14.sch
└── 21
│ ├── NewReleaseMessage_ReleaseProfile_Audio_21.sch
│ ├── NewReleaseMessage_ReleaseProfile_BoxedSetVariant_21.sch
│ ├── NewReleaseMessage_ReleaseProfile_ClassicalVariant_21.sch
│ ├── NewReleaseMessage_ReleaseProfile_DjMix_21.sch
│ ├── NewReleaseMessage_ReleaseProfile_LongFormMusicalWorkVideo_21.sch
│ ├── NewReleaseMessage_ReleaseProfile_MixedMedia_21.sch
│ ├── NewReleaseMessage_ReleaseProfile_ReleaseProfileTrackReleaseRules_21.sch
│ ├── NewReleaseMessage_ReleaseProfile_Ringtone_21.sch
│ ├── NewReleaseMessage_ReleaseProfile_SimpleAudioSingle_21.sch
│ ├── NewReleaseMessage_ReleaseProfile_SimpleVideoSingle_21.sch
│ ├── NewReleaseMessage_ReleaseProfile_Video_21.sch
│ ├── avs.xml
│ ├── release-notification-avs.sch
│ └── release-notification.xsd
├── iso_abstract_expand.xsl
├── iso_dsdl_include.xsl
├── iso_schematron_skeleton_for_saxon.xsl
└── iso_svrl_for_xslt2.xsl
/.gitignore:
--------------------------------------------------------------------------------
1 | # eclipse ignore
2 | .settings/
3 | .project
4 | .classpath
5 | # idea ignore
6 | .idea/
7 | *.ipr
8 | *.iml
9 | *.iws
10 | <<<<<<< HEAD
11 | =======
12 | /target/
13 | *.gz
14 | *.log
15 | 130295703_20171205033227.xml
16 | >>>>>>> sme/rob-local
17 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
DDEX XML Validator
2 | The DDEX Message Validator is an API that provides methods to validate DDEX XML based messages against
3 | the set of active schema versions and profile schematrons.
4 |
5 | Development Requirements
6 |
7 | Windows, Linux or MacOS
8 | Maven
9 | JDK 1.8+
10 |
11 | Building
12 | To build the source execute the following maven targets:
13 | mvn clean install
14 | After execution a file with the name ddex-message-validator-api-1.0-SNAPSHOT-bin.zip will appear in 'target/' directory. Unzip the file and and you will see three folders bin, etc, repo. Within the bin folder you will also see start-api.sh and start-api.bat. In your command line you can start the API by typing the following below.
15 | start-api <port>
16 | If a port is not specified the default port is 6060. The default profile has been set to "dev", this can be changed by setting spring.profiles.active environment variable.
17 | In cases where you are using IntelliJ or Eclipse you can also run it from within your IDE locally.
18 | Try the below URL in your browser to see if the service is running.
19 | localhost:6060/api/status
20 |
21 | Working with the code
22 | If you don't have a personal IDE preference we recommend you use IntelliJ when working with the code. We use the maven assembly and
23 | appassembly plugin for wrapper script packaging support.
24 | Technologies
25 |
26 | Java
27 | Spring
28 | Embedded Jetty
29 | SAX
30 | Logback
31 |
32 | The API uses Spring-WebMVC framework which provides a Model-View-Controller architecture. Having a MVC structure in our application allows for the input logic, business logic, and UI logic to be seperated but still have the flexible ability to loosely couple these elements together.
33 | As an alternative to creating a stand-alone bundled WAR app we have incorporated Embedded Jetty as our application instantiator. By doing this you're able to instantiate Jetty within your Java program.
34 |
35 | Ways to use API
36 |
37 | Curl
38 | DDEX XML Validator React Client
39 |
40 | You can use cURL command line tool to use the API to validate your XML documents.
41 | Schema (XSD) example
42 | curl -X POST -F 'messageSchemaVersionId=ern/341' -F 'messageFile=@location\xml\sme-album.xml' -F 'releaseProfileVersionId=commonreleasetypes/14/AudioAlbumMusicOnly' localhost:6060/api/json/validate
43 |
44 |
--------------------------------------------------------------------------------
/buildspec.yml:
--------------------------------------------------------------------------------
1 | version: 0.2
2 |
3 | env:
4 | variables:
5 | JAVA_HOME: "/usr/lib/jvm/java-8-openjdk-amd64"
6 |
7 | phases:
8 | install:
9 | commands:
10 | - apt-get update -y
11 | - apt-get install -y maven
12 | pre_build:
13 | commands:
14 | - echo Nothing to do in the pre_build phase...
15 | build:
16 | commands:
17 | - echo Build started on `date`
18 | - mvn package
19 | post_build:
20 | commands:
21 | - echo Build completed on `date`
22 | artifacts:
23 | files:
24 | - target/messageUtil-1.0.jar
25 | discard-paths: yes
--------------------------------------------------------------------------------
/config/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
7 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
8 |
9 |
10 |
11 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 | net.ddex
7 | ddex-message-validator-api
8 | 1.0-SNAPSHOT
9 | 2008
10 |
11 |
12 | The Apache Software License, Version 2.0
13 | http://www.apache.org/licenses/LICENSE-2.0.txt
14 | repo
15 |
16 |
17 |
18 |
19 |
20 | org.codehaus.mojo
21 | appassembler-maven-plugin
22 | 1.10
23 |
24 |
25 |
26 | generate-daemons
27 | create-repository
28 |
29 |
30 |
31 |
32 |
33 |
34 | start-api
35 | net.ddex.ern.initializer.EmbeddedJetty
36 |
37 | booter-unix
38 | booter-windows
39 |
40 |
41 |
42 |
43 |
44 |
45 | org.apache.maven.plugins
46 | maven-assembly-plugin
47 | 3.0.0
48 |
49 |
50 | package
51 |
52 | single
53 |
54 |
55 |
56 |
57 |
58 | src/main/assembly/bin.xml
59 |
60 |
61 |
62 |
63 | org.apache.maven.plugins
64 | maven-compiler-plugin
65 | 3.1
66 |
67 | 1.8
68 | 1.8
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 | org.codehaus.mojo.appassembler
79 | appassembler-booter
80 | 1.10
81 |
82 |
83 |
84 |
85 | org.springframework
86 | spring-webmvc
87 | 4.3.7.RELEASE
88 |
89 |
90 |
91 | org.eclipse.jetty
92 | jetty-servlets
93 | 9.4.19.v20190610
94 |
95 |
96 |
97 | org.eclipse.jetty
98 | jetty-server
99 | 9.4.19.v20190610
100 |
101 |
102 |
103 | commons-fileupload
104 | commons-fileupload
105 | 1.4
106 |
107 |
108 |
109 | org.eclipse.jetty
110 | jetty-http
111 | 9.4.19.v20190610
112 |
113 |
114 |
115 |
116 | org.eclipse.jetty
117 | jetty-util
118 | 9.4.19.v20190610
119 |
120 |
121 |
122 |
123 | org.eclipse.jetty
124 | jetty-io
125 | 9.4.19.v20190610
126 |
127 |
128 |
129 | ch.qos.logback
130 | logback-classic
131 | 1.1.7
132 |
133 |
134 | org.slf4j
135 | jcl-over-slf4j
136 | 1.7.21
137 |
138 |
139 |
140 | com.fasterxml.jackson.core
141 | jackson-core
142 | 2.11.0
143 |
144 |
145 |
146 | javax.servlet
147 | jstl
148 | 1.2
149 |
150 |
151 |
152 | com.fasterxml.jackson.core
153 | jackson-databind
154 | [2.9.9,)
155 |
156 |
157 |
158 | net.sf.saxon
159 | Saxon-HE
160 | 9.7.0-15
161 |
162 |
163 |
164 | junit
165 | junit
166 | 4.12
167 | test
168 |
169 |
170 |
171 | org.eclipse.jetty
172 | jetty-servlet
173 | 9.4.12.v20180830
174 |
175 |
176 |
177 |
178 |
179 | UTF-8
180 |
181 |
182 |
183 |
--------------------------------------------------------------------------------
/profiles/commonreleasetypes/14/MidiRingtone.xsl:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | /
47 |
48 |
49 |
50 |
52 | [ ]
53 |
54 |
55 | *[local-name()='
56 |
57 | ']
58 |
60 | [ ]
61 |
62 |
63 |
64 |
65 | /
66 |
67 | @
68 |
69 |
70 | @*[local-name()='
71 |
72 | ' and namespace-uri()='
73 |
74 | ']
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 | /
84 |
85 |
86 | [
87 |
88 | ]
89 |
90 |
91 |
92 | /@
93 |
94 |
95 |
96 |
98 |
99 |
100 | /
101 |
102 |
103 | [
104 |
105 | ]
106 |
107 |
108 |
109 | /@
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 | .
134 |
135 |
136 |
137 |
138 | U
139 |
140 | U
141 |
142 |
143 |
144 | U.
145 |
146 | n
147 |
148 |
149 |
150 | U.
151 |
152 | _
153 |
154 | _
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
165 |
166 |
167 |
168 |
169 |
170 |
171 | © 2006-2017 Digital Data Exchange, LLC (DDEX)
172 | This ISO Schematron file is, together with all DDEX standards, subject to two licences: If
173 | you wish to evaluate whether the standard meets your needs please have a look at the
174 | Evaluation Licence at https://kb.ddex.net/display/HBK/Evaluation+Licence+for+DDEX+Standards.
175 | If you want to implement and use this DDEX standard, please take out an Implementation
176 | Licence. For details please go to http://ddex.net/apply-ddex-implementation-licence.
177 | Failing a rule with a role of 'Fatal Error' means that the Conformance Tester must recommend
178 | to not award a Conformance Certificate or to retract a Conformance Certificate if one has
179 | already been issued. Failing a rule with a role of 'Conditional Fatal Error' is the same as a
180 | 'Fatal Error', however, the rule may be ignored if the Conformance Tester has no means of
181 | asserting whether the condition expressed in the rule has been met.
182 | Failing a rule a rule with a role of 'Error' means that the Conformance Tester must
183 | recommend to award a Partial Conformance Certificate or to downgrade a Conformance Certificate
184 | that has already been issued. However, if more than 1 rules (representing 50% of all rules
185 | with a role of 'Error' or 'Conditional Error') have been failed at least once, the Conformance
186 | Tester must recommend to not award a Conformance Certificate or to retract a Conformance
187 | Certificate if one has already been issued. Failing a rule with a role of 'Conditional Error'
188 | is the same as an 'Error', however, the rule may be ignored if the Conformance Tester has no
189 | means of asserting whether the condition expressed in the rule has been met.
190 | The following Clauses from the Release Profile standard are NOT checked by this ISO
191 | Schematron file: 3.3.1(1), 3.3.1(7)-(8), 3.4, 4.1, 4.2, 4.3(11), 4.3(14), 4.3(15a), 4.3(16b),
192 | 4.3(17), 4.3(19), 4.3(27)-(29), 4.3(37), 4.16(11)-(12), 4.7(11)-(12), 4.8(8), 4.8(9d),
193 | 4.8(10f), 4.8(11)-(12), 4.10(9) and similar clauses, 4.10(10) and similar clauses, 4.14(8) and
194 | 4.15(11).
195 |
196 |
197 |
198 |
199 | Ringtone_ReleaseProfileVersionId
200 | Ringtone_ReleaseProfileVersionId
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 | MultiProfile_TrackReleaseMustNotContainManyResources
209 | MultiProfile_TrackReleaseMustNotContainManyResources
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 | MidiRingtone_MustContainRingtoneComponentRelease
218 | MidiRingtone_MustContainRingtoneComponentRelease
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 | MultiProfile_DisplayArtistMustBeProvided
227 | MultiProfile_DisplayArtistMustBeProvided
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 | MultiProfile_DisplayArtistNamesMustBeDifferent
236 | MultiProfile_DisplayArtistNamesMustBeDifferent
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 | MultiProfile_MainReleaseMustHaveGridOrICPN
245 | MultiProfile_MainReleaseMustHaveGridOrICPN
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 | Ringtone_MustContainReleaseFromRelease
254 | Ringtone_MustContainReleaseFromRelease
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 | MultiProfile_SoundRecordingMustNotHaveDeprecatedFlags
263 | MultiProfile_SoundRecordingMustNotHaveDeprecatedFlags
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 | MultiProfile_LabelNameMustBeProvided2
272 | MultiProfile_LabelNameMustBeProvided2
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 | Schematron Release Profile for Midi Ringtone (version 1.4) for the
281 | NewReleaseMessage.
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
296 | Fatal Error
297 |
298 |
299 |
300 | Fatal Error: #Midi Ringtone) The ReleaseProfileVersionId should be
301 | 'CommonReleaseTypes/14/Ringtone' (Release Profile 1.4, Clause 3.2, Rule
302 | 1364-1).
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
320 |
322 |
323 |
324 |
325 |
327 | Fatal Error
328 |
329 |
330 |
331 | Fatal Error:
332 | #Midi Ringtone) A Track Release must not contain more than one Resource (Release Profile
333 | 1.4, Clause 3.1, Rule 1365-1).
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
350 |
351 |
352 |
353 |
354 |
355 |
357 | Fatal Error
358 |
359 |
360 |
361 | Fatal Error: #Midi Ringtone) A Ringtone must contain one
362 | RingtoneRelease or RingbackToneRelease (Release Profile 1.4, Clause 3.1, Rule
363 | 1366-1).
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
381 |
383 |
384 |
385 |
386 |
387 |
388 |
390 | Fatal Error
391 |
392 |
393 |
394 | Fatal Error:
395 | #Midi Ringtone) At least one DisplayArtist shall be provided (Release Profile 1.4,
396 | Clause 4.3(12c)+4.3(15b), Rule 1367-1).
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
414 |
416 |
417 |
418 |
419 |
421 | Error
422 |
423 |
424 |
425 | Error: #Midi Ringtone) DisplayArtistNames for Release and Resource must be
426 | different (Release Profile 1.4, Clause 4.3(16a), Rule 1368-1).
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
443 |
444 |
445 |
446 |
447 |
448 |
450 | Fatal Error
451 |
452 |
453 |
454 | Fatal Error: #Midi Ringtone) The MainRelease shall be identified by
455 | either a GRid or by an ICPN (Release Profile 1.4, Clause 4.9(4), Rule
456 | 1369-1).
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
474 |
476 |
477 |
478 |
479 |
480 |
481 |
483 | Fatal Error
484 |
485 |
486 |
487 | Fatal Error: #Midi Ringtone) A Ringtone must contain a RelatedRelease
488 | of type IsReleaseFromRelease (Release Profile 1.4, Clause 4.9(9), Rule
489 | 1372-1).
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
507 |
509 |
510 |
511 |
512 |
513 | Information
514 |
515 |
516 |
517 | Information: #Midi Ringtone) No
518 | deprecated Flags (IsHiddenResource) must be provided for SoundRecordings (Release
519 | Profile 1.4, Clause 4.10(7h), Rule 1373-1).
520 |
521 |
522 |
523 |
524 |
525 |
526 | Information
527 |
528 |
529 |
530 | Information: #Midi Ringtone) No
531 | deprecated Flags (IsBonusResource) must be provided for SoundRecordings (Release Profile
532 | 1.4, Clause 4.10(7h), Rule 1373-2).
533 |
534 |
535 |
536 |
537 |
538 |
539 |
540 |
541 |
542 |
543 |
544 |
545 |
546 |
549 |
551 |
552 |
553 |
554 |
555 |
556 |
558 | Fatal Error
559 |
560 |
561 |
562 | Fatal Error: #Midi
563 | Ringtone) A LabelName has to be specified for each Release (Release Profile 1.4,
564 | Clause 4.13(8), Rule 1374-1).
565 |
566 |
567 |
568 |
569 |
570 |
571 |
572 |
573 |
574 |
575 |
--------------------------------------------------------------------------------
/profiles/commonreleasetypes/21/BoxedSetVariant.xsl:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | /
49 |
50 |
51 |
52 |
53 |
54 | *:
55 |
56 | [namespace-uri()='
57 |
58 | ']
59 |
60 |
61 |
63 | [
64 |
65 | ]
66 |
67 |
68 |
69 | /
70 |
71 | @
72 |
73 |
74 | @*[local-name()='
75 |
76 | ' and namespace-uri()='
77 |
78 | ']
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 | /
88 |
89 |
90 | [
91 |
92 | ]
93 |
94 |
95 |
96 | /@
97 |
98 |
99 |
100 |
102 |
103 |
104 | /
105 |
106 |
107 | [
108 |
109 | ]
110 |
111 |
112 |
113 | /@
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 | .
138 |
139 |
140 |
141 |
142 | U
143 |
144 | U
145 |
146 |
147 |
148 | U.
149 |
150 | n
151 |
152 |
153 |
154 | U.
155 |
156 | _
157 |
158 | _
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
169 |
170 |
171 |
172 |
173 |
174 |
175 | © 2006-2018 Digital Data Exchange, LLC (DDEX)
176 | This ISO Schematron file is, together with all DDEX standards, subject to two licences: If you wish to evaluate whether the standard meets your needs please have a look at the Evaluation Licence at https://kb.ddex.net/display/HBK/Evaluation+Licence+for+DDEX+Standards. If you want to implement and use this DDEX standard, please take out an Implementation Licence. For details please go to http://ddex.net/apply-ddex-implementation-licence.
177 | Failing a rule with a role of 'Fatal Error' means that the Conformance Tester must recommend to not award a Conformance Certificate or to retract a Conformance Certificate if one has already been issued. Failing a rule with a role of 'Conditional Fatal Error' is the same as a 'Fatal Error', however, the rule may be ignored if the Conformance Tester has no means of asserting whether the condition expressed in the rule has been met.
178 | Failing a rule a rule with a role of 'Error' means that the Conformance Tester must recommend to award a Partial Conformance Certificate or to downgrade a Conformance Certificate that has already been issued. However, if more than 1 rules (representing 50% of all rules with a role of 'Error') have been failed at least once, the Conformance Tester must recommend to not award a Conformance Certificate or to retract a Conformance Certificate if one has already been issued. Failing a rule with a role of 'Conditional Error' is the same as an 'Error', however, the rule may be ignored if the Conformance Tester has no means of asserting whether the condition expressed in the rule has been met.
179 | The following Clauses from the Release Profile standard are NOT checked by this ISO Schematron file: 5.1.1 (partly), 5.3.1.1(1-3, 7.1, 7.3, 9), 5.3.1.2(2.1, 3-4, 5.1), 5.3.1.3(4-5), 5.3.1.4(3-5, 8), 5.3.3.1-2, 5.3.3.4, 5.4.1(4.1), 5.4.3(5), 5.4.4(3, 5), 5.5.1(2), 5.5.2(2.4, 3.5-3.7), 5.6(1, 3). This file also does not check any rules specified in the ERN Message Suite Standard (Version 4.1) specifications, sections 6.4 and 6.5, except for 6.4.8-10
180 |
181 |
182 |
183 |
184 | BoxedSet_ReleaseProfileVariantVersionId
185 | BoxedSet_ReleaseProfileVariantVersionId
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 | BoxedSet_ResourceGroupType
194 | BoxedSet_ResourceGroupType
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 | BoxedSet_MustContainResourceGroups
203 | BoxedSet_MustContainResourceGroups
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 | BoxedSet_MustContainReleaseId
212 | BoxedSet_MustContainReleaseId
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 | Schematron Release Profile for Boxed Set Variant (version 2.1) for the NewReleaseMessage.
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
235 | Fatal Error
236 |
237 |
238 |
239 | Fatal Error (Boxed Set Variant): The ReleaseProfileVariantVersionId should conform to clause 5.2.2 (Release Profile 2.1, Clause 5.2.2, Rule 1543-1).
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
257 |
259 |
260 |
261 |
262 |
263 |
264 |
266 | Fatal Error
267 |
268 |
269 |
270 | Fatal Error (Boxed Set Variant): For a Release of this type, second-level ResourceGroups shall have a ResourceGroupType of either Side, Component, ComponentRelease or ReleaseComponent (Release Profile 2.1, Clause 5.3.1.2(5.2), Rule 1544-1).
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
288 |
290 |
291 |
292 |
293 |
294 |
295 |
297 | Fatal Error
298 |
299 |
300 |
301 | Fatal Error (Boxed Set Variant): A Release of this type must contain at least two ResourceGroups of type ReleaseComponent (Release Profile 2.1, Clause 5.5.1(1), Rule 1545-1).
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
319 |
321 |
322 |
323 |
324 |
325 |
326 |
327 | Fatal Error
328 |
329 |
330 |
331 | Fatal Error (Boxed Set Variant): The identifier of the 'component' Releases that make up the Boxed Set Release shall be placed into the ReleaseId composite of the relevant ResourceGroup (Release Profile 2.1, Clause 5.5.1(3), Rule 1546-1).
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
342 | Fatal Error
343 |
344 |
345 |
346 | Fatal Error (Boxed Set Variant): The identifier of the 'component' Releases that make up the Boxed Set Release shall be identified by either a GRid or an ICPN (Release Profile 2.1, Clause 5.5.1(3), Rule 1546-2).
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
--------------------------------------------------------------------------------
/profiles/commonreleasetypes/21/ReleaseProfileTrackReleaseRules.xsl:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | /
49 |
50 |
51 |
52 |
53 |
54 | *:
55 |
56 | [namespace-uri()='
57 |
58 | ']
59 |
60 |
61 |
63 | [
64 |
65 | ]
66 |
67 |
68 |
69 | /
70 |
71 | @
72 |
73 |
74 | @*[local-name()='
75 |
76 | ' and namespace-uri()='
77 |
78 | ']
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 | /
88 |
89 |
90 | [
91 |
92 | ]
93 |
94 |
95 |
96 | /@
97 |
98 |
99 |
100 |
102 |
103 |
104 | /
105 |
106 |
107 | [
108 |
109 | ]
110 |
111 |
112 |
113 | /@
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 | .
138 |
139 |
140 |
141 |
142 | U
143 |
144 | U
145 |
146 |
147 |
148 | U.
149 |
150 | n
151 |
152 |
153 |
154 | U.
155 |
156 | _
157 |
158 | _
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
169 |
170 |
171 |
172 |
173 |
174 |
175 | © 2006-2018 Digital Data Exchange, LLC (DDEX)
176 | This ISO Schematron file is, together with all DDEX standards, subject to two licences: If you wish to evaluate whether the standard meets your needs please have a look at the Evaluation Licence at https://kb.ddex.net/display/HBK/Evaluation+Licence+for+DDEX+Standards. If you want to implement and use this DDEX standard, please take out an Implementation Licence. For details please go to http://ddex.net/apply-ddex-implementation-licence.
177 | Failing a rule with a role of 'Fatal Error' means that the Conformance Tester must recommend to not award a Conformance Certificate or to retract a Conformance Certificate if one has already been issued. Failing a rule with a role of 'Conditional Fatal Error' is the same as a 'Fatal Error', however, the rule may be ignored if the Conformance Tester has no means of asserting whether the condition expressed in the rule has been met.
178 | Failing a rule a rule with a role of 'Error' means that the Conformance Tester must recommend to award a Partial Conformance Certificate or to downgrade a Conformance Certificate that has already been issued. However, if more than 1 rules (representing 50% of all rules with a role of 'Error') have been failed at least once, the Conformance Tester must recommend to not award a Conformance Certificate or to retract a Conformance Certificate if one has already been issued. Failing a rule with a role of 'Conditional Error' is the same as an 'Error', however, the rule may be ignored if the Conformance Tester has no means of asserting whether the condition expressed in the rule has been met.
179 |
180 |
181 |
182 |
183 | MultiProfile_MustContainOneTrackReleasePerPrimaryResource
184 | MultiProfile_MustContainOneTrackReleasePerPrimaryResource
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 | MultiProfile_TrackReleaseMustNotHaveISRC
193 | MultiProfile_TrackReleaseMustNotHaveISRC
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 | MultiProfile_TrackReleaseMustHaveOnePrimaryResource
202 | MultiProfile_TrackReleaseMustHaveOnePrimaryResource
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 | MultiProfile_TrackReleaseMustNotHaveSecondaryResources
211 | MultiProfile_TrackReleaseMustNotHaveSecondaryResources
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 | MultiProfile_TrackReleaseMustNotHaveRedundantTitles
220 | MultiProfile_TrackReleaseMustNotHaveRedundantTitles
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 | Schematron Release Profile for Release Profile Track Release Rules (version 2.1) for the NewReleaseMessage.
229 |
230 |
231 |
232 |
233 |
234 |
237 |
239 |
240 |
241 |
242 |
243 |
244 |
246 | Fatal Error
247 |
248 |
249 |
250 | Fatal Error (Release Profile Track Release Rules): A Release of this type must contain exactly one TrackRelease for each Primary Resource referenced in the Main Release (Release Profile 2.1, Clause 5.1.1(b), Rule 1538-1).
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
268 |
270 |
271 |
272 |
273 |
274 | Fatal Error
275 |
276 |
277 |
278 | Fatal Error (Release Profile Track Release Rules): An ISRC as an identifier for a TrackRelease shall be communicated as a ProprietaryId (Release Profile 2.1, Clause 5.3.1.3(3), Rule 1539-1).
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
295 |
297 |
298 |
299 |
300 |
301 |
302 |
304 | Fatal Error
305 |
306 |
307 |
308 | Fatal Error (Release Profile Track Release Rules): A TrackRelease must refer to one Primary Resource (Release Profile 2.1, Clause 5.6(2a), Rule 1540-1).
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
326 |
328 |
329 |
330 |
331 |
333 | Fatal Error
334 |
335 |
336 |
337 | Fatal Error (Release Profile Track Release Rules): A TrackRelease must not refer to a Secondary Resource (Release Profile 2.1, Clause 5.6(2b), Rule 1541-1).
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
354 |
356 |
357 |
358 |
359 |
361 | Error
362 |
363 |
364 |
365 | Error (Release Profile Track Release Rules): Title information for TrackReleases shall only be provided if it differs from the title information provided on the Resource (Release Profile 2.1, Clause 5.6(4), Rule 1542-1).
366 |
367 |
368 |
369 |
370 |
371 |
373 | Error
374 |
375 |
376 |
377 | Error (Release Profile Track Release Rules): Title information for TrackReleases shall only be provided if it differs from the title information provided on the Resource (Release Profile 2.1, Clause 5.6(4), Rule 1542-2).
378 |
379 |
380 |
381 |
382 |
383 |
385 | Error
386 |
387 |
388 |
389 | Error (Release Profile Track Release Rules): Title information for TrackReleases shall only be provided if it differs from the title information provided on the Resource (Release Profile 2.1, Clause 5.6(4), Rule 1542-3).
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
--------------------------------------------------------------------------------
/schema/ERN-2454 - MEAD XSD.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ddexnet/ern-validator-api/9dcc5078f30826548832ba20bd377b535bfef8c1/schema/ERN-2454 - MEAD XSD.zip
--------------------------------------------------------------------------------
/src/main/assembly/bin.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 | bin
8 |
9 | zip
10 |
11 |
12 |
13 | ${project.basedir}
14 |
15 |
16 | ${project.basedir}/xml/**
17 |
18 |
19 | ${project.basedir}/.classpath
20 |
21 |
22 | ${project.basedir}/.settings/**
23 |
24 |
25 | ${project.basedir}/.project
26 |
27 |
28 | ${project.basedir}/application.log*
29 |
30 |
31 | ${project.basedir}/src/**
32 |
33 |
34 | ${project.basedir}/target/**
35 |
36 |
37 | ${project.basedir}/pom.xml
38 |
39 |
40 | ${project.basedir}/jetty_tutorial.iml
41 |
42 |
43 | ${project.basedir}/.idea/**
44 |
45 |
46 | bin
47 |
48 |
49 | target/appassembler/repo
50 | repo
51 |
52 | maven-metadata-appassembler.xml
53 |
54 |
55 |
56 | target/generated-resources/appassembler/booter-unix/etc
57 | etc
58 |
59 | start-api.xml
60 |
61 |
62 |
63 | target/generated-resources/appassembler/booter-unix/bin
64 | bin
65 | 0755
66 | unix
67 |
68 |
69 | target/generated-resources/appassembler/booter-windows/bin
70 | bin
71 | 0755
72 | dos
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/src/main/java/net/ddex/ern/config/AppConfig.java:
--------------------------------------------------------------------------------
1 | package net.ddex.ern.config;
2 |
3 | import org.springframework.context.annotation.Bean;
4 | import org.springframework.context.annotation.ComponentScan;
5 | import org.springframework.context.annotation.Configuration;
6 | import org.springframework.context.annotation.PropertySource;
7 | import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
8 |
9 | @Configuration
10 | @ComponentScan(basePackages = "net.ddex.ern")
11 | @PropertySource("classpath:application.properties")
12 | public class AppConfig {
13 |
14 | @Bean
15 | public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
16 | return new PropertySourcesPlaceholderConfigurer();
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/net/ddex/ern/config/WebMvcConfig.java:
--------------------------------------------------------------------------------
1 | package net.ddex.ern.config;
2 |
3 | import org.springframework.context.annotation.Bean;
4 | import org.springframework.context.annotation.Configuration;
5 | import org.springframework.web.multipart.commons.CommonsMultipartResolver;
6 | import org.springframework.web.servlet.config.annotation.EnableWebMvc;
7 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
8 |
9 | @Configuration
10 | @EnableWebMvc
11 | public class WebMvcConfig extends WebMvcConfigurerAdapter {
12 |
13 | @Bean
14 | public CommonsMultipartResolver multipartResolver() {
15 | CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
16 | multipartResolver.setDefaultEncoding("UTF-8");
17 | multipartResolver.setMaxUploadSize(-1);
18 | return multipartResolver;
19 | }
20 | }
--------------------------------------------------------------------------------
/src/main/java/net/ddex/ern/controller/ValidateController.java:
--------------------------------------------------------------------------------
1 | package net.ddex.ern.controller;
2 |
3 | import java.io.IOException;
4 | import java.util.AbstractMap;
5 | import java.util.ArrayList;
6 | import java.util.HashMap;
7 | import java.util.List;
8 | import java.util.Map;
9 | import java.util.Optional;
10 |
11 | import javax.xml.parsers.ParserConfigurationException;
12 | import javax.xml.stream.XMLStreamException;
13 | import javax.xml.transform.TransformerException;
14 | import javax.xml.xpath.XPathExpressionException;
15 |
16 | import org.slf4j.Logger;
17 | import org.slf4j.LoggerFactory;
18 | import org.springframework.beans.factory.annotation.Autowired;
19 | import org.springframework.beans.factory.annotation.Value;
20 | import org.springframework.web.bind.annotation.ExceptionHandler;
21 | import org.springframework.web.bind.annotation.GetMapping;
22 | import org.springframework.web.bind.annotation.PostMapping;
23 | import org.springframework.web.bind.annotation.RequestParam;
24 | import org.springframework.web.bind.annotation.RestController;
25 | import org.springframework.web.multipart.MultipartFile;
26 | import org.xml.sax.SAXException;
27 |
28 | import net.ddex.ern.exception.ValidatorException;
29 | import net.ddex.ern.service.SchemaService;
30 | import net.ddex.ern.service.SchematronService;
31 | import net.ddex.ern.vo.ValidationResponse;
32 |
33 | @RestController
34 | public class ValidateController {
35 |
36 | private static final Logger LOGGER = LoggerFactory.getLogger(ValidateController.class);
37 | private static String PROFILE_ROOT = "profiles/commonreleasetypes/";
38 |
39 | @Autowired
40 | private SchemaService schemaService;
41 |
42 | @Autowired
43 | private SchematronService schematronService;
44 |
45 | @Value("${max.input.file.size.kb}")
46 | private Long maxInputFileSizeinKb;
47 |
48 | @Value("#{${releaseProfileVersion.map.schema}}")
49 | private Map releaseProfileVersionMap;
50 |
51 | @GetMapping(path = "/status", produces = "text/plain")
52 | public String test() {
53 | return "The service is running";
54 | }
55 |
56 | @PostMapping(path = "/json/validate", produces = "application/json")
57 | public List> validate(@RequestParam(value = "messageFile") MultipartFile file,
58 | @RequestParam(value = "messageSchemaVersionId") Optional schemaVersion,
59 | @RequestParam(value = "releaseProfileVersionId") Optional releaseProfile,
60 | @RequestParam(value = "businessProfileValidationRequired", required = false, defaultValue = "false") boolean businessProfileValidationRequired)
61 | throws IOException, XMLStreamException, TransformerException, SAXException, XPathExpressionException,
62 | ValidatorException, ParserConfigurationException {
63 |
64 | LOGGER.info("file size is : {}", file.getSize() / 1000);
65 | if (file.getSize() / 1000 > maxInputFileSizeinKb) {
66 | throw new ValidatorException("MAX_FILE_SIZE_LIMIT_FAILED",
67 | "Input File Size cannot be greater than 15000 KB");
68 | }
69 | List> list = new ArrayList<>(2);
70 | Map map = new HashMap<>(2);
71 |
72 | String _schemaVersion = schemaVersion.isPresent() ? schemaVersion.get().replace(".", "") : "";
73 | _schemaVersion = _schemaVersion.startsWith("/") ? _schemaVersion.substring(1) : _schemaVersion;
74 | _schemaVersion = _schemaVersion.endsWith("/") ? _schemaVersion.substring(0, _schemaVersion.length() - 1)
75 | : _schemaVersion;
76 |
77 | String _releaseProfile = releaseProfile.isPresent() ? releaseProfile.get().replace(".", "") : "none";
78 | _releaseProfile = _releaseProfile.startsWith("/") ? _releaseProfile.substring(1) : _releaseProfile;
79 | _releaseProfile = _releaseProfile.endsWith("/") ? _releaseProfile.substring(0, _releaseProfile.length() - 1)
80 | : _releaseProfile;
81 |
82 | String releaseProfileVersion = releaseProfileVersionMap.get(_schemaVersion.replace("/", "")) != null ? releaseProfileVersionMap.get(_schemaVersion.replace("/", "")).concat("/") : "none";
83 | LOGGER.info("releaseProfileVersion is : {}", releaseProfileVersion);
84 | String releaseProfileXslPath = null;
85 | try {
86 | AbstractMap.SimpleEntry spec = schemaService.validateSchema(file.getInputStream(),
87 | _schemaVersion, _releaseProfile);
88 | map.put("schema", "Message validates against schema version " + spec.getKey());
89 | _schemaVersion = _schemaVersion.isEmpty() ? spec.getKey() : _schemaVersion;
90 | releaseProfileXslPath = _releaseProfile.isEmpty() ? String.format("%s%s", spec.getValue(), ".xsl")
91 | : String.format("%s%s%s%s", PROFILE_ROOT, releaseProfileVersion, _releaseProfile, ".xsl");
92 | } catch (SAXException e) {
93 | LOGGER.error(e.getMessage());
94 | map.put("schema", e.getMessage());
95 | list.add(map);
96 | return list;
97 | }
98 | if (!(_releaseProfile.equalsIgnoreCase("none") || _schemaVersion.equalsIgnoreCase("341"))) {
99 | map.put("schematron",
100 | schematronService.schematron2Map(file.getInputStream(), releaseProfileXslPath, _schemaVersion));
101 | }
102 | if (businessProfileValidationRequired) {
103 | map.put("businessProfileSchematron", schematronService.schematron2Map(file.getInputStream(),
104 | String.format("%s%s%s%s", PROFILE_ROOT, releaseProfileVersion, "BusinessProfile", ".xsl"), _schemaVersion));
105 | }
106 | list.add(map);
107 | return list;
108 | }
109 |
110 | @ExceptionHandler
111 | public ValidationResponse handleValidatorException(ValidatorException ex) {
112 | LOGGER.error(ex.getMessage());
113 | return new ValidationResponse(ex.getStatus(), ex.getErrorMessage());
114 | }
115 | }
--------------------------------------------------------------------------------
/src/main/java/net/ddex/ern/exception/ErrorResponse.java:
--------------------------------------------------------------------------------
1 | package net.ddex.ern.exception;
2 |
3 | /**
4 | * Created by eli on 8/7/2017.
5 | */
6 | public class ErrorResponse {
7 | private int errorCode;
8 | private String message;
9 |
10 | public int getErrorCode() {
11 | return errorCode;
12 | }
13 |
14 | public void setErrorCode(int errorCode) {
15 | this.errorCode = errorCode;
16 | }
17 |
18 | public String getMessage() {
19 | return message;
20 | }
21 |
22 | public void setMessage(String message) {
23 | this.message = message;
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/net/ddex/ern/exception/ExceptionControllerAdvice.java:
--------------------------------------------------------------------------------
1 | package net.ddex.ern.exception;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 | import org.springframework.http.HttpStatus;
6 | import org.springframework.http.ResponseEntity;
7 | import org.springframework.web.bind.annotation.ControllerAdvice;
8 | import org.springframework.web.bind.annotation.ExceptionHandler;
9 |
10 | /**
11 | * Created by eli on 8/7/2017.
12 | */
13 | @ControllerAdvice
14 | public class ExceptionControllerAdvice {
15 |
16 | private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionControllerAdvice.class);
17 |
18 | @ExceptionHandler(ValidatorException.class)
19 | public ResponseEntity exceptionHandler(ValidatorException ex) {
20 | ErrorResponse error = new ErrorResponse();
21 | error.setErrorCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
22 | System.out.println("##############################");
23 | error.setMessage(ex.getErrorMessage());
24 | LOGGER.error("An error occured while processing request. {}", ex.getMessage());
25 | return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR);
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/net/ddex/ern/exception/ValidatorException.java:
--------------------------------------------------------------------------------
1 | package net.ddex.ern.exception;
2 |
3 | import org.springframework.http.HttpStatus;
4 | import org.springframework.web.bind.annotation.ResponseStatus;
5 |
6 | @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR, reason = "Validator configuration error")
7 | public class ValidatorException extends Exception {
8 |
9 | private static final long serialVersionUID = 1L;
10 | private String status;
11 | private String errorMessage;
12 |
13 | public ValidatorException() {
14 | super();
15 | }
16 |
17 | public ValidatorException(String errorMessage) {
18 | super(errorMessage);
19 | this.errorMessage = errorMessage;
20 | }
21 |
22 | public ValidatorException(String status, String errorMessage) {
23 | super(errorMessage);
24 | this.status = status;
25 | this.errorMessage = errorMessage;
26 | }
27 |
28 | public ValidatorException(String errorMessage, Throwable throwable) {
29 | super(throwable);
30 | this.errorMessage = errorMessage;
31 | }
32 |
33 | public String getErrorMessage() {
34 | return errorMessage;
35 | }
36 |
37 | public String getStatus() {
38 | return status;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/net/ddex/ern/initializer/EmbeddedJetty.java:
--------------------------------------------------------------------------------
1 | package net.ddex.ern.initializer;
2 |
3 | import java.io.IOException;
4 |
5 | import org.eclipse.jetty.server.Server;
6 | import org.eclipse.jetty.servlet.FilterHolder;
7 | import org.eclipse.jetty.servlet.FilterMapping;
8 | import org.eclipse.jetty.servlet.ServletContextHandler;
9 | import org.eclipse.jetty.servlet.ServletHolder;
10 | import org.eclipse.jetty.servlets.CrossOriginFilter;
11 | import org.slf4j.Logger;
12 | import org.slf4j.LoggerFactory;
13 | import org.springframework.web.context.ContextLoaderListener;
14 | import org.springframework.web.context.WebApplicationContext;
15 | import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
16 | import org.springframework.web.servlet.DispatcherServlet;
17 |
18 | public class EmbeddedJetty {
19 |
20 | private static final Logger LOGGER = LoggerFactory.getLogger(EmbeddedJetty.class);
21 | private static final int DEFAULT_PORT = 6060;
22 | private static final String CONTEXT_PATH = "/";
23 | private static final String CONFIG_LOCATION = "net/ddex/ern/config";
24 | private static final String MAPPING_URL = "/api/*";
25 | private static final String DEFAULT_PROFILE = "dev";
26 | private static org.springframework.web.context.WebApplicationContext WebApplicationContext;
27 |
28 | public static void main(String[] args) throws Exception {
29 | new EmbeddedJetty().startJetty(getPortFromArgs(args));
30 | }
31 |
32 | private static int getPortFromArgs(String[] args) {
33 | if (args.length > 0) {
34 | try {
35 | return Integer.valueOf(args[0]);
36 | } catch (NumberFormatException ignore) {}
37 | }
38 | LOGGER.debug("No server port configured, falling back to {}", DEFAULT_PORT);
39 | return DEFAULT_PORT;
40 | }
41 |
42 | private void startJetty(int port) throws Exception {
43 | LOGGER.debug("Starting server at port {}", port);
44 | Server server = new Server(port);
45 | ServletContextHandler myHand = getServletContextHandler(getContext());
46 | setAccessControlAllowOrigin(myHand);
47 | server.setHandler(myHand);
48 | server.start();
49 | LOGGER.info("Server started at port {}", port);
50 | server.join();
51 | }
52 |
53 | private static ServletContextHandler getServletContextHandler(WebApplicationContext context) throws IOException {
54 |
55 | ServletContextHandler contextHandler = new ServletContextHandler();
56 | contextHandler.setContextPath(CONTEXT_PATH);
57 | contextHandler.setWelcomeFiles(new String[]{ "index.html" });
58 | contextHandler.setErrorHandler(null);
59 | contextHandler.addServlet(new ServletHolder(new DispatcherServlet(context)), MAPPING_URL);
60 | contextHandler.addEventListener(new ContextLoaderListener(context));
61 |
62 | return contextHandler;
63 |
64 | }
65 |
66 | private static void setAccessControlAllowOrigin(ServletContextHandler context) {
67 | FilterHolder holder = new FilterHolder(CrossOriginFilter.class);
68 | holder.setInitParameter(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, "*");
69 | holder.setInitParameter(CrossOriginFilter.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER, "http://localhost:8000/");
70 | holder.setInitParameter(CrossOriginFilter.ALLOWED_METHODS_PARAM, "GET,POST,PUT,HEAD");
71 | holder.setInitParameter(CrossOriginFilter.ALLOWED_HEADERS_PARAM, "X-Requested-With,Content-Type,Accept,Origin");
72 | holder.setName("cross-origin");
73 | FilterMapping fm = new FilterMapping();
74 | fm.setFilterName("cross-origin");
75 | fm.setPathSpec("*");
76 | context.getServletHandler().addFilter(holder, fm);
77 | }
78 |
79 | private static WebApplicationContext getContext() {
80 | AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
81 | context.setConfigLocation(CONFIG_LOCATION);
82 | context.getEnvironment().setDefaultProfiles(DEFAULT_PROFILE);
83 | return context;
84 | }
85 |
86 | }
--------------------------------------------------------------------------------
/src/main/java/net/ddex/ern/schema/Schema.java:
--------------------------------------------------------------------------------
1 | package net.ddex.ern.schema;
2 |
3 | import net.ddex.ern.exception.ValidatorException;
4 | import org.w3c.dom.Document;
5 | import org.xml.sax.SAXException;
6 |
7 | import javax.xml.transform.Result;
8 | import javax.xml.validation.Validator;
9 |
10 | /**
11 | * Created by rdewilde on 5/13/2017.
12 | */
13 | public interface Schema {
14 | Validator getValidator();
15 |
16 | String validate(Document ern, Result result) throws SAXException, ValidatorException;
17 | }
--------------------------------------------------------------------------------
/src/main/java/net/ddex/ern/schema/SchemaFactory.java:
--------------------------------------------------------------------------------
1 | package net.ddex.ern.schema;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 |
6 | /**
7 | * Created by rdewilde on 5/13/2017.
8 | */
9 | public class SchemaFactory {
10 |
11 | private static final Logger logger = LoggerFactory.getLogger(SchemaFactory.class);
12 |
13 | public Schema getSchema() {
14 | return new ThreeFourOneSchema();
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/net/ddex/ern/schema/SchemaValidator.java:
--------------------------------------------------------------------------------
1 | package net.ddex.ern.schema;
2 |
3 | import java.io.IOException;
4 |
5 | import javax.xml.transform.Result;
6 | import javax.xml.transform.dom.DOMSource;
7 |
8 | import org.slf4j.Logger;
9 | import org.slf4j.LoggerFactory;
10 | import org.springframework.beans.factory.annotation.Autowired;
11 | import org.springframework.stereotype.Component;
12 | import org.w3c.dom.Document;
13 | import org.xml.sax.SAXException;
14 |
15 | import net.ddex.ern.exception.ValidatorException;
16 | import net.ddex.ern.util.SchemaBuilder;
17 |
18 | @Component
19 | public class SchemaValidator {
20 |
21 | private static final Logger LOGGER = LoggerFactory.getLogger(SchemaValidator.class);
22 | private javax.xml.validation.Schema schema;
23 |
24 | @Autowired
25 | private SchemaBuilder schemaBuilder;
26 |
27 | public void validate(String schemaVersion, String profile, Document ern, Result result)
28 | throws SAXException, ValidatorException {
29 | DOMSource source = new DOMSource(ern);
30 | try {
31 | schema = schemaBuilder.getSchema(schemaVersion);
32 | schema.newValidator().validate(source, result);
33 | } catch (IOException e) {
34 | LOGGER.error("IOException while validating schema.", e);
35 | throw new ValidatorException(e.getMessage(), e);
36 | }
37 | }
38 | }
--------------------------------------------------------------------------------
/src/main/java/net/ddex/ern/schema/ThreeFourOneSchema.java:
--------------------------------------------------------------------------------
1 | package net.ddex.ern.schema;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 |
6 | import javax.xml.XMLConstants;
7 | import javax.xml.transform.Result;
8 | import javax.xml.transform.Source;
9 | import javax.xml.transform.dom.DOMSource;
10 | import javax.xml.transform.stream.StreamSource;
11 | import javax.xml.validation.SchemaFactory;
12 | import javax.xml.validation.Validator;
13 |
14 | import org.slf4j.Logger;
15 | import org.slf4j.LoggerFactory;
16 | import org.w3c.dom.Document;
17 | import org.xml.sax.SAXException;
18 |
19 | import net.ddex.ern.exception.ValidatorException;
20 |
21 | /**
22 | * Electronic Release Notification 3.4.1
23 | */
24 | public class ThreeFourOneSchema implements Schema {
25 |
26 | private static final Logger logger = LoggerFactory.getLogger(ThreeFourOneSchema.class);
27 | private static javax.xml.validation.Schema schema;
28 |
29 | static {
30 | Source[] schemaFiles = new Source[]{
31 | new StreamSource(new File("schema/release-notification.xsd")),
32 | new StreamSource(new File("schema/ddexC.xsd")),
33 | new StreamSource(new File("schema/ddex.xsd")),
34 | new StreamSource(new File("schema/iso3166a2.xsd")),
35 | new StreamSource(new File("schema/iso4217a.xsd")),
36 | new StreamSource(new File("schema/iso639a2.xsd"))
37 | };
38 |
39 | SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
40 | try {
41 | factory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
42 | factory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
43 | schema = factory.newSchema(schemaFiles);
44 | } catch (SAXException e) {
45 | e.printStackTrace();
46 | // TODO: Catch this on startup earlier
47 | System.exit(2);
48 | }
49 | }
50 |
51 | @Override
52 | public Validator getValidator() {
53 | return schema.newValidator();
54 | }
55 |
56 | @Override
57 | public String validate(Document ern, Result result) throws ValidatorException {
58 | DOMSource source = new DOMSource(ern);
59 | String valid = "Document is valid";
60 | try {
61 | getValidator().validate(source);
62 | } catch (IOException e) {
63 | // logger.error(e.getMessage());
64 | throw new ValidatorException(e.getMessage(), e);
65 | } catch (SAXException e) {
66 | // logger.error(e.getMessage());
67 | throw new ValidatorException(e.getMessage(), e);
68 | }
69 | return valid;
70 |
71 | }
72 | }
--------------------------------------------------------------------------------
/src/main/java/net/ddex/ern/schema/ThreeSevenOneSchema.java:
--------------------------------------------------------------------------------
1 | package net.ddex.ern.schema;
2 |
3 | import net.ddex.ern.exception.ValidatorException;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 | import org.w3c.dom.Document;
7 | import org.xml.sax.SAXException;
8 |
9 | import javax.xml.XMLConstants;
10 | import javax.xml.transform.Result;
11 | import javax.xml.transform.Source;
12 | import javax.xml.transform.dom.DOMSource;
13 | import javax.xml.transform.stream.StreamSource;
14 | import javax.xml.validation.SchemaFactory;
15 | import javax.xml.validation.Validator;
16 | import java.io.File;
17 | import java.io.IOException;
18 |
19 | /**
20 | * Electronic Release Notification 3.4.1
21 | */
22 | public class ThreeSevenOneSchema implements Schema {
23 |
24 | private static final Logger logger = LoggerFactory.getLogger(ThreeFourOneSchema.class);
25 | private static javax.xml.validation.Schema schema;
26 |
27 | static {
28 | Source[] schemaFiles = new Source[]{
29 | new StreamSource(new File("schema/release-notification.xsd")),
30 | new StreamSource(new File("schema/ddexC.xsd")),
31 | new StreamSource(new File("schema/ddex.xsd")),
32 | new StreamSource(new File("schema/iso3166a2.xsd")),
33 | new StreamSource(new File("schema/iso4217a.xsd")),
34 | new StreamSource(new File("schema/iso639a2.xsd"))
35 | };
36 |
37 | SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
38 | try {
39 | factory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
40 | factory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
41 | schema = factory.newSchema(schemaFiles);
42 | } catch (SAXException e) {
43 | e.printStackTrace();
44 | // TODO: Catch this on startup earlier
45 | System.exit(2);
46 | }
47 | }
48 |
49 | @Override
50 | public Validator getValidator() {
51 | return schema.newValidator();
52 | }
53 |
54 | @Override
55 | public String validate(Document ern, Result result) throws ValidatorException {
56 | DOMSource source = new DOMSource(ern);
57 | String valid = "Document is valid";
58 | try {
59 | getValidator().validate(source);
60 | } catch (IOException e) {
61 | // logger.error(e.getMessage());
62 | throw new ValidatorException(e.getMessage(), e);
63 | } catch (SAXException e) {
64 | // logger.error(e.getMessage());
65 | throw new ValidatorException(e.getMessage(), e);
66 | }
67 | return valid;
68 |
69 | }
70 | }
--------------------------------------------------------------------------------
/src/main/java/net/ddex/ern/service/SchemaService.java:
--------------------------------------------------------------------------------
1 | package net.ddex.ern.service;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 | import java.util.AbstractMap;
6 |
7 | import javax.xml.XMLConstants;
8 | import javax.xml.parsers.DocumentBuilder;
9 | import javax.xml.parsers.DocumentBuilderFactory;
10 | import javax.xml.parsers.ParserConfigurationException;
11 | import javax.xml.xpath.XPath;
12 | import javax.xml.xpath.XPathConstants;
13 | import javax.xml.xpath.XPathExpressionException;
14 | import javax.xml.xpath.XPathFactory;
15 |
16 | import org.slf4j.Logger;
17 | import org.slf4j.LoggerFactory;
18 | import org.springframework.beans.factory.annotation.Autowired;
19 | import org.springframework.stereotype.Service;
20 | import org.w3c.dom.Document;
21 | import org.w3c.dom.Element;
22 | import org.w3c.dom.Node;
23 | import org.w3c.dom.NodeList;
24 | import org.xml.sax.SAXException;
25 |
26 | import net.ddex.ern.exception.ValidatorException;
27 | import net.ddex.ern.schema.SchemaValidator;
28 |
29 | /**
30 | * Created by rdewilder on 4/16/2017.
31 | */
32 |
33 | @Service("schemaService")
34 | public class SchemaService {
35 |
36 | private static final Logger LOGGER = LoggerFactory.getLogger(SchemaService.class);
37 |
38 | private static final String XPATH_EXPRESSION = "/*";
39 |
40 | @Autowired
41 | private SchemaValidator schemaValidator;
42 |
43 | // Todo: https://stackoverflow.com/questions/15732/whats-the-best-way-to-validate-an-xml-file-against-an-xsd-file
44 | // use SAX instead of Dom
45 | public AbstractMap.SimpleEntry validateSchema(InputStream is, String schemaVersion, String profile)
46 | throws SAXException, ValidatorException, ParserConfigurationException {
47 |
48 | // DocumentBuilderFactory and DocumentBuilder are not thread safe
49 | DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
50 | dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
51 | dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
52 | dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
53 | dbf.setNamespaceAware(true);
54 | Document doc;
55 |
56 | // Try to create the DOM from the uploaded file
57 | try {
58 | DocumentBuilder parser = dbf.newDocumentBuilder();
59 | doc = parser.parse(is);
60 | } catch (ParserConfigurationException e) {
61 | LOGGER.error(e.getMessage());
62 | throw new ValidatorException("Could not create XML parser", e);
63 | } catch (IOException e) {
64 | LOGGER.error(e.getMessage());
65 | throw new ValidatorException("IOException during XML parse", e);
66 | }
67 |
68 | // Extract the Schema and profile from XML if not in request
69 | if (schemaVersion.isEmpty() || profile.isEmpty()) {
70 | AbstractMap.SimpleEntry schemaProfile = exractProfileAndSchemaVersion(doc);
71 |
72 | if (schemaVersion.isEmpty() && !"".equals(schemaProfile.getKey()))
73 | schemaVersion = schemaProfile.getKey();
74 | else if (schemaVersion.isEmpty()) {
75 | LOGGER.error("Schema Version not found in request or XML.");
76 | throw new ValidatorException("MANDATORY_PARAMS_NOT_FOUND",
77 | "Error occurred while validating XML. Message Schema Version not found in request or XML.");
78 | }
79 |
80 | if (profile.isEmpty() && !"".equals(schemaProfile.getValue()))
81 | profile = schemaProfile.getValue();
82 | else if (profile.isEmpty()) {
83 | LOGGER.error("Profile not found in request or XML.");
84 | throw new ValidatorException("MANDATORY_PARAMS_NOT_FOUND",
85 | "Error occurred while validating XML. Release Profile Version not found in request or XML.");
86 | }
87 | }
88 | LOGGER.info("schemaVersion: {}, profile: {}", schemaVersion, profile);
89 | schemaValidator.validate(schemaVersion, profile, doc, null);
90 | return new AbstractMap.SimpleEntry<>(schemaVersion, profile);
91 | }
92 |
93 | // Todo: use SAX instead of DOM
94 | private AbstractMap.SimpleEntry exractProfileAndSchemaVersion(Document doc)
95 | throws ValidatorException {
96 | XPath xPath = XPathFactory.newInstance().newXPath();
97 | String schemaVersion = "";
98 | String profile = "";
99 | try {
100 | NodeList nodeList = (NodeList) xPath.compile(SchemaService.XPATH_EXPRESSION).evaluate(doc, XPathConstants.NODESET);
101 | for (int i = 0; i < nodeList.getLength(); i++) {
102 | Node nNode = nodeList.item(i);
103 | if (nNode.getNodeType() == Node.ELEMENT_NODE) {
104 | Element eElement = (Element) nNode;
105 | if (!"".equals(eElement.getAttribute("MessageSchemaVersionId"))) {
106 | schemaVersion = eElement.getAttribute("MessageSchemaVersionId");
107 | schemaVersion = schemaVersion.startsWith("/") ? schemaVersion.substring(1) : schemaVersion;
108 | }
109 | if (!"".equals(eElement.getAttribute("ReleaseProfileVersionId "))) {
110 | profile = eElement.getAttribute("ReleaseProfileVersionId ");
111 | profile = profile.startsWith("/") ? profile.substring(1) : profile;
112 | }
113 | }
114 | }
115 | } catch (XPathExpressionException e) {
116 | LOGGER.error(e.getMessage());
117 | throw new ValidatorException("XPath error during schema version extraction", e);
118 | }
119 |
120 | return new AbstractMap.SimpleEntry<>(schemaVersion, profile);
121 | }
122 | }
--------------------------------------------------------------------------------
/src/main/java/net/ddex/ern/service/SchematronService.java:
--------------------------------------------------------------------------------
1 | package net.ddex.ern.service;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 | import java.util.ArrayList;
6 | import java.util.HashMap;
7 | import java.util.Iterator;
8 | import java.util.List;
9 | import java.util.Map;
10 |
11 | import javax.xml.XMLConstants;
12 | import javax.xml.namespace.NamespaceContext;
13 | import javax.xml.stream.XMLStreamException;
14 | import javax.xml.transform.Transformer;
15 | import javax.xml.transform.TransformerException;
16 | import javax.xml.transform.TransformerFactory;
17 | import javax.xml.transform.dom.DOMResult;
18 | import javax.xml.transform.sax.SAXSource;
19 | import javax.xml.transform.sax.SAXTransformerFactory;
20 | import javax.xml.transform.stream.StreamSource;
21 | import javax.xml.xpath.XPath;
22 | import javax.xml.xpath.XPathConstants;
23 | import javax.xml.xpath.XPathExpression;
24 | import javax.xml.xpath.XPathExpressionException;
25 | import javax.xml.xpath.XPathFactory;
26 |
27 | import org.slf4j.Logger;
28 | import org.slf4j.LoggerFactory;
29 | import org.springframework.stereotype.Service;
30 | import org.w3c.dom.NodeList;
31 | import org.xml.sax.InputSource;
32 |
33 | import net.ddex.ern.exception.ValidatorException;
34 |
35 | /**
36 | * Created by rdewilde on 4/16/2017.
37 | */
38 |
39 | @Service("schematronService")
40 | public class SchematronService {
41 |
42 | // private SAXTransformerFactory stf = new net.sf.saxon.TransformerFactoryImpl();
43 | private static final Logger LOGGER = LoggerFactory.getLogger(SchematronService.class);
44 |
45 | public List> schematron2Map(InputStream is, String profileVersion, String schemaVersion)
46 | throws XMLStreamException, IOException, TransformerException, XPathExpressionException, ValidatorException {
47 |
48 | SAXSource saxSource = new SAXSource(new InputSource(is));
49 | DOMResult result = new DOMResult();
50 | // SAXTransformerFactory stf = new net.sf.saxon.TransformerFactoryImpl();
51 | try {
52 | TransformerFactory sf = SAXTransformerFactory.newInstance();
53 | sf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
54 | sf.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
55 | Transformer transformer = sf.newTransformer(new StreamSource(profileVersion));
56 | transformer.transform(saxSource, result);
57 | } catch (TransformerException ex) {
58 | LOGGER.error("Exception: {}", ex.getMessage());
59 | String releaseProfile = profileVersion.substring(profileVersion.lastIndexOf("/") + 1,
60 | profileVersion.lastIndexOf("."));
61 | throw new ValidatorException(
62 | String.format("%s%s%s%s", "Error while validating Schematron. Release profile ", releaseProfile,
63 | " does not exist for schema version ", schemaVersion),
64 | ex);
65 | }
66 | XPathFactory xPathfactory = XPathFactory.newInstance();
67 | XPath xpath = xPathfactory.newXPath();
68 |
69 | xpath.setNamespaceContext(getNamespaceContext());
70 |
71 | XPathExpression expr = xpath.compile("/svrl:schematron-output/svrl:failed-assert");
72 | NodeList nl = (NodeList) expr.evaluate(result.getNode(), XPathConstants.NODESET);
73 |
74 | List> data = new ArrayList<>();
75 | int fatalErrors = 0;
76 | int conditionalErrors = 0;
77 | int errors = 0;
78 | int conditionalFatalErrors = 0;
79 | if (nl.getLength() > 0) {
80 | for (int i = 0; i < nl.getLength(); i++) {
81 | String role = String.format("/svrl:schematron-output/svrl:failed-assert[%d]/@role", i + 1);
82 | String msg = String.format("/svrl:schematron-output/svrl:failed-assert[%d]/svrl:text", i + 1);
83 | XPathExpression exprMsg = xpath.compile(msg);
84 | XPathExpression exprRole = xpath.compile(role);
85 |
86 | Map failure = new HashMap<>();
87 | if (exprRole.evaluate(result.getNode()).equalsIgnoreCase("Fatal Error")) {
88 | fatalErrors = fatalErrors + 1;
89 | }
90 | if (exprRole.evaluate(result.getNode()).equalsIgnoreCase("Conditional Error")) {
91 | conditionalErrors = conditionalErrors + 1;
92 | }
93 | if (exprRole.evaluate(result.getNode()).equalsIgnoreCase("Error")) {
94 | errors = errors + 1;
95 | }
96 | if (exprRole.evaluate(result.getNode()).equalsIgnoreCase("Conditional Fatal Error")) {
97 | conditionalFatalErrors = conditionalFatalErrors + 1;
98 | }
99 | failure.put("role", exprRole.evaluate(result.getNode()));
100 | failure.put("msg", exprMsg.evaluate(result.getNode()));
101 | data.add(failure);
102 | }
103 |
104 | Map errorCountMap = new HashMap<>();
105 | errorCountMap.put("fatalErrors", String.valueOf(fatalErrors));
106 | errorCountMap.put("conditionalErrors", String.valueOf(conditionalErrors));
107 | errorCountMap.put("errors", String.valueOf(errors));
108 | errorCountMap.put("conditionalFatalErrors", String.valueOf(conditionalFatalErrors));
109 | data.add(errorCountMap);
110 | } else {
111 | Map errorCountMap = new HashMap<>();
112 | errorCountMap.put("noError", "Message validates against Profile.");
113 | data.add(errorCountMap);
114 | }
115 | return data;
116 |
117 | }
118 |
119 | private NamespaceContext getNamespaceContext() {
120 | NamespaceContext ctx = new NamespaceContext() {
121 | @Override
122 | public String getNamespaceURI(String prefix) {
123 | if (prefix.equals("svrl")) {
124 | return "http://purl.oclc.org/dsdl/svrl";
125 | } else {
126 | return null;
127 | }
128 | }
129 |
130 | @Override
131 | public String getPrefix(String namespaceURI) {
132 | return null; // not used
133 | }
134 |
135 | @Override
136 | public Iterator getPrefixes(String namespaceURI) {
137 | return null; // not used
138 | }
139 | };
140 | return ctx;
141 | }
142 |
143 | }
--------------------------------------------------------------------------------
/src/main/java/net/ddex/ern/util/SchemaBuilder.java:
--------------------------------------------------------------------------------
1 | package net.ddex.ern.util;
2 |
3 | import java.io.File;
4 | import java.util.Arrays;
5 | import java.util.List;
6 | import java.util.concurrent.ConcurrentHashMap;
7 |
8 | import javax.xml.XMLConstants;
9 | import javax.xml.transform.Source;
10 | import javax.xml.transform.stream.StreamSource;
11 | import javax.xml.validation.Schema;
12 | import javax.xml.validation.SchemaFactory;
13 |
14 | import org.slf4j.Logger;
15 | import org.slf4j.LoggerFactory;
16 | import org.springframework.stereotype.Component;
17 | import org.xml.sax.SAXException;
18 |
19 | import net.ddex.ern.exception.ValidatorException;
20 | import org.xml.sax.SAXNotRecognizedException;
21 | import org.xml.sax.SAXNotSupportedException;
22 |
23 | @Component
24 | public class SchemaBuilder {
25 |
26 | private static final Logger LOGGER = LoggerFactory.getLogger(SchemaBuilder.class);
27 | private static final String FILE_PATH_PREFIX = "schema/";
28 | private ConcurrentHashMap schemaMap = new ConcurrentHashMap<>();
29 | private SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
30 |
31 | // what happens when schema directory is empty
32 | public Schema getSchema(String schemaVersion) throws ValidatorException, SAXNotSupportedException, SAXNotRecognizedException {
33 | String schemaKey = schemaVersion.toLowerCase();
34 | if (!schemaMap.containsKey(schemaKey)) {
35 | //List schemaFiles = Arrays.asList(env.getProperty(schemaKey).split("\\s*,\\s*"));
36 | List schemaFiles = loadSchemaFiles(schemaKey);
37 | Source[] sources = new Source[schemaFiles.size()];
38 | factory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
39 | factory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
40 | for (int i = 0; i < schemaFiles.size(); i++) {
41 | sources[i] = new StreamSource(new File(String.format("%s/%s/%s", SchemaBuilder.FILE_PATH_PREFIX, schemaVersion, schemaFiles.get(i))));
42 | }
43 | try {
44 | schemaMap.put(schemaKey, factory.newSchema(sources));
45 | } catch (SAXException e) {
46 | LOGGER.error("SAXException while building Schema Object");
47 | throw new ValidatorException(e.getMessage(), e);
48 | }
49 | }
50 | return schemaMap.get(schemaKey);
51 | }
52 |
53 | private List loadSchemaFiles(String schemaVersion) throws ValidatorException {
54 | File dir = new File(FILE_PATH_PREFIX + schemaVersion);
55 | if(!dir.isDirectory() || !dir.exists()) {
56 | throw new ValidatorException(schemaVersion + " is not a valid message version");
57 | }
58 | return Arrays.asList(dir.list());
59 | }
60 | }
--------------------------------------------------------------------------------
/src/main/java/net/ddex/ern/vo/ValidationResponse.java:
--------------------------------------------------------------------------------
1 | package net.ddex.ern.vo;
2 |
3 | import com.fasterxml.jackson.annotation.JsonInclude;
4 |
5 | import java.util.List;
6 |
7 | /**
8 | * Created by rdewilde on 5/16/2017.
9 | */
10 | @JsonInclude(JsonInclude.Include.NON_EMPTY)
11 | public class ValidationResponse {
12 |
13 | private Boolean isError = false;
14 | private Boolean isSchemaValid;
15 | private Boolean isSchematronValid;
16 |
17 | private List schemaMessages;
18 | private List schematronMessages;
19 |
20 | private String status;
21 | private String message;
22 |
23 | public ValidationResponse(String status, String message) {
24 | this.isError = true;
25 | this.status = status;
26 | this.message = message;
27 | }
28 |
29 | public boolean isError() {
30 | return isError;
31 | }
32 |
33 | public void setError(Boolean error) {
34 | isError = error;
35 | }
36 |
37 | public Boolean isSchemaValid() {
38 | return isSchemaValid;
39 | }
40 |
41 | public void setSchemaValid(Boolean schemaValid) {
42 | isSchemaValid = schemaValid;
43 | }
44 |
45 | public Boolean isSchematronValid() {
46 |
47 | return isSchematronValid;
48 | }
49 |
50 | public void setSchematronValid(boolean schematronValid) {
51 | isSchematronValid = schematronValid;
52 | }
53 |
54 | public List getSchemaMessages() {
55 | return schemaMessages;
56 | }
57 |
58 | public void setSchemaMessages(List schemaMessages) {
59 | this.schemaMessages = schemaMessages;
60 | }
61 |
62 | public List getSchematronMessages() {
63 | return schematronMessages;
64 | }
65 |
66 | public void setSchematronMessages(List schematronMessages) {
67 | this.schematronMessages = schematronMessages;
68 | }
69 |
70 | public String getStatus() {
71 | return status;
72 | }
73 |
74 | public void setStatus(String status) {
75 | this.status = status;
76 | }
77 |
78 | public String getMessage() {
79 | return message;
80 | }
81 |
82 | public void setMessage(String message) {
83 | this.message = message;
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/main/java/net/ddex/ern/vo/ValidationResult.java:
--------------------------------------------------------------------------------
1 | package net.ddex.ern.vo;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * Created by rdewilde on 5/18/2017.
8 | */
9 | public class ValidationResult {
10 |
11 | private Boolean isValid;
12 | private List messages = null;
13 |
14 | public Boolean getValid() {
15 | return isValid;
16 | }
17 |
18 | public void setValid(Boolean valid) {
19 | isValid = valid;
20 | }
21 |
22 | public List getMessages() {
23 | return messages;
24 | }
25 |
26 | public void setMessages(List messages) {
27 | this.messages = messages;
28 | }
29 |
30 | public void addMessage(String msg) {
31 | if (messages == null) {
32 | messages = new ArrayList<>();
33 | }
34 | messages.add(msg);
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | max.input.file.size.kb=15000
2 | releaseProfileVersion.map.schema={\
3 | ern371 : 13, \
4 | ern382 : 14, \
5 | ern383 : 14, \
6 | ern41 : 21, \
7 | ern411 : 21 \
8 | }
9 |
--------------------------------------------------------------------------------
/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | %d [%thread] %-5p %c - %m%n
8 |
9 |
10 | info
11 |
12 |
13 |
14 | true
15 | application.log
16 |
17 | %d %-4relative [%thread] %-5level %logger{35} - %msg%n
18 |
19 |
20 | application.log.%d{yyyy-MM-dd}.gz
21 | 90
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/src/main/schematron/commonreleasetypes/14/NewReleaseMessage_ReleaseProfile_MidiRingtone_14.sch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 | Schematron Release Profile for Midi Ringtone (version 1.4) for the
10 | NewReleaseMessage.
11 | © 2006-2017 Digital Data Exchange, LLC (DDEX)
12 | This ISO Schematron file is, together with all DDEX standards, subject to two licences: If
13 | you wish to evaluate whether the standard meets your needs please have a look at the
14 | Evaluation Licence at https://kb.ddex.net/display/HBK/Evaluation+Licence+for+DDEX+Standards.
15 | If you want to implement and use this DDEX standard, please take out an Implementation
16 | Licence. For details please go to http://ddex.net/apply-ddex-implementation-licence.
17 | Failing a rule with a role of 'Fatal Error' means that the Conformance Tester must recommend
18 | to not award a Conformance Certificate or to retract a Conformance Certificate if one has
19 | already been issued. Failing a rule with a role of 'Conditional Fatal Error' is the same as a
20 | 'Fatal Error', however, the rule may be ignored if the Conformance Tester has no means of
21 | asserting whether the condition expressed in the rule has been met.
22 | Failing a rule a rule with a role of 'Error' means that the Conformance Tester must
23 | recommend to award a Partial Conformance Certificate or to downgrade a Conformance Certificate
24 | that has already been issued. However, if more than 1 rules (representing 50% of all rules
25 | with a role of 'Error' or 'Conditional Error') have been failed at least once, the Conformance
26 | Tester must recommend to not award a Conformance Certificate or to retract a Conformance
27 | Certificate if one has already been issued. Failing a rule with a role of 'Conditional Error'
28 | is the same as an 'Error', however, the rule may be ignored if the Conformance Tester has no
29 | means of asserting whether the condition expressed in the rule has been met.
30 | The following Clauses from the Release Profile standard are NOT checked by this ISO
31 | Schematron file: 3.3.1(1), 3.3.1(7)-(8), 3.4, 4.1, 4.2, 4.3(11), 4.3(14), 4.3(15a), 4.3(16b),
32 | 4.3(17), 4.3(19), 4.3(27)-(29), 4.3(37), 4.16(11)-(12), 4.7(11)-(12), 4.8(8), 4.8(9d),
33 | 4.8(10f), 4.8(11)-(12), 4.10(9) and similar clauses, 4.10(10) and similar clauses, 4.14(8) and
34 | 4.15(11).
35 |
36 |
37 |
38 | Fatal Error: #Midi Ringtone) The ReleaseProfileVersionId should be
40 | 'CommonReleaseTypes/14/Ringtone' (Release Profile 1.4, Clause 3.2, Rule
41 | 1364-1).
42 |
43 |
44 |
45 |
46 |
48 | Fatal Error:
49 | #Midi Ringtone) A Track Release must not contain more than one Resource (Release Profile
50 | 1.4, Clause 3.1, Rule 1365-1).
51 |
52 |
53 |
54 |
55 |
56 | Fatal Error: #Midi Ringtone) A Ringtone must contain one
59 | RingtoneRelease or RingbackToneRelease (Release Profile 1.4, Clause 3.1, Rule
60 | 1366-1).
61 |
62 |
63 |
64 |
65 |
66 | Fatal Error:
67 | #Midi Ringtone) At least one DisplayArtist shall be provided (Release Profile 1.4,
68 | Clause 4.3(12c)+4.3(15b), Rule 1367-1).
69 |
70 |
71 |
72 |
73 |
74 | Error: #Midi Ringtone) DisplayArtistNames for Release and Resource must be
77 | different (Release Profile 1.4, Clause 4.3(16a), Rule 1368-1).
78 |
79 |
80 |
81 |
82 |
83 | Fatal Error: #Midi Ringtone) The MainRelease shall be identified by
86 | either a GRid or by an ICPN (Release Profile 1.4, Clause 4.9(4), Rule
87 | 1369-1).
88 |
89 |
90 |
91 |
92 |
93 | Fatal Error: #Midi Ringtone) A Ringtone must contain a RelatedRelease
96 | of type IsReleaseFromRelease (Release Profile 1.4, Clause 4.9(9), Rule
97 | 1372-1).
98 |
99 |
100 |
101 |
102 |
103 | Information: #Midi Ringtone) No
104 | deprecated Flags (IsHiddenResource) must be provided for SoundRecordings (Release
105 | Profile 1.4, Clause 4.10(7h), Rule 1373-1).
106 | Information: #Midi Ringtone) No
107 | deprecated Flags (IsBonusResource) must be provided for SoundRecordings (Release Profile
108 | 1.4, Clause 4.10(7h), Rule 1373-2).
109 |
110 |
111 |
112 |
113 |
114 | Fatal Error: #Midi
115 | Ringtone) A LabelName has to be specified for each Release (Release Profile 1.4,
116 | Clause 4.13(8), Rule 1374-1).
117 |
118 |
119 |
120 |
--------------------------------------------------------------------------------
/src/main/schematron/commonreleasetypes/14/NewReleaseMessage_ReleaseProfile_SingleResourceRelease_14.sch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 | Schematron Release Profile for Single Resource Release (version 1.4) for the
10 | NewReleaseMessage.
11 | © 2006-2017 Digital Data Exchange, LLC (DDEX)
12 | This ISO Schematron file is, together with all DDEX standards, subject to two licences: If
13 | you wish to evaluate whether the standard meets your needs please have a look at the
14 | Evaluation Licence at https://kb.ddex.net/display/HBK/Evaluation+Licence+for+DDEX+Standards.
15 | If you want to implement and use this DDEX standard, please take out an Implementation
16 | Licence. For details please go to http://ddex.net/apply-ddex-implementation-licence.
17 | Failing a rule with a role of 'Fatal Error' means that the Conformance Tester must recommend
18 | to not award a Conformance Certificate or to retract a Conformance Certificate if one has
19 | already been issued. Failing a rule with a role of 'Conditional Fatal Error' is the same as a
20 | 'Fatal Error', however, the rule may be ignored if the Conformance Tester has no means of
21 | asserting whether the condition expressed in the rule has been met.
22 | Failing a rule a rule with a role of 'Error' means that the Conformance Tester must
23 | recommend to award a Partial Conformance Certificate or to downgrade a Conformance Certificate
24 | that has already been issued. However, if more than 2 rules (representing 50% of all rules
25 | with a role of 'Error' or 'Conditional Error') have been failed at least once, the Conformance
26 | Tester must recommend to not award a Conformance Certificate or to retract a Conformance
27 | Certificate if one has already been issued. Failing a rule with a role of 'Conditional Error'
28 | is the same as an 'Error', however, the rule may be ignored if the Conformance Tester has no
29 | means of asserting whether the condition expressed in the rule has been met.
30 | The following Clauses from the Release Profile standard are NOT checked by this ISO
31 | Schematron file: 3.3.1(1), 3.3.1(7)-(8), 3.4, 4.1, 4.2, 4.3(11), 4.3(14), 4.3(15a), 4.3(16b),
32 | 4.3(17), 4.3(19), 4.3(27)-(29), 4.3(37), 4.16(11)-(12), 4.7(11)-(12), 4.8(8), 4.8(9d),
33 | 4.8(10f), 4.8(11)-(12), 4.10(9) and similar clauses, 4.10(10) and similar clauses, 4.14(8) and
34 | 4.15(11).
35 |
36 |
37 |
38 | Fatal Error: #Single Resource Release) The ReleaseProfileVersionId
40 | should be 'CommonReleaseTypes/14/SingleResourceRelease' (Release Profile 1.4, Clause
41 | 3.2, Rule 1463-1).
42 |
43 |
44 |
45 |
46 |
48 | Error: #Single Resource Release) Primary Video Resources should be
51 | identified with an ISRC (Release Profile 1.4, Clause 3.1, Rule 1464-1).
52 |
53 |
54 |
55 |
56 |
57 | Fatal Error:
58 | #Single Resource Release) A Single Resource Release must contain one (and only one)
59 | Resource (Release Profile 1.4, Clause 3.1, Rule 1465-1).
60 |
61 |
62 |
63 |
64 |
65 | Fatal Error: #Single Resource Release) A Single Resource Release must contain one
67 | SingleResourceRelease release (Release Profile 1.4, Clause 3.1, Rule
68 | 1466-1).
69 |
70 |
71 |
72 |
73 |
74 | Fatal Error: #Single
75 | Resource Release) A Single Resource Release must not contain a release resource
76 | structure (Release Profile 1.4, Clause 3.1, Rule 1467-1).
77 |
78 |
79 |
80 |
81 |
82 | Fatal Error: #Single Resource Release) A Single Resource Release must
85 | not contain any Secondary Resources (Release Profile 1.4, Clause 3.1, Rule
86 | 1468-1).
87 |
88 |
89 |
90 |
91 |
92 | Fatal Error:
93 | #Single Resource Release) At least one DisplayArtist shall be provided (Release Profile
94 | 1.4, Clause 4.3(12c)+4.3(15b), Rule 1469-1).
95 |
96 |
97 |
98 |
99 |
100 | Error: #Single Resource Release) DisplayArtistNames for Release and
103 | Resource must be different (Release Profile 1.4, Clause 4.3(16a), Rule
104 | 1470-1).
105 |
106 |
107 |
108 |
109 |
110 | Fatal Error: #Single Resource Release) The MainRelease shall be
113 | identified by either a GRid or by an ICPN (Release Profile 1.4, Clause 4.12(4), Rule
114 | 1471-1).
115 |
116 |
117 |
118 |
119 |
121 | Fatal Error: #Single Resource Release) Primary SoundRecording
124 | Resources shall be identified with an ISRC (Release Profile 1.4, Clause 4.12(5), Rule
125 | 1472-1).
126 |
127 |
128 |
129 |
130 |
132 | Fatal Error: #Single Resource Release) Secondary Resources shall be
135 | identified by a ProprietaryId (Release Profile 1.4, Clause 4.12(6), Rule
136 | 1473-1).
137 |
138 |
139 |
140 |
141 |
142 | Fatal Error: #Single Resource Release) A
143 | Single Resource Release must not contain any Resource Group (Release Profile 1.4,
144 | Clause 4.12(7), Rule 1474-1).
145 |
146 |
147 |
148 |
149 |
150 | Fatal Error:
151 | #Single Resource Release) A LabelName has to be specified for each Release (Release
152 | Profile 1.4, Clause 4.12(8), Rule 1475-1).
153 |
154 |
155 |
156 |
--------------------------------------------------------------------------------
/src/main/schematron/commonreleasetypes/21/NewReleaseMessage_ReleaseProfile_BoxedSetVariant_21.sch:
--------------------------------------------------------------------------------
1 |
2 |
5 |
10 | Schematron Release Profile for Boxed Set Variant (version 2.1) for the NewReleaseMessage.
11 | © 2006-2018 Digital Data Exchange, LLC (DDEX)
12 | This ISO Schematron file is, together with all DDEX standards, subject to two licences: If you wish to evaluate whether the standard meets your needs please have a look at the Evaluation Licence at https://kb.ddex.net/display/HBK/Evaluation+Licence+for+DDEX+Standards. If you want to implement and use this DDEX standard, please take out an Implementation Licence. For details please go to http://ddex.net/apply-ddex-implementation-licence.
13 | Failing a rule with a role of 'Fatal Error' means that the Conformance Tester must recommend to not award a Conformance Certificate or to retract a Conformance Certificate if one has already been issued. Failing a rule with a role of 'Conditional Fatal Error' is the same as a 'Fatal Error', however, the rule may be ignored if the Conformance Tester has no means of asserting whether the condition expressed in the rule has been met.
14 | Failing a rule a rule with a role of 'Error' means that the Conformance Tester must recommend to award a Partial Conformance Certificate or to downgrade a Conformance Certificate that has already been issued. However, if more than 1 rules (representing 50% of all rules with a role of 'Error') have been failed at least once, the Conformance Tester must recommend to not award a Conformance Certificate or to retract a Conformance Certificate if one has already been issued. Failing a rule with a role of 'Conditional Error' is the same as an 'Error', however, the rule may be ignored if the Conformance Tester has no means of asserting whether the condition expressed in the rule has been met.
15 | The following Clauses from the Release Profile standard are NOT checked by this ISO Schematron file: 5.1.1 (partly), 5.3.1.1(1-3, 7.1, 7.3, 9), 5.3.1.2(2.1, 3-4, 5.1), 5.3.1.3(4-5), 5.3.1.4(3-5, 8), 5.3.3.1-2, 5.3.3.4, 5.4.1(4.1), 5.4.3(5), 5.4.4(3, 5), 5.5.1(2), 5.5.2(2.4, 3.5-3.7), 5.6(1, 3). This file also does not check any rules specified in the ERN Message Suite Standard (Version 4.1) specifications, sections 6.4 and 6.5, except for 6.4.8-10
16 |
17 |
18 | Fatal Error (Boxed Set Variant): The ReleaseProfileVariantVersionId should conform to clause 5.2.2 (Release Profile 2.1, Clause 5.2.2, Rule 1543-1).
20 |
21 |
22 |
23 |
24 | Fatal Error (Boxed Set Variant): For a Release of this type, second-level ResourceGroups shall have a ResourceGroupType of either Side, Component, ComponentRelease or ReleaseComponent (Release Profile 2.1, Clause 5.3.1.2(5.2), Rule 1544-1).
26 |
27 |
28 |
29 |
30 | Fatal Error (Boxed Set Variant): A Release of this type must contain at least two ResourceGroups of type ReleaseComponent (Release Profile 2.1, Clause 5.5.1(1), Rule 1545-1).
32 |
33 |
34 |
35 |
36 | Fatal Error (Boxed Set Variant): The identifier of the 'component' Releases that make up the Boxed Set Release shall be placed into the ReleaseId composite of the relevant ResourceGroup (Release Profile 2.1, Clause 5.5.1(3), Rule 1546-1).
37 | Fatal Error (Boxed Set Variant): The identifier of the 'component' Releases that make up the Boxed Set Release shall be identified by either a GRid or an ICPN (Release Profile 2.1, Clause 5.5.1(3), Rule 1546-2).
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/src/main/schematron/commonreleasetypes/21/NewReleaseMessage_ReleaseProfile_ClassicalVariant_21.sch:
--------------------------------------------------------------------------------
1 |
2 |
5 |
10 | Schematron Release Profile for Classical Variant (version 2.1) for the NewReleaseMessage.
11 | © 2006-2018 Digital Data Exchange, LLC (DDEX)
12 | This ISO Schematron file is, together with all DDEX standards, subject to two licences: If you wish to evaluate whether the standard meets your needs please have a look at the Evaluation Licence at https://kb.ddex.net/display/HBK/Evaluation+Licence+for+DDEX+Standards. If you want to implement and use this DDEX standard, please take out an Implementation Licence. For details please go to http://ddex.net/apply-ddex-implementation-licence.
13 | Failing a rule with a role of 'Fatal Error' means that the Conformance Tester must recommend to not award a Conformance Certificate or to retract a Conformance Certificate if one has already been issued. Failing a rule with a role of 'Conditional Fatal Error' is the same as a 'Fatal Error', however, the rule may be ignored if the Conformance Tester has no means of asserting whether the condition expressed in the rule has been met.
14 | Failing a rule a rule with a role of 'Error' means that the Conformance Tester must recommend to award a Partial Conformance Certificate or to downgrade a Conformance Certificate that has already been issued. However, if more than 1 rules (representing 50% of all rules with a role of 'Error') have been failed at least once, the Conformance Tester must recommend to not award a Conformance Certificate or to retract a Conformance Certificate if one has already been issued. Failing a rule with a role of 'Conditional Error' is the same as an 'Error', however, the rule may be ignored if the Conformance Tester has no means of asserting whether the condition expressed in the rule has been met.
15 | The following Clauses from the Release Profile standard are NOT checked by this ISO Schematron file: 5.1.1 (partly), 5.3.1.1(1-3, 7.1, 7.3, 9), 5.3.1.2(2.1, 3-4, 5.1), 5.3.1.3(4-5), 5.3.1.4(3-5, 8), 5.3.3.1-2, 5.3.3.4, 5.4.1(4.1), 5.4.3(5), 5.4.4(3, 5), 5.5.1(2), 5.5.2(2.4, 3.5-3.7), 5.6(1, 3). This file also does not check any rules specified in the ERN Message Suite Standard (Version 4.1) specifications, sections 6.4 and 6.5, except for 6.4.8-10
16 |
17 |
18 | Fatal Error (Classical Variant): The ReleaseProfileVariantVersionId should conform to clause 5.2.2 (Release Profile 2.1, Clause 5.2.2, Rule 1547-1).
20 |
21 |
22 |
23 |
24 | Fatal Error (Classical Variant): For a Release of this type, second-level ResourceGroups shall have a ResourceGroupType of either Side, Component or MultiWorkPart (Release Profile 2.1, Clause 5.3.1.2(5.2), Rule 1548-1).
26 |
27 |
28 |
29 |
30 | Fatal Error (Classical Variant): A Release of this type must contain SoundRecordings of type MusicalWorkSoundRecording (Release Profile 2.1, Clause 5.5.2(1), Rule 1549-1).
32 |
33 |
34 |
35 |
36 | Fatal Error (Classical Variant): A Release of this type must contain at least one ResourceGroup of type MultiWorkPart (Release Profile 2.1, Clause 5.5.2(2.1), Rule 1550-1).
38 |
39 |
40 |
41 |
42 | Conditional Fatal Error (Classical Variant): A Release of this type must contain at least two ResourceGroupContentItems in each ResourceGroup of type MultiWorkPart (Release Profile 2.1, Clause 5.5.2(2.2), Rule 1551-1).
44 |
45 |
46 |
47 |
48 | Fatal Error (Classical Variant): (Release Profile 2.1, Clause 5.5.2(2.5), Rule 1552-1).
50 |
51 |
52 |
53 |
54 | Warning (Classical Variant): A Resource in a Release of this type must contain an AdditionalTitle of type FormalTitle (Release Profile 2.1, Clause 5.5.2(3.1), Rule 1553-1).
55 |
56 |
57 |
58 |
59 | Warning (Classical Variant): A Resource in a Release of this type may contain an AdditionalTitle of type GroupingTitle (Release Profile 2.1, Clause 5.5.2(3.2), Rule 1554-1).
60 |
61 |
62 |
63 |
64 | Fatal Error (Classical Variant): A ResourceGroup in a Release of this type must contain a DisplayTitle and/or a DisplayTitleText (Release Profile 2.1, Clause 5.5.2(3.3), Rule 1555-1).
65 |
66 |
67 |
68 |
69 | Warning (Classical Variant): A ResourceGroup in a Release of this type shall contain an AdditionalTitle of type FormalTitle (Release Profile 2.1, Clause 5.5.2(3.4), Rule 1556-1).
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/src/main/schematron/commonreleasetypes/21/NewReleaseMessage_ReleaseProfile_ReleaseProfileTrackReleaseRules_21.sch:
--------------------------------------------------------------------------------
1 |
2 |
5 |
10 | Schematron Release Profile for Release Profile Track Release Rules (version 2.1) for the NewReleaseMessage.
11 | © 2006-2018 Digital Data Exchange, LLC (DDEX)
12 | This ISO Schematron file is, together with all DDEX standards, subject to two licences: If you wish to evaluate whether the standard meets your needs please have a look at the Evaluation Licence at https://kb.ddex.net/display/HBK/Evaluation+Licence+for+DDEX+Standards. If you want to implement and use this DDEX standard, please take out an Implementation Licence. For details please go to http://ddex.net/apply-ddex-implementation-licence.
13 | Failing a rule with a role of 'Fatal Error' means that the Conformance Tester must recommend to not award a Conformance Certificate or to retract a Conformance Certificate if one has already been issued. Failing a rule with a role of 'Conditional Fatal Error' is the same as a 'Fatal Error', however, the rule may be ignored if the Conformance Tester has no means of asserting whether the condition expressed in the rule has been met.
14 | Failing a rule a rule with a role of 'Error' means that the Conformance Tester must recommend to award a Partial Conformance Certificate or to downgrade a Conformance Certificate that has already been issued. However, if more than 1 rules (representing 50% of all rules with a role of 'Error') have been failed at least once, the Conformance Tester must recommend to not award a Conformance Certificate or to retract a Conformance Certificate if one has already been issued. Failing a rule with a role of 'Conditional Error' is the same as an 'Error', however, the rule may be ignored if the Conformance Tester has no means of asserting whether the condition expressed in the rule has been met.
15 |
16 |
17 | Fatal Error (Release Profile Track Release Rules): A Release of this type must contain exactly one TrackRelease for each Primary Resource referenced in the Main Release (Release Profile 2.1, Clause 5.1.1(b), Rule 1538-1).
19 |
20 |
21 |
22 |
23 | Fatal Error (Release Profile Track Release Rules): An ISRC as an identifier for a TrackRelease shall be communicated as a ProprietaryId (Release Profile 2.1, Clause 5.3.1.3(3), Rule 1539-1).
24 |
25 |
26 |
27 |
28 | Fatal Error (Release Profile Track Release Rules): A TrackRelease must refer to one Primary Resource (Release Profile 2.1, Clause 5.6(2a), Rule 1540-1).
29 |
30 |
31 |
32 |
33 | Fatal Error (Release Profile Track Release Rules): A TrackRelease must not refer to a Secondary Resource (Release Profile 2.1, Clause 5.6(2b), Rule 1541-1).
35 |
36 |
37 |
38 |
39 | Error (Release Profile Track Release Rules): Title information for TrackReleases shall only be provided if it differs from the title information provided on the Resource (Release Profile 2.1, Clause 5.6(4), Rule 1542-1).
41 | Error (Release Profile Track Release Rules): Title information for TrackReleases shall only be provided if it differs from the title information provided on the Resource (Release Profile 2.1, Clause 5.6(4), Rule 1542-2).
43 | Error (Release Profile Track Release Rules): Title information for TrackReleases shall only be provided if it differs from the title information provided on the Resource (Release Profile 2.1, Clause 5.6(4), Rule 1542-3).
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/src/main/schematron/iso_abstract_expand.xsl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
20 |
43 |
66 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
111 |
112 |
113 |
129 |
130 |
131 |
132 | Suppressed abstract pattern
133 | was here
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 | Start pattern based on abstract
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
194 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
--------------------------------------------------------------------------------
/src/main/schematron/iso_svrl_for_xslt2.xsl:
--------------------------------------------------------------------------------
1 |
2 |
102 |
125 |
126 |
127 |
128 |
140 |
141 |
150 |
151 |
154 |
155 |
156 |
163 |
164 | true
165 | true
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 | #ALL
177 |
178 |
179 | false
180 | true
181 | true
182 |
183 |
184 |
185 |
186 | false
187 |
188 |
189 | default
190 |
191 |
192 |
193 |
194 | 1
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 | xslt1
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 | TERMINATING
321 |
322 |
323 | TERMINATING
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 | TERMINATING
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
519 |
520 |
521 |
522 |
523 |
524 |
525 |
526 |
527 |
528 |
529 |
530 |
531 |
532 |
533 |
534 |
535 |
536 |
537 |
538 |
539 |
540 |
541 |
542 |
543 |
544 |
545 |
546 |
547 |
548 |
549 |
550 |
551 |
552 |
553 |
554 |
555 |
556 |
557 |
558 |
559 |
560 |
561 |
562 |
563 |
564 |
565 |
566 |
567 |
568 |
569 |
570 |
571 |
572 |
573 |
574 |
575 |
576 |
577 |
578 |
579 |
580 |
581 |
582 |
583 |
584 |
585 |
586 |
587 |
588 |
589 |
590 |
591 |
592 |
593 |
594 |
595 |
596 |
597 |
598 |
599 |
600 |
601 |
602 |
603 |
604 |
605 |
606 |
607 |
608 |
609 |
610 |
611 |
612 |
613 |
614 |
615 |
616 |
617 |
618 |
619 |
620 |
621 |
622 |
623 |
624 |
625 |
626 |
627 |
628 |
629 |
630 |
631 |
632 |
633 |
634 |
635 |
636 |
637 |
638 |
639 |
640 |
641 |
642 |
643 |
644 |
646 |
647 |
648 |
649 |
650 |
651 |
652 |
653 |
654 |
655 |
656 |
657 |
658 |
659 |
660 |
661 |
662 |
663 |
664 |
665 |
666 |
667 |
668 |
669 |
670 |
671 |
672 |
673 |
674 |
675 |
676 |
677 |
678 |
679 |
680 |
681 |
682 |
683 |
684 |
685 |
686 |
687 |
--------------------------------------------------------------------------------