<commit_before>package tigase.jaxmpp.core.client.xmpp.modules.disco;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import tigase.jaxmpp.core.client.AsyncCallback;
import tigase.jaxmpp.core.client.JID;
import tigase.jaxmpp.core.client.SessionObject;
import tigase.jaxmpp.core.client.XMPPException;
import tigase.jaxmpp.core.client.XMPPException.ErrorCondition;
import tigase.jaxmpp.core.client.criteria.Criteria;
import tigase.jaxmpp.core.client.criteria.ElementCriteria;
import tigase.jaxmpp.core.client.criteria.Or;
import tigase.jaxmpp.core.client.eventbus.EventHandler;
import tigase.jaxmpp.core.client.eventbus.JaxmppEvent;
import tigase.jaxmpp.core.client.exceptions.JaxmppException;
import tigase.jaxmpp.core.client.xml.Element;
import tigase.jaxmpp.core.client.xml.ElementFactory;
import tigase.jaxmpp.core.client.xml.XMLException;
import tigase.jaxmpp.core.client.xml.XmlTools;
import tigase.jaxmpp.core.client.xmpp.modules.AbstractIQModule;
import tigase.jaxmpp.core.client.xmpp.modules.ModuleProvider;
import tigase.jaxmpp.core.client.xmpp.modules.ResourceBinderModule;
import tigase.jaxmpp.core.client.xmpp.modules.SoftwareVersionModule;
import tigase.jaxmpp.core.client.xmpp.modules.disco.DiscoveryModule.ServerFeaturesReceivedHandler.ServerFeaturesReceivedEvent;
import tigase.jaxmpp.core.client.xmpp.stanzas.IQ;
import tigase.jaxmpp.core.client.xmpp.stanzas.Stanza;
import tigase.jaxmpp.core.client.xmpp.stanzas.StanzaType;

public class DiscoveryModule extends AbstractIQModule {

	public static class DefaultNodeDetailsCallback implements NodeDetailsCallback {

		private DiscoveryModule discoveryModule;

		public DefaultNodeDetailsCallback(DiscoveryModule discoveryModule) {
			super();
			this.discoveryModule = discoveryModule;
		}

		@Override
		public String[] getFeatures(SessionObject sessionObject, IQ requestStanza, String node) {
			return discoveryModule.moduleProvider.getAvailableFeatures().toArray(new String[] {});
		}

		@Override
		public Identity getIdentity(SessionObject sessionObject, IQ requestStanza, String node) {
			Identity identity = new Identity();

			String category = sessionObject.getProperty(IDENTITY_CATEGORY_KEY);
			String type = sessionObject.getProperty(IDENTITY_TYPE_KEY);
			String nme = sessionObject.getProperty(SoftwareVersionModule.NAME_KEY);
			identity.setCategory(category == null ? "client" : category);
			identity.setName(nme == null ? SoftwareVersionModule.DEFAULT_NAME_VAL : nme);
			identity.setType(type == null ? "pc" : type);

			return identity;
		}

		@Override
		public Item[] getItems(SessionObject sessionObject, IQ requestStanza, String node) {
			return null;
		}

	}

	public static abstract class DiscoInfoAsyncCallback implements AsyncCallback {

		private String requestedNode;

		protected Stanza responseStanza;

		public DiscoInfoAsyncCallback(final String requestedNode) {
			this.requestedNode = requestedNode;
		}

		protected abstract void onInfoReceived(String node, Collection<Identity> identities, Collection<String> features)
				throws XMLException;

		@Override
		public void onSuccess(Stanza responseStanza) throws XMLException {
			this.responseStanza = responseStanza;
			Element query = responseStanza.getChildrenNS("query", INFO_XMLNS);
			List<Element> identities = query.getChildren("identity");
			ArrayList<Identity> idres = new ArrayList<Identity>();
			for (Element id : identities) {
				Identity t = new Identity();
				t.setName(id.getAttribute("name"));
				t.setType(id.getAttribute("type"));
				t.setCategory(id.getAttribute("category"));
				idres.add(t);
			}

			List<Element> features = query.getChildren("feature");
			ArrayList<String> feres = new ArrayList<String>();
			for (Element element : features) {
				String v = element.getAttribute("var");
				if (v != null)
					feres.add(v);
			}

			String n = query.getAttribute("node");
			onInfoReceived(n == null ? requestedNode : n, idres, feres);
		}
	}

	public static abstract class DiscoItemsAsyncCallback implements AsyncCallback {

		public abstract void onInfoReceived(String attribute, ArrayList<Item> items) throws XMLException;

