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.pubsub; 018 019import java.util.List; 020 021import org.jivesoftware.smack.packet.ExtensionElement; 022import org.jivesoftware.smack.packet.NamedElement; 023import org.jivesoftware.smack.packet.XmlElement; 024import org.jivesoftware.smack.util.XmlStringBuilder; 025 026/** 027 * This class is used for multiple purposes. 028 * <ul> 029 * <li>It can represent an event containing a list of items that have been published 030 * <li>It can represent an event containing a list of retracted (deleted) items. 031 * <li>It can represent a request to delete a list of items. 032 * <li>It can represent a request to get existing items. 033 * </ul> 034 * 035 * <p><b>Please note, this class is used for internal purposes, and is not required for usage of 036 * pubsub functionality.</b></p> 037 * 038 * @author Robin Collier 039 */ 040public class ItemsExtension extends NodeExtension implements EmbeddedPacketExtension { 041 protected ItemsElementType type; 042 protected Boolean notify; 043 protected List<? extends NamedElement> items; 044 045 public enum ItemsElementType { 046 /** An items element, which has an optional <b>max_items</b> attribute when requesting items. */ 047 items(PubSubElementType.ITEMS, "max_items"), 048 049 /** A retract element, which has an optional <b>notify</b> attribute when publishing deletions. */ 050 retract(PubSubElementType.RETRACT, "notify"); 051 052 private final PubSubElementType elem; 053 private final String att; 054 055 ItemsElementType(PubSubElementType nodeElement, String attribute) { 056 elem = nodeElement; 057 att = attribute; 058 } 059 060 public PubSubElementType getNodeElement() { 061 return elem; 062 } 063 064 public String getElementAttribute() { 065 return att; 066 } 067 } 068 069 /** 070 * Construct an instance with a list representing items that have been published or deleted. 071 * 072 * <p>Valid scenarios are:</p> 073 * <ul> 074 * <li>Request items from node - itemsType = {@link ItemsElementType#items}, items = list of {@link Item} and an 075 * optional value for the <b>max_items</b> attribute. 076 * <li>Request to delete items - itemsType = {@link ItemsElementType#retract}, items = list of {@link Item} containing 077 * only id's and an optional value for the <b>notify</b> attribute. 078 * <li>Items published event - itemsType = {@link ItemsElementType#items}, items = list of {@link Item} and 079 * attributeValue = <code>null</code> 080 * <li>Items deleted event - itemsType = {@link ItemsElementType#items}, items = list of {@link RetractItem} and 081 * attributeValue = <code>null</code> 082 * </ul> 083 * 084 * @param itemsType Type of representation 085 * @param nodeId The node to which the items are being sent or deleted 086 * @param items The list of {@link Item} or {@link RetractItem} 087 */ 088 public ItemsExtension(ItemsElementType itemsType, String nodeId, List<? extends NamedElement> items) { 089 super(itemsType.getNodeElement(), nodeId); 090 type = itemsType; 091 this.items = items; 092 } 093 094 /** 095 * Construct an instance with a list representing items that have been published or deleted. 096 * 097 * <p>Valid scenarios are:</p> 098 * <ul> 099 * <li>Request items from node - itemsType = {@link ItemsElementType#items}, items = list of {@link Item} and an 100 * optional value for the <b>max_items</b> attribute. 101 * <li>Request to delete items - itemsType = {@link ItemsElementType#retract}, items = list of {@link Item} containing 102 * only id's and an optional value for the <b>notify</b> attribute. 103 * <li>Items published event - itemsType = {@link ItemsElementType#items}, items = list of {@link Item} and 104 * attributeValue = <code>null</code> 105 * <li>Items deleted event - itemsType = {@link ItemsElementType#items}, items = list of {@link RetractItem} and 106 * attributeValue = <code>null</code> 107 * </ul> 108 * 109 * @param nodeId The node to which the items are being sent or deleted 110 * @param items The list of {@link Item} or {@link RetractItem} 111 * @param notify TODO javadoc me please 112 */ 113 public ItemsExtension(String nodeId, List<? extends ExtensionElement> items, boolean notify) { 114 super(ItemsElementType.retract.getNodeElement(), nodeId); 115 type = ItemsElementType.retract; 116 this.items = items; 117 this.notify = notify; 118 } 119 120 /** 121 * Get the type of element. 122 * 123 * @return The element type 124 */ 125 public ItemsElementType getItemsElementType() { 126 return type; 127 } 128 129 @Override 130 @SuppressWarnings("unchecked") 131 public List<XmlElement> getExtensions() { 132 return (List<XmlElement>) getItems(); 133 } 134 135 /** 136 * Gets the items related to the type of request or event. 137 * 138 * @return List of {@link Item}, {@link RetractItem}, or null 139 */ 140 // TODO: Shouldn't this return List<Item>? Why is RetractItem not a subtype of item? 141 public List<? extends NamedElement> getItems() { 142 return items; 143 } 144 145 /** 146 * Gets the value of the optional attribute related to the {@link ItemsElementType}. 147 * 148 * @return The attribute value 149 */ 150 public boolean getNotify() { 151 return notify; 152 } 153 154 @Override 155 protected void addXml(XmlStringBuilder xml) { 156 if ((items == null) || (items.size() == 0)) { 157 xml.closeEmptyElement(); 158 return; 159 } 160 161 if (notify != null) { 162 xml.attribute(type.getElementAttribute(), notify); 163 xml.rightAngleBracket(); 164 } else { 165 xml.rightAngleBracket(); 166 xml.append(items); 167 } 168 169 xml.closeElement(this); 170 } 171 172 @Override 173 public String toString() { 174 return getClass().getName() + "Content [" + toXML() + "]"; 175 } 176 177}