001/** 002 * 003 * Copyright © 2016 Florian Schmaus 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.jivesoftware.smackx.iot.data.provider; 018 019import java.io.IOException; 020import java.text.ParseException; 021import java.util.ArrayList; 022import java.util.Date; 023import java.util.List; 024import java.util.logging.Logger; 025 026import org.jivesoftware.smack.provider.ExtensionElementProvider; 027import org.jivesoftware.smack.util.ParserUtils; 028import org.jivesoftware.smackx.iot.data.element.IoTDataField; 029import org.jivesoftware.smackx.iot.data.element.IoTFieldsExtension; 030import org.jivesoftware.smackx.iot.data.element.NodeElement; 031import org.jivesoftware.smackx.iot.data.element.TimestampElement; 032import org.jivesoftware.smackx.iot.element.NodeInfo; 033import org.jivesoftware.smackx.iot.parser.NodeInfoParser; 034import org.jxmpp.util.XmppDateTime; 035import org.xmlpull.v1.XmlPullParser; 036import org.xmlpull.v1.XmlPullParserException; 037 038public class IoTFieldsExtensionProvider extends ExtensionElementProvider<IoTFieldsExtension> { 039 040 private static final Logger LOGGER = Logger.getLogger(IoTFieldsExtensionProvider.class.getName()); 041 042 @Override 043 public IoTFieldsExtension parse(XmlPullParser parser, int initialDepth) throws Exception { 044 int seqNr = ParserUtils.getIntegerAttributeOrThrow(parser, "seqnr", "IoT data request <accepted/> without sequence number"); 045 boolean done = ParserUtils.getBooleanAttribute(parser, "done", false); 046 List<NodeElement> nodes = new ArrayList<>(); 047 outerloop: while (true) { 048 final int eventType = parser.next(); 049 final String name = parser.getName(); 050 switch (eventType) { 051 case XmlPullParser.START_TAG: 052 switch (name) { 053 case NodeElement.ELEMENT: 054 NodeElement node = parseNode(parser); 055 nodes.add(node); 056 break; 057 } 058 break; 059 case XmlPullParser.END_TAG: 060 if (parser.getDepth() == initialDepth) { 061 break outerloop; 062 } 063 break; 064 } 065 } 066 return new IoTFieldsExtension(seqNr, done, nodes); 067 } 068 069 public NodeElement parseNode(XmlPullParser parser) throws XmlPullParserException, IOException, ParseException { 070 final int initialDepth = parser.getDepth(); 071 final NodeInfo nodeInfo = NodeInfoParser.parse(parser); 072 List<TimestampElement> timestampElements = new ArrayList<>(); 073 outerloop: while (true) { 074 final int eventType = parser.next(); 075 final String name = parser.getName(); 076 switch (eventType) { 077 case XmlPullParser.START_TAG: 078 switch (name){ 079 case TimestampElement.ELEMENT: 080 TimestampElement timestampElement = parseTimestampElement(parser); 081 timestampElements.add(timestampElement); 082 break; 083 } 084 break; 085 case XmlPullParser.END_TAG: 086 if (parser.getDepth() == initialDepth) { 087 break outerloop; 088 } 089 break; 090 } 091 } 092 return new NodeElement(nodeInfo, timestampElements); 093 } 094 095 public TimestampElement parseTimestampElement(XmlPullParser parser) throws ParseException, XmlPullParserException, IOException { 096 final int initialDepth = parser.getDepth(); 097 final String dateString = parser.getAttributeValue(null, "value"); 098 final Date date = XmppDateTime.parseDate(dateString); 099 List<IoTDataField> fields = new ArrayList<>(); 100 outerloop: while (true) { 101 final int eventType = parser.next(); 102 final String name = parser.getName(); 103 switch (eventType) { 104 case XmlPullParser.START_TAG: 105 IoTDataField field = null; 106 final String fieldName = parser.getAttributeValue(null, "name"); 107 final String fieldValue = parser.getAttributeValue(null, "value"); 108 switch (name) { 109 case "int": { 110 int value = Integer.parseInt(fieldValue); 111 field = new IoTDataField.IntField(fieldName, value); 112 } 113 break; 114 case "boolean": { 115 boolean value = Boolean.parseBoolean(fieldValue); 116 field = new IoTDataField.BooleanField(fieldName, value); 117 } 118 break; 119 default: 120 LOGGER.warning("IoT Data field type '" + name + "' not implement yet. Ignoring."); 121 break; 122 } 123 if (field != null) { 124 fields.add(field); 125 } 126 break; 127 case XmlPullParser.END_TAG: 128 if (parser.getDepth() == initialDepth) { 129 break outerloop; 130 } 131 break; 132 } 133 } 134 return new TimestampElement(date, fields); 135 } 136}