View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17  package org.apache.log4j.net;
    18
    19  import java.lang.reflect.Constructor;
    20  import java.lang.reflect.InvocationTargetException;
    21  import java.lang.reflect.Method;
    22  import java.util.HashMap;
    23  import java.util.Hashtable;
    24  import java.util.Map;
    25
    26  import org.apache.log4j.helpers.LogLog;
    27
    28  public class ZeroConfSupport {
    29      private static Object jmDNS = initializeJMDNS();
    30
    31      Object serviceInfo;
    32      private static Class jmDNSClass;
    33      private static Class serviceInfoClass;
    34
    35      public ZeroConfSupport(String zone, int port, String name, Map properties) {
    36          //if version 3 is available, use it to constuct a serviceInfo instance, otherwise support the version1 API
    37          boolean isVersion3 = false;
    38          try {
    39              //create method is in version 3, not version 1
    40              jmDNSClass.getMethod("create", null);
    41              isVersion3 = true;
    42          } catch (NoSuchMethodException e) {
    43              //no-op
    44          }
    45
    46          if (isVersion3) {
    47              LogLog.debug("using JmDNS version 3 to construct serviceInfo instance");
    48              serviceInfo = buildServiceInfoVersion3(zone, port, name, properties);
    49          } else {
    50              LogLog.debug("using JmDNS version 1.0 to construct serviceInfo instance");
    51              serviceInfo = buildServiceInfoVersion1(zone, port, name, properties);
    52          }
    53      }
    54
    55      public ZeroConfSupport(String zone, int port, String name) {
    56          this(zone, port, name, new HashMap());
    57      }
    58
    59      private static Object createJmDNSVersion1()
    60      {
    61          try {
    62              return jmDNSClass.newInstance();
    63          } catch (InstantiationException e) {
    64              LogLog.warn("Unable to instantiate JMDNS", e);
    65          } catch (IllegalAccessException e) {
    66              LogLog.warn("Unable to instantiate JMDNS", e);
    67          }
    68          return null;
    69      }
    70
    71      private static Object createJmDNSVersion3()
    72      {
    73          try {
    74              Method jmDNSCreateMethod = jmDNSClass.getMethod("create", null);
    75              return jmDNSCreateMethod.invoke(null, null);
    76          } catch (IllegalAccessException e) {
    77              LogLog.warn("Unable to instantiate jmdns class", e);
    78          } catch (NoSuchMethodException e) {
    79              LogLog.warn("Unable to access constructor", e);
    80          } catch (InvocationTargetException e) {
    81                  LogLog.warn("Unable to call constructor", e);
    82          }
    83          return null;
    84      }
    85
    86      private Object buildServiceInfoVersion1(String zone, int port, String name, Map properties) {
    87          //version 1 uses a hashtable
    88          Hashtable hashtableProperties = new Hashtable(properties);
    89          try {
    90              Class[] args = new Class[6];
    91              args[0] = String.class;
    92              args[1] = String.class;
    93              args[2] = int.class;
    94              args[3] = int.class; //weight (0)
    95              args[4] = int.class; //priority (0)
    96              args[5] = Hashtable.class;
    97              Constructor constructor  = serviceInfoClass.getConstructor(args);
    98              Object[] values = new Object[6];
    99              values[0] = zone;
    100             values[1] = name;
    101             values[2] = new Integer(port);
    102             values[3] = new Integer(0);
    103             values[4] = new Integer(0);
    104             values[5] = hashtableProperties;
    105             Object result = constructor.newInstance(values);
    106             LogLog.debug("created serviceinfo: " + result);
    107             return result;
    108         } catch (IllegalAccessException e) {
    109             LogLog.warn("Unable to construct ServiceInfo instance", e);
    110         } catch (NoSuchMethodException e) {
    111             LogLog.warn("Unable to get ServiceInfo constructor", e);
    112         } catch (InstantiationException e) {
    113             LogLog.warn("Unable to construct ServiceInfo instance", e);
    114         } catch (InvocationTargetException e) {
    115             LogLog.warn("Unable to construct ServiceInfo instance", e);
    116         }
    117         return null;
    118     }
    119
    120     private Object buildServiceInfoVersion3(String zone, int port, String name, Map properties) {
    121         try {
    122             Class[] args = new Class[6];
    123             args[0] = String.class; //zone/type
    124             args[1] = String.class; //display name
    125             args[2] = int.class; //port
    126             args[3] = int.class; //weight (0)
    127             args[4] = int.class; //priority (0)
    128             args[5] = Map.class;
    129             Method serviceInfoCreateMethod = serviceInfoClass.getMethod("create", args);
    130             Object[] values = new Object[6];
    131             values[0] = zone;
    132             values[1] = name;
    133             values[2] = new Integer(port);
    134             values[3] = new Integer(0);
    135             values[4] = new Integer(0);
    136             values[5] = properties;
    137             Object result = serviceInfoCreateMethod.invoke(null, values);
    138             LogLog.debug("created serviceinfo: " + result);
    139             return result;
    140         } catch (IllegalAccessException e) {
    141             LogLog.warn("Unable to invoke create method", e);
    142         } catch (NoSuchMethodException e) {
    143             LogLog.warn("Unable to find create method", e);
    144         } catch (InvocationTargetException e) {
    145                 LogLog.warn("Unable to invoke create method", e);
    146         }
    147         return null;
    148     }
    149
    150     public void advertise() {
    151         try {
    152             Method method = jmDNSClass.getMethod("registerService", new Class[]{serviceInfoClass});
    153             method.invoke(jmDNS, new Object[]{serviceInfo});
    154             LogLog.debug("registered serviceInfo: " + serviceInfo);
    155         } catch(IllegalAccessException e) {
    156             LogLog.warn("Unable to invoke registerService method", e);
    157         } catch(NoSuchMethodException e) {
    158             LogLog.warn("No registerService method", e);
    159         } catch(InvocationTargetException e) {
    160             LogLog.warn("Unable to invoke registerService method", e);
    161         }
    162     }
    163
    164     public void unadvertise() {
    165         try {
    166             Method method = jmDNSClass.getMethod("unregisterService", new Class[]{serviceInfoClass});
    167             method.invoke(jmDNS, new Object[]{serviceInfo});
    168             LogLog.debug("unregistered serviceInfo: " + serviceInfo);
    169         } catch(IllegalAccessException e) {
    170             LogLog.warn("Unable to invoke unregisterService method", e);
    171         } catch(NoSuchMethodException e) {
    172             LogLog.warn("No unregisterService method", e);
    173         } catch(InvocationTargetException e) {
    174             LogLog.warn("Unable to invoke unregisterService method", e);
    175        }
    176     }
    177
    178     private static Object initializeJMDNS() {
    179         try {
    180             jmDNSClass = Class.forName("javax.jmdns.JmDNS");
    181             serviceInfoClass = Class.forName("javax.jmdns.ServiceInfo");
    182         } catch (ClassNotFoundException e) {
    183             LogLog.warn("JmDNS or serviceInfo class not found", e);
    184         }
    185
    186         //if version 3 is available, use it to constuct a serviceInfo instance, otherwise support the version1 API
    187         boolean isVersion3 = false;
    188         try {
    189             //create method is in version 3, not version 1
    190             jmDNSClass.getMethod("create", null);
    191             isVersion3 = true;
    192         } catch (NoSuchMethodException e) {
    193             //no-op
    194         }
    195
    196         if (isVersion3) {
    197             return createJmDNSVersion3();
    198         } else {
    199             return createJmDNSVersion1();
    200         }
    201     }
    202
    203     public static Object getJMDNSInstance() {
    204         return jmDNS;
    205     }
    206 }