001/*
002 * HA-JDBC: High-Availability JDBC
003 * Copyright (C) 2012  Paul Ferraro
004 *
005 * This program is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU Lesser General Public License as published by
007 * the Free Software Foundation, either version 3 of the License, or
008 * (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013 * GNU Lesser General Public License for more details.
014 *
015 * You should have received a copy of the GNU Lesser General Public License
016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
017 */
018package net.sf.hajdbc.management;
019
020import java.lang.management.ManagementFactory;
021import java.util.Hashtable;
022
023import javax.management.JMException;
024import javax.management.MBeanServer;
025import javax.management.MalformedObjectNameException;
026import javax.management.ObjectName;
027
028import net.sf.hajdbc.Database;
029import net.sf.hajdbc.DatabaseCluster;
030import net.sf.hajdbc.logging.Level;
031import net.sf.hajdbc.logging.Logger;
032import net.sf.hajdbc.logging.LoggerFactory;
033
034/**
035 * @author Paul Ferraro
036 */
037public class DefaultMBeanRegistrar<Z, D extends Database<Z>> implements MBeanRegistrar<Z, D>
038{
039        private static final String TYPE_ATTRIBUTE = "type";
040        private static final String CLUSTER_ATTRIBUTE = "cluster";
041        private static final String DATABASE_ATTRIBUTE = "database";
042        
043        private static final String CLUSTER_TYPE = "DatabaseCluster";
044        private static final String DATABASE_TYPE = "Database";
045        
046        private static final Logger logger = LoggerFactory.getLogger(DefaultMBeanRegistrar.class);
047        
048        private final MBeanServer server;
049        private String domain = DatabaseCluster.class.getPackage().getName();
050        
051        public DefaultMBeanRegistrar()
052        {
053                this(ManagementFactory.getPlatformMBeanServer());
054        }
055        
056        public DefaultMBeanRegistrar(MBeanServer server)
057        {
058                this.server = server;
059        }
060        
061        public void setDomain(String domain)
062        {
063                this.domain = domain;
064        }
065        
066        /**
067         * {@inheritDoc}
068         * @see net.sf.hajdbc.management.MBeanRegistrar#register(net.sf.hajdbc.DatabaseCluster)
069         */
070        @Override
071        public void register(DatabaseCluster<Z, D> cluster) throws JMException
072        {
073                this.register(cluster, this.createAttributes(cluster));
074        }
075
076        /**
077         * {@inheritDoc}
078         * @see net.sf.hajdbc.management.MBeanRegistrar#register(net.sf.hajdbc.DatabaseCluster, net.sf.hajdbc.Database)
079         */
080        @Override
081        public void register(DatabaseCluster<Z, D> cluster, D database) throws JMException
082        {
083                this.register(database, this.createAttributes(cluster, database));
084        }
085
086        private void register(Object object, Hashtable<String, String> attributes) throws JMException
087        {
088                ObjectName name = this.createObjectName(attributes);
089                
090                this.server.registerMBean(new AnnotatedMBean(object), name);
091        }
092
093        /**
094         * {@inheritDoc}
095         * @see net.sf.hajdbc.management.MBeanRegistrar#unregister(net.sf.hajdbc.DatabaseCluster)
096         */
097        @Override
098        public void unregister(DatabaseCluster<Z, D> cluster)
099        {
100                this.unregister(this.createAttributes(cluster));
101        }
102
103        /**
104         * {@inheritDoc}
105         * @see net.sf.hajdbc.management.MBeanRegistrar#unregister(net.sf.hajdbc.DatabaseCluster, net.sf.hajdbc.Database)
106         */
107        @Override
108        public void unregister(DatabaseCluster<Z, D> cluster, D database)
109        {
110                this.unregister(this.createAttributes(cluster, database));
111        }
112
113        private void unregister(Hashtable<String, String> attributes)
114        {
115                try
116                {
117                        ObjectName name = this.createObjectName(attributes);
118                        
119                        if (this.server.isRegistered(name))
120                        {
121                                this.server.unregisterMBean(name);
122                        }
123                }
124                catch (Exception e)
125                {
126                        logger.log(Level.WARN, e);
127                }
128        }
129
130        private Hashtable<String, String> createAttributes(DatabaseCluster<Z, D> cluster)
131        {
132                Hashtable<String, String> attributes = new Hashtable<String, String>();
133                attributes.put(TYPE_ATTRIBUTE, CLUSTER_TYPE);
134                attributes.put(CLUSTER_ATTRIBUTE, cluster.getId());
135                return attributes;
136        }
137
138        private Hashtable<String, String> createAttributes(DatabaseCluster<Z, D> cluster, D database)
139        {
140                Hashtable<String, String> attributes = new Hashtable<String, String>();
141                attributes.put(TYPE_ATTRIBUTE, DATABASE_TYPE);
142                attributes.put(CLUSTER_ATTRIBUTE, cluster.getId());
143                attributes.put(DATABASE_ATTRIBUTE, database.getId());
144                return attributes;
145        }
146        
147        private ObjectName createObjectName(Hashtable<String, String> attributes) throws MalformedObjectNameException
148        {
149                return ObjectName.getInstance(this.domain, attributes);
150        }
151}