Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/main/RdfMapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ export class RdfMapper {
* @param type
* @param ttlData
*/
public static async deserializeAsync<T>(type: { new(): T }, ttlData: string): Promise<T> {
public static async deserializeAsync<T>(type: { new(): T }, ttlData: string): Promise<T|T[]> {
const deserializeProcessor: DeserializerProcessor = new DeserializerProcessor();
return deserializeProcessor.deserializeAsync(type, ttlData);
}

public static deserialize<T>(type: { new(): T }, ttlData: string): T {
public static deserialize<T>(type: { new(): T }, ttlData: string): T|T[] {
const deserializeProcessor: DeserializerProcessor = new DeserializerProcessor();
return deserializeProcessor.deserialize(type, ttlData);
}
Expand Down
21 changes: 12 additions & 9 deletions src/main/processors/DeserializerProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export class DeserializerProcessor {

constructor() {}

public async deserializeAsync<T>(type: { new(): T }, ttlData: string): Promise<T> {
public async deserializeAsync<T>(type: { new(): T }, ttlData: string): Promise<T|T[]> {
let qa: QuadsAndPrefixes;
try {
qa = await this.getQuadsAndPrefixes(ttlData);
Expand All @@ -45,13 +45,13 @@ export class DeserializerProcessor {
}
}

public deserialize<T>(type: { new(): T }, ttlData: string): T {
public deserialize<T>(type: { new(): T }, ttlData: string): T|T[] {
let qs: Quad[];
try {
qs = this.getQuads(ttlData);
const store: N3Store = new Store();
store.addQuads(qs);
const dtoInstance: T = this.process(type, store);
const dtoInstance: T|T[] = this.process(type, store);
return dtoInstance;
} catch (e) {
throw new TurtleParseError(e);
Expand Down Expand Up @@ -133,17 +133,16 @@ export class DeserializerProcessor {
return dtoInstance;
}

private process<T>(type: { new(): T }, store: N3Store, object?: Quad_Object): T {
const dtoInstance = new type();
private process<T>(type: { new(): T }, store: N3Store, object?: Quad_Object): T|T[] {

const ns: IRdfPrefixes = Reflect.getMetadata('RdfPrefixes', type.prototype);
const beanType: string = Reflect.getMetadata('RdfBean', type.prototype);
const properties: IRdfPropertyMetadata[] = Reflect.getMetadata('RdfProperty-non-instance', type.prototype);
const subject: IRdfSubjectMetadata = Reflect.getMetadata('RdfSubject-non-instance', type.prototype);

const numTriples: Quad[] = this.getNumTriplesByBeanType(beanType, store, ns);
if (numTriples.length > 0) {
const triple: Quad = numTriples[0];
const dtoInstances = numTriples.map((triple: Quad) => {
const dtoInstance = new type();
// Get URI and set the value for key which contains @RdfSubject annotation
if (subject) {
dtoInstance[subject.key] = Utils.getUUIDFromResourceSubject(triple.subject.value, subject.prop, ns);
Expand Down Expand Up @@ -184,11 +183,15 @@ export class DeserializerProcessor {
}
}
});
return dtoInstance;
})

if (numTriples.length === 1) {
return dtoInstances[0]
} else {
return dtoInstances
}

return dtoInstance;

}

private processPrimitiveByXSDType(value: string, xsdType: string): any {
Expand Down
34 changes: 27 additions & 7 deletions src/test/deserialize.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {RdfMapper} from '../main/RdfMapper';
import {Person, personTTL, recipeVideoTTL} from './models/models';
import {Person, personsTTL, personTTL, recipeVideoTTL} from './models/models';
import {oneToOneRelationship, PersonHasAddress} from './models/oneToOneModels';
import {Recipe, Video} from './models/recipes';

Expand All @@ -14,7 +14,7 @@ function logResult(assertName: string, result: any, logOnlyMe = false) {

describe('Test TTL Deserialization', () => {
it('Deserialize basic ttl (async)', async (done) => {
const instance: Person = await RdfMapper.deserializeAsync(Person, personTTL);
const instance: Person = await RdfMapper.deserializeAsync(Person, personTTL) as Person;

// console.log(JSON.stringify(instance));
expect(instance.firstName).toEqual('David');
Expand All @@ -28,7 +28,7 @@ describe('Test TTL Deserialization', () => {
});

it('Deserialize basic ttl', () => {
const instance: Person = RdfMapper.deserialize(Person, personTTL);
const instance: Person|Person[] = RdfMapper.deserialize(Person, personTTL) as Person;

// console.log(JSON.stringify(instance));
expect(instance.firstName).toEqual('David');
Expand All @@ -39,8 +39,28 @@ describe('Test TTL Deserialization', () => {
expect(instance.title).toEqual('Mr');
});

it('Deserialize basic ttl with more than one instance', () => {
const instance: Person|Person[] = RdfMapper.deserialize(Person, personsTTL);
// console.log(JSON.stringify(instance));
expect(typeof instance).toEqual('array');

expect(instance[0].firstName).toEqual('David');
expect(instance[0].uuid).toEqual('1234567');
expect(instance[0].name).toEqual('David Banner');
expect(instance[0].nick).toEqual('hulk');
expect(instance[0].surname).toEqual('Banner');
expect(instance[0].title).toEqual('Mr');

expect(instance[1].firstName).toEqual('Sally');
expect(instance[1].uuid).toEqual('7654321');
expect(instance[1].name).toEqual('Sally Flickard');
expect(instance[1].nick).toEqual('punchy');
expect(instance[1].surname).toEqual('Flickard');
expect(instance[1].title).toEqual('Ms');
});

it('Deserialize ttl with one-to-one relationship (async)', async (done) => {
const instance: PersonHasAddress = await RdfMapper.deserializeAsync(PersonHasAddress, oneToOneRelationship);
const instance: PersonHasAddress = await RdfMapper.deserializeAsync(PersonHasAddress, oneToOneRelationship) as PersonHasAddress;
expect(instance.uuid).toEqual('person-uuid');
expect(instance.name).toEqual('John');
expect(instance.address.uuid).toEqual('address-uuid');
Expand All @@ -49,15 +69,15 @@ describe('Test TTL Deserialization', () => {
});

it('Deserialize ttl with one-to-one relationship', () => {
const instance: PersonHasAddress = RdfMapper.deserialize(PersonHasAddress, oneToOneRelationship);
const instance: PersonHasAddress = RdfMapper.deserialize(PersonHasAddress, oneToOneRelationship) as PersonHasAddress;
expect(instance.uuid).toEqual('person-uuid');
expect(instance.name).toEqual('John');
expect(instance.address.uuid).toEqual('address-uuid');
expect(instance.address.streetName).toEqual('Jasmine');
});

it('Deserialize blank nodes (async)', async (done) => {
const recipe: Recipe = await RdfMapper.deserializeAsync(Recipe, recipeVideoTTL);
const recipe: Recipe = await RdfMapper.deserializeAsync(Recipe, recipeVideoTTL) as Recipe;
expect(recipe instanceof Recipe).toBeTruthy();
expect(recipe.video).toBeDefined();
expect(recipe.video instanceof Video).toBeTruthy();
Expand All @@ -68,7 +88,7 @@ describe('Test TTL Deserialization', () => {
});

it('Deserialize blank nodes', () => {
const recipe: Recipe = RdfMapper.deserialize(Recipe, recipeVideoTTL);
const recipe: Recipe = RdfMapper.deserialize(Recipe, recipeVideoTTL) as Recipe;
expect(recipe instanceof Recipe).toBeTruthy();
expect(recipe.video).toBeDefined();
expect(recipe.video instanceof Video).toBeTruthy();
Expand Down
2 changes: 1 addition & 1 deletion src/test/dieGracefully.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ function logResult(assertName: string, result: any) {
describe('Meaningful Exceptions should be thrown', () => {
it('Should throw TurtleParseError when turtle is invalid', async (done) => {
try {
const instance: Person = await RdfMapper.deserializeAsync(Person, invalidTTL);
const instance: Person|Person[] = await RdfMapper.deserializeAsync(Person, invalidTTL);
} catch (e) {
expect(e instanceof TurtleParseError).toBeTruthy();
expect(e.name).toEqual('TurtleParseError');
Expand Down