001/** 002 * 003 * Copyright the original author or authors 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.privacy.provider; 018 019import java.io.IOException; 020import java.util.ArrayList; 021 022import org.jivesoftware.smack.SmackException; 023import org.jivesoftware.smack.provider.IQProvider; 024import org.jivesoftware.smack.util.ParserUtils; 025 026import org.jivesoftware.smackx.privacy.packet.Privacy; 027import org.jivesoftware.smackx.privacy.packet.PrivacyItem; 028 029import org.xmlpull.v1.XmlPullParser; 030import org.xmlpull.v1.XmlPullParserException; 031 032/** 033 * The PrivacyProvider parses {@link Privacy} packets. {@link Privacy} 034 * Parses the <tt>query</tt> sub-document and creates an instance of {@link Privacy}. 035 * For each <tt>item</tt> in the <tt>list</tt> element, it creates an instance 036 * of {@link PrivacyItem}. 037 * 038 * @author Francisco Vives 039 */ 040public class PrivacyProvider extends IQProvider<Privacy> { 041 042 @Override 043 public Privacy parse(XmlPullParser parser, int initialDepth) 044 throws XmlPullParserException, IOException, SmackException { 045 Privacy privacy = new Privacy(); 046 boolean done = false; 047 while (!done) { 048 int eventType = parser.next(); 049 if (eventType == XmlPullParser.START_TAG) { 050 // CHECKSTYLE:OFF 051 if (parser.getName().equals("active")) { 052 String activeName = parser.getAttributeValue("", "name"); 053 if (activeName == null) { 054 privacy.setDeclineActiveList(true); 055 } else { 056 privacy.setActiveName(activeName); 057 } 058 } 059 else if (parser.getName().equals("default")) { 060 String defaultName = parser.getAttributeValue("", "name"); 061 if (defaultName == null) { 062 privacy.setDeclineDefaultList(true); 063 } else { 064 privacy.setDefaultName(defaultName); 065 } 066 } 067 // CHECKSTYLE:ON 068 else if (parser.getName().equals("list")) { 069 parseList(parser, privacy); 070 } 071 } 072 else if (eventType == XmlPullParser.END_TAG) { 073 if (parser.getName().equals("query")) { 074 done = true; 075 } 076 } 077 } 078 079 return privacy; 080 } 081 082 // Parse the list complex type 083 private static void parseList(XmlPullParser parser, Privacy privacy) throws XmlPullParserException, IOException, SmackException { 084 boolean done = false; 085 String listName = parser.getAttributeValue("", "name"); 086 ArrayList<PrivacyItem> items = new ArrayList<>(); 087 while (!done) { 088 int eventType = parser.next(); 089 if (eventType == XmlPullParser.START_TAG) { 090 if (parser.getName().equals("item")) { 091 // CHECKSTYLE:OFF 092 items.add(parseItem(parser)); 093 // CHECKSTYLE:ON 094 } 095 } 096 else if (eventType == XmlPullParser.END_TAG) { 097 if (parser.getName().equals("list")) { 098 done = true; 099 } 100 } 101 } 102 103 privacy.setPrivacyList(listName, items); 104 // CHECKSTYLE:OFF 105 } 106 107 // Parse the list complex type 108 private static PrivacyItem parseItem(XmlPullParser parser) throws XmlPullParserException, IOException, SmackException { 109 // CHECKSTYLE:ON 110 // Retrieves the required attributes 111 String actionValue = parser.getAttributeValue("", "action"); 112 // Set the order number, this attribute is required 113 long order = ParserUtils.getLongAttribute(parser, "order"); 114 115 // If type is not set, then it's the fall-through case 116 String type = parser.getAttributeValue("", "type"); 117 118 /* 119 * According the action value it sets the allow status. The fall-through action is assumed 120 * to be "allow" 121 */ 122 boolean allow; 123 switch (actionValue) { 124 case "allow": 125 allow = true; 126 break; 127 case "deny": 128 allow = false; 129 break; 130 default: 131 throw new SmackException("Unknown action value '" + actionValue + "'"); 132 } 133 134 PrivacyItem item; 135 if (type != null) { 136 // If the type is not null, then we are dealing with a standard privacy item 137 String value = parser.getAttributeValue("", "value"); 138 item = new PrivacyItem(PrivacyItem.Type.valueOf(type), value, allow, order); 139 } 140 else { 141 // If the type is null, then we are dealing with the fall-through privacy item. 142 item = new PrivacyItem(allow, order); 143 } 144 parseItemChildElements(parser, item); 145 return item; 146 // CHECKSTYLE:OFF 147 } 148 // CHECKSTYLE:ON 149 150 private static void parseItemChildElements(XmlPullParser parser, PrivacyItem privacyItem) throws XmlPullParserException, IOException { 151 final int initialDepth = parser.getDepth(); 152 153 outerloop: while (true) { 154 int eventType = parser.next(); 155 switch (eventType) { 156 case XmlPullParser.START_TAG: 157 String name = parser.getName(); 158 switch (name) { 159 case "iq": 160 privacyItem.setFilterIQ(true); 161 break; 162 case "message": 163 privacyItem.setFilterMessage(true); 164 break; 165 case "presence-in": 166 privacyItem.setFilterPresenceIn(true); 167 break; 168 case "presence-out": 169 privacyItem.setFilterPresenceOut(true); 170 break; 171 } 172 break; 173 case XmlPullParser.END_TAG: 174 if (parser.getDepth() == initialDepth) { 175 break outerloop; 176 } 177 } 178 } 179 } 180}