2019-06-24 11:58:36 +02:00
using System ;
using System.Configuration ;
using System.IO ;
2020-01-17 13:31:22 +11:00
using System.Threading ;
2020-03-03 13:42:07 +01:00
using Umbraco.Core.Configuration ;
2019-06-24 11:58:36 +02:00
using Umbraco.Core ;
2019-10-28 18:02:52 +11:00
using Umbraco.Core.IO ;
2019-06-24 11:58:36 +02:00
2020-03-03 11:18:54 +00:00
namespace Umbraco.Configuration
2019-06-24 11:58:36 +02:00
{
/// <summary>
/// Represents the models builder configuration.
/// </summary>
2019-10-28 18:02:52 +11:00
public class ModelsBuilderConfig : IModelsBuilderConfig
2019-06-24 11:58:36 +02:00
{
2020-03-17 16:26:56 +01:00
2020-01-17 13:31:22 +11:00
private const string Prefix = "Umbraco.ModelsBuilder." ;
private object _modelsModelLock ;
private bool _modelsModelConfigured ;
private ModelsMode _modelsMode ;
private object _flagOutOfDateModelsLock ;
private bool _flagOutOfDateModelsConfigured ;
private bool _flagOutOfDateModels ;
2020-03-03 14:15:30 +01:00
2019-12-04 14:03:39 +01:00
2020-03-17 16:26:56 +01:00
public string DefaultModelsDirectory = > "~/App_Data/Models" ;
2019-06-24 11:58:36 +02:00
/// <summary>
2019-10-28 18:02:52 +11:00
/// Initializes a new instance of the <see cref="ModelsBuilderConfig"/> class.
2019-06-24 11:58:36 +02:00
/// </summary>
2020-03-17 16:26:56 +01:00
public ModelsBuilderConfig ( )
2019-06-24 11:58:36 +02:00
{
2019-10-29 11:02:18 +11:00
// giant kill switch, default: false
// must be explicitely set to true for anything else to happen
2020-01-17 13:31:22 +11:00
Enable = ConfigurationManager . AppSettings [ Prefix + "Enable" ] = = "true" ;
2019-10-29 11:02:18 +11:00
2019-06-24 11:58:36 +02:00
// ensure defaults are initialized for tests
2020-03-03 14:15:30 +01:00
ModelsNamespace = Constants . ModelsBuilder . DefaultModelsNamespace ;
2019-12-04 14:03:39 +01:00
ModelsDirectory = DefaultModelsDirectory ;
2019-06-24 11:58:36 +02:00
DebugLevel = 0 ;
2019-10-29 11:02:18 +11:00
// stop here, everything is false
if ( ! Enable ) return ;
2019-06-24 11:58:36 +02:00
// default: false
2020-01-17 13:31:22 +11:00
AcceptUnsafeModelsDirectory = ConfigurationManager . AppSettings [ Prefix + "AcceptUnsafeModelsDirectory" ] . InvariantEquals ( "true" ) ;
2019-06-24 11:58:36 +02:00
// default: true
2020-01-17 13:31:22 +11:00
EnableFactory = ! ConfigurationManager . AppSettings [ Prefix + "EnableFactory" ] . InvariantEquals ( "false" ) ;
2019-06-24 11:58:36 +02:00
// default: initialized above with DefaultModelsNamespace const
2020-01-17 13:31:22 +11:00
var value = ConfigurationManager . AppSettings [ Prefix + "ModelsNamespace" ] ;
2019-06-24 11:58:36 +02:00
if ( ! string . IsNullOrWhiteSpace ( value ) )
ModelsNamespace = value ;
// default: initialized above with DefaultModelsDirectory const
2020-01-17 13:31:22 +11:00
value = ConfigurationManager . AppSettings [ Prefix + "ModelsDirectory" ] ;
2019-06-24 11:58:36 +02:00
if ( ! string . IsNullOrWhiteSpace ( value ) )
{
// GetModelsDirectory will ensure that the path is safe
2020-03-17 16:26:56 +01:00
ModelsDirectory = value ;
2019-06-24 11:58:36 +02:00
}
// default: 0
2020-01-17 13:31:22 +11:00
value = ConfigurationManager . AppSettings [ Prefix + "DebugLevel" ] ;
2019-06-24 11:58:36 +02:00
if ( ! string . IsNullOrWhiteSpace ( value ) )
{
2020-01-17 13:31:22 +11:00
if ( ! int . TryParse ( value , out var debugLevel ) )
2019-06-24 11:58:36 +02:00
throw new ConfigurationErrorsException ( $"Invalid debug level \" { value } \ "." ) ;
DebugLevel = debugLevel ;
}
}
/// <summary>
2019-10-28 18:02:52 +11:00
/// Initializes a new instance of the <see cref="ModelsBuilderConfig"/> class.
2019-06-24 11:58:36 +02:00
/// </summary>
2020-03-17 16:26:56 +01:00
public ModelsBuilderConfig (
2019-10-29 11:02:18 +11:00
bool enable = false ,
2019-06-24 11:58:36 +02:00
ModelsMode modelsMode = ModelsMode . Nothing ,
string modelsNamespace = null ,
bool enableFactory = true ,
bool flagOutOfDateModels = true ,
string modelsDirectory = null ,
bool acceptUnsafeModelsDirectory = false ,
int debugLevel = 0 )
{
2019-10-29 11:02:18 +11:00
Enable = enable ;
2020-01-16 19:39:17 +01:00
_modelsMode = modelsMode ;
2019-06-24 11:58:36 +02:00
2020-03-03 14:15:30 +01:00
ModelsNamespace = string . IsNullOrWhiteSpace ( modelsNamespace ) ? Constants . ModelsBuilder . DefaultModelsNamespace : modelsNamespace ;
2019-06-24 11:58:36 +02:00
EnableFactory = enableFactory ;
2020-01-16 19:39:17 +01:00
_flagOutOfDateModels = flagOutOfDateModels ;
2019-06-24 11:58:36 +02:00
ModelsDirectory = string . IsNullOrWhiteSpace ( modelsDirectory ) ? DefaultModelsDirectory : modelsDirectory ;
AcceptUnsafeModelsDirectory = acceptUnsafeModelsDirectory ;
DebugLevel = debugLevel ;
}
2019-10-29 11:02:18 +11:00
/// <summary>
/// Gets a value indicating whether the whole models experience is enabled.
/// </summary>
/// <remarks>
/// <para>If this is false then absolutely nothing happens.</para>
/// <para>Default value is <c>false</c> which means that unless we have this setting, nothing happens.</para>
/// </remarks>
public bool Enable { get ; }
2019-06-24 11:58:36 +02:00
/// <summary>
/// Gets the models mode.
/// </summary>
2020-01-17 13:31:22 +11:00
public ModelsMode ModelsMode = >
LazyInitializer . EnsureInitialized ( ref _modelsMode , ref _modelsModelConfigured , ref _modelsModelLock , ( ) = >
2020-01-16 19:39:17 +01:00
{
2020-01-17 13:31:22 +11:00
// mode
var modelsMode = ConfigurationManager . AppSettings [ Prefix + "ModelsMode" ] ;
if ( string . IsNullOrWhiteSpace ( modelsMode ) ) return ModelsMode . Nothing ; //default
switch ( modelsMode )
2020-01-16 19:39:17 +01:00
{
2020-01-17 13:31:22 +11:00
case nameof ( ModelsMode . Nothing ) :
return ModelsMode . Nothing ;
case nameof ( ModelsMode . PureLive ) :
return ModelsMode . PureLive ;
case nameof ( ModelsMode . AppData ) :
return ModelsMode . AppData ;
case nameof ( ModelsMode . LiveAppData ) :
return ModelsMode . LiveAppData ;
default :
throw new ConfigurationErrorsException ( $"ModelsMode \" { modelsMode } \ " is not a valid mode." + " Note that modes are case-sensitive. Possible values are: " + string . Join ( ", " , Enum . GetNames ( typeof ( ModelsMode ) ) ) ) ;
2020-01-16 19:39:17 +01:00
}
2020-01-17 13:31:22 +11:00
} ) ;
2019-06-24 11:58:36 +02:00
/// <summary>
/// Gets a value indicating whether system.web/compilation/@debug is true.
/// </summary>
public bool IsDebug
{
get
{
2020-03-03 11:18:54 +00:00
if ( ConfigurationManager . GetSection ( "system.web/compilation" ) is ConfigurationSection section & &
bool . TryParse ( section . ElementInformation . Properties [ "debug" ] . Value . ToString ( ) , out var isDebug ) )
{
return isDebug ;
}
return false ;
2019-06-24 11:58:36 +02:00
}
}
/// <summary>
/// Gets the models namespace.
/// </summary>
/// <remarks>That value could be overriden by other (attribute in user's code...). Return default if no value was supplied.</remarks>
public string ModelsNamespace { get ; }
/// <summary>
/// Gets a value indicating whether we should enable the models factory.
/// </summary>
/// <remarks>Default value is <c>true</c> because no factory is enabled by default in Umbraco.</remarks>
public bool EnableFactory { get ; }
/// <summary>
/// Gets a value indicating whether we should flag out-of-date models.
/// </summary>
/// <remarks>Models become out-of-date when data types or content types are updated. When this
/// setting is activated the ~/App_Data/Models/ood.txt file is then created. When models are
/// generated through the dashboard, the files is cleared. Default value is <c>false</c>.</remarks>
2020-01-16 19:39:17 +01:00
public bool FlagOutOfDateModels
2020-01-17 13:31:22 +11:00
= > LazyInitializer . EnsureInitialized ( ref _flagOutOfDateModels , ref _flagOutOfDateModelsConfigured , ref _flagOutOfDateModelsLock , ( ) = >
2020-01-16 19:39:17 +01:00
{
2020-01-17 13:31:22 +11:00
var flagOutOfDateModels = ! ConfigurationManager . AppSettings [ Prefix + "FlagOutOfDateModels" ] . InvariantEquals ( "false" ) ;
if ( ModelsMode = = ModelsMode . Nothing | | ModelsMode . IsLive ( ) )
2020-01-16 19:39:17 +01:00
{
2020-01-17 13:31:22 +11:00
flagOutOfDateModels = false ;
2020-01-16 19:39:17 +01:00
}
2020-01-17 13:31:22 +11:00
return flagOutOfDateModels ;
} ) ;
2019-06-24 11:58:36 +02:00
/// <summary>
/// Gets the models directory.
/// </summary>
/// <remarks>Default is ~/App_Data/Models but that can be changed.</remarks>
public string ModelsDirectory { get ; }
/// <summary>
/// Gets a value indicating whether to accept an unsafe value for ModelsDirectory.
/// </summary>
/// <remarks>An unsafe value is an absolute path, or a relative path pointing outside
/// of the website root.</remarks>
public bool AcceptUnsafeModelsDirectory { get ; }
/// <summary>
/// Gets a value indicating the debug log level.
/// </summary>
/// <remarks>0 means minimal (safe on live site), anything else means more and more details (maybe not safe).</remarks>
public int DebugLevel { get ; }
}
}