/*
* Tigase Jabber/XMPP Server
* Copyright (C) 2004-2012 "Artur Hefczyc" <artur.hefczyc@tigase.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. Look for COPYING file in the top folder.
* If not, see http://www.gnu.org/licenses/.
*
* $Rev$
* Last modified by $Author$
* $Date$
*/
package tigase.server.ext;
//~--- non-JDK imports --------------------------------------------------------
import tigase.db.comp.RepositoryItemAbstract;
import tigase.net.ConnectionType;
import tigase.server.Command;
import tigase.server.Packet;
import tigase.server.ext.lb.LoadBalancerIfc;
import tigase.server.ext.lb.ReceiverBareJidLB;
import tigase.xml.Element;
//~--- JDK imports ------------------------------------------------------------
import java.util.logging.Level;
import java.util.logging.Logger;
//~--- classes ----------------------------------------------------------------
/**
* Created: Oct 3, 2009 4:39:51 PM
*
* @author <a href="mailto:artur.hefczyc@tigase.org">Artur Hefczyc</a>
* @version $Rev$
*/
public class CompRepoItem extends RepositoryItemAbstract {
/**
* Variable <code>log</code> is a class logger.
*/
private static final Logger log = Logger.getLogger(CompRepoItem.class.getName());
/** Field description */
public static final String REPO_ITEM_ELEM_NAME = "item";
/** Field description */
public static final String DOMAIN_ATTR = "domain";
/** Field description */
public static final String REMOTE_HOST_ATTR = "remote";
/** Field description */
public static final String CONN_TYPE_ATTR = "type";
/** Field description */
public static final String PORT_NO_ATTR = "port";
/** Field description */
public static final String PASSWORD_ATTR = "pass";
/** Field description */
public static final String PROTO_XMLNS_ATTR = "proto-xmlns";
/** Field description */
public static final String ROUTINGS_ATTR = "routings";
public static final String LB_NAME_ATTR = "lb-class";
/** Field description */
public static final String DOMAIN_NAME_LABEL = "Domain name";
/** Field description */
public static final String DOMAIN_PASS_LABEL = "Domain password";
/** Field description */
public static final String CONNECTION_TYPE_LABEL = "Connection type";
/** Field description */
public static final String PORT_NO_LABEL = "Port number";
/** Field description */
public static final String REMOTE_HOST_LABEL = "Remote host";
/** Field description */
public static final String PROTO_XMLNS_LABEL = "Protocol";
/** Field description */
public static final String ROUTINGS_LABEL = "(Optional) Routings";
public static final String LB_CLASS_LABEL = "Load balancer class";
public static final LoadBalancerIfc DEF_LB_CLASS = new ReceiverBareJidLB();
// ~--- fields ---------------------------------------------------------------
private String auth_pass = null;
// "accept:muc.domain.tld:5277:user:passwd"
private String domain = null;
private int port = -1;
private String prop_xmlns = null;
private String remoteHost = null;
private String[] routings = null;
private ConnectionType type = ConnectionType.accept;
private String xmlns = null;
private LoadBalancerIfc lb = DEF_LB_CLASS;
// ~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param packet
*/
@Override
public void addCommandFields(Packet packet) {
Command.addFieldValue(packet, DOMAIN_NAME_LABEL, ((domain != null) ? domain : ""));
Command.addFieldValue(packet, DOMAIN_PASS_LABEL, ((auth_pass != null) ? auth_pass
: ""));
String[] types = new String[ConnectionType.values().length];
int i = 0;
for (ConnectionType t : ConnectionType.values()) {
types[i++] = t.name();
}
Command.addFieldValue(packet, CONNECTION_TYPE_LABEL, type.name(),
CONNECTION_TYPE_LABEL, types, types);
Command.addFieldValue(packet, PORT_NO_LABEL, ((port > 0) ? "" + port : ""));
Command.addFieldValue(packet, REMOTE_HOST_LABEL, ((remoteHost != null) ? remoteHost
: ""));
Command.addFieldValue(packet, PROTO_XMLNS_LABEL, ((prop_xmlns != null) ? prop_xmlns
: ""));
Command.addFieldValue(packet, LB_CLASS_LABEL, ((lb != null) ? lb.getClass().getName()
: ""));
Command.addFieldValue(packet, ROUTINGS_LABEL, "");
super.addCommandFields(packet);
}
// ~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @return
*/
public String getAuthPasswd() {
return auth_pass;
}
/**
* Method description
*
*
* @return
*/
public ConnectionType getConnectionType() {
return type;
}
public LoadBalancerIfc getLoadBalancer() {
return lb;
}
/**
* Method description
*
*
* @return
*/
public String getDomain() {
return domain;
}
/**
* Method description
*
*
* @return
*/
@Override
public String getElemName() {
return REPO_ITEM_ELEM_NAME;
}
/**
* Method description
*
*
* @return
*/
@Override
public String getKey() {
return domain;
}
/**
* Method description
*
*
* @return
*/
public int getPort() {
return port;
}
/**
* Method description
*
*
* @return
*/
public String getRemoteHost() {
return remoteHost;
}
/**
* Method description
*
*
* @return
*/
public String[] getRoutings() {
return routings;
}
/**
* Method description
*
*
* @return
*/
public String getXMLNS() {
return xmlns;
}
// ~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param packet
*/
@Override
public void initFromCommand(Packet packet) {
super.initFromCommand(packet);
domain = Command.getFieldValue(packet, DOMAIN_NAME_LABEL);
routings = new String[] { domain, ".*@" + domain, ".*\\." + domain };
auth_pass = Command.getFieldValue(packet, DOMAIN_PASS_LABEL);
String tmp = Command.getFieldValue(packet, REMOTE_HOST_LABEL);
if ((tmp != null) && !tmp.isEmpty()) {
remoteHost = tmp;
}
tmp = Command.getFieldValue(packet, CONNECTION_TYPE_LABEL);
if ((tmp != null) && !tmp.isEmpty()) {
type = parseConnectionType(tmp);
}
tmp = Command.getFieldValue(packet, PORT_NO_LABEL);
if ((tmp != null) && !tmp.isEmpty()) {
port = parsePortNo(tmp);
}
tmp = Command.getFieldValue(packet, PROTO_XMLNS_LABEL);
if ((tmp != null) && !tmp.isEmpty()) {
prop_xmlns = tmp;
xmlns = parseProtoXMLNS(prop_xmlns);
}
tmp = Command.getFieldValue(packet, LB_CLASS_LABEL);
if ((tmp != null) && !tmp.trim().isEmpty()) {
lb = lbInstance(tmp);
}
tmp = Command.getFieldValue(packet, ROUTINGS_LABEL);
if ((tmp != null) && !tmp.isEmpty()) {
routings = tmp.split(",");
}
}
/**
* @param tmp
* @return
*/
private LoadBalancerIfc lbInstance(String cls_name) {
String class_name = cls_name;
// if (!class_name.endsWith(".class")) {
// class_name = class_name + ".class";
// }
log.log(Level.INFO, "Activating load-balancer for domain: {0}, class: {1}",
new Object[] { domain, class_name });
LoadBalancerIfc result = null;
try {
result = (LoadBalancerIfc) Class.forName(class_name).newInstance();
} catch (Exception ex1) {
class_name = "tigase.server.ext.lb." + class_name;
log.log(Level.INFO, "Cannot active load balancer for class: {0}, trying: {1}",
new Object[] { cls_name, class_name });
try {
result = (LoadBalancerIfc) Class.forName(class_name).newInstance();
} catch (Exception ex2) {
log.log(Level.WARNING, "Cannot active load balancer for class:"
+ " {0}, or: {1}, errors: {2} or {3}, using default LB: {4}", new Object[] {
cls_name, class_name, ex1, ex2, DEF_LB_CLASS.getClass().getName() });
result = DEF_LB_CLASS;
}
}
log.log(Level.INFO, "Activated load-balancer for domain: {0}, class: {1}",
new Object[] { domain, result.getClass().getName()});
return result;
}
/**
* Method description
*
*
* @param elem
*/
@Override
public void initFromElement(Element elem) {
if (elem.getName() != REPO_ITEM_ELEM_NAME) {
throw new IllegalArgumentException("Incorrect element name, expected: "
+ REPO_ITEM_ELEM_NAME);
}
super.initFromElement(elem);
setDomain(elem.getAttribute(DOMAIN_ATTR));
auth_pass = elem.getAttribute(PASSWORD_ATTR);
remoteHost = elem.getAttribute(REMOTE_HOST_ATTR);
String tmp = elem.getAttribute(CONN_TYPE_ATTR);
if (tmp != null) {
setConnectionType(tmp);
}
tmp = elem.getAttribute(PORT_NO_ATTR);
if (tmp != null) {
port = parsePortNo(tmp);
}
tmp = elem.getAttribute(PROTO_XMLNS_ATTR);
if (tmp != null) {
setProtocol(tmp);
}
tmp = elem.getAttribute(LB_NAME_ATTR);
if (tmp != null) {
lb = lbInstance(tmp);
}
tmp = elem.getAttribute(ROUTINGS_ATTR);
if (tmp != null) {
routings = tmp.split(",");
}
}
/**
* Method description
*
*
* @param propString
*/
@Override
public void initFromPropertyString(String propString) {
String[] props = propString.split(":");
if (props.length > 0) {
setDomain(props[0]);
}
if (props.length > 1) {
auth_pass = props[1];
}
if (props.length > 2) {
setConnectionType(props[2]);
}
if (props.length > 3) {
port = parsePortNo(props[3]);
}
if (props.length > 4) {
remoteHost = props[4];
}
if (props.length > 5) {
setProtocol(props[5]);
}
if (props.length > 6) {
lb = lbInstance(props[6]);
}
}
// ~--- set methods ----------------------------------------------------------
/**
* Method description
*
*
* @param domain
*/
public void setDomain(String domain) {
this.domain = domain;
routings = new String[] { domain, ".*@" + domain, ".*\\." + domain };
}
// ~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @return
*/
@Override
public Element toElement() {
Element elem = super.toElement();
elem.addAttribute(DOMAIN_ATTR, domain);
elem.addAttribute(PASSWORD_ATTR, auth_pass);
if ((remoteHost != null) && !remoteHost.isEmpty()) {
elem.addAttribute(REMOTE_HOST_ATTR, remoteHost);
}
elem.addAttribute(CONN_TYPE_ATTR, type.name());
if (port > 0) {
elem.addAttribute(PORT_NO_ATTR, "" + port);
}
elem.addAttribute(PROTO_XMLNS_ATTR, prop_xmlns);
elem.addAttribute(LB_NAME_ATTR, lb.getClass().getName());
StringBuilder route = new StringBuilder();
for (String r : routings) {
if (route.length() > 0) {
route.append(',');
}
route.append(r);
}
elem.addAttribute(ROUTINGS_ATTR, route.toString());
return elem;
}
/**
* Method description
*
*
* @return
*/
@Override
public String toPropertyString() {
return domain + ":" + auth_pass + ":" + type.name() + ":" + port + ":" + remoteHost
+ ":" + prop_xmlns + ":" + lb.getClass().getName();
}
/**
* Method description
*
*
* @return
*/
@Override
public String toString() {
return toPropertyString();
}
// ~--- set methods ----------------------------------------------------------
void setConnectionType(String connection_type) {
this.type = parseConnectionType(connection_type);
}
void setPassword(String password) {
this.auth_pass = password;
}
void setPort(int port) {
this.port = port;
}
void setProtocol(String protocol) {
this.prop_xmlns = protocol;
this.xmlns = parseProtoXMLNS(protocol);
}
void setRemoteDomain(String remote_domain) {
this.remoteHost = remote_domain;
}
// ~--- methods --------------------------------------------------------------
private ConnectionType parseConnectionType(String input) {
ConnectionType result = ConnectionType.accept;
if (input.equals("connect")) {
result = ConnectionType.connect;
}
if (input.equals("accept") || input.equals("listen")) {
result = ConnectionType.accept;
}
return result;
}
private int parsePortNo(String input) {
int result = -1;
try {
result = Integer.parseInt(input);
} catch (Exception e) {
result = 5277;
log.warning("Incorrect port number, can't parse: " + input);
}
return result;
}
private String parseProtoXMLNS(String input) {
String result = input;
if (input.equals("accept")) {
result = "jabber:component:accept";
}
if (input.equals("client")) {
result = "jabber:client";
}
if (input.equals("connect")) {
result = "jabber:component:connect";
}
return result;
}
}
// ~ Formatted in Sun Code Convention
// ~ Formatted by Jindent --- http://www.jindent.com