new singleton class GenericDevice.cs
Code: Select all
using System.Collections.Generic;
namespace WURFL.Resource
{
/// <summary>
/// Singleton for GenericDevice
/// </summary>
class GenericDevice
{
private static volatile GenericDevice instance;
private static object syncLock = new object();
public IModelDevice Device { get; private set; }
public IDictionary<string, string> DeviceCapabilieties { get; set; }
/// <summary>
/// Prevents a default instance of the <see cref="GenericDevice"/> class from being created.
/// </summary>
/// <param name="device">The device.</param>
private GenericDevice(IModelDevice device)
{
Device = device;
DeviceCapabilieties = device.GetCapabilities();
}
/// <summary>
/// Gets the generic device instance.
/// </summary>
/// <param name="device">The device.</param>
/// <returns></returns>
public static GenericDevice GetInstance(IModelDevice device)
{
if (instance == null)
{
lock (syncLock)
{
if (instance == null)
instance = new GenericDevice(device);
}
}
return instance;
}
}
}
Code: Select all
#region Copyright and license information
/*
* Copyright (c) 2012 ScientiaMobile, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* Refer to the COPYING file distributed with this package.
*/
#endregion
using System;
using System.Collections.Generic;
using WURFL.Commons;
using WURFL.Exceptions;
namespace WURFL.Resource
{
internal class ResourceData
{
private readonly IDictionary<String, IModelDevice> _idToDevice;
private readonly WurflInfo _wurflInfo;
internal ResourceData(WurflInfo wurflInfo, IDictionary<string, IModelDevice> idToDevice)
{
this._wurflInfo = wurflInfo;
this._idToDevice = idToDevice;
VerifyConsistency();
}
internal ICollection<IModelDevice> ModelDevices
{
get { return _idToDevice.Values; }
}
internal WurflInfo WurflInfo
{
get { return _wurflInfo; }
}
internal GenericDevice Generic
{
get
{
return GenericDevice.GetInstance(_idToDevice[Constants.Generic]);
}
}
private void VerifyConsistency()
{
List<string> hierarchyVerifiedDevices = new List<string>();
VerifyGeneric();
foreach (IModelDevice modelDevice in _idToDevice.Values)
{
VerifyHierarchy(modelDevice, hierarchyVerifiedDevices);
hierarchyVerifiedDevices.Add(modelDevice.Id);
VerifyGroups(modelDevice);
VerifyCapabilities(modelDevice);
}
}
private void VerifyGeneric()
{
if (!_idToDevice.ContainsKey(Constants.Generic))
{
throw new Exception("Can't find generic device in wurfl");
}
}
private void VerifyHierarchy(IModelDevice device, List<string> hierarchyVerifiedDevicesId)
{
var hierarchy = new List<string>(10);
var deviceId = device.Id;
hierarchy.Add(deviceId);
while (!string.Equals(Constants.Generic, deviceId))
{
IModelDevice examineDevice = Generic.Device;
String fallbackId = examineDevice.FallBackId;
if (hierarchyVerifiedDevicesId.Contains(fallbackId))
{
// OK
return;
}
if (!_idToDevice.ContainsKey(fallbackId))
{
throw new OrphanHierarchyException(hierarchy);
}
int hierarchyIndex = hierarchy.IndexOf(fallbackId);
if (hierarchyIndex != -1)
{
throw new CircularHierarchyException(hierarchy.GetRange(hierarchyIndex, hierarchy.Count));
}
hierarchy.Add(fallbackId);
deviceId = fallbackId;
}
}
private void VerifyGroups(IModelDevice device)
{
IModelDevice generic = Generic.Device;
ICollection<string> deviceGroups = device.Groups();
ICollection<string> genericGroups = generic.Groups();
foreach (string deviceGroup in deviceGroups)
{
if (!genericGroups.Contains(deviceGroup))
{
throw new MissingGroupException(device, deviceGroup);
}
}
}
private void VerifyCapabilities(IModelDevice device)
{
IDictionary<string, string> deviceCapabilities = device.GetCapabilities();
foreach (KeyValuePair<string, string> deviceCapability in deviceCapabilities)
{
string capabilityName = deviceCapability.Key;
if (!Generic.DeviceCapabilieties.ContainsKey(capabilityName))
{
throw new MissingCapabilityException(device, capabilityName);
}
var deviceGroup = GetGroupForCapability(device, capabilityName);
var genericGroup = GetGroupForCapability(Generic.Device, capabilityName);
if (!string.Equals(deviceGroup, genericGroup))
{
throw new BadCapabilityGroupException(device, capabilityName,
deviceGroup, genericGroup);
}
}
}
private static String GetGroupForCapability(IModelDevice device, string capabilityName)
{
IDictionary<string, IDictionary<string, string>> groupIdToCaps = device.CapabilitiesByGroupId;
foreach (KeyValuePair<string, IDictionary<string, string>> keyValuePair in groupIdToCaps)
{
if (keyValuePair.Value.ContainsKey(capabilityName))
{
return keyValuePair.Key;
}
}
throw new Exception(string.Format("capability {0} is not defined in for device {1}", capabilityName,
device.Id));
}
}
}