/// <summary> /// This extension method determines whether the current type needs to be disambiguated. /// If the current type needs dismabiguation, we then provide a fully qualified /// import statement for the model. /// This currently operates only on entities whose name ends in "Request". We do this /// because every entity results in a request object. For example, assume we have the following /// two entities: timeOff and timeOffRequest. The timeOff entity will trigger the generation /// of classes named model.timeOff and request.timeOffRequest. The timeOffRequest entity /// will trigger the generation of a model.timeOffRequest and request.timeOffRequestRequest. /// The request.timeOffRequest and model.timeOffRequest classes will result in a name collision in /// a few files. /// Assumptions: 1) host.CurrentType is an OdcmProperty. /// </summary> /// <param name="host">The T4Host that orchestrates applying templates to the OdcmModel.</param> /// <returns>A boolean value that indicates whether the current type needs to be disambiguated.</returns> public static bool DoesCurrentTypeNeedDisambiguation(this CustomT4Host host) { // At this point this is only applicable to OdcmProperty. // Challenging this assumption will require a lot more investigation. if (!(host.CurrentType is OdcmProperty)) { return(false); } // We only support "Request" dismabiguation at this point. Check whether the // current type ends in "Request". var requestSuffix = "Request"; var currentTypeName = (host.CurrentType as OdcmProperty).Type.Name; int index = currentTypeName.IndexOf(requestSuffix); if (index == -1 || !currentTypeName.EndsWith(requestSuffix)) { return(false); // Doesn't need disambiguation } // If it does end in "Request", let's capture the base name to check if an entity of that name // exists in the schema. string entityNameToCheckForCollision = currentTypeName.Remove(index, requestSuffix.Length); // Search across namespaces, looking only at EntityType, to determine whether this type requires // disambiguation. This needs to be supported across namespaces. var classes = host.CurrentModel.Namespaces.SelectMany(n => n.Classes); var shouldDisambiguate = classes.Where(entity => entity.Kind == OdcmClassKind.Entity && entity.Name == entityNameToCheckForCollision).Any(); return(shouldDisambiguate); }
protected static CustomT4Host Host(TemplateFileInfo templateInfo, String templatesDirectory, OdcmObject odcmObject, OdcmModel odcmModel) { if (_host == null) { _host = new CustomT4Host(templateInfo, templatesDirectory, odcmObject, odcmModel); } else { _host.Reset(templateInfo, templatesDirectory, odcmObject, odcmModel); } return(_host); }
public string LogErrors(CustomT4Host host, TemplateFileInfo templateInfo) { var sb = new StringBuilder(); if (host.Errors == null || host.Errors.Count <= 0) { return(sb.ToString()); } foreach (CompilerError error in host.Errors) { sb.AppendLine("TemplateProcessor ERROR"). AppendFormat(@"Name: {0}{1}", templateInfo.TemplateName, Environment.NewLine). AppendFormat(@"Line: {0}{1}", error.Line, Environment.NewLine). AppendFormat(@"Details: {0}{1}", error.ErrorText, Environment.NewLine). AppendLine(). AppendLine(); } return(sb.ToString()); }
/// <summary> /// An extension method to get an import statement for the fully qualified name of the current type. /// Assumptions: 1) host.CurrentType is an OdcmProperty. 2) the generated namespace of the current type /// is in models.generated output namespace (in the generated file, not in the metadata). /// This method should support multiple namespaces. /// This currently (6/2020) applies to the following templates: /// BaseEntityCollectionRequest.java.tt /// IBaseEntityCollectionRequest.java.tt /// IBaseEntityCollectionPage.java.tt /// This currently unintentionally applies to the following templates when the disambiguation condition is met. /// This is not an issue as there is already a wild card import for the namespace that we should address first. /// IBaseEntityCollectionRequestBuilder.java.tt /// BaseEntityCollectionRequestBuilder.java.tt /// </summary> /// <param name="host">The T4Host that orchestrates applying templates to the OdcmModel.</param> /// <returns>A string that represents the import statement of the fully qualified name of the current type.</returns> public static string GetFullyQualifiedImportStatementForModel(this CustomT4Host host) { // By default, we don't need to disambiguate the model in the generated code file. // This will be the general case. var importStatement = ""; // Check whether we need to disambiguate the current type for generation of the model in the code file. var shouldDisambiguate = host.DoesCurrentTypeNeedDisambiguation(); if (shouldDisambiguate) { // Form the import statement to disambiguate the model in the generated code file. var thisType = (host.CurrentType as OdcmProperty).Projection.Type; var thisNamespace = thisType.Namespace.Name.AddPrefix(); var thisTypeName = thisType.Name.ToUpperFirstChar(); importStatement = $"\nimport {thisNamespace}.models.extensions.{thisTypeName};"; } return(importStatement); }