		@Override
		public void onSuccess(Stanza responseStanza) throws XMLException {
			final Element query = responseStanza.getChildrenNS("query", ITEMS_XMLNS);
			List<Element> ritems = query.getChildren("item");
			ArrayList<Item> items = new ArrayList<Item>();
			for (Element i : ritems) {
				Item to = new Item();
				if (i.getAttribute("jid") != null)
					to.setJid(JID.jidInstance(i.getAttribute("jid")));
				to.setName(i.getAttribute("name"));
				to.setNode(i.getAttribute("node"));
				items.add(to);
			}
			onInfoReceived(query.getAttribute("node"), items);
		}

	}

	public static class Identity {
		private String category;

		private String name;

		private String type;

		public String getCategory() {
			return category == null ? "" : category;
		}

		public String getName() {
			return name == null ? "" : name;
		}

		public String getType() {
			return type == null ? "" : type;
		}

		public void setCategory(String category) {
			this.category = category;
		}

		public void setName(String name) {
			this.name = name;
		}

		public void setType(String type) {
			this.type = type;
		}
	}

	public static class Item {

		private JID jid;

		private String name;

		private String node;

		public JID getJid() {
			return jid;
		}

		public String getName() {
			return name;
		}

		public String getNode() {
			return node;
		}

		public void setJid(JID jid) {
			this.jid = jid;
		}

		public void setName(String name) {
			this.name = name;
		}

		public void setNode(String node) {
			this.node = node;
		}
	}

	public interface ServerFeaturesReceivedHandler extends EventHandler {

		public static class ServerFeaturesReceivedEvent extends JaxmppEvent<ServerFeaturesReceivedHandler> {

			private final String[] features;

			private final IQ stanza;

			public ServerFeaturesReceivedEvent(SessionObject sessionObject, IQ responseStanza, String[] features) {
				super(sessionObject);
				this.stanza = responseStanza;
				this.features = features;
			}

			@Override
			protected void dispatch(ServerFeaturesReceivedHandler handler) {
				handler.onServerFeaturesReceived(sessionObject, stanza, features);
			}<commit_msg>additional info in DiscoveryModule<commit_after>package tigase.jaxmpp.core.client.xmpp.modules.disco;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import tigase.jaxmpp.core.client.AsyncCallback;
import tigase.jaxmpp.core.client.JID;
import tigase.jaxmpp.core.client.SessionObject;
import tigase.jaxmpp.core.client.XMPPException;
import tigase.jaxmpp.core.client.XMPPException.ErrorCondition;
import tigase.jaxmpp.core.client.criteria.Criteria;
import tigase.jaxmpp.core.client.criteria.ElementCriteria;
import tigase.jaxmpp.core.client.criteria.Or;
import tigase.jaxmpp.core.client.eventbus.EventHandler;
import tigase.jaxmpp.core.client.eventbus.JaxmppEvent;
import tigase.jaxmpp.core.client.exceptions.JaxmppException;
import tigase.jaxmpp.core.client.xml.Element;
import tigase.jaxmpp.core.client.xml.ElementFactory;
import tigase.jaxmpp.core.client.xml.XMLException;
import tigase.jaxmpp.core.client.xml.XmlTools;
import tigase.jaxmpp.core.client.xmpp.modules.AbstractIQModule;
import tigase.jaxmpp.core.client.xmpp.modules.ModuleProvider;
import tigase.jaxmpp.core.client.xmpp.modules.ResourceBinderModule;
import tigase.jaxmpp.core.client.xmpp.modules.SoftwareVersionModule;
import tigase.jaxmpp.core.client.xmpp.modules.disco.DiscoveryModule.ServerFeaturesReceivedHandler.ServerFeaturesReceivedEvent;
import tigase.jaxmpp.core.client.xmpp.stanzas.IQ;
import tigase.jaxmpp.core.client.xmpp.stanzas.Stanza;
import tigase.jaxmpp.core.client.xmpp.stanzas.StanzaType;

public class DiscoveryModule extends AbstractIQModule {

	public static class DefaultNodeDetailsCallback implements NodeDetailsCallback {

		private DiscoveryModule discoveryModule;

		public DefaultNodeDetailsCallback(DiscoveryModule discoveryModule) {
			super();
			this.discoveryModule = discoveryModule;
		}

		@Override
		public String[] getFeatures(SessionObject sessionObject, IQ requestStanza, String node) {
			return discoveryModule.moduleProvider.getAvailableFeatures().toArray(new String[] {});
		}

