refactor: Move file related metadata to FileResourceStore

This commit is contained in:
Joachim Van Herwegen
2020-09-23 17:05:59 +02:00
parent 22962192ff
commit fa935cc4c7
3 changed files with 55 additions and 30 deletions

View File

@@ -3,7 +3,7 @@ import { createReadStream, createWriteStream, promises as fsPromises } from 'fs'
import { posix } from 'path';
import type { Readable } from 'stream';
import { DataFactory } from 'n3';
import type { Quad } from 'rdf-js';
import type { NamedNode, Quad } from 'rdf-js';
import streamifyArray from 'streamify-array';
import type { Representation } from '../ldp/representation/Representation';
import { RepresentationMetadata } from '../ldp/representation/RepresentationMetadata';
@@ -16,8 +16,8 @@ import { UnsupportedMediaTypeHttpError } from '../util/errors/UnsupportedMediaTy
import type { InteractionController } from '../util/InteractionController';
import type { MetadataController } from '../util/MetadataController';
import { CONTENT_TYPE, DCTERMS, HTTP, POSIX, RDF, XSD } from '../util/UriConstants';
import { toTypedLiteral } from '../util/UriUtil';
import { ensureTrailingSlash } from '../util/Util';
import { toNamedNode, toTypedLiteral } from '../util/UriUtil';
import { ensureTrailingSlash, pushQuad } from '../util/Util';
import type { ExtensionBasedMapper } from './ExtensionBasedMapper';
import type { ResourceLink } from './FileIdentifierMapper';
import type { ResourceStore } from './ResourceStore';
@@ -244,11 +244,11 @@ export class FileResourceStore implements ResourceStore {
*/
private async getDirectoryRepresentation(resourceLink: ResourceLink, stats: Stats): Promise<Representation> {
const files = await fsPromises.readdir(resourceLink.filePath);
const quads: Quad[] = [];
const containerURI = resourceLink.identifier.path;
const containerURI = DataFactory.namedNode(resourceLink.identifier.path);
quads.push(...this.metadataController.generateResourceQuads(containerURI, stats));
const quads = this.metadataController.generateResourceQuads(containerURI, true);
quads.push(...this.generatePosixQuads(containerURI, stats));
quads.push(...await this.getDirChildrenQuadRepresentation(files, resourceLink.filePath, containerURI));
let rawMetadata: Quad[] = [];
@@ -259,9 +259,11 @@ export class FileResourceStore implements ResourceStore {
// Metadata file doesn't exist so lets keep `rawMetaData` an empty array.
}
const metadata = new RepresentationMetadata(containerURI).addQuads(rawMetadata)
.set(DCTERMS.modified, toTypedLiteral(stats.mtime.toISOString(), XSD.dateTime))
.set(CONTENT_TYPE, INTERNAL_QUADS);
const metadata = new RepresentationMetadata(containerURI, {
[DCTERMS.modified]: toTypedLiteral(stats.mtime.toISOString(), XSD.dateTime),
[CONTENT_TYPE]: INTERNAL_QUADS,
});
metadata.addQuads(rawMetadata);
return {
binary: false,
@@ -278,7 +280,8 @@ export class FileResourceStore implements ResourceStore {
*
* @returns A promise containing all quads.
*/
private async getDirChildrenQuadRepresentation(files: string[], path: string, containerURI: string): Promise<Quad[]> {
private async getDirChildrenQuadRepresentation(files: string[], path: string, containerURI: NamedNode):
Promise<Quad[]> {
const quads: Quad[] = [];
const childURIs: string[] = [];
for (const childName of files) {
@@ -290,7 +293,9 @@ export class FileResourceStore implements ResourceStore {
const childLink = await this.resourceMapper
.mapFilePathToUrl(joinPath(path, childName), childStats.isDirectory());
quads.push(...this.metadataController.generateResourceQuads(childLink.identifier.path, childStats));
const subject = DataFactory.namedNode(childLink.identifier.path);
quads.push(...this.metadataController.generateResourceQuads(subject, childStats.isDirectory()));
quads.push(...this.generatePosixQuads(subject, childStats));
childURIs.push(childLink.identifier.path);
} catch {
// Skip the child if there is an error.
@@ -302,6 +307,21 @@ export class FileResourceStore implements ResourceStore {
return quads.concat(containsQuads);
}
/**
* Helper function to add file system related metadata
* @param subject - Subject for the new quads.
* @param stats - Stats of the file/directory corresponding to the resource.
*/
private generatePosixQuads(subject: NamedNode, stats: Stats): Quad[] {
const quads: Quad[] = [];
pushQuad(quads, subject, toNamedNode(POSIX.size), toTypedLiteral(stats.size, XSD.integer));
pushQuad(quads, subject, toNamedNode(DCTERMS.modified), toTypedLiteral(stats.mtime.toISOString(), XSD.dateTime));
pushQuad(quads, subject, toNamedNode(POSIX.mtime), toTypedLiteral(
Math.floor(stats.mtime.getTime() / 1000), XSD.integer,
));
return quads;
}
/**
* Helper function to (re)write file for the resource if no container with that identifier exists.
* @param path - The path to the directory of the file.