/**
* $RCSfile: ,v $
* $Revision: $
* $Date: $
*
* Copyright (C) 2004-2011 Jive Software. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.sparkimpl.plugin.privacy;
import org.jivesoftware.sparkimpl.plugin.privacy.list.PrivacyPresenceHandler;
import org.jivesoftware.sparkimpl.plugin.privacy.list.SparkPrivacyList;
import org.jivesoftware.sparkimpl.plugin.privacy.list.SparkPrivacyListListener;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.jivesoftware.smack.PrivacyList;
import org.jivesoftware.smack.PrivacyListManager;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.PrivacyItem;
import org.jivesoftware.smack.util.DNSUtil;
import org.jivesoftware.smackx.ServiceDiscoveryManager;
import org.jivesoftware.smackx.packet.DiscoverInfo;
import org.jivesoftware.smackx.packet.DiscoverInfo.Feature;
import org.jivesoftware.spark.SparkManager;
import org.jivesoftware.spark.util.log.Log;
/**
* @author Zolotarev Konstantin, Bergunde Holger
*/
public class PrivacyManager {
private static PrivacyManager singleton;
private static final Object LOCK = new Object();
private List<SparkPrivacyList> _privacyLists = new ArrayList<SparkPrivacyList>();
private PrivacyListManager privacyManager;
private PrivacyPresenceHandler _presenceHandler = new PrivacyPresenceHandler();
private Set<SparkPrivacyListListener> _listListeners = new HashSet<SparkPrivacyListListener>();
private boolean _active = false;
/**
* Creating PrivacyListManager instance
*/
private PrivacyManager() {
XMPPConnection conn = SparkManager.getConnection();
if (conn == null) {
Log.error("Privacy plugin: Connection not initialized.");
}
_active = checkIfPrivacyIsSupported(conn);
if (_active)
{
privacyManager = PrivacyListManager.getInstanceFor(conn);
initializePrivacyLists();
}
}
/**
* Get Class instance
*
* @return instance of {@link PrivacyManager}
*/
public static PrivacyManager getInstance() {
// Synchronize on LOCK to ensure that we don't end up creating
// two singletons.
synchronized (LOCK) {
if (null == singleton) {
singleton = new PrivacyManager();
}
}
return singleton;
}
private boolean checkIfPrivacyIsSupported(XMPPConnection conn) {
ServiceDiscoveryManager servDisc = ServiceDiscoveryManager.getInstanceFor(conn);
DiscoverInfo info = null;
//Re: SPARK-1483 comment the loop as it causes Out Of Memory (infinite loop) if info not found
//If really necessary to try more times, a Thread Pool may be used: java ScheduledThreadPoolExecutor for example
//while (info == null){
try {
String xmppHost = DNSUtil.resolveXMPPDomain(conn.getServiceName()).getHost();
info = servDisc.discoverInfo(xmppHost);
} catch (XMPPException e) {
// We could not query the server
}
//}
if (info != null) {
for (Iterator<Feature> i = info.getFeatures(); i.hasNext();) {
String s = i.next().getVar();
if (s.contains("jabber:iq:privacy")) {
return true;
}
}
}
return false;
}
private void initializePrivacyLists()
{
try {
PrivacyList[] lists = privacyManager.getPrivacyLists();
for (PrivacyList list: lists)
{
SparkPrivacyList sparkList = new SparkPrivacyList(list);
sparkList.addSparkPrivacyListener(_presenceHandler);
_privacyLists.add(sparkList);
}
} catch (XMPPException e) {
Log.error("Could not load PrivacyLists");
e.printStackTrace();
}
if(hasDefaultList())
{
setListAsActive(getDefaultList().getListName());
}
}
public void removePrivacyList(String listName) {
try {
privacyManager.deletePrivacyList(listName);
_privacyLists.remove(getPrivacyList(listName));
} catch (XMPPException e) {
Log.warning("Could not remove PrivacyList " + listName);
e.printStackTrace();
}
}
/**
* Check for active list existence
*
* @return boolean
*/
public boolean hasActiveList() {
for (SparkPrivacyList list: _privacyLists)
{
if (list.isActive())
return true;
}
return false;
}
/**
* Returns the active PrivacyList
*
* @return the list if there is one, else null
*/
public SparkPrivacyList getActiveList() {
for (SparkPrivacyList list: _privacyLists)
{
if (list.isActive())
return list;
}
return null;
}
/**
* Returns the sparkprivacylist that the manager keeps local, to get updated
* version try to forcereloadlists
*
* @param s
* the name of the list
* @return SparkPrivacyList
*/
public SparkPrivacyList getPrivacyList(String s) {
for (SparkPrivacyList list: _privacyLists)
{
if (list.getListName().equals(s))
return list;
}
return createPrivacyList(s);
}
/**
* Check if active list exist
*
* @return boolean
*/
public boolean hasDefaultList() {
for (SparkPrivacyList list: _privacyLists)
{
if (list.isDefault())
return true;
}
return false;
}
public SparkPrivacyList getDefaultList()
{
for (SparkPrivacyList list: _privacyLists)
{
if (list.isDefault())
return list;
}
return null;
}
/**
* Get <code>org.jivesoftware.smack.PrivacyListManager</code> instance
*
* @return PrivacyListManager
*/
public PrivacyListManager getPrivacyListManager() {
return privacyManager;
}
public SparkPrivacyList createPrivacyList(String listName) {
PrivacyItem item = new PrivacyItem(null,true,999999);
ArrayList<PrivacyItem> items = new ArrayList<PrivacyItem>();
items.add(item);
SparkPrivacyList sparklist = null;
try {
privacyManager.createPrivacyList(listName, items);
privacyManager.getPrivacyList(listName).getItems().remove(item);
sparklist = new SparkPrivacyList(privacyManager.getPrivacyList(listName));
_privacyLists.add(sparklist);
sparklist.addSparkPrivacyListener(_presenceHandler);
} catch (XMPPException e) {
Log.warning("Could not create PrivacyList "+listName);
e.printStackTrace();
}
return sparklist;
}
/**
* The server can store different privacylists. This method will return the
* names of the lists, currently available on the server
*
* @return All Listnames
*/
public List<SparkPrivacyList> getPrivacyLists() {
return new ArrayList<SparkPrivacyList>(_privacyLists);
}
public void setListAsActive(String listname)
{
try {
privacyManager.setActiveListName(listname);
fireListActivated(listname);
if (hasActiveList())
{
_presenceHandler.removeIconsForList(getActiveList());
}
getPrivacyList(listname).setListAsActive(true);
for (SparkPrivacyList plist : _privacyLists) {
if (!plist.getListName().equals(listname))
plist.setListAsActive(false);
}
_presenceHandler.setIconsForList(getActiveList());
} catch (XMPPException e) {
Log.warning("Could not activate PrivacyList " + listname);
e.printStackTrace();
}
}
public void setListAsDefault(String listname) {
try {
privacyManager.setDefaultListName(listname);
fireListSetAsDefault(listname);
getPrivacyList(listname).setListIsDefault(true);
for (SparkPrivacyList plist : _privacyLists) {
if (!plist.getListName().equals(listname))
plist.setListIsDefault(false);
}
} catch (XMPPException e) {
Log.warning("Could not set PrivacyList " + listname+" as default");
e.printStackTrace();
}
}
public void declineActiveList()
{
try {
if(hasActiveList())
{
privacyManager.declineActiveList();
fireListDeActivated(getActiveList().getListName());
_presenceHandler.removeIconsForList(getActiveList());
}
for (SparkPrivacyList plist : _privacyLists) {
plist.setListAsActive(false);
}
} catch (XMPPException e) {
Log.warning("Could not decline active privacy list");
e.printStackTrace();
}
}
public void declineDefaultList()
{
try {
if (hasDefaultList())
{
privacyManager.declineDefaultList();
fireListRemovedAsDefault(getDefaultList().getListName());
for (SparkPrivacyList plist : _privacyLists) {
plist.setListIsDefault(false);
}
}
} catch (XMPPException e) {
Log.warning("Could not decline default privacy list");
e.printStackTrace();
}
}
public boolean isPrivacyActive()
{
return _active ;
}
public void addListListener (SparkPrivacyListListener listener)
{
_listListeners.add(listener);
}
public void deleteListListener (SparkPrivacyListListener listener)
{
_listListeners.remove(listener);
}
private void fireListActivated(String listname)
{
for (SparkPrivacyListListener listener: _listListeners)
{
listener.listActivated(listname);
}
}
private void fireListDeActivated(String listname)
{
for (SparkPrivacyListListener listener: _listListeners)
{
listener.listDeActivated(listname);
}
}
private void fireListSetAsDefault(String listname)
{
for (SparkPrivacyListListener listener: _listListeners)
{
listener.listSetAsDefault(listname);
}
}
private void fireListRemovedAsDefault(String listname)
{
for (SparkPrivacyListListener listener: _listListeners)
{
listener.listRemovedAsDefault(listname);
}
}
}