@@ -13,20 +13,20 @@ const crypto = require('crypto')
1313
1414const DEFAULT_TARGET_TYPE = 'text/turtle'
1515
16- // Patch handlers by request body content type
17- const PATCHERS = {
18- 'application/sparql-update' : require ( './patch/sparql-update-patcher .js' ) ,
19- 'text/n3' : require ( './patch/n3-patcher .js' )
16+ // Patch parsers by request body content type
17+ const PATCH_PARSERS = {
18+ 'application/sparql-update' : require ( './patch/sparql-update-parser .js' ) ,
19+ 'text/n3' : require ( './patch/n3-patch-parser .js' )
2020}
2121
2222// Handles a PATCH request
2323function patchHandler ( req , res , next ) {
24- debug ( ' PATCH -- ' + req . originalUrl )
24+ debug ( ` PATCH -- ${ req . originalUrl } ` )
2525 res . header ( 'MS-Author-Via' , 'SPARQL' )
2626
2727 // Obtain details of the target resource
2828 const ldp = req . app . locals . ldp
29- const root = ! ldp . idp ? ldp . root : ldp . root + req . hostname + '/'
29+ const root = ! ldp . idp ? ldp . root : ` ${ ldp . root } ${ req . hostname } /`
3030 const target = { }
3131 target . file = utils . uriToFilename ( req . path , root )
3232 target . uri = utils . uriAbs ( req ) + req . originalUrl
@@ -39,17 +39,18 @@ function patchHandler (req, res, next) {
3939 patch . uri = `${ target . uri } #patch-${ hash ( patch . text ) } `
4040 patch . contentType = ( req . get ( 'content-type' ) || '' ) . match ( / ^ [ ^ ; \s ] * / ) [ 0 ]
4141 debug ( 'PATCH -- Received patch (%d bytes, %s)' , patch . text . length , patch . contentType )
42-
43- // Find the appropriate patcher for the given content type
44- const patchGraph = PATCHERS [ patch . contentType ]
45- if ( ! patchGraph ) {
46- return next ( error ( 415 , 'Unsupported patch content type: ' + patch . contentType ) )
42+ const parsePatch = PATCH_PARSERS [ patch . contentType ]
43+ if ( ! parsePatch ) {
44+ return next ( error ( 415 , `Unsupported patch content type: ${ patch . contentType } ` ) )
4745 }
4846
49- // Read the RDF graph to be patched from the file
50- readGraph ( target )
47+ // Parse the target graph and the patch document
48+ Promise . all ( [
49+ readGraph ( target ) ,
50+ parsePatch ( target . uri , patch . uri , patch . text )
51+ ] )
5152 // Patch the graph and write it back to the file
52- . then ( graph => patchGraph ( graph , target . uri , patch . uri , patch . text ) )
53+ . then ( ( [ graph , patchObject ] ) => applyPatch ( patchObject , graph , target ) )
5354 . then ( graph => writeGraph ( graph , target ) )
5455 // Send the result to the client
5556 . then ( result => { res . send ( result ) } )
@@ -74,7 +75,7 @@ function readGraph (resource) {
7475 fileContents = ''
7576 // Fail on all other errors
7677 } else {
77- return reject ( error ( 500 , 'Patch: Original file read error:' + err ) )
78+ return reject ( error ( 500 , ` Original file read error: ${ err } ` ) )
7879 }
7980 }
8081 debug ( 'PATCH -- Read target file (%d bytes)' , fileContents . length )
@@ -88,22 +89,38 @@ function readGraph (resource) {
8889 try {
8990 $rdf . parse ( fileContents , graph , resource . uri , resource . contentType )
9091 } catch ( err ) {
91- throw error ( 500 , ' Patch: Target ' + resource . contentType + ' file syntax error:' + err )
92+ throw error ( 500 , ` Patch: Target ${ resource . contentType } file syntax error: ${ err } ` )
9293 }
9394 debug ( 'PATCH -- Parsed target file' )
9495 return graph
9596 } )
9697}
9798
99+ // Applies the patch to the RDF graph
100+ function applyPatch ( patchObject , graph , target ) {
101+ debug ( 'PATCH -- Applying patch' )
102+ return new Promise ( ( resolve , reject ) =>
103+ graph . applyPatch ( patchObject , graph . sym ( target . uri ) , ( err ) => {
104+ if ( err ) {
105+ const message = err . message || err // returns string at the moment
106+ debug ( `PATCH -- FAILED. Returning 409. Message: '${ message } '` )
107+ return reject ( error ( 409 , `The patch could not be applied. ${ message } ` ) )
108+ }
109+ resolve ( graph )
110+ } )
111+ )
112+ }
113+
98114// Writes the RDF graph to the given resource
99115function writeGraph ( graph , resource ) {
116+ debug ( 'PATCH -- Writing patched file' )
100117 return new Promise ( ( resolve , reject ) => {
101118 const resourceSym = graph . sym ( resource . uri )
102119 const serialized = $rdf . serialize ( resourceSym , graph , resource . uri , resource . contentType )
103120
104121 fs . writeFile ( resource . file , serialized , { encoding : 'utf8' } , function ( err ) {
105122 if ( err ) {
106- return reject ( error ( 500 , ' Failed to write file back after patch: ' + err ) )
123+ return reject ( error ( 500 , ` Failed to write file after patch: ${ err } ` ) )
107124 }
108125 debug ( 'PATCH -- applied successfully' )
109126 resolve ( 'Patch applied successfully.\n' )
0 commit comments