1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.ims.rcs.uce.presence.pidfparser.pidf; 18 19 import com.android.ims.rcs.uce.presence.pidfparser.ElementBase; 20 import com.android.ims.rcs.uce.presence.pidfparser.capabilities.ServiceCaps; 21 import com.android.ims.rcs.uce.presence.pidfparser.omapres.ServiceDescription; 22 23 import org.xmlpull.v1.XmlPullParser; 24 import org.xmlpull.v1.XmlPullParserException; 25 import org.xmlpull.v1.XmlSerializer; 26 27 import java.io.IOException; 28 import java.util.ArrayList; 29 import java.util.Collections; 30 import java.util.List; 31 32 /** 33 * The "tuple" element of the pidf. 34 */ 35 public class Tuple extends ElementBase { 36 /** 37 * The tuple element consists the following elements: 38 * 1: one "status" element 39 * 2: any number of optional extension elements 40 * 3: an optional "contact" element 41 * 4: any number of optional "note" elements 42 * 5: an optional "timestamp" element 43 */ 44 45 /** The name of this element */ 46 public static final String ELEMENT_NAME = "tuple"; 47 48 private static final String ATTRIBUTE_NAME_TUPLE_ID = "id"; 49 50 private static long sTupleId = 0; 51 52 private static final Object LOCK = new Object(); 53 54 private String mId; 55 private Status mStatus; 56 private ServiceDescription mServiceDescription; 57 private ServiceCaps mServiceCaps; 58 private Contact mContact; 59 private List<Note> mNoteList = new ArrayList<>(); 60 private Timestamp mTimestamp; 61 62 private boolean mMalformed; 63 Tuple()64 public Tuple() { 65 mId = getTupleId(); 66 mMalformed = false; 67 } 68 69 @Override initNamespace()70 protected String initNamespace() { 71 return PidfConstant.NAMESPACE; 72 } 73 74 @Override initElementName()75 protected String initElementName() { 76 return ELEMENT_NAME; 77 } 78 setStatus(Status status)79 public void setStatus(Status status) { 80 mStatus = status; 81 } 82 getStatus()83 public Status getStatus() { 84 return mStatus; 85 } 86 setServiceDescription(ServiceDescription servDescription)87 public void setServiceDescription(ServiceDescription servDescription) { 88 mServiceDescription = servDescription; 89 } 90 getServiceDescription()91 public ServiceDescription getServiceDescription() { 92 return mServiceDescription; 93 } 94 setServiceCaps(ServiceCaps serviceCaps)95 public void setServiceCaps(ServiceCaps serviceCaps) { 96 mServiceCaps = serviceCaps; 97 } 98 getServiceCaps()99 public ServiceCaps getServiceCaps() { 100 return mServiceCaps; 101 } 102 setContact(Contact contact)103 public void setContact(Contact contact) { 104 mContact = contact; 105 } 106 getContact()107 public Contact getContact() { 108 return mContact; 109 } 110 addNote(Note note)111 public void addNote(Note note) { 112 mNoteList.add(note); 113 } 114 getNoteList()115 public List<Note> getNoteList() { 116 return Collections.unmodifiableList(mNoteList); 117 } 118 setTimestamp(Timestamp timestamp)119 public void setTimestamp(Timestamp timestamp) { 120 mTimestamp = timestamp; 121 } 122 getTimestamp()123 public Timestamp getTimestamp() { 124 return mTimestamp; 125 } 126 setMalformed(boolean malformed)127 public void setMalformed(boolean malformed) { 128 mMalformed = malformed; 129 } 130 getMalformed()131 public boolean getMalformed() { 132 return mMalformed; 133 } 134 135 @Override serialize(XmlSerializer serializer)136 public void serialize(XmlSerializer serializer) throws IOException { 137 String namespace = getNamespace(); 138 String elementName = getElementName(); 139 140 serializer.startTag(namespace, elementName); 141 // id attribute 142 serializer.attribute(XmlPullParser.NO_NAMESPACE, ATTRIBUTE_NAME_TUPLE_ID, mId); 143 144 // status element 145 mStatus.serialize(serializer); 146 147 // Service description 148 if (mServiceDescription != null) { 149 mServiceDescription.serialize(serializer); 150 } 151 152 // Service capabilities 153 if (mServiceCaps != null) { 154 mServiceCaps.serialize(serializer); 155 } 156 157 // contact element 158 if (mContact != null) { 159 mContact.serialize(serializer); 160 } 161 162 // note element 163 for (Note note: mNoteList) { 164 note.serialize(serializer); 165 } 166 167 // Timestamp 168 if (mTimestamp != null) { 169 mTimestamp.serialize(serializer); 170 } 171 serializer.endTag(namespace, elementName); 172 } 173 174 @Override parse(XmlPullParser parser)175 public void parse(XmlPullParser parser) throws IOException, XmlPullParserException { 176 String namespace = parser.getNamespace(); 177 String name = parser.getName(); 178 179 if (!verifyParsingElement(namespace, name)) { 180 throw new XmlPullParserException("Incorrect element: " + namespace + ", " + name); 181 } 182 183 // id attribute 184 mId = parser.getAttributeValue(XmlPullParser.NO_NAMESPACE, ATTRIBUTE_NAME_TUPLE_ID); 185 186 // Move to the next event. 187 int eventType = parser.next(); 188 189 while(!(eventType == XmlPullParser.END_TAG 190 && getNamespace().equals(parser.getNamespace()) 191 && getElementName().equals(parser.getName()))) { 192 193 if (eventType == XmlPullParser.START_TAG) { 194 String tagName = parser.getName(); 195 196 if (Status.ELEMENT_NAME.equals(tagName)) { 197 Status status = new Status(); 198 status.parse(parser); 199 mStatus = status; 200 } else if (ServiceDescription.ELEMENT_NAME.equals(tagName)) { 201 ServiceDescription serviceDescription = new ServiceDescription(); 202 serviceDescription.parse(parser); 203 mServiceDescription = serviceDescription; 204 } else if (ServiceCaps.ELEMENT_NAME.equals(tagName)) { 205 ServiceCaps serviceCaps = new ServiceCaps(); 206 serviceCaps.parse(parser); 207 mServiceCaps = serviceCaps; 208 } else if (Contact.ELEMENT_NAME.equals(tagName)) { 209 Contact contact = new Contact(); 210 contact.parse(parser); 211 mContact = contact; 212 } else if (Note.ELEMENT_NAME.equals(tagName)) { 213 Note note = new Note(); 214 note.parse(parser); 215 mNoteList.add(note); 216 } else if (Timestamp.ELEMENT_NAME.equals(tagName)) { 217 Timestamp timestamp = new Timestamp(); 218 timestamp.parse(parser); 219 mTimestamp = timestamp; 220 } 221 } 222 223 eventType = parser.next(); 224 225 // Leave directly if the event type is the end of the document. 226 if (eventType == XmlPullParser.END_DOCUMENT) { 227 return; 228 } 229 } 230 } 231 getTupleId()232 private String getTupleId() { 233 synchronized (LOCK) { 234 return "tid" + (sTupleId++); 235 } 236 } 237 } 238