X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=srcjar_unused%2Forg%2Fapache%2Flog4j%2Fnet%2FJMSAppender.java;fp=srcjar_unused%2Forg%2Fapache%2Flog4j%2Fnet%2FJMSAppender.java;h=7e1e62ead5edce3bde0437997bee8cec476dc1b3;hb=8a43b8353b89a47002ef17c959ed61281fc4d826;hp=0000000000000000000000000000000000000000;hpb=55bfdb07355198ae1a1a8b5e14933b4669113ca6;p=jalview.git diff --git a/srcjar_unused/org/apache/log4j/net/JMSAppender.java b/srcjar_unused/org/apache/log4j/net/JMSAppender.java new file mode 100644 index 0000000..7e1e62e --- /dev/null +++ b/srcjar_unused/org/apache/log4j/net/JMSAppender.java @@ -0,0 +1,447 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.log4j.net; + +import org.apache.log4j.AppenderSkeleton; +import org.apache.log4j.helpers.LogLog; +import org.apache.log4j.spi.ErrorCode; +import org.apache.log4j.spi.LoggingEvent; + +import javax.jms.JMSException; +import javax.jms.ObjectMessage; +import javax.jms.Session; +import javax.jms.Topic; +import javax.jms.TopicConnection; +import javax.jms.TopicConnectionFactory; +import javax.jms.TopicPublisher; +import javax.jms.TopicSession; +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NameNotFoundException; +import javax.naming.NamingException; +import java.util.Properties; + +/** + * A simple appender that publishes events to a JMS Topic. The events + * are serialized and transmitted as JMS message type {@link + * ObjectMessage}. + + *

JMS {@link Topic topics} and {@link TopicConnectionFactory topic + * connection factories} are administered objects that are retrieved + * using JNDI messaging which in turn requires the retrieval of a JNDI + * {@link Context}. + + *

There are two common methods for retrieving a JNDI {@link + * Context}. If a file resource named jndi.properties is + * available to the JNDI API, it will use the information found + * therein to retrieve an initial JNDI context. To obtain an initial + * context, your code will simply call: + +

+   InitialContext jndiContext = new InitialContext();
+   
+ + *

Calling the no-argument InitialContext() method + * will also work from within Enterprise Java Beans (EJBs) because it + * is part of the EJB contract for application servers to provide each + * bean an environment naming context (ENC). + + *

In the second approach, several predetermined properties are set + * and these properties are passed to the InitialContext + * constructor to connect to the naming service provider. For example, + * to connect to JBoss naming service one would write: + +

+   Properties env = new Properties( );
+   env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
+   env.put(Context.PROVIDER_URL, "jnp://hostname:1099");
+   env.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
+   InitialContext jndiContext = new InitialContext(env);
+
+ + * where hostname is the host where the JBoss application + * server is running. + * + *

To connect to the the naming service of Weblogic application + * server one would write: + +

+   Properties env = new Properties( );
+   env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
+   env.put(Context.PROVIDER_URL, "t3://localhost:7001");
+   InitialContext jndiContext = new InitialContext(env);
+
+ + *

Other JMS providers will obviously require different values. + * + * The initial JNDI context can be obtained by calling the + * no-argument InitialContext() method in EJBs. Only + * clients running in a separate JVM need to be concerned about the + * jndi.properties file and calling {@link + * InitialContext#InitialContext()} or alternatively correctly + * setting the different properties before calling {@link + * InitialContext#InitialContext(java.util.Hashtable)} method. + + + @author Ceki Gülcü */ +public class JMSAppender extends AppenderSkeleton { + + String securityPrincipalName; + String securityCredentials; + String initialContextFactoryName; + String urlPkgPrefixes; + String providerURL; + String topicBindingName; + String tcfBindingName; + String userName; + String password; + boolean locationInfo; + + TopicConnection topicConnection; + TopicSession topicSession; + TopicPublisher topicPublisher; + + public + JMSAppender() { + } + + /** + The TopicConnectionFactoryBindingName option takes a + string value. Its value will be used to lookup the appropriate + TopicConnectionFactory from the JNDI context. + */ + public + void setTopicConnectionFactoryBindingName(String tcfBindingName) { + this.tcfBindingName = tcfBindingName; + } + + /** + Returns the value of the TopicConnectionFactoryBindingName option. + */ + public + String getTopicConnectionFactoryBindingName() { + return tcfBindingName; + } + + /** + The TopicBindingName option takes a + string value. Its value will be used to lookup the appropriate + Topic from the JNDI context. + */ + public + void setTopicBindingName(String topicBindingName) { + this.topicBindingName = topicBindingName; + } + + /** + Returns the value of the TopicBindingName option. + */ + public + String getTopicBindingName() { + return topicBindingName; + } + + + /** + Returns value of the LocationInfo property which + determines whether location (stack) info is sent to the remote + subscriber. */ + public + boolean getLocationInfo() { + return locationInfo; + } + + /** + * Options are activated and become effective only after calling + * this method.*/ + public void activateOptions() { + TopicConnectionFactory topicConnectionFactory; + + try { + Context jndi; + + LogLog.debug("Getting initial context."); + if(initialContextFactoryName != null) { + Properties env = new Properties( ); + env.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactoryName); + if(providerURL != null) { + env.put(Context.PROVIDER_URL, providerURL); + } else { + LogLog.warn("You have set InitialContextFactoryName option but not the " + +"ProviderURL. This is likely to cause problems."); + } + if(urlPkgPrefixes != null) { + env.put(Context.URL_PKG_PREFIXES, urlPkgPrefixes); + } + + if(securityPrincipalName != null) { + env.put(Context.SECURITY_PRINCIPAL, securityPrincipalName); + if(securityCredentials != null) { + env.put(Context.SECURITY_CREDENTIALS, securityCredentials); + } else { + LogLog.warn("You have set SecurityPrincipalName option but not the " + +"SecurityCredentials. This is likely to cause problems."); + } + } + jndi = new InitialContext(env); + } else { + jndi = new InitialContext(); + } + + LogLog.debug("Looking up ["+tcfBindingName+"]"); + topicConnectionFactory = (TopicConnectionFactory) lookup(jndi, tcfBindingName); + LogLog.debug("About to create TopicConnection."); + if(userName != null) { + topicConnection = topicConnectionFactory.createTopicConnection(userName, + password); + } else { + topicConnection = topicConnectionFactory.createTopicConnection(); + } + + LogLog.debug("Creating TopicSession, non-transactional, " + +"in AUTO_ACKNOWLEDGE mode."); + topicSession = topicConnection.createTopicSession(false, + Session.AUTO_ACKNOWLEDGE); + + LogLog.debug("Looking up topic name ["+topicBindingName+"]."); + Topic topic = (Topic) lookup(jndi, topicBindingName); + + LogLog.debug("Creating TopicPublisher."); + topicPublisher = topicSession.createPublisher(topic); + + LogLog.debug("Starting TopicConnection."); + topicConnection.start(); + + jndi.close(); + } catch(JMSException e) { + errorHandler.error("Error while activating options for appender named ["+name+ + "].", e, ErrorCode.GENERIC_FAILURE); + } catch(NamingException e) { + errorHandler.error("Error while activating options for appender named ["+name+ + "].", e, ErrorCode.GENERIC_FAILURE); + } catch(RuntimeException e) { + errorHandler.error("Error while activating options for appender named ["+name+ + "].", e, ErrorCode.GENERIC_FAILURE); + } + } + + protected Object lookup(Context ctx, String name) throws NamingException { + try { + return ctx.lookup(name); + } catch(NameNotFoundException e) { + LogLog.error("Could not find name ["+name+"]."); + throw e; + } + } + + protected boolean checkEntryConditions() { + String fail = null; + + if(this.topicConnection == null) { + fail = "No TopicConnection"; + } else if(this.topicSession == null) { + fail = "No TopicSession"; + } else if(this.topicPublisher == null) { + fail = "No TopicPublisher"; + } + + if(fail != null) { + errorHandler.error(fail +" for JMSAppender named ["+name+"]."); + return false; + } else { + return true; + } + } + + /** + Close this JMSAppender. Closing releases all resources used by the + appender. A closed appender cannot be re-opened. */ + public synchronized void close() { + // The synchronized modifier avoids concurrent append and close operations + + if(this.closed) { + return; + } + + LogLog.debug("Closing appender ["+name+"]."); + this.closed = true; + + try { + if(topicSession != null) { + topicSession.close(); + } + if(topicConnection != null) { + topicConnection.close(); + } + } catch(JMSException e) { + LogLog.error("Error while closing JMSAppender ["+name+"].", e); + } catch(RuntimeException e) { + LogLog.error("Error while closing JMSAppender ["+name+"].", e); + } + // Help garbage collection + topicPublisher = null; + topicSession = null; + topicConnection = null; + } + + /** + This method called by {@link AppenderSkeleton#doAppend} method to + do most of the real appending work. */ + public void append(LoggingEvent event) { + if(!checkEntryConditions()) { + return; + } + + try { + ObjectMessage msg = topicSession.createObjectMessage(); + if(locationInfo) { + event.getLocationInformation(); + } + msg.setObject(event); + topicPublisher.publish(msg); + } catch(JMSException e) { + errorHandler.error("Could not publish message in JMSAppender ["+name+"].", e, + ErrorCode.GENERIC_FAILURE); + } catch(RuntimeException e) { + errorHandler.error("Could not publish message in JMSAppender ["+name+"].", e, + ErrorCode.GENERIC_FAILURE); + } + } + + /** + * Returns the value of the InitialContextFactoryName option. + * See {@link #setInitialContextFactoryName} for more details on the + * meaning of this option. + * */ + public String getInitialContextFactoryName() { + return initialContextFactoryName; + } + + /** + * Setting the InitialContextFactoryName method will cause + * this JMSAppender instance to use the {@link + * InitialContext#InitialContext(Hashtable)} method instead of the + * no-argument constructor. If you set this option, you should also + * at least set the ProviderURL option. + * + * @see #setProviderURL(String) + * */ + public void setInitialContextFactoryName(String initialContextFactoryName) { + this.initialContextFactoryName = initialContextFactoryName; + } + + public String getProviderURL() { + return providerURL; + } + + public void setProviderURL(String providerURL) { + this.providerURL = providerURL; + } + + String getURLPkgPrefixes( ) { + return urlPkgPrefixes; + } + + public void setURLPkgPrefixes(String urlPkgPrefixes ) { + this.urlPkgPrefixes = urlPkgPrefixes; + } + + public String getSecurityCredentials() { + return securityCredentials; + } + + public void setSecurityCredentials(String securityCredentials) { + this.securityCredentials = securityCredentials; + } + + + public String getSecurityPrincipalName() { + return securityPrincipalName; + } + + public void setSecurityPrincipalName(String securityPrincipalName) { + this.securityPrincipalName = securityPrincipalName; + } + + public String getUserName() { + return userName; + } + + /** + * The user name to use when {@link + * TopicConnectionFactory#createTopicConnection(String, String) + * creating a topic session}. If you set this option, you should + * also set the Password option. See {@link + * #setPassword(String)}. + * */ + public void setUserName(String userName) { + this.userName = userName; + } + + public String getPassword() { + return password; + } + + /** + * The paswword to use when creating a topic session. + */ + public void setPassword(String password) { + this.password = password; + } + + + /** + If true, the information sent to the remote subscriber will + include caller's location information. By default no location + information is sent to the subscriber. */ + public void setLocationInfo(boolean locationInfo) { + this.locationInfo = locationInfo; + } + + /** + * Returns the TopicConnection used for this appender. Only valid after + * activateOptions() method has been invoked. + */ + protected TopicConnection getTopicConnection() { + return topicConnection; + } + + /** + * Returns the TopicSession used for this appender. Only valid after + * activateOptions() method has been invoked. + */ + protected TopicSession getTopicSession() { + return topicSession; + } + + /** + * Returns the TopicPublisher used for this appender. Only valid after + * activateOptions() method has been invoked. + */ + protected TopicPublisher getTopicPublisher() { + return topicPublisher; + } + + /** + * The JMSAppender sends serialized events and consequently does not + * require a layout. + */ + public boolean requiresLayout() { + return false; + } +}