📄 iqdiscoinfohandler.java
字号:
* @param provider the ServerFeaturesProvider that provides new server features.
*/
private void addServerFeaturesProvider(ServerFeaturesProvider provider) {
for (Iterator<String> it = provider.getFeatures(); it.hasNext();) {
addServerFeature(it.next());
}
}
/**
* Adds one specific feature to the information returned whenever a disco for information is
* made against the server.
*
* @param namespace the namespace identifying the new server feature.
*/
public void addServerFeature(String namespace) {
if (localServerFeatures.add(namespace)) {
Lock lock = CacheFactory.getLock(namespace, serverFeatures);
try {
lock.lock();
Set<NodeID> nodeIDs = serverFeatures.get(namespace);
if (nodeIDs == null) {
nodeIDs = new HashSet<NodeID>();
}
nodeIDs.add(XMPPServer.getInstance().getNodeID());
serverFeatures.put(namespace, nodeIDs);
}
finally {
lock.unlock();
}
}
}
/**
* Removes a feature from the information returned whenever a disco for information is
* made against the server.
*
* @param namespace the namespace of the feature to be removed.
*/
public void removeServerFeature(String namespace) {
if (localServerFeatures.remove(namespace)) {
Lock lock = CacheFactory.getLock(namespace, serverFeatures);
try {
lock.lock();
Set<NodeID> nodeIDs = serverFeatures.get(namespace);
if (nodeIDs != null) {
nodeIDs.remove(XMPPServer.getInstance().getNodeID());
if (nodeIDs.isEmpty()) {
serverFeatures.remove(namespace);
}
else {
serverFeatures.put(namespace, nodeIDs);
}
}
}
finally {
lock.unlock();
}
}
}
public void initialize(XMPPServer server) {
super.initialize(server);
serverFeatures = CacheFactory.createCache("Disco Server Features");
addServerFeature(NAMESPACE_DISCO_INFO);
// Track the implementors of ServerFeaturesProvider so that we can collect the features
// provided by the server
for (ServerFeaturesProvider provider : server.getServerFeaturesProviders()) {
addServerFeaturesProvider(provider);
}
// Collect the implementors of ServerIdentitiesProvider so that we can collect the identities
// for protocols supported by the server
for (ServerIdentitiesProvider provider : server.getServerIdentitiesProviders()) {
for (Iterator<Element> it = provider.getIdentities(); it.hasNext();) {
serverIdentities.add(it.next());
}
}
// Collect the implementors of UserIdentitiesProvider so that we can collect identities
// for registered users.
for (UserIdentitiesProvider provider : server.getUserIdentitiesProviders()) {
for (Iterator<Element> it = provider.getIdentities(); it.hasNext();) {
registeredUserIdentities.add(it.next());
}
}
setProvider(server.getServerInfo().getXMPPDomain(), getServerInfoProvider());
// Listen to cluster events
ClusterManager.addListener(this);
}
public void joinedCluster() {
restoreCacheContent();
}
public void joinedCluster(byte[] nodeID) {
// Do nothing
}
public void leftCluster() {
if (!XMPPServer.getInstance().isShuttingDown()) {
restoreCacheContent();
}
}
public void leftCluster(byte[] nodeID) {
if (ClusterManager.isSeniorClusterMember()) {
NodeID leftNode = NodeID.getInstance(nodeID);
// Remove server features added by node that is gone
for (Map.Entry<String, Set<NodeID>> entry : serverFeatures.entrySet()) {
String namespace = entry.getKey();
Lock lock = CacheFactory.getLock(namespace, serverFeatures);
try {
lock.lock();
Set<NodeID> nodeIDs = entry.getValue();
if (nodeIDs.remove(leftNode)) {
if (nodeIDs.isEmpty()) {
serverFeatures.remove(namespace);
}
else {
serverFeatures.put(namespace, nodeIDs);
}
}
}
finally {
lock.unlock();
}
}
}
}
public void markedAsSeniorClusterMember() {
// Do nothing
}
private void restoreCacheContent() {
for (String feature : localServerFeatures) {
Lock lock = CacheFactory.getLock(feature, serverFeatures);
try {
lock.lock();
Set<NodeID> nodeIDs = serverFeatures.get(feature);
if (nodeIDs == null) {
nodeIDs = new HashSet<NodeID>();
}
nodeIDs.add(XMPPServer.getInstance().getNodeID());
serverFeatures.put(feature, nodeIDs);
}
finally {
lock.unlock();
}
}
}
/**
* Returns the DiscoInfoProvider responsible for providing information at the server level. This
* means that this DiscoInfoProvider will provide information whenever a disco request whose
* recipient JID is the server (e.g. localhost) is made.
*
* @return the DiscoInfoProvider responsible for providing information at the server level.
*/
private DiscoInfoProvider getServerInfoProvider() {
return new DiscoInfoProvider() {
final ArrayList<Element> identities = new ArrayList<Element>();
public Iterator<Element> getIdentities(String name, String node, JID senderJID) {
if (node != null && serverNodeProviders.get(node) != null) {
// Redirect the request to the disco info provider of the specified node
return serverNodeProviders.get(node).getIdentities(name, node, senderJID);
}
if (name == null) {
// Answer identity of the server
synchronized (identities) {
if (identities.isEmpty()) {
Element identity = DocumentHelper.createElement("identity");
identity.addAttribute("category", "server");
identity.addAttribute("name", JiveGlobals.getProperty(
"xmpp.server.name", "Openfire Server"));
identity.addAttribute("type", "im");
identities.add(identity);
// Include identities from modules that implement ServerIdentitiesProvider
for (Element identityElement : serverIdentities) {
identities.add(identityElement);
}
}
}
return identities.iterator();
}
else {
if (SessionManager.getInstance().isAnonymousRoute(name)) {
// Answer identity of an anonymous user.
return anonymousUserIdentities.iterator();
}
else {
// Answer identity of a registered user.
// Note: We know that this user exists because #hasInfo returned true
return registeredUserIdentities.iterator();
}
}
}
public Iterator<String> getFeatures(String name, String node, JID senderJID) {
if (node != null && serverNodeProviders.get(node) != null) {
// Redirect the request to the disco info provider of the specified node
return serverNodeProviders.get(node).getFeatures(name, node, senderJID);
}
if (name == null) {
// Answer features of the server
return new HashSet<String>(serverFeatures.keySet()).iterator();
}
else {
// Answer features of the user
return userFeatures.iterator();
}
}
public boolean hasInfo(String name, String node, JID senderJID) {
if (node != null) {
if (serverNodeProviders.get(node) != null) {
// Redirect the request to the disco info provider of the specified node
return serverNodeProviders.get(node).hasInfo(name, node, senderJID);
}
// Unknown node
return false;
}
try {
// True if it is an info request of the server, a registered user or an
// anonymous user. We now support disco of user's bare JIDs
return name == null || UserManager.getInstance().getUser(name) != null ||
SessionManager.getInstance().isAnonymousRoute(name);
}
catch (UserNotFoundException e) {
return false;
}
}
public XDataFormImpl getExtendedInfo(String name, String node, JID senderJID) {
if (node != null && serverNodeProviders.get(node) != null) {
// Redirect the request to the disco info provider of the specified node
return serverNodeProviders.get(node).getExtendedInfo(name, node, senderJID);
}
return null;
}
};
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -