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=4f30214e8098748469c6a4269ac2ed6c5750e4b0;hp=0000000000000000000000000000000000000000;hpb=9dabc02511e3a334a5749a504f57f69d6c9017bd;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;
+ }
+}