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 android.annotation.NonNull; 20 import android.net.Uri; 21 22 import com.android.ims.rcs.uce.presence.pidfparser.ElementBase; 23 import com.android.internal.annotations.VisibleForTesting; 24 25 import org.xmlpull.v1.XmlPullParser; 26 import org.xmlpull.v1.XmlPullParserException; 27 import org.xmlpull.v1.XmlSerializer; 28 29 import java.io.IOException; 30 import java.util.ArrayList; 31 import java.util.Collections; 32 import java.util.List; 33 34 /** 35 * The "present" element is the root element of an "application/pidf+xml" object. 36 */ 37 public class Presence extends ElementBase { 38 /** 39 * The presence element consists the following elements: 40 * 1: Any number (including 0) of <tuple> elements 41 * 2: Any number (including 0) of <note> elements 42 * 3: Any number of OPTIONAL extension elements from other namespaces. 43 */ 44 45 /** The name of this element */ 46 public static final String ELEMENT_NAME = "presence"; 47 48 private static final String ATTRIBUTE_NAME_ENTITY = "entity"; 49 50 // The presence element must have an "entity" attribute. 51 private String mEntity; 52 53 // The presence element contains any number of <tuple> elements 54 private final List<Tuple> mTupleList = new ArrayList<>(); 55 56 // The presence element contains any number of <note> elements; 57 private final List<Note> mNoteList = new ArrayList<>(); 58 Presence()59 public Presence() { 60 } 61 Presence(@onNull Uri contact)62 public Presence(@NonNull Uri contact) { 63 initEntity(contact); 64 } 65 initEntity(Uri contact)66 private void initEntity(Uri contact) { 67 mEntity = contact.toString(); 68 } 69 70 @VisibleForTesting setEntity(String entity)71 public void setEntity(String entity) { 72 mEntity = entity; 73 } 74 75 @Override initNamespace()76 protected String initNamespace() { 77 return PidfConstant.NAMESPACE; 78 } 79 80 @Override initElementName()81 protected String initElementName() { 82 return ELEMENT_NAME; 83 } 84 getEntity()85 public String getEntity() { 86 return mEntity; 87 } 88 addTuple(@onNull Tuple tuple)89 public void addTuple(@NonNull Tuple tuple) { 90 mTupleList.add(tuple); 91 } 92 getTupleList()93 public @NonNull List<Tuple> getTupleList() { 94 return Collections.unmodifiableList(mTupleList); 95 } 96 addNote(@onNull Note note)97 public void addNote(@NonNull Note note) { 98 mNoteList.add(note); 99 } 100 getNoteList()101 public @NonNull List<Note> getNoteList() { 102 return Collections.unmodifiableList(mNoteList); 103 } 104 105 @Override serialize(XmlSerializer serializer)106 public void serialize(XmlSerializer serializer) throws IOException { 107 String namespace = getNamespace(); 108 String elementName = getElementName(); 109 110 serializer.startTag(namespace, elementName); 111 // entity attribute 112 serializer.attribute(XmlPullParser.NO_NAMESPACE, ATTRIBUTE_NAME_ENTITY, mEntity); 113 114 // tuple elements 115 for (Tuple tuple : mTupleList) { 116 tuple.serialize(serializer); 117 } 118 119 // note elements 120 for (Note note : mNoteList) { 121 note.serialize(serializer); 122 } 123 serializer.endTag(namespace, elementName); 124 } 125 126 @Override parse(XmlPullParser parser)127 public void parse(XmlPullParser parser) throws IOException, XmlPullParserException { 128 String namespace = parser.getNamespace(); 129 String name = parser.getName(); 130 131 if (!verifyParsingElement(namespace, name)) { 132 throw new XmlPullParserException("Incorrect element: " + namespace + ", " + name); 133 } 134 135 mEntity = parser.getAttributeValue(XmlPullParser.NO_NAMESPACE, ATTRIBUTE_NAME_ENTITY); 136 137 // Move to the next event. 138 int eventType = parser.next(); 139 140 while(!(eventType == XmlPullParser.END_TAG 141 && getNamespace().equals(parser.getNamespace()) 142 && getElementName().equals(parser.getName()))) { 143 144 if (eventType == XmlPullParser.START_TAG) { 145 String tagName = parser.getName(); 146 147 if (isTupleElement(eventType, tagName)) { 148 Tuple tuple = new Tuple(); 149 tuple.parse(parser); 150 mTupleList.add(tuple); 151 } else if (isNoteElement(eventType, tagName)) { 152 Note note = new Note(); 153 note.parse(parser); 154 mNoteList.add(note); 155 } 156 } 157 158 eventType = parser.next(); 159 160 // Leave directly if the event type is the end of the document. 161 if (eventType == XmlPullParser.END_DOCUMENT) { 162 return; 163 } 164 } 165 } 166 isTupleElement(int eventType, String name)167 private boolean isTupleElement(int eventType, String name) { 168 return (eventType == XmlPullParser.START_TAG && Tuple.ELEMENT_NAME.equals(name)) ? 169 true : false; 170 } 171 isNoteElement(int eventType, String name)172 private boolean isNoteElement(int eventType, String name) { 173 return (eventType == XmlPullParser.START_TAG && Note.ELEMENT_NAME.equals(name)) ? 174 true : false; 175 } 176 } 177