merge with 6.1.0

This commit is contained in:
Stephan
2013-03-31 19:19:24 -02:00
7 changed files with 265 additions and 31 deletions

View File

@@ -58,9 +58,14 @@ namespace Umbraco.Core.Strings
static void InitializeLegacyUrlReplaceCharacters()
{
var replaceChars = UmbracoSettings.UrlReplaceCharacters;
foreach (var node in replaceChars.SelectNodes("char").Cast<System.Xml.XmlNode>())
if (replaceChars == null) return;
var nodes = replaceChars.SelectNodes("char");
if (nodes == null) return;
foreach (var node in nodes.Cast<System.Xml.XmlNode>())
{
var org = node.Attributes.GetNamedItem("org");
var attributes = node.Attributes;
if (attributes == null) continue;
var org = attributes.GetNamedItem("org");
if (org != null && org.Value != "")
UrlReplaceCharacters[org.Value] = XmlHelper.GetNodeValue(node);
}

View File

@@ -0,0 +1,217 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.XPath;
using NUnit.Framework;
namespace Umbraco.Tests.CoreXml
{
[TestFixture]
public class FrameworkXmlTests
{
const string Xml1 = @"<root>
<items>
<item1 />
<item2>
<item21>text21</item21>
</item2>
<item3>
<item31>text31</item31>
</item3>
<item4 />
<item5 />
<item6 />
</items>
</root>";
// Umbraco : the following test shows that when legacy imports the whole tree in a
// "contentAll" xslt macro parameter, the entire collection of nodes is cloned ie is
// duplicated.
//
// What is the impact on memory?
// What happens for non-xslt macros?
[Test]
public void ImportNodeClonesImportedNode()
{
var doc1 = new XmlDocument();
doc1.LoadXml(Xml1);
var node1 = doc1.SelectSingleNode("//item2");
Assert.IsNotNull(node1);
var doc2 = new XmlDocument();
doc2.LoadXml("<nodes />");
var node2 = doc2.ImportNode(node1, true);
var root2 = doc2.DocumentElement;
Assert.IsNotNull(root2);
root2.AppendChild(node2);
var node3 = doc2.SelectSingleNode("//item2");
Assert.AreNotSame(node1, node2); // has been cloned
Assert.AreSame(node2, node3); // has been appended
Assert.AreNotSame(node1.FirstChild, node2.FirstChild); // deep clone
}
// Umbraco: the CanRemove...NodeAndNavigate tests shows that if the underlying XmlDocument
// is modified while navigating, then strange situations can be created. For xslt macros,
// the result depends on what the xslt engine is doing at the moment = unpredictable.
//
// What happens for non-xslt macros?
[Test]
public void CanRemoveCurrentNodeAndNavigate()
{
var doc1 = new XmlDocument();
doc1.LoadXml(Xml1);
var nav1 = doc1.CreateNavigator();
Assert.IsTrue(nav1.MoveToFirstChild());
Assert.AreEqual("root", nav1.Name);
Assert.IsTrue(nav1.MoveToFirstChild());
Assert.AreEqual("items", nav1.Name);
Assert.IsTrue(nav1.MoveToFirstChild());
Assert.AreEqual("item1", nav1.Name);
Assert.IsTrue(nav1.MoveToNext());
Assert.AreEqual("item2", nav1.Name);
var node1 = doc1.SelectSingleNode("//item2");
Assert.IsNotNull(node1);
var parent1 = node1.ParentNode;
Assert.IsNotNull(parent1);
parent1.RemoveChild(node1);
// navigator now navigates on an isolated fragment
// that is rooted on the node that was removed
Assert.AreEqual("item2", nav1.Name);
Assert.IsFalse(nav1.MoveToPrevious());
Assert.IsFalse(nav1.MoveToNext());
Assert.IsFalse(nav1.MoveToParent());
Assert.IsTrue(nav1.MoveToFirstChild());
Assert.AreEqual("item21", nav1.Name);
Assert.IsTrue(nav1.MoveToParent());
Assert.AreEqual("item2", nav1.Name);
nav1.MoveToRoot();
Assert.AreEqual("item2", nav1.Name);
}
[Test]
public void CanRemovePathNodeAndNavigate()
{
var doc1 = new XmlDocument();
doc1.LoadXml(Xml1);
var nav1 = doc1.CreateNavigator();
Assert.IsTrue(nav1.MoveToFirstChild());
Assert.AreEqual("root", nav1.Name);
Assert.IsTrue(nav1.MoveToFirstChild());
Assert.AreEqual("items", nav1.Name);
Assert.IsTrue(nav1.MoveToFirstChild());
Assert.AreEqual("item1", nav1.Name);
Assert.IsTrue(nav1.MoveToNext());
Assert.AreEqual("item2", nav1.Name);
Assert.IsTrue(nav1.MoveToFirstChild());
Assert.AreEqual("item21", nav1.Name);
var node1 = doc1.SelectSingleNode("//item2");
Assert.IsNotNull(node1);
var parent1 = node1.ParentNode;
Assert.IsNotNull(parent1);
parent1.RemoveChild(node1);
// navigator now navigates on an isolated fragment
// that is rooted on the node that was removed
Assert.AreEqual("item21", nav1.Name);
Assert.IsTrue(nav1.MoveToParent());
Assert.AreEqual("item2", nav1.Name);
Assert.IsFalse(nav1.MoveToPrevious());
Assert.IsFalse(nav1.MoveToNext());
Assert.IsFalse(nav1.MoveToParent());
nav1.MoveToRoot();
Assert.AreEqual("item2", nav1.Name);
}
[Test]
public void CanRemoveOutOfPathNodeAndNavigate()
{
var doc1 = new XmlDocument();
doc1.LoadXml(Xml1);
var nav1 = doc1.CreateNavigator();
Assert.IsTrue(nav1.MoveToFirstChild());
Assert.AreEqual("root", nav1.Name);
Assert.IsTrue(nav1.MoveToFirstChild());
Assert.AreEqual("items", nav1.Name);
Assert.IsTrue(nav1.MoveToFirstChild());
Assert.AreEqual("item1", nav1.Name);
Assert.IsTrue(nav1.MoveToNext());
Assert.AreEqual("item2", nav1.Name);
Assert.IsTrue(nav1.MoveToNext());
Assert.AreEqual("item3", nav1.Name);
Assert.IsTrue(nav1.MoveToNext());
Assert.AreEqual("item4", nav1.Name);
var node1 = doc1.SelectSingleNode("//item2");
Assert.IsNotNull(node1);
var parent1 = node1.ParentNode;
Assert.IsNotNull(parent1);
parent1.RemoveChild(node1);
// navigator sees the change
Assert.AreEqual("item4", nav1.Name);
Assert.IsTrue(nav1.MoveToPrevious());
Assert.AreEqual("item3", nav1.Name);
Assert.IsTrue(nav1.MoveToPrevious());
Assert.AreEqual("item1", nav1.Name);
}
// Umbraco: the following test shows that if the underlying XmlDocument is modified while
// iterating, then strange situations can be created. For xslt macros, the result depends
// on what the xslt engine is doing at the moment = unpredictable.
//
// What happens for non-xslt macros?
[Test]
public void CanRemoveNodeAndIterate()
{
var doc1 = new XmlDocument();
doc1.LoadXml(Xml1);
var nav1 = doc1.CreateNavigator();
var iter1 = nav1.Select("//items/*");
var iter2 = nav1.Select("//items/*");
Assert.AreEqual(6, iter1.Count);
var node1 = doc1.SelectSingleNode("//item2");
Assert.IsNotNull(node1);
var parent1 = node1.ParentNode;
Assert.IsNotNull(parent1);
parent1.RemoveChild(node1);
// iterator partially sees the change
Assert.AreEqual(6, iter1.Count); // has been cached, not updated
Assert.AreEqual(5, iter2.Count); // not calculated yet, correct value
var count = 0;
while (iter1.MoveNext())
count++;
Assert.AreEqual(5, count);
}
}
}

View File

@@ -175,6 +175,7 @@
<Compile Include="CodeFirst\TopologicalSorter.cs" />
<Compile Include="CodeFirst\TypeInheritanceTest.cs" />
<Compile Include="Configurations\FileSystemProviderTests.cs" />
<Compile Include="CoreXml\FrameworkXmlTests.cs" />
<Compile Include="PublishedCache\PublishedMediaCacheTests.cs" />
<Compile Include="CoreStrings\CmsHelperCasingTests.cs" />
<Compile Include="CoreStrings\ShortStringHelperResolverTest.cs" />

View File

@@ -209,12 +209,15 @@ namespace Umbraco.Web.Cache
if (payloads.Any(x => x.Type == typeof(IContentType).Name)
&& !payloads.All(x => x.IsNew)) //if they are all new then don't proceed
{
//we need to clear the routes cache here!
var contentCache = PublishedContentCacheResolver.Current.ContentCache as PublishedContentCache;
// SD: we need to clear the routes cache here!
//
// zpqrtbnk: no, not here, in fact the caches should subsribe to refresh events else we
// are creating a nasty dependency - but keep it like that for the time being while
// SD is cleaning cache refreshers up.
var contentCache = PublishedCachesResolver.Current.Caches.ContentCache as PublishedContentCache;
if (contentCache != null)
{
contentCache.RoutesCache.Clear();
}
}
}
}

