// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace Microsoft.AspNet.Mvc.Razor
{
///
/// Contains methods to locate _ViewStart.cshtml and _GlobalImport.cshtml
///
public static class ViewHierarchyUtility
{
private const string ViewStartFileName = "_ViewStart.cshtml";
private const string GlobalImportFileName = "_GlobalImport.cshtml";
///
/// Gets the view start locations that are applicable to the specified path.
///
/// The application relative path of the file to locate
/// _ViewStarts for.
/// A sequence of paths that represent potential view start locations.
///
/// This method returns paths starting from the directory of and
/// moves upwards until it hits the application root.
/// e.g.
/// /Views/Home/View.cshtml -> [ /Views/Home/_ViewStart.cshtml, /Views/_ViewStart.cshtml, /_ViewStart.cshtml ]
///
public static IEnumerable GetViewStartLocations(string applicationRelativePath)
{
return GetHierarchicalPath(applicationRelativePath, ViewStartFileName);
}
///
/// Gets the locations for _GlobalImports that are applicable to the specified path.
///
/// The application relative path of the file to locate
/// _GlobalImports for.
/// A sequence of paths that represent potential _GlobalImport locations.
///
/// This method returns paths starting from the directory of and
/// moves upwards until it hits the application root.
/// e.g.
/// /Views/Home/View.cshtml -> [ /Views/Home/_GlobalImport.cshtml, /Views/_GlobalImport.cshtml,
/// /_GlobalImport.cshtml ]
///
public static IEnumerable GetGlobalImportLocations(string applicationRelativePath)
{
return GetHierarchicalPath(applicationRelativePath, GlobalImportFileName);
}
private static IEnumerable GetHierarchicalPath(string relativePath, string fileName)
{
if (string.IsNullOrEmpty(relativePath))
{
return Enumerable.Empty();
}
if (relativePath.StartsWith("~/", StringComparison.Ordinal))
{
relativePath = relativePath.Substring(2);
}
if (relativePath.StartsWith("/", StringComparison.Ordinal))
{
relativePath = relativePath.Substring(1);
}
if (Path.IsPathRooted(relativePath))
{
// If the path looks like it's not app relative, don't attempt to construct paths.
return Enumerable.Empty();
}
if (string.Equals(Path.GetFileName(relativePath), fileName, StringComparison.OrdinalIgnoreCase))
{
// If the specified path is for the file hierarchy being constructed, then the first file that applies
// to it is in a parent directory.
relativePath = Path.GetDirectoryName(relativePath);
if (string.IsNullOrEmpty(relativePath))
{
return Enumerable.Empty();
}
}
var locations = new List();
while (!string.IsNullOrEmpty(relativePath))
{
relativePath = Path.GetDirectoryName(relativePath);
var path = Path.Combine(relativePath, fileName);
locations.Add(path);
}
return locations;
}
}
}