		@Override
		public Identity getIdentity(SessionObject sessionObject, IQ requestStanza, String node) {
			Identity identity = new Identity();

			String category = sessionObject.getProperty(IDENTITY_CATEGORY_KEY);
			String type = sessionObject.getProperty(IDENTITY_TYPE_KEY);
			String nme = sessionObject.getProperty(SoftwareVersionModule.NAME_KEY);
			identity.setCategory(category == null ? "client" : category);
			identity.setName(nme == null ? SoftwareVersionModule.DEFAULT_NAME_VAL : nme);
			identity.setType(type == null ? "pc" : type);

			return identity;
		}

		@Override
		public Item[] getItems(SessionObject sessionObject, IQ requestStanza, String node) {
			return null;
		}

	}

	public static abstract class DiscoInfoAsyncCallback implements AsyncCallback {

		private String requestedNode;

		protected Stanza responseStanza;

		public DiscoInfoAsyncCallback(final String requestedNode) {
			this.requestedNode = requestedNode;
		}

		protected abstract void onInfoReceived(String node, Collection<Identity> identities, Collection<String> features)
				throws XMLException;

		@Override
		public void onSuccess(Stanza responseStanza) throws XMLException {
			this.responseStanza = responseStanza;
			Element query = responseStanza.getChildrenNS("query", INFO_XMLNS);
			List<Element> identities = query.getChildren("identity");
			ArrayList<Identity> idres = new ArrayList<Identity>();
			for (Element id : identities) {
				Identity t = new Identity();
				t.setName(id.getAttribute("name"));
				t.setType(id.getAttribute("type"));
				t.setCategory(id.getAttribute("category"));
				idres.add(t);
			}

			List<Element> features = query.getChildren("feature");
			ArrayList<String> feres = new ArrayList<String>();
			for (Element element : features) {
				String v = element.getAttribute("var");
				if (v != null)
					feres.add(v);
			}

			String n = query.getAttribute("node");
			onInfoReceived(n == null ? requestedNode : n, idres, feres);
		}
	}

	public static abstract class DiscoItemsAsyncCallback implements AsyncCallback {

		public abstract void onInfoReceived(String attribute, ArrayList<Item> items) throws XMLException;

		@Override
		public void onSuccess(Stanza responseStanza) throws XMLException {
			final Element query = responseStanza.getChildrenNS("query", ITEMS_XMLNS);
			List<Element> ritems = query.getChildren("item");
			ArrayList<Item> items = new ArrayList<Item>();
			for (Element i : ritems) {
				Item to = new Item();
				if (i.getAttribute("jid") != null)
					to.setJid(JID.jidInstance(i.getAttribute("jid")));
				to.setName(i.getAttribute("name"));
				to.setNode(i.getAttribute("node"));
				items.add(to);
			}
			onInfoReceived(query.getAttribute("node"), items);
		}

	}

	public static class Identity {
		private String category;

		private String name;

		private String type;

		public String getCategory() {
			return category == null ? "" : category;
		}

		public String getName() {
			return name == null ? "" : name;
		}

		public String getType() {
			return type == null ? "" : type;
		}

		public void setCategory(String category) {
			this.category = category;
		}

		public void setName(String name) {
			this.name = name;
		}

		public void setType(String type) {
			this.type = type;
		}
	}

	public static class Item {

		private JID jid;

		private String name;

		private String node;

		public JID getJid() {
			return jid;
		}

		public String getName() {
			return name;
		}

		public String getNode() {
			return node;
		}

		public void setJid(JID jid) {
			this.jid = jid;
		}

		public void setName(String name) {
			this.name = name;
		}

		public void setNode(String node) {
			this.node = node;
		}

		@Override
		public String toString() {
			return "Item{" + "jid=" + jid + ", name=" + name + ", node=" + node + '}';
		}

	}

	public interface ServerFeaturesReceivedHandler extends EventHandler {

		public static class ServerFeaturesReceivedEvent extends JaxmppEvent<ServerFeaturesReceivedHandler> {

			private final String[] features;

			private final IQ stanza;

			public ServerFeaturesReceivedEvent(SessionObject sessionObject, IQ responseStanza, String[] features) {
				super(sessionObject);
				this.stanza = responseStanza;
				this.features = features;
			}

			@Override
			protected void dispatch(ServerFeaturesReceivedHandler handler) {
				handler.onServerFeaturesReceived(sessionObject, stanza, features);
			}
{'fraction_non_alphanumeric': 0.10406327543424318, 'fraction_numerical': 0.0, 'mean_word_length': 4.65906099166301, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 8}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1094185', 'n_tokens_mistral': 4428, 'n_tokens_neox': 3898, 'n_words': 849}