View File

@@ -41,12 +41,16 @@ namespace Umbraco.Web.Cache
private void ClearCache()
{
ApplicationContext.Current.ApplicationCache.ClearCacheItem(CacheKeys.DomainCacheKey);
//we need to clear the routes cache here!
// SD: we need to clear the routes cache here!
//
// zpqrtbnk: no, not here, in fact the caches should subsribe to refresh events else we
// are creating a nasty dependency - but keep it like that for the time being while
// SD is cleaning cache refreshers up.
var contentCache = PublishedContentCacheResolver.Current.ContentCache as PublishedContentCache;
if (contentCache != null)
{
contentCache.RoutesCache.Clear();
}
}
}
}

View File

@@ -87,14 +87,16 @@ namespace Umbraco.Web.Routing
if (_pcr.IsRedirect)
return;
// safety
if (!_pcr.HasPublishedContent)
_pcr.Is404 = true;
{
// safety
_pcr.Is404 = true;
// handle 404 : return
// whoever called us is in charge of doing what's appropriate
if (_pcr.Is404)
return;
// whoever called us is in charge of doing what's appropriate
return;
}
// we may be 404 _and_ have a content
// can't go beyond that point without a PublishedContent to render
// it's ok not to have a template, in order to give MVC a chance to hijack routes

