001: /**
002: * $RCSfile$
003: * $Revision: 1623 $
004: * $Date: 2005-07-12 18:40:57 -0300 (Tue, 12 Jul 2005) $
005: *
006: * Copyright (C) 2004 Jive Software. All rights reserved.
007: *
008: * This software is published under the terms of the GNU Public License (GPL),
009: * a copy of which is included in this distribution.
010: */package org.jivesoftware.openfire.muc.spi;
011:
012: import org.dom4j.DocumentHelper;
013: import org.dom4j.Element;
014: import org.dom4j.QName;
015: import org.jivesoftware.openfire.forms.DataForm;
016: import org.jivesoftware.openfire.forms.FormField;
017: import org.jivesoftware.openfire.forms.spi.XDataFormImpl;
018: import org.jivesoftware.openfire.forms.spi.XFormFieldImpl;
019: import org.jivesoftware.openfire.muc.ConflictException;
020: import org.jivesoftware.openfire.muc.ForbiddenException;
021: import org.jivesoftware.openfire.muc.MUCRoom;
022: import org.jivesoftware.openfire.muc.MultiUserChatServer;
023: import org.jivesoftware.util.ElementUtil;
024: import org.jivesoftware.util.LocaleUtils;
025: import org.jivesoftware.util.Log;
026: import org.xmpp.packet.IQ;
027: import org.xmpp.packet.PacketError;
028: import org.xmpp.packet.Presence;
029:
030: import java.util.ArrayList;
031: import java.util.Iterator;
032: import java.util.List;
033:
034: /**
035: * This class is responsible for handling packets with namespace jabber:iq:register that were
036: * sent to the MUC service. MultiUserChatServer will receive all the IQ packets and if the
037: * namespace of the IQ is jabber:iq:register then this class will handle the packet.
038: *
039: * @author Gaston Dombiak
040: */
041: class IQMUCRegisterHandler {
042:
043: private static Element probeResult;
044: private MultiUserChatServer mucServer;
045:
046: public IQMUCRegisterHandler(MultiUserChatServer mucServer) {
047: this .mucServer = mucServer;
048: initialize();
049: }
050:
051: public void initialize() {
052: if (probeResult == null) {
053: // Create the registration form of the room which contains information
054: // such as: first name, last name and nickname.
055: XDataFormImpl registrationForm = new XDataFormImpl(
056: DataForm.TYPE_FORM);
057: registrationForm.setTitle(LocaleUtils
058: .getLocalizedString("muc.form.reg.title"));
059: registrationForm.addInstruction(LocaleUtils
060: .getLocalizedString("muc.form.reg.instruction"));
061:
062: XFormFieldImpl field = new XFormFieldImpl("FORM_TYPE");
063: field.setType(FormField.TYPE_HIDDEN);
064: field.addValue("http://jabber.org/protocol/muc#register");
065: registrationForm.addField(field);
066:
067: field = new XFormFieldImpl("muc#register_first");
068: field.setType(FormField.TYPE_TEXT_SINGLE);
069: field.setLabel(LocaleUtils
070: .getLocalizedString("muc.form.reg.first-name"));
071: field.setRequired(true);
072: registrationForm.addField(field);
073:
074: field = new XFormFieldImpl("muc#register_last");
075: field.setType(FormField.TYPE_TEXT_SINGLE);
076: field.setLabel(LocaleUtils
077: .getLocalizedString("muc.form.reg.last-name"));
078: field.setRequired(true);
079: registrationForm.addField(field);
080:
081: field = new XFormFieldImpl("muc#register_roomnick");
082: field.setType(FormField.TYPE_TEXT_SINGLE);
083: field.setLabel(LocaleUtils
084: .getLocalizedString("muc.form.reg.nickname"));
085: field.setRequired(true);
086: registrationForm.addField(field);
087:
088: field = new XFormFieldImpl("muc#register_url");
089: field.setType(FormField.TYPE_TEXT_SINGLE);
090: field.setLabel(LocaleUtils
091: .getLocalizedString("muc.form.reg.url"));
092: registrationForm.addField(field);
093:
094: field = new XFormFieldImpl("muc#register_email");
095: field.setType(FormField.TYPE_TEXT_SINGLE);
096: field.setLabel(LocaleUtils
097: .getLocalizedString("muc.form.reg.email"));
098: registrationForm.addField(field);
099:
100: field = new XFormFieldImpl("muc#register_faqentry");
101: field.setType(FormField.TYPE_TEXT_MULTI);
102: field.setLabel(LocaleUtils
103: .getLocalizedString("muc.form.reg.faqentry"));
104: registrationForm.addField(field);
105:
106: // Create the probeResult and add the registration form
107: probeResult = DocumentHelper.createElement(QName.get(
108: "query", "jabber:iq:register"));
109: probeResult.add(registrationForm.asXMLElement());
110: }
111: }
112:
113: public IQ handleIQ(IQ packet) {
114: IQ reply = null;
115: // Get the target room
116: MUCRoom room = null;
117: String name = packet.getTo().getNode();
118: if (name != null) {
119: room = mucServer.getChatRoom(name);
120: }
121: if (room == null) {
122: // The room doesn't exist so answer a NOT_FOUND error
123: reply = IQ.createResultIQ(packet);
124: reply
125: .setChildElement(packet.getChildElement()
126: .createCopy());
127: reply.setError(PacketError.Condition.item_not_found);
128: return reply;
129: } else if (!room.isRegistrationEnabled()) {
130: // The room does not accept users to register
131: reply = IQ.createResultIQ(packet);
132: reply
133: .setChildElement(packet.getChildElement()
134: .createCopy());
135: reply.setError(PacketError.Condition.not_allowed);
136: return reply;
137: }
138:
139: if (IQ.Type.get == packet.getType()) {
140: reply = IQ.createResultIQ(packet);
141: String nickname = room.getReservedNickname(packet.getFrom()
142: .toBareJID());
143: Element currentRegistration = probeResult.createCopy();
144: if (nickname != null) {
145: // The user is already registered with the room so answer a completed form
146: ElementUtil.setProperty(currentRegistration,
147: "query.registered", null);
148: Element form = currentRegistration.element(QName.get(
149: "x", "jabber:x:data"));
150: Iterator fields = form.elementIterator("field");
151: Element field;
152: while (fields.hasNext()) {
153: field = (Element) fields.next();
154: if ("muc#register_roomnick".equals(field
155: .attributeValue("var"))) {
156: field.addElement("value").addText(nickname);
157: }
158: }
159: reply.setChildElement(currentRegistration);
160: } else {
161: // The user is not registered with the room so answer an empty form
162: reply.setChildElement(currentRegistration);
163: }
164: } else if (IQ.Type.set == packet.getType()) {
165: try {
166: // Keep a registry of the updated presences
167: List<Presence> presences = new ArrayList<Presence>();
168:
169: reply = IQ.createResultIQ(packet);
170: Element iq = packet.getChildElement();
171:
172: if (ElementUtil.includesProperty(iq, "query.remove")) {
173: // The user is deleting his registration
174: presences.addAll(room.addNone(packet.getFrom()
175: .toBareJID(), room.getRole()));
176: } else {
177: // The user is trying to register with a room
178: Element formElement = iq.element("x");
179: // Check if a form was used to provide the registration info
180: if (formElement != null) {
181: // Get the sent form
182: XDataFormImpl registrationForm = new XDataFormImpl();
183: registrationForm.parse(formElement);
184: // Get the desired nickname sent in the form
185: Iterator<String> values = registrationForm
186: .getField("muc#register_roomnick")
187: .getValues();
188: String nickname = (values.hasNext() ? values
189: .next() : null);
190:
191: // TODO The rest of the fields of the form are ignored. If we have a
192: // requirement in the future where we need those fields we'll have to change
193: // MUCRoom.addMember in order to receive a RegistrationInfo (new class)
194:
195: // Add the new member to the members list
196: presences.addAll(room.addMember(packet
197: .getFrom().toBareJID(), nickname, room
198: .getRole()));
199: } else {
200: reply.setChildElement(packet.getChildElement()
201: .createCopy());
202: reply
203: .setError(PacketError.Condition.bad_request);
204: }
205: }
206: // Send the updated presences to the room occupants
207: for (Presence presence : presences) {
208: room.send(presence);
209: }
210:
211: } catch (ForbiddenException e) {
212: reply = IQ.createResultIQ(packet);
213: reply.setChildElement(packet.getChildElement()
214: .createCopy());
215: reply.setError(PacketError.Condition.forbidden);
216: } catch (ConflictException e) {
217: reply = IQ.createResultIQ(packet);
218: reply.setChildElement(packet.getChildElement()
219: .createCopy());
220: reply.setError(PacketError.Condition.conflict);
221: } catch (Exception e) {
222: Log.error(e);
223: }
224: }
225: return reply;
226: }
227: }
|