001/**
002 *
003 * Copyright 2014 Vyacheslav Blinov
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.amp;
018
019import org.jivesoftware.smack.ConnectionCreationListener;
020import org.jivesoftware.smack.SmackException.NoResponseException;
021import org.jivesoftware.smack.SmackException.NotConnectedException;
022import org.jivesoftware.smack.XMPPConnection;
023import org.jivesoftware.smack.XMPPConnectionRegistry;
024import org.jivesoftware.smack.XMPPException.XMPPErrorException;
025
026import org.jivesoftware.smackx.amp.packet.AMPExtension;
027import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
028
029/**
030 * Manages AMP stanzas within messages. A AMPManager provides a high level access to
031 * get and set AMP rules to messages.
032 *
033 * See http://xmpp.org/extensions/xep-0079.html for AMP extension details
034 *
035 * @author Vyacheslav Blinov
036 */
037public class AMPManager {
038
039
040    // Enable the AMP support on every established connection
041    // The ServiceDiscoveryManager class should have been already initialized
042    static {
043        XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
044            @Override
045            public void connectionCreated(XMPPConnection connection) {
046                AMPManager.setServiceEnabled(connection, true);
047            }
048        });
049    }
050
051    /**
052     * Enables or disables the AMP support on a given connection.<p>
053     *
054     * Before starting to send AMP messages to a user, check that the user can handle XHTML
055     * messages. Enable the AMP support to indicate that this client handles XHTML messages.
056     *
057     * @param connection the connection where the service will be enabled or disabled
058     * @param enabled indicates if the service will be enabled or disabled
059     */
060    public static synchronized void setServiceEnabled(XMPPConnection connection, boolean enabled) {
061        if (isServiceEnabled(connection) == enabled)
062            return;
063
064        if (enabled) {
065            ServiceDiscoveryManager.getInstanceFor(connection).addFeature(AMPExtension.NAMESPACE);
066        }
067        else {
068            ServiceDiscoveryManager.getInstanceFor(connection).removeFeature(AMPExtension.NAMESPACE);
069        }
070    }
071
072    /**
073     * Returns true if the AMP support is enabled for the given connection.
074     *
075     * @param connection the connection to look for AMP support
076     * @return a boolean indicating if the AMP support is enabled for the given connection
077     */
078    public static boolean isServiceEnabled(XMPPConnection connection) {
079        connection.getXMPPServiceDomain();
080        return ServiceDiscoveryManager.getInstanceFor(connection).includesFeature(AMPExtension.NAMESPACE);
081    }
082
083    /**
084     * Check if server supports specified action.
085     * @param connection active xmpp connection
086     * @param action action to check
087     * @return true if this action is supported.
088     * @throws XMPPErrorException if there was an XMPP error returned.
089     * @throws NoResponseException if there was no response from the remote entity.
090     * @throws NotConnectedException if the XMPP connection is not connected.
091     * @throws InterruptedException if the calling thread was interrupted.
092     */
093    public static boolean isActionSupported(XMPPConnection connection, AMPExtension.Action action) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
094        String featureName = AMPExtension.NAMESPACE + "?action=" + action.toString();
095        return isFeatureSupportedByServer(connection, featureName);
096    }
097
098    /**
099     * Check if server supports specified condition.
100     * @param connection active xmpp connection
101     * @param conditionName name of condition to check
102     * @return true if this condition is supported.
103     * @throws XMPPErrorException if there was an XMPP error returned.
104     * @throws NoResponseException if there was no response from the remote entity.
105     * @throws NotConnectedException if the XMPP connection is not connected.
106     * @throws InterruptedException if the calling thread was interrupted.
107     * @see AMPDeliverCondition
108     * @see AMPExpireAtCondition
109     * @see AMPMatchResourceCondition
110     */
111    public static boolean isConditionSupported(XMPPConnection connection, String conditionName) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
112        String featureName = AMPExtension.NAMESPACE + "?condition=" + conditionName;
113        return isFeatureSupportedByServer(connection, featureName);
114    }
115
116    private static boolean isFeatureSupportedByServer(XMPPConnection connection, String featureName) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
117        return ServiceDiscoveryManager.getInstanceFor(connection).serverSupportsFeature(featureName);
118    }
119}