private void _AppendReadonly(List<string> readOnlyProperties,WrappedStringBuilder sb,bool minimize){ if (readOnlyProperties.Count > 0) { sb.AppendLine((minimize ? "_revertReadonlyFields:function(){" : "\t_revertReadonlyFields : function(){")); foreach (string str in readOnlyProperties) { sb.AppendFormat((minimize ? "if(this.changedAttributes.{0}!=this.previousAttributes.{0}){{this.set({{{0}:this.previousAttributes.{0}}});}}" :@" if (this.changedAttributes.{0} != this.previousAttributes.{0}){{ this.set({{{0}:this.previousAttributes.{0}}}); }}"),str); } sb.AppendLine((minimize ? "" : "\t")+"},"); sb.AppendLine((minimize ? "_save:function(key,val,options){if(key==null||typeof key==='object'){attrs=key;options=val;}else{(attrs={})[key]=val;}if(!this.isNew()){" :@"_save : function (key, val, options) { if (key == null || typeof key === 'object') { attrs = key; options = val; } else { (attrs = {})[key] = val; } if (!this.isNew()){")); foreach (string str in readOnlyProperties) sb.AppendLine(string.Format((minimize ? "if(attrs.{0}!=undefined){{delete attrs.{0};}}" :"if (attrs.{0}!=undefined){{delete attrs.{0};}}"), str)); sb.AppendLine((minimize ? "}options=_.extend({validate:true},options);this._baseSave(attrs, options);}," :@"} options = _.extend({ validate: true }, options); this._baseSave(attrs, options); },")); } }
private void _AppendDefaults(Type modelType,List<string> properties,WrappedStringBuilder sb,bool minimize) { if (modelType.GetConstructor(Type.EmptyTypes) != null) { sb.AppendLine((minimize ? "" : "\t")+"defaults:{"); object obj = modelType.GetConstructor(Type.EmptyTypes).Invoke(new object[0]); if (obj != null) { WrappedStringBuilder sbProps = new WrappedStringBuilder(minimize); foreach (string propName in properties) { if (propName != "id") { object pobj = modelType.GetProperty(propName).GetValue(obj, new object[0]); sbProps.AppendLine((minimize ? "" : "\t\t") + propName + ":" + (pobj == null ? "null" : JSON.JsonEncode(pobj)) + (properties.IndexOf(propName) == properties.Count - 1 ? "" : ",")); } } sb.Append(sbProps.ToString().TrimEnd(",\r\n".ToCharArray())); } sb.AppendLine((minimize ? "" : "\t")+"},"); } }
private void _AppendValidate(Type modelType, List<string> properties, WrappedStringBuilder sb,bool minimize) { bool add = false; foreach (string str in properties) { if (modelType.GetProperty(str).GetCustomAttributes(typeof(ModelRequiredField),false).Length > 0 || modelType.GetProperty(str).GetCustomAttributes(typeof(ModelFieldValidationRegex), false).Length > 0) { add = true; break; } } if (add) { sb.AppendLine((minimize ? "validate:function(attrs){var atts=this.attributes;_.extend(atts,attrs);var errors = new Array();" :@" validate : function(attrs) { var atts = this.attributes; _.extend(atts,attrs); var errors = new Array();")); foreach (string str in properties) { if (modelType.GetProperty(str).GetCustomAttributes(typeof(ModelRequiredField), false).Length > 0) { ModelRequiredField mrf = (ModelRequiredField)modelType.GetProperty(str).GetCustomAttributes(typeof(ModelRequiredField), false)[0]; sb.AppendFormat((minimize ? "if(atts.{0}==null||atts.{0}==undefined){{errors.push({{field:'{0}',error:Backbone.TranslateValidationError('{1}')}});}}" :@" if (atts.{0}==null || atts.{0}==undefined){{ errors.push({{field:'{0}',error:Backbone.TranslateValidationError('{1}')}}); }}"),str,mrf.ErrorMessageName); } else if (modelType.GetProperty(str).GetCustomAttributes(typeof(ModelFieldValidationRegex), false).Length > 0) { ModelFieldValidationRegex mfvr = (ModelFieldValidationRegex)modelType.GetProperty(str).GetCustomAttributes(typeof(ModelFieldValidationRegex), false)[0]; sb.AppendFormat((minimize ? "if(!new RegExp('{0}').test((atts.{1}==null||atts.{1}==undefined?'':atts.{1}))){{errors.push({{field:'{1}',error:Backbone.TranslateValidationError('{2}')}});}}" :@" if (!new RegExp('{0}').test((atts.{1}==null || atts.{1}==undefined ? '' : atts.{1}))){{ errors.push({{field:'{1}',error:Backbone.TranslateValidationError('{2}')}}); }}"), mfvr.Regex.Replace("'", "\'"),str,mfvr.ErrorMessageName); } } sb.AppendLine((minimize ? "this.errors=errors;if(errors.length>0){return errors;}}," :@" this.errors = errors; if (errors.length>0){return errors;} },")); } }
private void _AppendBlockUpdate(WrappedStringBuilder sb,bool minimize) { sb.AppendLine((minimize ? "save:function(key,value,options){if(this.isNew()){this._save(key,value,options);}else{return false;}}," : "\tsave : function(key, value, options){if (this.isNew()){this._save(key,value,options);}else{return false;}},")); }
private void _AppendBlockSave(WrappedStringBuilder sb, bool minimize) { sb.AppendLine((minimize ? "save:function(key,value,options){return false;}," : "\tsave : function(key, value, options){return false;},")); }
private void _AppendBlockDestroy(WrappedStringBuilder sb,bool minimize) { sb.AppendLine((minimize ? "destroy:function(options){return false;}," : "\tdestroy : function(options){return false;},")); }
public string GenerateJS(Type modelType, string host, List<string> readOnlyProperties, List<string> properties, List<string> viewIgnoreProperties, bool hasUpdate, bool hasAdd, bool hasDelete,bool minimize) { WrappedStringBuilder sb = new WrappedStringBuilder(minimize); sb.AppendFormat((minimize ? "{0}=_.extend(true,{0},{{Model:Backbone.Model.extend({{initialize:function(){{if(this._revertReadonlyFields!=undefined){{this.on(\"change\",this._revertReadonlyFields);}}}}," :@"//Org.Reddragonit.BackBoneDotNet.JSGenerators.ModelDefinitionGenerator {0} = _.extend(true,{0}, {{Model : Backbone.Model.extend({{ initialize : function() {{ if (this._revertReadonlyFields != undefined){{ this.on(""change"",this._revertReadonlyFields); }} }},"), ModelNamespace.GetFullNameForModel(modelType, host)); _AppendDefaults(modelType,properties,sb,minimize); if (!hasDelete) _AppendBlockDestroy(sb, minimize); if (!hasAdd && !hasUpdate) _AppendBlockSave(sb, minimize); else if (!hasAdd) _AppendBlockAdd(sb, minimize); else if (!hasUpdate) _AppendBlockUpdate(sb, minimize); _AppendReadonly(readOnlyProperties, sb, minimize); _AppendValidate(modelType, properties, sb, minimize); _AppendParse(modelType, host, properties, readOnlyProperties, sb, minimize); string urlRoot = ""; foreach (ModelRoute mr in modelType.GetCustomAttributes(typeof(ModelRoute), false)) { if (mr.Host == host) { urlRoot = mr.Path; break; } } if (urlRoot == "") { foreach (ModelRoute mr in modelType.GetCustomAttributes(typeof(ModelRoute), false)) { if (mr.Host == "*") { urlRoot = mr.Path; break; } } } _AppendExposedMethods(modelType, urlRoot, host, sb, minimize); sb.AppendLine(string.Format((minimize ? "urlRoot:\"{0}\"}})}});" : "\turlRoot : \"{0}\"}})}});"),urlRoot)); return sb.ToString(); }
private void _AppendExposedMethods(Type modelType, string urlRoot,string host, WrappedStringBuilder sb,bool minimize) { foreach (MethodInfo mi in modelType.GetMethods(BindingFlags.Public | BindingFlags.Instance)) { if (mi.GetCustomAttributes(typeof(ExposedMethod), false).Length > 0) StaticExposedMethodGenerator.AppendMethodCall(urlRoot,host, mi,((ExposedMethod)mi.GetCustomAttributes(typeof(ExposedMethod), false)[0]).AllowNullResponse, ref sb,minimize); } }
private void _AppendParse(Type modelType,string host, List<string> properties,List<string> readOnlyProperties, WrappedStringBuilder sb,bool minimize) { bool add = false; foreach (string str in properties) { Type propType = modelType.GetProperty(str).PropertyType; if (propType.FullName.StartsWith("System.Nullable")) { if (propType.IsGenericType) propType = propType.GetGenericArguments()[0]; else propType = propType.GetElementType(); } if (propType.IsArray) propType = propType.GetElementType(); else if (propType.IsGenericType) { if (propType.GetGenericTypeDefinition() == typeof(List<>)) propType = propType.GetGenericArguments()[0]; } if (new List<Type>(propType.GetInterfaces()).Contains(typeof(IModel)) || (propType == typeof(DateTime))) { add = true; break; } else if (readOnlyProperties.Contains(str)) { add = true; break; } } if (add) { WrappedStringBuilder jsonb = new WrappedStringBuilder(minimize); string lazyLoads = ""; jsonb.AppendLine((minimize ? "toJSON:function(){var attrs={};this._changedFields=(this._changedFields==undefined?[]:this._changedFields);" :@" toJSON : function(){ var attrs = {}; this._changedFields = (this._changedFields == undefined ? [] : this._changedFields);")); sb.AppendLine((minimize ? "parse:function(response){var attrs={};this._origAttributes=(this._origAttributes==undefined?{}:this._origAttributes);if(response.Backbone!=undefined){_.extend(Backbone,response.Backbone);response=response.response;}if(response!=true){" :@" parse: function(response) { var attrs = {}; this._origAttributes = (this._origAttributes==undefined ? {} : this._origAttributes); if(response.Backbone!=undefined){ _.extend(Backbone,response.Backbone); response=response.response; } if (response!=true){")); foreach (string str in properties) { bool isReadOnly = modelType.GetProperty(str).GetCustomAttributes(typeof(ReadOnlyModelProperty), false).Length > 0 || !modelType.GetProperty(str).CanWrite; Type propType = modelType.GetProperty(str).PropertyType; bool array = false; if (propType.FullName.StartsWith("System.Nullable")) { if (propType.IsGenericType) propType = propType.GetGenericArguments()[0]; else propType = propType.GetElementType(); } if (propType.IsArray) { array = true; propType = propType.GetElementType(); } else if (propType.IsGenericType) { if (propType.GetGenericTypeDefinition() == typeof(List<>)) { array = true; propType = propType.GetGenericArguments()[0]; } } if (new List<Type>(propType.GetInterfaces()).Contains(typeof(IModel))) { bool isLazy = modelType.GetProperty(str).GetCustomAttributes(typeof(ModelPropertyLazyLoadExternalModel), false).Length > 0; if (isLazy) lazyLoads += ",'" + str + "'"; sb.AppendLine(string.Format((minimize ? "if(response.{0}!=undefined){{" : "\t\tif (response.{0} != undefined){{"),str)); if (array) { sb.AppendFormat((minimize ? "if({0}.Collection!=undefined){{attrs.{1}=new {0}.Collection();for(var x=0;x<response.{1}.length;x++){{attrs.{1}.add(new {0}.Model({{'id':response.{1}[x].id}}));attrs.{1}.at(x).attributes=attrs.{1}.at(x).parse(response.{1}[x]);}}}}else{{attrs.{1}=[];for(var x=0;x<response.{1}.length;x++){{attrs.{1}.push(new {0}.Model({{'id':response.{1}[x].id}}));attrs.{1}[x].attributes=attrs.{1}[x].parse(response.{1}[x]);}}}}" :@" if({0}.Collection!=undefined){{ attrs.{1} = new {0}.Collection(); for (var x=0;x<response.{1}.length;x++){{ attrs.{1}.add(new {0}.Model({{'id':response.{1}[x].id}})); attrs.{1}.at(x).attributes=attrs.{1}.at(x).parse(response.{1}[x]); }} }}else{{ attrs.{1}=[]; for (var x=0;x<response.{1}.length;x++){{ attrs.{1}.push(new {0}.Model({{'id':response.{1}[x].id}})); attrs.{1}[x].attributes=attrs.{1}[x].parse(response.{1}[x]); }} }}"), ModelNamespace.GetFullNameForModel(propType, host), str); if (isReadOnly) jsonb.AppendLine((minimize ? "if(this.isNew()){" : "if (this.isNew()){")); jsonb.AppendFormat((minimize ? "if(this._changedFields.indexOf('{0}')>=0||this.isNew()){{attrs.{0}=[];if(this.attributes['{0}']!=null){{for(var x=0;x<this.attributes['{0}'].length;x++){{if(this.attributes['{0}'].at!=undefined){{attrs.{0}.push({{id:this.attributes['{0}'].at(x).id}});}}else{{attrs.{0}.push({{id:this.attributes['{0}'][x].id}});}}}}}}}}" :@" if(this._changedFields.indexOf('{0}')>=0||this.isNew()){{ attrs.{0} = []; if (this.attributes['{0}']!=null){{ for(var x=0;x<this.attributes['{0}'].length;x++){{ if(this.attributes['{0}'].at!=undefined){{ attrs.{0}.push({{id:this.attributes['{0}'].at(x).id}}); }}else{{ attrs.{0}.push({{id:this.attributes['{0}'][x].id}}); }} }} }} }}"),str); if (isReadOnly) jsonb.AppendLine("}"); } else { sb.AppendFormat((minimize ? "attrs.{0}=new {1}.Model({{'id':response.{0}.id}});attrs.{0}.attributes=attrs.{0}.parse(response.{0});" :@" attrs.{0} = new {1}.Model({{'id':response.{0}.id}}); attrs.{0}.attributes=attrs.{0}.parse(response.{0});"), str, ModelNamespace.GetFullNameForModel(propType, host)); if (isReadOnly) jsonb.AppendLine((minimize? "if(this.isNew()){": "if (this.isNew()){")); jsonb.AppendFormat((minimize ? "if(this._changedFields.indexOf('{0}')>=0||this.isNew()){{if(this.attributes['{0}']!=null){{attrs.{0}={{id:this.attributes['{0}'].id}};}}else{{attrs.{0}=null;}}}}" :@" if(this._changedFields.indexOf('{0}')>=0||this.isNew()){{ if (this.attributes['{0}']!=null){{ attrs.{0} = {{id : this.attributes['{0}'].id}}; }}else{{ attrs.{0} = null; }} }}"),str); if (isReadOnly) jsonb.AppendLine("}"); } sb.AppendLine((minimize ? "" : "\t\t")+"}"); } else { sb.AppendLine(string.Format((minimize ? "if(response.{0}!=undefined){{" : "\t\tif (response.{0} != undefined){{"),str)); if (propType == typeof(DateTime)) sb.AppendLine(string.Format((minimize ? "attrs.{0}=new Date(response.{0});" :"\t\tattrs.{0} = new Date(response.{0});"), str)); else sb.AppendLine(string.Format((minimize ? "attrs.{0}=response.{0};":"\t\tattrs.{0} = response.{0};"),str)); sb.AppendLine((minimize ? "" : "\t\t")+"}"); if (isReadOnly) jsonb.AppendLine((minimize ? "if(this.isNew()){":"if (this.isNew()){")); jsonb.AppendFormat((minimize ? "if(this._changedFields.indexOf('{0}')>=0||this.isNew()){{attrs.{0}=this.attributes['{0}'];}}" :@" if(this._changedFields.indexOf('{0}')>=0||this.isNew()){{ attrs.{0} = this.attributes['{0}']; }}"), str); if (isReadOnly) jsonb.AppendLine("}"); } } sb.AppendFormat((minimize ? "}}return attrs;}},{0}return attrs;}}," :@" }} return attrs; }},{0} return attrs; }},"), jsonb.ToString()); if (lazyLoads.Length > 0) { sb.AppendLine(string.Format((minimize ? "LazyLoadAttributes:[{0}],": "\tLazyLoadAttributes : [{0}],"),lazyLoads.Substring(1))); } } else { sb.AppendLine((minimize ? "parse:function(response){if(response.Backbone!=undefined){_.extend(Backbone,response.Backbone);response=response.response;}return response;}," :@" parse: function(response) { if(response.Backbone!=undefined){ _.extend(Backbone,response.Backbone); response=response.response; } return response; },")); } }