1d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpackage org.jivesoftware.smackx;
2d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
3d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.HashMap;
4d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.Iterator;
5d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.List;
6d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.Map;
7d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
8d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.Connection;
9d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.PacketCollector;
10d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.PacketListener;
11d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.Roster;
12d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.RosterEntry;
13d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.SmackConfiguration;
14d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.XMPPException;
15d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.filter.PacketIDFilter;
16d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.filter.PacketTypeFilter;
17d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.packet.IQ;
18d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.packet.Packet;
19d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.packet.Presence;
20d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.packet.Registration;
21d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.util.StringUtils;
22d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smackx.packet.DiscoverInfo;
23d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smackx.packet.DiscoverInfo.Identity;
24d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
25d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/**
26d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * This class provides an abstract view to gateways/transports. This class handles all
27d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * actions regarding gateways and transports.
28d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @author Till Klocke
29d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *
30d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */
31d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic class Gateway {
32d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
33d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	private Connection connection;
34d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	private ServiceDiscoveryManager sdManager;
35d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	private Roster roster;
36d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	private String entityJID;
37d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	private Registration registerInfo;
38d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	private Identity identity;
39d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	private DiscoverInfo info;
40d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
41d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	Gateway(Connection connection, String entityJID){
42d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		this.connection = connection;
43d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		this.roster = connection.getRoster();
44d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		this.sdManager = ServiceDiscoveryManager.getInstanceFor(connection);
45d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		this.entityJID = entityJID;
46d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	}
47d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
48d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	Gateway(Connection connection, String entityJID, DiscoverInfo info, Identity identity){
49d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		this(connection, entityJID);
50d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		this.info = info;
51d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		this.identity = identity;
52d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	}
53d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
54d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	private void discoverInfo() throws XMPPException{
55d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		info = sdManager.discoverInfo(entityJID);
56d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		Iterator<Identity> iterator = info.getIdentities();
57d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		while(iterator.hasNext()){
58d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			Identity temp = iterator.next();
59d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			if(temp.getCategory().equalsIgnoreCase("gateway")){
60d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen				this.identity = temp;
61d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen				break;
62d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			}
63d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		}
64d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	}
65d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
66d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	private Identity getIdentity() throws XMPPException{
67d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		if(identity==null){
68d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			discoverInfo();
69d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		}
70d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		return identity;
71d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	}
72d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
73d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	private Registration getRegisterInfo(){
74d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		if(registerInfo==null){
75d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			refreshRegisterInfo();
76d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		}
77d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		return registerInfo;
78d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	}
79d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
80d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	private void refreshRegisterInfo(){
81d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		Registration packet = new Registration();
82d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		packet.setFrom(connection.getUser());
83d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		packet.setType(IQ.Type.GET);
84d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		packet.setTo(entityJID);
85d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		PacketCollector collector =
86d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			connection.createPacketCollector(new PacketIDFilter(packet.getPacketID()));
87d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		connection.sendPacket(packet);
88d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		Packet result = collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
89d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		collector.cancel();
90d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		if(result instanceof Registration && result.getError()==null){
91d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			Registration register = (Registration)result;
92d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			this.registerInfo = register;
93d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		}
94d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	}
95d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
96d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	/**
97d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * Checks if this gateway supports In-Band registration
98d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * @return true if In-Band registration is supported
99d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * @throws XMPPException
100d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 */
101d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	public boolean canRegister() throws XMPPException{
102d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		if(info==null){
103d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			discoverInfo();
104d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		}
105d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		return info.containsFeature("jabber:iq:register");
106d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	}
107d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
108d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	/**
109d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * Returns all fields that are required to register to this gateway
110d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * @return a list of required fields
111d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 */
112d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	public List<String> getRequiredFields(){
113d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		return getRegisterInfo().getRequiredFields();
114d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	}
115d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
116d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	/**
117d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * Returns the name as proposed in this gateways identity discovered via service
118d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * discovery
119d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * @return a String of its name
120d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * @throws XMPPException
121d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 */
122d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	public String getName() throws XMPPException{
123d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		if(identity==null){
124d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			discoverInfo();
125d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		}
126d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		return identity.getName();
127d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	}
128d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
129d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	/**
130d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * Returns the type as proposed in this gateways identity discovered via service
131d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * discovery. See {@link http://xmpp.org/registrar/disco-categories.html} for
132d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * possible types
133d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * @return a String describing the type
134d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * @throws XMPPException
135d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 */
136d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	public String getType() throws XMPPException{
137d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		if(identity==null){
138d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			discoverInfo();
139d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		}
140d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		return identity.getType();
141d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	}
142d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
143d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	/**
144d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * Returns true if the registration informations indicates that you are already
145d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * registered with this gateway
146d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * @return true if already registered
147d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * @throws XMPPException
148d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 */
149d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	public boolean isRegistered() throws XMPPException{
150d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		return getRegisterInfo().isRegistered();
151d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	}
152d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
153d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	/**
154d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * Returns the value of specific field of the registration information. Can be used
155d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * to retrieve for example to retrieve username/password used on an already registered
156d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * gateway.
157d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * @param fieldName name of the field
158d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * @return a String containing the value of the field or null
159d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 */
160d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	public String getField(String fieldName){
161d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		return getRegisterInfo().getField(fieldName);
162d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	}
163d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
164d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	/**
165d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * Returns a List of Strings of all field names which contain values.
166d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * @return a List of field names
167d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 */
168d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	public List<String> getFieldNames(){
169d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		return getRegisterInfo().getFieldNames();
170d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	}
171d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
172d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	/**
173d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * A convenience method for retrieving the username of an existing account
174d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * @return String describing the username
175d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 */
176d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	public String getUsername(){
177d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		return getField("username");
178d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	}
179d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
180d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	/**
181d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * A convenience method for retrieving the password of an existing accoung
182d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * @return String describing the password
183d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 */
184d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	public String getPassword(){
185d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		return getField("password");
186d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	}
187d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
188d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	/**
189d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * Returns instructions for registering with this gateway
190d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * @return String containing instructions
191d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 */
192d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	public String getInstructions(){
193d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		return getRegisterInfo().getInstructions();
194d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	}
195d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
196d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	/**
197d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * With this method you can register with this gateway or modify an existing registration
198d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * @param username String describing the username
199d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * @param password String describing the password
200d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * @param fields additional fields like email.
201d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * @throws XMPPException
202d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 */
203d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	public void register(String username, String password, Map<String,String> fields)throws XMPPException{
204d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		if(getRegisterInfo().isRegistered()) {
205d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			throw new IllegalStateException("You are already registered with this gateway");
206d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		}
207d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		Registration register = new Registration();
208d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		register.setFrom(connection.getUser());
209d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		register.setTo(entityJID);
210d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		register.setType(IQ.Type.SET);
211d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		register.setUsername(username);
212d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		register.setPassword(password);
213d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		for(String s : fields.keySet()){
214d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			register.addAttribute(s, fields.get(s));
215d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		}
216d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		PacketCollector resultCollector =
217d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			connection.createPacketCollector(new PacketIDFilter(register.getPacketID()));
218d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		connection.sendPacket(register);
219d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		Packet result =
220d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			resultCollector.nextResult(SmackConfiguration.getPacketReplyTimeout());
221d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		resultCollector.cancel();
222d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		if(result!=null && result instanceof IQ){
223d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			IQ resultIQ = (IQ)result;
224d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			if(resultIQ.getError()!=null){
225d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen				throw new XMPPException(resultIQ.getError());
226d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			}
227d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			if(resultIQ.getType()==IQ.Type.ERROR){
228d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen				throw new XMPPException(resultIQ.getError());
229d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			}
230d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			connection.addPacketListener(new GatewayPresenceListener(),
231d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen					new PacketTypeFilter(Presence.class));
232d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			roster.createEntry(entityJID, getIdentity().getName(), new String[]{});
233d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		}
234d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		else{
235d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			throw new XMPPException("Packet reply timeout");
236d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		}
237d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	}
238d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
239d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	/**
240d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * A convenience method for registering or modifying an account on this gateway without
241d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * additional fields
242d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * @param username String describing the username
243d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * @param password String describing the password
244d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * @throws XMPPException
245d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 */
246d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	public void register(String username, String password) throws XMPPException{
247d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		register(username, password,new HashMap<String,String>());
248d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	}
249d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
250d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	/**
251d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * This method removes an existing registration from this gateway
252d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * @throws XMPPException
253d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 */
254d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	public void unregister() throws XMPPException{
255d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		Registration register = new Registration();
256d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		register.setFrom(connection.getUser());
257d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		register.setTo(entityJID);
258d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		register.setType(IQ.Type.SET);
259d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		register.setRemove(true);
260d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		PacketCollector resultCollector =
261d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			connection.createPacketCollector(new PacketIDFilter(register.getPacketID()));
262d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		connection.sendPacket(register);
263d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		Packet result = resultCollector.nextResult(SmackConfiguration.getPacketReplyTimeout());
264d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		resultCollector.cancel();
265d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		if(result!=null && result instanceof IQ){
266d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			IQ resultIQ = (IQ)result;
267d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			if(resultIQ.getError()!=null){
268d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen				throw new XMPPException(resultIQ.getError());
269d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			}
270d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			if(resultIQ.getType()==IQ.Type.ERROR){
271d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen				throw new XMPPException(resultIQ.getError());
272d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			}
273d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			RosterEntry gatewayEntry = roster.getEntry(entityJID);
274d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			roster.removeEntry(gatewayEntry);
275d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		}
276d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		else{
277d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			throw new XMPPException("Packet reply timeout");
278d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		}
279d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	}
280d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
281d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	/**
282d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * Lets you login manually in this gateway. Normally a gateway logins you when it
283d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * receives the first presence broadcasted by your server. But it is possible to
284d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * manually login and logout by sending a directed presence. This method sends an
285d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * empty available presence direct to the gateway.
286d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 */
287d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	public void login(){
288d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		Presence presence = new Presence(Presence.Type.available);
289d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		login(presence);
290d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	}
291d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
292d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	/**
293d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * This method lets you send the presence direct to the gateway. Type, To and From
294d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * are modified.
295d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * @param presence the presence used to login to gateway
296d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 */
297d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	public void login(Presence presence){
298d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		presence.setType(Presence.Type.available);
299d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		presence.setTo(entityJID);
300d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		presence.setFrom(connection.getUser());
301d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		connection.sendPacket(presence);
302d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	}
303d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
304d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	/**
305d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * This method logs you out from this gateway by sending an unavailable presence
306d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * to directly to this gateway.
307d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 */
308d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	public void logout(){
309d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		Presence presence = new Presence(Presence.Type.unavailable);
310d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		presence.setTo(entityJID);
311d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		presence.setFrom(connection.getUser());
312d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		connection.sendPacket(presence);
313d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	}
314d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
315d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	private class GatewayPresenceListener implements PacketListener{
316d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
317d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		public void processPacket(Packet packet) {
318d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			if(packet instanceof Presence){
319d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen				Presence presence = (Presence)packet;
320d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen				if(entityJID.equals(presence.getFrom()) &&
321d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen						roster.contains(presence.getFrom()) &&
322d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen						presence.getType().equals(Presence.Type.subscribe)){
323d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen					Presence response = new Presence(Presence.Type.subscribed);
324d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen					response.setTo(presence.getFrom());
325d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen					response.setFrom(StringUtils.parseBareAddress(connection.getUser()));
326d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen					connection.sendPacket(response);
327d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen				}
328d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			}
329d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
330d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		}
331d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	}
332d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
333d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen}
334