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