@@ -70,16 +70,54 @@ val extractors = Server.getInstance().getAvailableExtractorNames(language)
7070 <option value =" rdf-json" >RDF / JSON </option >
7171 </select ><br />
7272 Select Extractors :< br/>
73- <label for =" mappings" >Mappings Only <input type =" checkbox" name =" extractors" value =" mappings" id =" mappings" /></label ><br />
74- <label for =" custom" >All Enabled Extractors <input type =" checkbox" name =" extractors" value =" custom" id =" custom" /></label ><br />
75- {extractors.map(extractor => {
76- val sanitizedId = extractor.replaceAll(" [^a-zA-Z0-9_-]" , " _" )
77- <span >
78- <label for ={sanitizedId}>{extractor} <input type =" checkbox" name =" extractors" value ={extractor} id ={sanitizedId}/></label ><br />
79- </span >
73+ <select id =" extractorMode" onchange =" toggleCustomExtractors()" >
74+ <option value =" mappings" >Mappings Only </option >
75+ <option value =" custom" >All Enabled Extractors </option >
76+ <option value =" custom-selection" >Custom </option >
77+ </select ><br />
78+ <div id =" customExtractors" style =" display:none; margin-top:10px; padding:10px; border:1px solid #ddd; background-color:#f9f9f9;" >
79+ <strong >Select extractors to combine:</ strong>< br/>
80+ <label ><input type =" checkbox" name =" extractors" value =" mappings" id =" cb-mappings" /> Mappings Only </label ><br />
81+ <label ><input type =" checkbox" name =" extractors" value =" custom" id =" cb-custom" /> All Enabled Extractors </label ><br />
82+ {extractors.map(extractor => {
83+ val sanitizedId = " cb-" + extractor.replaceAll(" [^a-zA-Z0-9_-]" , " _" )
84+ <label ><input type =" checkbox" name =" extractors" value ={extractor} id ={sanitizedId}/> {extractor}</label ><br />
8085})}
86+ </div >
8187 <input type =" submit" value =" Extract" />
8288 </form >
89+ <script type =" text/javascript" >
90+ {scala.xml.Unparsed ("""
91+ function toggleCustomExtractors() {
92+ var mode = document.getElementById('extractorMode').value;
93+ var customDiv = document.getElementById('customExtractors');
94+
95+ if (mode === 'custom-selection') {
96+ customDiv.style.display = 'block';
97+ } else {
98+ customDiv.style.display = 'none';
99+ }
100+ }
101+
102+ document.querySelector('form').addEventListener('submit', function(e) {
103+ var mode = document.getElementById('extractorMode').value;
104+
105+ if (mode === 'mappings') {
106+ var input = document.createElement('input');
107+ input.type = 'hidden';
108+ input.name = 'extractors';
109+ input.value = 'mappings';
110+ this.appendChild(input);
111+ } else if (mode === 'custom') {
112+ var input = document.createElement('input');
113+ input.type = 'hidden';
114+ input.name = 'extractors';
115+ input.value = 'custom';
116+ this.appendChild(input);
117+ }
118+ });
119+ """ )}
120+ </script >
83121 </div >
84122 </div >
85123 </body >
@@ -251,23 +289,34 @@ name match {
251289 }
252290
253291 if (errors.nonEmpty) {
292+ logger.warning(s " Partial extraction completed with errors: ${errors.mkString(" ; " )}" )
293+ if (collector.quads.isEmpty) {
254294 val errorMessage = if (errors.size == 1 ) errors.head
255295 else s " Multiple extractor errors: \n ${errors.mkString(" \n " )}"
256296 val statusCode = if (errors.exists(_.contains(" not found" ))) Response .Status .BAD_REQUEST
257297 else Response .Status .INTERNAL_SERVER_ERROR
258298 throw new WebApplicationException (new Exception (errorMessage), statusCode)
299+ }
259300 }
260301
261302 val writer = new StringWriter
262303 val formatter = createFormatter(finalFormat, writer)
304+
305+ if (errors.nonEmpty && (finalFormat.contains(" turtle" ) || finalFormat.contains(" n-triples" ) || finalFormat.contains(" n-quads" ))) {
306+ writer.write(" # Warning: Partial results - some extractors failed:\n " )
307+ errors.foreach(err => writer.write(s " # - $err\n " ))
308+ writer.write(" \n " )
309+ }
310+
263311 val finalDestination = new DeduplicatingDestination (new WriterDestination (() => writer, formatter))
264312 finalDestination.open()
265313 finalDestination.write(collector.quads)
266314 finalDestination.close()
267315
268- Response .ok(writer.toString)
316+ val responseBuilder = Response .ok(writer.toString)
269317 .header(HttpHeaders .CONTENT_TYPE , contentType + " ; charset=UTF-8" )
270- .build()
318+ if (errors.nonEmpty) responseBuilder.header(" X-Extraction-Warnings" , errors.mkString(" ; " ))
319+ responseBuilder.build()
271320
272321 case specificExtractor =>
273322 val writer = new StringWriter
0 commit comments