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