| /* |
| * Copyright 1999,2004-2005 The Apache Software Foundation. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.catalina.cluster.tcp; |
| |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.lang.reflect.Constructor; |
| import java.net.InetAddress; |
| import java.util.Iterator; |
| import java.util.Properties; |
| |
| import org.apache.catalina.cluster.Member; |
| import org.apache.catalina.util.StringManager; |
| |
| /** |
| * Create DataSender for different modes. DataSender factory load mode list from |
| * <code>org/apache/catalina/cluster/tcp/DataSenders.properties</code> resource. |
| * |
| * @author Peter Rossbach |
| * @version $Revision$ $Date$ |
| * @since 5.5.7 |
| */ |
| public class IDataSenderFactory { |
| |
| private static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory |
| .getLog(IDataSenderFactory.class); |
| |
| private static final String DATASENDERS_PROPERTIES = "org/apache/catalina/cluster/tcp/DataSenders.properties"; |
| public static final String SYNC_MODE = "synchronous"; |
| public static final String ASYNC_MODE = "asynchronous"; |
| public static final String POOLED_SYNC_MODE = "pooled"; |
| public static final String FAST_ASYNC_QUEUE_MODE = "fastasyncqueue"; |
| |
| /** |
| * The string manager for this package. |
| */ |
| protected static StringManager sm = StringManager |
| .getManager(Constants.Package); |
| |
| // ----------------------------------------------------- Instance Variables |
| |
| /** |
| * The descriptive information about this implementation. |
| */ |
| private static final String info = "IDataSenderFactory/2.0"; |
| |
| private IDataSenderFactory() { |
| } |
| |
| private Properties senderModes; |
| |
| private static IDataSenderFactory factory ; |
| |
| static { |
| factory = new IDataSenderFactory(); |
| factory.loadSenderModes(); |
| } |
| |
| // ------------------------------------------------------------- Properties |
| |
| /** |
| * Return descriptive information about this implementation and the |
| * corresponding version number, in the format |
| * <code><description>/<version></code>. |
| */ |
| public static String getInfo() { |
| return (info); |
| } |
| |
| // ------------------------------------------------------------- static |
| |
| /** |
| * Create a new DataSender |
| * @param mode replicaton mode |
| * @param mbr sender target |
| * @return new sender object |
| * @throws java.io.IOException |
| */ |
| public synchronized static IDataSender getIDataSender(String mode, |
| Member mbr) throws java.io.IOException { |
| // Identify the class name of the DataSender we should configure |
| IDataSender sender = factory.getSender(mode,mbr); |
| if(sender == null) |
| throw new java.io.IOException("Invalid replication mode=" + mode); |
| return sender ; |
| } |
| |
| /** |
| * Check that mode is valid |
| * @param mode |
| * @return The replication mode (may be null if sender mode) |
| */ |
| public static String validateMode(String mode) { |
| if(factory.isSenderMode(mode)) |
| return null ; |
| else { |
| StringBuffer buffer = new StringBuffer("Replication mode has to be '"); |
| for (Iterator iter = factory.senderModes.keySet().iterator(); iter.hasNext();) { |
| String key = (String) iter.next(); |
| buffer.append(key); |
| if(iter.hasNext()) |
| buffer.append("', '"); |
| } |
| return buffer.toString(); |
| } |
| } |
| |
| // ------------------------------------------------------------- private |
| |
| private boolean isSenderMode(String mode){ |
| return senderModes != null && senderModes.containsKey(mode) ; |
| } |
| |
| private IDataSender getSender(String mode,Member mbr) { |
| IDataSender sender = null; |
| String senderName = null; |
| senderName = senderModes.getProperty(mode); |
| if (senderName != null) { |
| |
| // Instantiate and install a data replication sender of the requested class |
| try { |
| Class senderClass = Class.forName(senderName); |
| Class paramTypes[] = new Class[3]; |
| paramTypes[0] = Class.forName("java.lang.String"); |
| paramTypes[1] = Class.forName("java.net.InetAddress"); |
| paramTypes[2] = Integer.TYPE ; |
| Constructor constructor = senderClass.getConstructor(paramTypes); |
| if (constructor != null) { |
| Object paramValues[] = new Object[3]; |
| paramValues[0] = mbr.getDomain(); |
| paramValues[1] = InetAddress.getByName(mbr.getHost()); |
| paramValues[2] = new Integer(mbr.getPort()); |
| sender = (IDataSender) constructor.newInstance(paramValues); |
| } else { |
| log.error(sm.getString("IDataSender.senderModes.Instantiate", |
| senderName)); |
| } |
| } catch (Throwable t) { |
| log.error(sm.getString("IDataSender.senderModes.Instantiate", |
| senderName), t); |
| } |
| } else { |
| log.error(sm.getString("IDataSender.senderModes.Missing", mode)); |
| } |
| return sender; |
| } |
| |
| private synchronized void loadSenderModes() { |
| // Load our mapping properties if necessary |
| if (senderModes == null) { |
| try { |
| InputStream is = IDataSender.class |
| .getClassLoader() |
| .getResourceAsStream( |
| DATASENDERS_PROPERTIES); |
| if (is != null) { |
| senderModes = new Properties(); |
| senderModes.load(is); |
| } else { |
| log.error(sm.getString("IDataSender.senderModes.Resources")); |
| return; |
| } |
| } catch (IOException e) { |
| log.error(sm.getString("IDataSender.senderModes.Resources"), e); |
| return; |
| } |
| } |
| |
| } |
| |
| } |