1 /* 2 * Copyright (C) 2005-2008 Jive Software. All rights reserved. 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 org.jivesoftware.openfire.disco; 18 19 import org.dom4j.DocumentHelper; 20 import org.dom4j.Element; 21 import org.xmpp.packet.JID; 22 import org.xmpp.resultsetmanagement.Result; 23 24 /** 25 * An item is associated with an XMPP Entity, usually thought of a children of 26 * the parent entity and normally are addressable as a JID.<p> 27 * 28 * An item associated with an entity may not be addressable as a JID. In order 29 * to handle such items, Service Discovery uses an optional 'node' attribute 30 * that supplements the 'jid' attribute. 31 * 32 * @author Gaston Dombiak 33 */ 34 public class DiscoItem implements Result { 35 36 private final JID jid; 37 private final String name; 38 private final String node; 39 private final String action; 40 private final Element element; 41 42 private volatile String uid = null; 43 DiscoItem(Element element)44 public DiscoItem(Element element) { 45 this.element = element; 46 jid = new JID(element.attributeValue("jid")); 47 action = element.attributeValue("action"); 48 name = element.attributeValue("name"); 49 node = element.attributeValue("node"); 50 } 51 52 /** 53 * Creates a new DiscoItem instance. 54 * 55 * @param jid 56 * specifies the Jabber ID of the item "owner" or location 57 * (required). 58 * @param name 59 * specifies a natural-language name for the item (can be null). 60 * @param node 61 * specifies the particular node associated with the JID of the 62 * item "owner" or location (can be null). 63 * @param action 64 * specifies the action to be taken for the item. 65 * @throws IllegalArgumentException 66 * If a required parameter was null, or if the supplied 'action' 67 * parameter has another value than 'null', "update" or 68 * "remove". 69 */ DiscoItem(JID jid, String name, String node, String action)70 public DiscoItem(JID jid, String name, String node, String action) { 71 if (jid == null) { 72 throw new IllegalArgumentException("Argument 'jid' cannot be null."); 73 } 74 75 if (action != null && !action.equals("update") 76 && !action.equals("remove")) { 77 throw new IllegalArgumentException( 78 "Argument 'jid' cannot have any other value than null, \"update\" or \"remove\"."); 79 } 80 81 this.jid = jid; 82 this.name = name; 83 this.node = node; 84 this.action = action; 85 86 element = DocumentHelper.createElement("item"); 87 element.addAttribute("jid", jid.toString()); 88 if (action != null) { 89 element.addAttribute("action", action); 90 } 91 if (name != null) { 92 element.addAttribute("name", name); 93 } 94 if (node != null) { 95 element.addAttribute("node", node); 96 } 97 } 98 99 /** 100 * <p> 101 * Returns the entity's ID. 102 * </p> 103 * 104 * @return the entity's ID. 105 */ getJID()106 public JID getJID() { 107 return jid; 108 } 109 110 /** 111 * <p> 112 * Returns the node attribute that supplements the 'jid' attribute. A node 113 * is merely something that is associated with a JID and for which the JID 114 * can provide information. 115 * </p> 116 * <p> 117 * Node attributes SHOULD be used only when trying to provide or query 118 * information which is not directly addressable. 119 * </p> 120 * 121 * @return the node attribute that supplements the 'jid' attribute 122 */ getNode()123 public String getNode() { 124 return node; 125 } 126 127 /** 128 * <p> 129 * Returns the entity's name. The entity's name specifies in 130 * natural-language the name for the item. 131 * </p> 132 * 133 * @return the entity's name. 134 */ getName()135 public String getName() { 136 return name; 137 } 138 139 /** 140 * <p> 141 * Returns the action (i.e. update or remove) that indicates what must be 142 * done with this item or null if none. An "update" action requests the 143 * server to create or update the item. Whilst a "remove" action requests to 144 * remove the item. 145 * </p> 146 * 147 * @return the action (i.e. update or remove) that indicates what must be 148 * done with this item or null if none. 149 */ getAction()150 public String getAction() { 151 return action; 152 } 153 154 /** 155 * Returns a dom4j element that represents this DiscoItem object. 156 * 157 * @return element representing this object. 158 */ getElement()159 public Element getElement() { 160 return element; 161 } 162 163 /* 164 * (non-Javadoc) 165 * 166 * @see org.jivesoftware.util.resultsetmanager.Result#getUID() 167 */ 168 @Override getUID()169 public String getUID() { 170 if (uid == null) { 171 synchronized(this) { 172 if (uid == null) { 173 final StringBuilder sb = new StringBuilder(jid.toString()); 174 if (name != null) { 175 sb.append(name); 176 } 177 if (node != null) { 178 sb.append(node); 179 } 180 if (action != null) { 181 sb.append(action); 182 } 183 uid = sb.toString(); 184 } 185 } 186 } 187 return uid; 188 } 189 190 @Override hashCode()191 public int hashCode() { 192 return getUID().hashCode(); 193 } 194 195 @Override equals(Object obj)196 public boolean equals(Object obj) { 197 return obj instanceof DiscoItem && getUID().equals(((DiscoItem)obj).getUID()); 198 } 199 200 @Override toString()201 public String toString() { 202 return element.asXML(); 203 } 204 205 } 206