Bug Fix: OHIF Study Metadata API implementation not correctly reading Study and Series level data + Adding ES5.1 properties to Study Metadata API abstract classes to prevent protected attribute override

This commit is contained in:
Emanuel F. Oliveira 2017-02-09 09:29:37 -02:00 committed by Eloízio Salgado
parent 5d5df29e09
commit 2b22aecc15
8 changed files with 140 additions and 38 deletions

View File

@ -308,10 +308,11 @@ HP.ProtocolEngine = class ProtocolEngine {
* @returns {any|*} The number of available prior studies with the same patientId * @returns {any|*} The number of available prior studies with the same patientId
*/ */
getNumberOfAvailablePriors(study) { getNumberOfAvailablePriors(study) {
var studies = StudyListStudies.find({ const instance = study.getFirstInstance();
patientId: study.patientId, const studies = StudyListStudies.find({
patientId: instance.getRawValue('x00100020'), // PatientID,
studyDate: { studyDate: {
$lt: study.studyDate $lt: instance.getRawValue('x00080020') // StudyDate
} }
}); });

View File

@ -7,16 +7,47 @@ export class OHIFInstanceMetadata extends InstanceMetadata {
/** /**
* @param {Object} Instance object. * @param {Object} Instance object.
*/ */
constructor(data) { constructor(data, series, study) {
super(data); super(data);
this._cache = Object.create(null); // Object with null prototype for fast and safe lookups... this.init(series, study);
this.init();
} }
init() { init(series, study) {
const data = this.getData(); const instance = this.getData();
// set protected property...
this._sopInstanceUID = data.sopInstanceUid; // Initialize Private Properties
Object.defineProperties(this, {
_sopInstanceUID: {
configurable: false,
enumerable: false,
writable: false,
value: instance.sopInstanceUid
},
_study: {
configurable: false,
enumerable: false,
writable: false,
value: study
},
_series: {
configurable: false,
enumerable: false,
writable: false,
value: series
},
_instance: {
configurable: false,
enumerable: false,
writable: false,
value: instance
},
_cache: {
configurable: false,
enumerable: false,
writable: false,
value: Object.create(null)
}
});
} }
// Override // Override
@ -28,8 +59,16 @@ export class OHIFInstanceMetadata extends InstanceMetadata {
} }
const propertyName = OHIFInstanceMetadata.getPropertyName(tagOrProperty); const propertyName = OHIFInstanceMetadata.getPropertyName(tagOrProperty);
const data = this.getData();
const rawValue = data[propertyName]; // Search property value in the whole study metadata chain...
let rawValue;
if (propertyName in this._instance) {
rawValue = this._instance[propertyName];
} else if (propertyName in this._series) {
rawValue = this._series[propertyName];
} else if (propertyName in this._study) {
rawValue = this._study[propertyName];
}
if (rawValue !== void 0) { if (rawValue !== void 0) {
// if rawValue value is not undefined, cache result... // if rawValue value is not undefined, cache result...
@ -44,9 +83,7 @@ export class OHIFInstanceMetadata extends InstanceMetadata {
tagExists(tagOrProperty) { tagExists(tagOrProperty) {
const propertyName = OHIFInstanceMetadata.getPropertyName(tagOrProperty); const propertyName = OHIFInstanceMetadata.getPropertyName(tagOrProperty);
const data = this.getData(); return (propertyName in this._instance || propertyName in this._series || propertyName in this._study);
return (propertyName in data);
} }
// Override // Override
@ -72,7 +109,7 @@ export class OHIFInstanceMetadata extends InstanceMetadata {
if (tagInfo.propertyName !== null) { if (tagInfo.propertyName !== null) {
// This function tries to translate standard DICOM property names into local naming convention. // This function tries to translate standard DICOM property names into local naming convention.
propertyName = tagInfo.propertyName.replace(/^SOP/, 'sop').replace(/UID$/, 'Uid'); propertyName = tagInfo.propertyName.replace(/^SOP/, 'sop').replace(/UID$/, 'Uid').replace(/ID$/, 'Id');
propertyName = propertyName.charAt(0).toLowerCase() + propertyName.substr(1); propertyName = propertyName.charAt(0).toLowerCase() + propertyName.substr(1);
} }

View File

@ -6,19 +6,25 @@ export class OHIFSeriesMetadata extends Viewerbase.metadata.SeriesMetadata {
/** /**
* @param {Object} Series object. * @param {Object} Series object.
*/ */
constructor(data) { constructor(data, study) {
super(data); super(data);
this.init(); this.init(study);
} }
init() { init(study) {
const data = this.getData(); const series = this.getData();
// define "_seriesInstanceUID" protected property...
Object.defineProperty(this, '_seriesInstanceUID', {
configurable: false,
enumerable: false,
writable: false,
value: series.seriesInstanceUid
});
// set protected property...
this._seriesInstanceUID = data.seriesInstanceUid;
// populate internal list of instances... // populate internal list of instances...
data.instances.forEach(instance => { series.instances.forEach(instance => {
this.addInstance(new OHIFInstanceMetadata(instance)); this.addInstance(new OHIFInstanceMetadata(instance, series, study));
}); });
} }

View File

@ -12,13 +12,19 @@ export class OHIFStudyMetadata extends Viewerbase.metadata.StudyMetadata {
} }
init() { init() {
const data = this.getData(); const study = this.getData();
// define "_studyInstanceUID" protected property...
Object.defineProperty(this, '_studyInstanceUID', {
configurable: false,
enumerable: false,
writable: false,
value: study.studyInstanceUid
});
// set protected property...
this._studyInstanceUID = data.studyInstanceUid;
// populate internal list of series... // populate internal list of series...
data.seriesList.forEach(series => { study.seriesList.forEach(series => {
this.addSeries(new OHIFSeriesMetadata(series)); this.addSeries(new OHIFSeriesMetadata(series, study));
}); });
} }

View File

@ -11,8 +11,21 @@ export class InstanceMetadata extends Metadata {
constructor(data) { constructor(data) {
super(data); super(data);
this._sopInstanceUID = null; // Initialize Private Properties
this._imageId = null; Object.defineProperties(this, {
_sopInstanceUID: {
configurable: true, // configurable so that it can be redefined in sub-classes...
enumerable: false,
writable: true,
value: null
},
_imageId: {
configurable: true, // configurable so that it can be redefined in sub-classes...
enumerable: false,
writable: true,
value: null
}
});
// Initialize Public Properties // Initialize Public Properties
this._definePublicProperties(); this._definePublicProperties();
} }

View File

@ -6,6 +6,7 @@
const STRING = 'string'; const STRING = 'string';
const NUMBER = 'number'; const NUMBER = 'number';
const FUNCTION = 'function'; const FUNCTION = 'function';
const OBJECT = 'object';
export class Metadata { export class Metadata {
@ -14,7 +15,14 @@ export class Metadata {
*/ */
constructor(data) { constructor(data) {
this._data = data; // Define the main "_data" private property as an immutable property.
// IMPORTANT: This property can only be set during instance construction.
Object.defineProperty(this, '_data', {
configurable: false,
enumerable: false,
writable: false,
value: data
});
} }
getData() { getData() {
@ -24,7 +32,7 @@ export class Metadata {
getDataProperty(propertyName) { getDataProperty(propertyName) {
let propertyValue; let propertyValue;
const _data = this._data; const _data = this._data;
if (_data instanceof Object || typeof _data === 'object' && _data !== null) { if (_data instanceof Object || typeof _data === OBJECT && _data !== null) {
propertyValue = _data[propertyName]; propertyValue = _data[propertyName];
} }
return propertyValue; return propertyValue;

View File

@ -5,8 +5,21 @@ export class SeriesMetadata extends Metadata {
constructor(data) { constructor(data) {
super(data); super(data);
this._seriesInstanceUID = null; // Initialize Private Properties
this._instances = []; // InstanceMetadata[] Object.defineProperties(this, {
_seriesInstanceUID: {
configurable: true, // configurable so that it can be redefined in sub-classes...
enumerable: false,
writable: true,
value: null
},
_instances: {
configurable: false,
enumerable: false,
writable: false,
value: []
}
});
// Initialize Public Properties // Initialize Public Properties
this._definePublicProperties(); this._definePublicProperties();
} }

View File

@ -6,9 +6,27 @@ export class StudyMetadata extends Metadata {
constructor(data) { constructor(data) {
super(data); super(data);
this._studyInstanceUID = null; // Initialize Private Properties
this._series = []; // SeriesMetadata[] Object.defineProperties(this, {
this._displaySets = []; __studyInstanceUID: {
configurable: true, // configurable so that it can be redefined in sub-classes...
enumerable: false,
writable: true,
value: null
},
_series: {
configurable: false,
enumerable: false,
writable: false,
value: []
},
_displaySets: {
configurable: false,
enumerable: false,
writable: false,
value: []
}
});
// Initialize Public Properties // Initialize Public Properties
this._definePublicProperties(); this._definePublicProperties();
} }