Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Montage data converters#1 #2010

Merged
merged 72 commits into from
Aug 11, 2019
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
9592b13
Allows an object to receive deserializedSelf every time
marchant Feb 11, 2019
63ccacf
Creates a new root class for converters dedicated to be used
marchant Feb 11, 2019
8a2bd24
- _addChildService can be called several times without side effects
marchant Feb 11, 2019
6191519
Adds a new converter to create embedded full objects of the right type
marchant Feb 11, 2019
ccb1603
Allows an object to receive deserializedSelf every time
marchant Feb 11, 2019
de359b4
Creates a new root class for converters dedicated to be used
marchant Feb 11, 2019
bafd719
- _addChildService can be called several times without side effects
marchant Feb 11, 2019
63fe025
Adds a new converter to create embedded full objects of the right type
marchant Feb 11, 2019
8f63f2c
- Makes revertSyntax, compiledRevertSyntax more robust
marchant Feb 12, 2019
57c7766
adds resolveObjectForTypeRawData method
marchant Feb 12, 2019
62563b0
- fixes bugs
marchant Feb 12, 2019
291d4d8
Merge branch 'montage-data-converters#1' of github.com:marchant/monta…
marchant Feb 12, 2019
b3b1f4b
Bootstrap scripts from main app package
cdebost Jan 31, 2019
620b811
Use mr#feature/npm3
cdebost Jan 31, 2019
10c74d5
Fix bad mainPackageLocation in getMontageDeserializer
cdebost Jan 31, 2019
75be71f
Enable node 6, 8, 10 in travis
cdebost Jan 31, 2019
f8dd5df
Remove legacy bundling option from travis
cdebost Jan 31, 2019
c2323d9
Run integration with mop#feature/npm3
cdebost Jan 31, 2019
13305c9
Remove useless bluebird injection code
cdebost Jan 31, 2019
099766b
Bump version to 18.0.0-rc1
cdebost Feb 7, 2019
19d947c
Allows an object to receive deserializedSelf every time
marchant Feb 11, 2019
e582eac
Creates a new root class for converters dedicated to be used
marchant Feb 11, 2019
023d207
- _addChildService can be called several times without side effects
marchant Feb 11, 2019
fa5d2a6
Adds a new converter to create embedded full objects of the right type
marchant Feb 11, 2019
d7638c0
- Makes revertSyntax, compiledRevertSyntax more robust
marchant Feb 12, 2019
e95490b
adds resolveObjectForTypeRawData method
marchant Feb 12, 2019
75a890f
- fixes bugs
marchant Feb 12, 2019
dca0a2d
Removes unused ModuleReference and adds a method documentation
marchant Feb 22, 2019
f89d15d
Renames converters and adds backward compatibility
marchant Feb 23, 2019
677ad82
Fix conflicts
marchant Feb 23, 2019
6aa8e7c
Removes comment and fixes eslint ternery expression warning
marchant Feb 23, 2019
bfc24a2
Fixes TO-DO -> TODO
marchant Feb 23, 2019
9e23414
Simplify Promise.resolve(undefined) -> Promise.resolve()
marchant Feb 23, 2019
c993508
Simplifies Promiser.resolve()
marchant Feb 23, 2019
81f2d07
Merge branch 'master' of github.com:montagejs/montage into montage-da…
marchant Feb 23, 2019
1ea8ccb
Implements the new delegate compiler for mr, here to process the depe…
marchant Mar 24, 2019
a40f903
Removes the need for node.js bootstrap environment to deal with mjson
marchant Mar 24, 2019
208136c
Adds a new object property to ModuleObjectDescriptor
marchant Mar 24, 2019
93a3a6d
Fixes a bug is no value is passed to the convert method
marchant Mar 24, 2019
2726b4c
Adds debug option on rule itself similar to syntax used for bindings,
marchant Mar 24, 2019
99665df
Move use of a property name to a propertyDescriptor
marchant Mar 25, 2019
29188b0
Modifies childServices deserialization to work with
marchant Mar 25, 2019
cf2a404
Fixes bugs for synchrounous deserialization and
marchant Mar 25, 2019
6ba4c76
Fixes some specs
marchant Mar 27, 2019
67670e1
Refctors to pass whole module to deserializer.init
marchant Mar 31, 2019
8f225f1
Don't set objectDescriptor when deserializing if value is undefined o…
marchant Apr 1, 2019
3cff419
Addresses the last issues and regressions involving loading a graph o…
marchant Apr 1, 2019
9be43a6
removes vscode plugin .eslintrc.json file
marchant Apr 1, 2019
9e582b4
Adds useful input from tejaede for further evolution/context
marchant Apr 1, 2019
62fea61
Fixes jslint warnings
marchant Apr 1, 2019
39dedf9
adds the ability to process the value of object-descriptor-reference’…
marchant Aug 6, 2019
4687575
Backward compatibility improvement.
marchant Aug 6, 2019
8220b11
Exposes isSync API on deserializer, interpreter & reviver
marchant Aug 6, 2019
e1b7a02
Updates version to rc2 and engines dependencies
marchant Aug 8, 2019
7f787c6
Updates node version for lint
marchant Aug 9, 2019
0a8082e
Merge branch 'master' into montage-data-converters#1
marchant Aug 9, 2019
9523eae
Fix for xvfb issue
marchant Aug 9, 2019
33cbde8
Merge branch 'montage-data-converters#1' of github.com:marchant/monta…
marchant Aug 9, 2019
f64754c
Removes committed version of package-lock.json
marchant Aug 9, 2019
7ce7367
Use node 8+ for tests
marchant Aug 9, 2019
b24833b
Specify node 8 and 10 for test stage
marchant Aug 9, 2019
2cecdba
Removes tests with node 4 and 6
marchant Aug 9, 2019
f134bd6
Adds missing spec files
marchant Aug 9, 2019
6fa2ca2
Updates mr dependency to fix tests
marchant Aug 9, 2019
dfc03a4
Updates Karma dependencies to run on node 8+
marchant Aug 9, 2019
a7f661e
Updates base node version to 10
marchant Aug 9, 2019
4217a32
Changing Karma to connect to the xvfb display on DISPLAY=:0 to try t…
marchant Aug 10, 2019
b1f070f
Adds browserSocketTimeout to attempt to fix karma tests on travis
marchant Aug 10, 2019
a7b20ff
Updates browserSocketTimeout to 80000
marchant Aug 10, 2019
87cdea7
Change to try to get travis test to run in Chrome
marchant Aug 11, 2019
0444552
reverts to node 8 for travis tests
marchant Aug 11, 2019
ccb6fcf
Comments use of process.env as process is undefined??
marchant Aug 11, 2019
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
9 changes: 8 additions & 1 deletion core/serialization/deserializer/montage-reviver.js
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,14 @@ var MontageReviver = exports.MontageReviver = Montage.specialize(/** @lends Mont
object = value && "prototype" in value ?
Object.create(module.montageObject) : module.montageObject;
context.setObjectLabel(object, label);
return this.instantiateMJSONObject(value, object, objectName, context, label);

if(label === "root") {
return this.instantiateMontageObject(value, object, objectName, context, label);
}
else {
return this.instantiateMJSONObject(value, object, objectName, context, label);
marchant marked this conversation as resolved.
Show resolved Hide resolved
}

} else {
object = this.getMontageObject(value, module, objectName, context, label);
context.setObjectLabel(object, label);
Expand Down
378 changes: 378 additions & 0 deletions data/converter/expression-data-mapping-converter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,378 @@
var Converter = require("core/converter/converter").Converter,
Criteria = require("core/criteria").Criteria,
DataQuery = require("data/model/data-query").DataQuery,
ObjectDescriptorReference = require("core/meta/object-descriptor-reference").ObjectDescriptorReference,
Promise = require("core/promise").Promise,
Scope = require("frb/scope"),
parse = require("frb/parse"),
compile = require("frb/compile-evaluator");

/**
* @class ExpressionDataMappingConverter
* @classdesc Converts a property value of raw data to the referenced object.
* @extends Converter
*/
exports.ExpressionDataMappingConverter = Converter.specialize( /** @lends ExpressionDataMappingConverter# */ {

/*
converter.expression = converter.expression || rule.expression;
converter.foreignDescriptor = converter.foreignDescriptor || propertyDescriptor.valueDescriptor;
converter.objectDescriptor = this.objectDescriptor;
converter.serviceIdentifier = rule.serviceIdentifier;

*/


/*********************************************************************
* Serialization
*/

serializeSelf: {
value: function (serializer) {

serializer.setProperty("convertExpression", this.convertExpression);

serializer.setProperty("foreignDescriptor", this._foreignDescriptorReference);

serializer.setProperty("revertExpression", this.revertExpression);

serializer.setProperty("root", this.owner);

serializer.setProperty("serviceIdentifier", this.serviceIdentifier);
serializer.setProperty("service", this.service);

}
},

deserializeSelf: {
value: function (deserializer) {
var value = deserializer.getProperty("convertExpression");
if (value) {
this.convertExpression = value;
}

value = deserializer.getProperty("revertExpression");
if (value) {
this.revertExpression = value;
}

value = deserializer.getProperty("foreignDescriptor");
if (value instanceof ObjectDescriptorReference) {
this._foreignDescriptorReference = value;
} else if (value) {
this.foreignDescriptor = value;
}

value = deserializer.getProperty("service");
if (value) {
this.service = value;
}

value = deserializer.getObjectByLabel("root");
if (value) {
this.owner = value;
}

value = deserializer.getProperty("serviceIdentifier");
if (value) {
this.serviceIdentifier = value;
}

deserializer.deserializeUnit("bindings");
}
},

/*********************************************************************
* Initialization
*/

/**
* @param {string} convertExpression the expression to be used for building a criteria to obtain the object corresponding to the value to convert.
* @return itself
*/
initWithConvertExpression: {
value: function (convertExpression) {
this.convertExpression = convertExpression;
return this;
}
},

/*********************************************************************
* Properties
*/


_convertExpression: {
value: null
},

/**
* The expression used to convert a raw value into a modeled one, for example a foreign property value into the objet it represents.
* @type {string}
* */
convertExpression: {
get: function() {
return this._convertExpression;
},
set: function(value) {
if(value !== this._convertExpression) {
this._convertExpression = value;
this._convertSyntax = undefined;
}
}
},

_convertSyntax: {
value: undefined
},

/**
* Object created by parsing .convertExpression using frb/grammar.js that will
* be used to initialize the convert query criteria
* @type {Object}
* */

convertSyntax: {
get: function() {
return this._convertSyntax || (this._convertSyntax === undefined
? this._convertSyntax = this.convertExpression ? parse(this.convertExpression) : null
: null);
}
},

_revertExpression: {
value: null
},

/**
* The expression used to revert the modeled value into a raw one. For example,
* reverting an object into it's primary key.
* @type {string}
* */
revertExpression: {
get: function() {
return this._revertExpression;
},
set: function(value) {
if(value !== this._revertExpression) {
this._revertExpression = value;
this._revertSyntax = undefined;
}
}
},

_revertSyntax: {
value: undefined
},

/**
* Object created by parsing .revertExpression using frb/grammar.js that will
* be used to revert the modeled value into a raw one
* @type {Object}
* */
revertSyntax: {
get: function() {
return this._revertSyntax || (this._revertSyntax === undefined
? this._revertSyntax = this.revertExpression ? parse(this.revertExpression) : null
: null);
}
},

_compiledRevertSyntax: {
value: undefined
},

compiledRevertSyntax: {
get: function () {

return this._compiledRevertSyntax || (this._compiledRevertSyntax === undefined
? this._compiledRevertSyntax = this.revertSyntax ? compile(this.revertSyntax) : null
: null);
marchant marked this conversation as resolved.
Show resolved Hide resolved
}
},


/**
* The descriptor of the destination object. If one is not provided,
* .objectDescriptor will be used. If .objectDescriptor is not provided,
* the value descriptor of the property descriptor that defines the
* relationship will be used.
* @type {?ObjectDescriptorReference}
* */
foreignDescriptor: {
serializable: false,
get: function () {
var isReference = this._foreignDescriptor instanceof ObjectDescriptorReference;
return isReference ? this._foreignDescriptor :
this._foreignDescriptor ? Promise.resolve(this._foreignDescriptor) :
this._foreignDescriptorReference && this._foreignDescriptorReference.promise(require);
},
set: function (descriptor) {
this._foreignDescriptor = descriptor;
}
},

/**
* The descriptor of the source object. It will be used only if it is provided and
* .foreignDescriptor is not provided.
* @type {?ObjectDescriptorReference}
**/
objectDescriptor: {
get: function () {
return this._objectDescriptor ? Promise.resolve(this._objectDescriptor) :
this.owner && this.owner.objectDescriptor ? Promise.resolve(this.owner.objectDescriptor) :
this._isAsync(this.owner) ? this._objectDescriptorReference :
undefined;
},
set: function (value) {
this._objectDescriptor = value;
}
},

_objectDescriptorReference: {
get: function () {
var self = this;
return this.owner.then(function (object) {
var objectDescriptor = object.objectDescriptor;
self.objectDescriptor = objectDescriptor;
return objectDescriptor;
});
}
},

_isAsync: {
value: function (object) {
return object && object.then && typeof object.then === "function";
}
},


/**
* The descriptor for which to perform the fetch.
* This returns foreignDescriptor, if it exists, and otherwise
* returns objectDescriptor.
* @type {?ObjectDescriptorReference}
**/
_descriptorToFetch: {
get: function () {
if (!this.__descriptorToFetch) {
if (this.foreignDescriptor && this.foreignDescriptor.promise) {
this.__descriptorToFetch = this.foreignDescriptor.promise(require);
} else if (this.foreignDescriptor) {
this.__descriptorToFetch = this.foreignDescriptor;
} else {
this.__descriptorToFetch = this.objectDescriptor;
}
}
return this.__descriptorToFetch;

// this.__descriptorToFetch = this._foreignDescriptor ? this._foreignDescriptor.then(function (descriptor) {
// return descriptor || self.objectDescriptor;
// }) : Promise.resolve(this.objectDescriptor);
// return this.foreignDescriptor || this.objectDescriptor;
}
},

owner: {
get: function () {
return this._owner ? this._owner.then ? this._owner : Promise.resolve(this._owner) : undefined;
},
set: function (value) {
this._owner = value;
}
},

__scope: {
value: null
},

/**
* Scope with which convert and revert expressions are evaluated.
* @type {?Scope}
**/
scope: {
get: function() {
return this.__scope || (this.__scope = new Scope(this));
}
},

/**
* The service to use to make requests.
*/
service: {
get: function () {
return this._service ? this._service :
this.owner ? this.owner.then(function (object) { return object.service; }) :
undefined;
},
set: function (value) {
this._service = !value || value.then ? value : Promise.resolve(value);
}
},

/**
* Identifier of the child of .service that the query should be routed to
*/
serviceIdentifier: {
value: undefined
},

/*********************************************************************
* Public API
*/

/**
* Converts the fault for the relationship to an actual object that has an ObjectDescriptor.
* @function
* @param {Property} v The value to format.
* @returns {Promise} A promise for the referenced object. The promise is
* fulfilled after the object is successfully fetched.
*/
convert: {
value: function (v) {
var self = this,
criteria = new Criteria().initWithSyntax(self.convertSyntax, v),
query;

return this._descriptorToFetch.then(function (typeToFetch) {
var type = [typeToFetch.module.id, typeToFetch.name].join("/");

if (self.serviceIdentifier) {
criteria.parameters.serviceIdentifier = self.serviceIdentifier;
}

query = DataQuery.withTypeAndCriteria(type, criteria);

return self.service ? self.service.then(function (service) {
return service.rootService.fetchData(query);
}) : null;
});
}
},



/**
* Reverts the relationship back to raw data.
* @function
* @param {Scope} v The value to revert.
* @returns {string} v
*/
revert: {
value: function (v) {
if (v) {
if (!this.compiledRevertSyntax) {
return Promise.resolve(v);
} else {
var scope = this.scope;
//Parameter is what is accessed as $ in expressions
scope.value = v;
return Promise.resolve(this.compiledRevertSyntax(scope));
}

}
return Promise.resolve(undefined);
}
}

});
Loading