Exemplo n.º 1
0
            public DataPage(XElement Element, SimplifiedSchema KnownSchema, int Page)
            {
                if (KnownSchema == null)
                {
                    throw new SchemaMissMatchException();
                }

                string NewSchemaVersion = Element.Attribute("schemaversion").Value;

                if (NewSchemaVersion != KnownSchema.GetVersion())
                {
                    throw new SchemaMissMatchException();
                }

                Schema            = KnownSchema;
                this.NrTotalPages = (int)(((double)Convert.ToInt32(Element.Attribute("totalpoints").Value) + 0.5) / (double)PointsPerPage);


                foreach (var it in Element.Elements(LWTSD.Namespace + "resource"))
                {
                    ResourcePath Path = it.Attribute("path").Value;
                    switch (KnownSchema.Resources[Path].SimpleType)
                    {
                    case SimplifiedType.String:
                        Data.Add(new ResourceString(it));
                        break;

                    case SimplifiedType.Integer:
                        Data.Add(new ResourceInteger(it));
                        break;

                    case SimplifiedType.Base64Binary:
                        Data.Add(new ResourceBase64Binary(it));
                        break;

                    case SimplifiedType.DateTime:
                        Data.Add(new ResourceDateTime(it));
                        break;

                    case SimplifiedType.Boolean:
                        Data.Add(new ResourceBoolean(it));
                        break;

                    case SimplifiedType.Decimal:
                        Data.Add(new ResourceDecimal(it));
                        break;

                    case SimplifiedType.Duration:
                        Data.Add(new ResourceDuration(it));
                        break;

                    case SimplifiedType.Float:
                        Data.Add(new ResourceFloat(it));
                        break;

                    case SimplifiedType.Time:
                        Data.Add(new ResourceTime(it));
                        break;

                    case SimplifiedType.Double:
                        Data.Add(new ResourceDouble(it));
                        break;
                    }
                }
            }
Exemplo n.º 2
0
        void HandleReadData(StanzaIQ Request)
        {
            XElement ReadDataElement = Request.Payload.Elements().First();

            try
            {
                List <ResourceAccess> LimitedAccess = GetAccessRights(Request.From, LWTSD.GetAccessToken(ReadDataElement));

                int       maxpoints   = XmlConvert.ToInt32(ReadDataElement.Attribute("maxpoints").Value);
                int       startindex  = XmlConvert.ToInt32(ReadDataElement.Attribute("startindex").Value);
                SortOrder OrderByTime = SortOrder.None;
                if (ReadDataElement.Attribute("orderedbytime") != null)
                {
                    OrderByTime = SortOrderMethods.LoadFromString(ReadDataElement.Attribute("orderedbytime").Value);
                }

                StanzaIQ Response = new StanzaIQ(StanzaIQ.StanzaIQType.Result);
                Response.ID = Request.ID;
                Response.To = Request.From;

                XElement DataElement = new XElement(LWTSD.Namespace + "data");

                List <Resource> MatchingResources = new List <Resource>();

                foreach (XElement ReadElement in ReadDataElement.Elements(LWTSD.Namespace + "read"))
                {
                    if (ReadElement.Attribute("maxpoints") != null)
                    {
                        if (XmlConvert.ToInt32(ReadElement.Attribute("maxpoints").Value) < 1)
                        {
                            throw new InvalidOperationException("Maxpoints < 0 in read");
                        }
                    }
                    if (ReadElement.Attribute("startindex") != null)
                    {
                        int localstartindex = XmlConvert.ToInt32(ReadElement.Attribute("startindex").Value);
                        if (localstartindex < 1)
                        {
                            throw new InvalidOperationException("startindex < 0 in read");
                        }
                        if (localstartindex > 1)
                        {
                            continue; // We only have one point / resource
                        }
                    }

                    ResourcePath Path = ReadElement.Attribute("resource-path").Value;

                    if (!ResourceAccess.AllowsRead(LimitedAccess, Path))
                    {
                        throw new AccessViolation();
                    }

                    if (!Resources.ContainsKey(Path))
                    {
                        // Todo: Explicit exception to set proper error code
                        throw new Exception("Path does not exist: " + Path);
                    }

                    Resource Res = Resources[Path];
                    if (!Res.SupportsRead)
                    {
                        throw new InvalidOperationException("Resource does not support read: " + Path);
                    }

                    MatchingResources.Add(Res);
                }

                lock (Schema)
                {
                    int Index          = 0;
                    int ReturnedPoints = 0;

                    foreach (Resource Res in MatchingResources)
                    {
                        if (Index < startindex)
                        {
                            Index++;
                            continue;
                        }
                        if ((Index - startindex) >= maxpoints)
                        {
                            Index++;
                            break;
                        }

                        Index++;
                        ReturnedPoints++;

                        XElement ResourceElement = new XElement(LWTSD.Namespace + "resource");
                        ResourceElement.SetAttributeValue("path", Res.Path);
                        ResourceElement.SetAttributeValue("returnedpoints", "1");
                        ResourceElement.SetAttributeValue("totalpoints", "1");
                        XElement PointElement = Res.GetPoint();
                        ResourceElement.Add(PointElement);

                        DataElement.Add(ResourceElement);
                    }

                    DataElement.SetAttributeValue("schemaversion", Schema.GetVersion());
                    DataElement.SetAttributeValue("returnedpoints", XmlConvert.ToString(ReturnedPoints));
                    DataElement.SetAttributeValue("totalpoints", XmlConvert.ToString(MatchingResources.Count));
                }

                foreach (XElement ReSubscribeElement in ReadDataElement.Elements(LWTSD.Namespace + "re-subscribe"))
                {
                    string localsid = ReSubscribeElement.Attribute("subscriptionid").Value;
                    string sid      = GetSafeSubscriptionID(Request.From, localsid);

                    if (!Subscribers.ContainsKey(sid))
                    {
                        throw new InvalidOperationException("Subscription ID does not exist: " + localsid);
                    }

                    Subscriber Subscription = Subscribers[sid];
                    Subscription.LastResubscribed = DateTime.UtcNow;
                }

                Response.Payload.Add(DataElement);
                Uplink.SendStanza(Response);
            }
            catch (System.Exception ex)
            {
                StanzaIQ ErrorResponse = new StanzaIQ(StanzaIQ.StanzaIQType.Error);
                ErrorResponse.ID = Request.ID;
                ErrorResponse.To = Request.From;
                XElement ErroReasonElement = new XElement(LWTSD.Namespace + "errorreason");
                ErroReasonElement.SetAttributeValue("reason", ErrorReason.InvalidData);
                ErroReasonElement.Value = ex.ToString();
                ErrorResponse.Payload.Add(ErroReasonElement);
                Uplink.SendStanza(ErrorResponse);
            }
        }