Skip to content

Commit

Permalink
Merge 740509b into 4b4f737
Browse files Browse the repository at this point in the history
  • Loading branch information
joachimvh committed Nov 2, 2020
2 parents 4b4f737 + 740509b commit a04d111
Show file tree
Hide file tree
Showing 10 changed files with 726 additions and 22 deletions.
3 changes: 3 additions & 0 deletions .eslintrc.js
Expand Up @@ -5,6 +5,9 @@ module.exports = {
tsconfigRootDir: __dirname, // this is the reason this is a .js file
project: ['./tsconfig.json'],
},
globals: {
NodeJS: 'readonly'
},
plugins: [
'tsdoc',
'import',
Expand Down
1 change: 1 addition & 0 deletions index.ts
Expand Up @@ -84,6 +84,7 @@ export * from './src/server/HttpResponse';
export * from './src/storage/accessors/DataAccessor';
export * from './src/storage/accessors/FileDataAccessor';
export * from './src/storage/accessors/InMemoryDataAccessor';
export * from './src/storage/accessors/SparqlDataAccessor';

// Storage/Conversion
export * from './src/storage/conversion/ChainedConverter';
Expand Down
99 changes: 99 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Expand Up @@ -74,6 +74,7 @@
"@types/n3": "^1.4.4",
"@types/node": "^14.10.2",
"@types/rdf-js": "^4.0.0",
"@types/sparqljs": "^3.1.0",
"@types/streamify-array": "^1.0.0",
"@types/uuid": "^8.3.0",
"@types/yargs": "^15.0.5",
Expand All @@ -82,12 +83,14 @@
"componentsjs": "^3.6.0",
"cors": "^2.8.5",
"express": "^4.17.1",
"fetch-sparql-endpoint": "^1.8.0",
"mime-types": "^2.1.27",
"n3": "^1.6.3",
"rdf-parse": "^1.5.0",
"rdf-serialize": "^1.0.0",
"rdf-terms": "^1.5.1",
"sparqlalgebrajs": "^2.3.1",
"sparqljs": "^3.1.2",
"streamify-array": "^1.0.1",
"uuid": "^8.3.0",
"winston": "^3.3.3",
Expand Down
60 changes: 52 additions & 8 deletions src/storage/RepresentationConvertingStore.ts
Expand Up @@ -9,9 +9,15 @@ import { PassthroughStore } from './PassthroughStore';
import type { ResourceStore } from './ResourceStore';

/**
* Store that overrides the `getRepresentation` function.
* Tries to convert the {@link Representation} it got from the source store
* so it matches one of the given type preferences.
* Store that overrides all functions that take or output a {@link Representation},
* so `getRepresentation`, `addResource`, and `setRepresentation`.
*
* For incoming representations, they will be converted if an incoming converter and preferences have been set.
* The converted Representation will be passed along.
*
* For outgoing representations, they will be converted if there is an outgoing converter.
*
* Conversions will only happen if required and will not happen if the Representation is already in the correct format.
*
* In the future this class should take the preferences of the request into account.
* Even if there is a match with the output from the store,
Expand All @@ -20,21 +26,47 @@ import type { ResourceStore } from './ResourceStore';
export class RepresentationConvertingStore<T extends ResourceStore = ResourceStore> extends PassthroughStore<T> {
protected readonly logger = getLoggerFor(this);

private readonly converter: RepresentationConverter;
private readonly inConverter?: RepresentationConverter;
private readonly outConverter?: RepresentationConverter;

private readonly inType?: string;

public constructor(source: T, converter: RepresentationConverter) {
/**
* TODO: This should take RepresentationPreferences instead of a type string when supported by Components.js.
*/
public constructor(source: T, options: {
outConverter?: RepresentationConverter;
inConverter?: RepresentationConverter;
inType?: string;
}) {
super(source);
this.converter = converter;
this.inConverter = options.inConverter;
this.outConverter = options.outConverter;
this.inType = options.inType;
}

public async getRepresentation(identifier: ResourceIdentifier, preferences: RepresentationPreferences,
conditions?: Conditions): Promise<Representation> {
const representation = await super.getRepresentation(identifier, preferences, conditions);
if (this.matchesPreferences(representation, preferences)) {
if (!this.outConverter || this.matchesPreferences(representation, preferences)) {
return representation;
}
this.logger.info(`Convert ${identifier.path} from ${representation.metadata.contentType} to ${preferences.type}`);
return this.converter.handleSafe({ identifier, representation, preferences });
return this.outConverter.handleSafe({ identifier, representation, preferences });
}

public async addResource(container: ResourceIdentifier, representation: Representation,
conditions?: Conditions): Promise<ResourceIdentifier> {
// We can potentially run into problems here if we convert a turtle document where the base IRI is required,
// since we don't know the resource IRI yet at this point.
representation = await this.convertInRepresentation(container, representation);
return this.source.addResource(container, representation, conditions);
}

public async setRepresentation(identifier: ResourceIdentifier, representation: Representation,
conditions?: Conditions): Promise<void> {
representation = await this.convertInRepresentation(identifier, representation);
return this.source.setRepresentation(identifier, representation, conditions);
}

private matchesPreferences(representation: Representation, preferences: RepresentationPreferences): boolean {
Expand All @@ -49,4 +81,16 @@ export class RepresentationConvertingStore<T extends ResourceStore = ResourceSto
matchingMediaType(type.value, contentType)),
);
}

private async convertInRepresentation(identifier: ResourceIdentifier, representation: Representation):
Promise<Representation> {
if (!this.inType) {
return representation;
}
const inPreferences: RepresentationPreferences = { type: [{ value: this.inType, weight: 1 }]};
if (!inPreferences || !this.inConverter || this.matchesPreferences(representation, inPreferences)) {
return representation;
}
return this.inConverter.handleSafe({ identifier, representation, preferences: inPreferences });
}
}

0 comments on commit a04d111

Please sign in to comment.