#region Copyright (c) 2003, newtelligence AG. All rights reserved.
/*
// Copyright (c) 2003, newtelligence AG. (http://www.newtelligence.com)
// Original BlogX Source Code: Copyright (c) 2003, Chris Anderson (http://simplegeek.com)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted
// provided that the following conditions are met:
//
// (1) Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
// (2) Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
// (3) Neither the name of the newtelligence AG nor the names of its contributors may be used
// to endorse or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// -------------------------------------------------------------------------
//
// Original BlogX source code (c) 2003 by Chris Anderson (http://simplegeek.com)
//
// newtelligence is a registered trademark of newtelligence Aktiengesellschaft.
//
// For portions of this software, the some additional copyright notices may apply
// which can either be found in the license.txt file included in the source distribution
// or following this notice.
//
*/
#endregion
using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using System.Collections;
using newtelligence.DasBlog.Runtime.Proxies;
using newtelligence.DasBlog.Util;
namespace newtelligence.DasBlog.Runtime{
[Serializable]
[XmlRoot(Namespace=Data.NamespaceURI)]
[XmlType(Namespace=Data.NamespaceURI)]
public class DayEntry : IDayEntry
{
private object entriesLock = new object(); //the entries collection is shared and must be protected
private bool Loaded
{
[DebuggerStepThrough()] get { return _loaded; }
[DebuggerStepThrough()] set { _loaded = value; }
}
private bool _loaded = false;
public string FileName
{
get
{
// Use Invariant Culture, not host culture (or user override), for date formats.
return DateUtc.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture) + ".dayentry.xml";
}
}
[XmlIgnore]
public DateTime DateUtc
{
[DebuggerStepThrough()] get { return _date; }
[DebuggerStepThrough()] set { _date = value.Date; }
}
private DateTime _date;
[XmlElement("Date")]
public DateTime DateLocalTime
{
get { return (DateUtc==DateTime.MinValue||DateUtc==DateTime.MaxValue)?DateUtc:DateUtc.ToLocalTime(); }
set { DateUtc = (value==DateTime.MinValue||value==DateTime.MaxValue)?value:value.Date.ToUniversalTime(); }
}
[XmlArrayItem(typeof(Entry))]
public EntryCollection Entries
{
[DebuggerStepThrough()] get { return _entries; }
[DebuggerStepThrough()] set { _entries = value; }
}
private EntryCollection _entries = new EntryCollection();
[XmlAnyElement]
public XmlElement[] anyElements;
[XmlAnyAttribute]
public XmlAttribute[] anyAttributes;
public void Initialize()
{
DateUtc = DateTime.Now.ToUniversalTime().Date;
}
/// <summary>
/// Return EntryCollection excluding the private entries if the caller
/// is not in the admin role.
/// </summary>
public EntryCollection GetEntries()
{
return GetEntries(null);
}
/// <summary>
/// Return EntryCollection with the number of entries limited by <see paramref="maxResults" />
/// excluding the private entries if the caller is not in the admin role.
/// </summary>
public EntryCollection GetEntries(int maxResults)
{
return GetEntries(null, maxResults);
}
/// <summary>
/// Returns the entries that meet the include delegates criteria.
/// </summary>
/// <param name="include">The delegate indicating which items to include.</param>
public EntryCollection GetEntries(Predicate<Entry> include)
{
return GetEntries(include, Int32.MaxValue);
}
/// <summary>
/// Returns the entries that meet the include delegates criteria,
/// with the number of entries limited by <see paramref="maxResults" />.
/// </summary>
/// <param name="include">The delegate indicating which items to include.</param>
public EntryCollection GetEntries(Predicate<Entry> include, int maxResults)
{
lock(entriesLock)
{
Predicate<Entry> filter = null;
if(!System.Threading.Thread.CurrentPrincipal.IsInRole("admin"))
{
filter += EntryCollectionFilter.DefaultFilters.IsPublic();
}
if(include != null)
{
filter += include;
}
return EntryCollectionFilter.FindAll(Entries, filter, maxResults);
}
}
/// <param name="entryTitle">An URL-encoded entry title</param>
public Entry GetEntryByTitle(string entryTitle)
{
foreach (Entry entry in this.Entries)
{
string compressedTitle = entry.CompressedTitle.Replace("+", "");
if (CaseInsensitiveComparer.Default.Compare(compressedTitle,entryTitle) == 0)
{
return entry;
}
}
return null;
}
internal void Load(DataManager data)
{
if ( Loaded )
{
return;
}
lock(entriesLock)
{
if ( Loaded ) //SDH: standard thread-safe double check
{
return;
}
string fullPath = data.ResolvePath(FileName);
FileStream fileStream = FileUtils.OpenForRead(fullPath);
if ( fileStream != null )
{
try
{
XmlSerializer ser = new XmlSerializer(typeof(DayEntry),Data.NamespaceURI);
using (StreamReader reader = new StreamReader(fileStream))
{
//XmlNamespaceUpgradeReader upg = new XmlNamespaceUpgradeReader( reader, "", Data.NamespaceURI );
DayEntry e = (DayEntry)ser.Deserialize(reader);
Entries = e.Entries;
}
}
catch(Exception e)
{
ErrorTrace.Trace(System.Diagnostics.TraceLevel.Error,e);
}
finally
{
fileStream.Close();
}
}
Entries.Sort((left,right) => right.CreatedUtc.CompareTo(left.CreatedUtc));
Loaded = true;
}
}
internal void Save(DataManager data)
{
string fullPath = data.ResolvePath(FileName);
// We use the internal list to circumvent ignoring
// items where IsPublic is set to false.
if ( Entries.Count == 0 )
{
if ( File.Exists( fullPath ) )
{
File.Delete( fullPath );
}
}
else
{
System.Security.Principal.WindowsImpersonationContext wi = Impersonation.Impersonate();
FileStream fileStream = FileUtils.OpenForWrite(fullPath);
if ( fileStream != null )
{
try
{
XmlSerializer ser = new XmlSerializer(typeof(DayEntry),Data.NamespaceURI);
using (StreamWriter writer = new StreamWriter(fileStream))
{
ser.Serialize(writer, this);
}
}
catch(Exception e)
{
ErrorTrace.Trace(System.Diagnostics.TraceLevel.Error,e);
}
finally
{
fileStream.Close();
}
}
wi.Undo();
}
}
/// <summary>
/// Returns true if the specified DayEntry occurs before the day specified.
/// </summary>
/// <param name="dayEntry">The DayEntry to check the date of.</param>
/// <param name="dateTime">The date the DayEntry should occur before</param>
/// <returns>Returns true if the dayEntry occurs before the specified date.</returns>
public static bool OccursBefore(DayEntry dayEntry, DateTime dateTime)
{
return (dayEntry.DateUtc.Date <= dateTime);
}
public static bool OccursBetween(DayEntry dayEntry, TimeZone timeZone,
DateTime startDateTime, DateTime endDateTime)
{
//return ((timeZone.ToLocalTime(dayEntry.DateUtc) >= startDateTime)
// && (timeZone.ToLocalTime(dayEntry.DateUtc) <= endDateTime) );
return ((dayEntry.DateUtc >= startDateTime)
&& (dayEntry.DateUtc <= endDateTime) );
}
/// <summary>
/// Returns true if the specified DayEntry is within the same month as <c>month</c>;
/// </summary>
/// <param name="dayEntry"></param>
/// <param name="timeZone"></param>
/// <param name="month"></param>
/// <returns></returns>
public static bool OccursInMonth(DayEntry dayEntry, TimeZone timeZone,
DateTime month)
{
DateTime startOfMonth = new DateTime(month.Year, month.Month, 1, 0, 0, 0);
DateTime endOfMonth = new DateTime(month.Year, month.Month, 1, 0, 0, 0);
endOfMonth = endOfMonth.AddMonths(1);
endOfMonth = endOfMonth.AddSeconds(-1);
TimeSpan offset = timeZone.GetUtcOffset(endOfMonth);
endOfMonth = endOfMonth.AddHours(offset.Negate().Hours);
return ( OccursBetween(dayEntry, timeZone, startOfMonth, endOfMonth) );
}
}
}
|