2013-08-12 15:06:12 +02:00
using System ;
2014-11-12 18:06:10 +11:00
using System.Collections ;
2013-08-12 15:06:12 +02:00
using System.Collections.Generic ;
using System.Linq ;
using System.Xml.Linq ;
using Umbraco.Core ;
2013-10-09 14:31:30 +11:00
using Umbraco.Core.Models ;
2013-08-12 15:06:12 +02:00
using umbraco.businesslogic ;
2014-11-12 18:06:10 +11:00
using Umbraco.Core.Services ;
2013-08-12 15:06:12 +02:00
namespace Umbraco.Web.Trees
{
/// <summary>
/// A startup handler for putting the tree config in the config file based on attributes found
/// </summary>
2014-11-12 18:06:10 +11:00
/// <remarks>
/// TODO: This is really not a very ideal process but the code is found here because tree plugins are in the Web project or the legacy business logic project.
/// Moving forward we can put the base tree plugin classes in the core and then this can all just be taken care of normally within the service.
/// </remarks>
2013-08-12 15:06:12 +02:00
public sealed class ApplicationTreeRegistrar : ApplicationEventHandler
{
protected override void ApplicationStarted ( UmbracoApplicationBase umbracoApplication , ApplicationContext applicationContext )
{
2014-11-12 18:06:10 +11:00
//Call initialize on the tree service with the lazy enumerable class below, when the tree service needs to resolve,
// it will lazily do the scanning and comparing so it's not actually done on app start.
applicationContext . Services . ApplicationTreeService . Intitialize ( new LazyEnumerableTrees ( ) ) ;
2013-08-12 15:06:12 +02:00
}
/// <summary>
2014-11-12 18:06:10 +11:00
/// This class is here so that we can provide lazy access to tree scanning for when it is needed
2013-08-12 15:06:12 +02:00
/// </summary>
2014-11-12 18:06:10 +11:00
private class LazyEnumerableTrees : IEnumerable < ApplicationTree >
2013-08-12 15:06:12 +02:00
{
2014-11-12 18:06:10 +11:00
public LazyEnumerableTrees ( )
{
_lazyTrees = new Lazy < IEnumerable < ApplicationTree > > ( ( ) = >
{
var added = new List < string > ( ) ;
2013-10-09 14:31:30 +11:00
2014-11-12 18:06:10 +11:00
// Load all Controller Trees by attribute
var types = PluginManager . Current . ResolveAttributedTreeControllers ( ) ;
//convert them to ApplicationTree instances
var items = types
. Select ( x = >
new Tuple < Type , TreeAttribute > ( x , x . GetCustomAttributes < TreeAttribute > ( false ) . Single ( ) ) )
. Select ( x = > new ApplicationTree ( x . Item2 . Initialize , x . Item2 . SortOrder , x . Item2 . ApplicationAlias , x . Item2 . Alias , x . Item2 . Title , x . Item2 . IconClosed , x . Item2 . IconOpen , x . Item1 . GetFullNameWithAssembly ( ) ) )
. ToArray ( ) ;
2013-10-09 14:31:30 +11:00
2014-11-12 18:06:10 +11:00
added . AddRange ( items . Select ( x = > x . Alias ) ) ;
2013-10-09 14:31:30 +11:00
2014-11-12 18:06:10 +11:00
//find the legacy trees
var legacyTreeTypes = PluginManager . Current . ResolveAttributedTrees ( ) ;
//convert them to ApplicationTree instances
var legacyItems = legacyTreeTypes
. Select ( x = >
2014-11-13 17:44:03 +11:00
new Tuple < Type , global :: umbraco . businesslogic . TreeAttribute , ObsoleteAttribute > (
x ,
x . GetCustomAttributes < global :: umbraco . businesslogic . TreeAttribute > ( false ) . SingleOrDefault ( ) ,
x . GetCustomAttributes < ObsoleteAttribute > ( false ) . SingleOrDefault ( ) ) )
//ensure that the legacy tree attribute exists
2014-11-12 18:06:10 +11:00
. Where ( x = > x . Item2 ! = null )
2014-11-13 17:44:03 +11:00
//ensure that it's not obsoleted, any obsoleted tree will not be auto added to the config
. Where ( x = > x . Item3 = = null )
2014-11-12 18:06:10 +11:00
//make sure the legacy tree isn't added on top of the controller tree!
. Where ( x = > added . InvariantContains ( x . Item2 . Alias ) = = false )
. Select ( x = > new ApplicationTree ( x . Item2 . Initialize , x . Item2 . SortOrder , x . Item2 . ApplicationAlias , x . Item2 . Alias , x . Item2 . Title , x . Item2 . IconClosed , x . Item2 . IconOpen , x . Item1 . GetFullNameWithAssembly ( ) ) ) ;
2013-10-09 14:31:30 +11:00
2014-11-12 18:06:10 +11:00
return items . Concat ( legacyItems ) . ToArray ( ) ;
} ) ;
}
2013-10-09 14:31:30 +11:00
2014-11-12 18:06:10 +11:00
private readonly Lazy < IEnumerable < ApplicationTree > > _lazyTrees ;
2013-10-09 14:31:30 +11:00
2014-11-12 18:06:10 +11:00
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>
/// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
/// </returns>
public IEnumerator < ApplicationTree > GetEnumerator ( )
{
return _lazyTrees . Value . GetEnumerator ( ) ;
}
2013-08-12 15:06:12 +02:00
2014-11-12 18:06:10 +11:00
/// <summary>
/// Returns an enumerator that iterates through a collection.
/// </summary>
/// <returns>
/// An <see cref="T:System.Collections.IEnumerator"/> object that can be used to iterate through the collection.
/// </returns>
IEnumerator IEnumerable . GetEnumerator ( )
{
return GetEnumerator ( ) ;
}
2013-08-12 15:06:12 +02:00
}
}
}