View File

@@ -114,11 +114,13 @@ namespace Umbraco.Web
/// <param name="applicationContext"> </param>
/// <param name="contentCache">The published content cache.</param>
/// <param name="mediaCache">The published media cache.</param>
/// <param name="preview">An optional value overriding detection of preview mode.</param>
internal UmbracoContext(
HttpContextBase httpContext,
ApplicationContext applicationContext,
IPublishedContentCache contentCache,
IPublishedMediaCache mediaCache)
IPublishedMediaCache mediaCache,
bool? preview = null)
{
if (httpContext == null) throw new ArgumentNullException("httpContext");
if (applicationContext == null) throw new ArgumentNullException("applicationContext");
@@ -131,6 +133,7 @@ namespace Umbraco.Web
ContentCache = new ContextualPublishedContentCache(contentCache, this);
MediaCache = new ContextualPublishedMediaCache(mediaCache, this);
InPreviewMode = preview ?? DetectInPreviewModeFromRequest();
// set the urls...
//original request url
@@ -319,22 +322,21 @@ namespace Umbraco.Web
/// <summary>
/// Determines whether the current user is in a preview mode and browsing the site (ie. not in the admin UI)
/// </summary>
public bool InPreviewMode
{
get
{
var request = GetRequestFromContext();
if (request == null || request.Url == null)
return false;
public bool InPreviewMode { get; private set; }
var currentUrl = request.Url.AbsolutePath;
// zb-00004 #29956 : refactor cookies names & handling
return
StateHelper.Cookies.Preview.HasValue // has preview cookie
&& UmbracoUser != null // has user
&& !currentUrl.StartsWith(Umbraco.Core.IO.IOHelper.ResolveUrl(Umbraco.Core.IO.SystemDirectories.Umbraco)); // is not in admin UI
}
}
private bool DetectInPreviewModeFromRequest()
{
var request = GetRequestFromContext();
if (request == null || request.Url == null)
return false;
var currentUrl = request.Url.AbsolutePath;
// zb-00004 #29956 : refactor cookies names & handling
return
StateHelper.Cookies.Preview.HasValue // has preview cookie
&& UmbracoUser != null // has user
&& !currentUrl.StartsWith(Umbraco.Core.IO.IOHelper.ResolveUrl(Umbraco.Core.IO.SystemDirectories.Umbraco)); // is not in admin UI
}
private HttpRequestBase GetRequestFromContext()
{