Author: rwatler
Date: Tue May 12 19:05:38 2009
New Revision: 774021
URL: http://svn.apache.org/viewvc?rev=774021&view=rev
Log:
Initial import for apa-logging project
Added:
portals/applications/logging/
portals/applications/logging/trunk/
portals/applications/logging/trunk/pom.xml
portals/applications/logging/trunk/src/
portals/applications/logging/trunk/src/main/
portals/applications/logging/trunk/src/main/java/
portals/applications/logging/trunk/src/main/java/org/
portals/applications/logging/trunk/src/main/java/org/apache/
portals/applications/logging/trunk/src/main/java/org/apache/portals/
portals/applications/logging/trunk/src/main/java/org/apache/portals/applications/
portals/applications/logging/trunk/src/main/java/org/apache/portals/applications/logging/
portals/applications/logging/trunk/src/main/java/org/apache/portals/applications/logging/tomcat/
portals/applications/logging/trunk/src/main/java/org/apache/portals/applications/logging/tomcat/LoggingPropertiesServerListener.java
portals/applications/logging/trunk/src/main/java/org/apache/portals/applications/logging/tomcat/ServerXMLConfigurer.java
Added: portals/applications/logging/trunk/pom.xml
URL:
http://svn.apache.org/viewvc/portals/applications/logging/trunk/pom.xml?rev=774021&view=auto
==============================================================================
--- portals/applications/logging/trunk/pom.xml (added)
+++ portals/applications/logging/trunk/pom.xml Tue May 12 19:05:38 2009
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+
+ $Id:$
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+ <prerequisites>
+ <maven>2.0.4</maven>
+ </prerequisites>
+
+ <!-- POM Identification -->
+ <parent>
+ <groupId>org.apache.portals</groupId>
+ <artifactId>applications-pom</artifactId>
+ <version>1.0</version>
+ </parent>
+
+ <groupId>org.apache.portals.applications</groupId>
+ <artifactId>apa-logging</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <packaging>jar</packaging>
+ <name>Portals Logging</name>
+ <description>
+ Portals Logging
+ </description>
+
+ <!-- Properties -->
+
+ <properties>
+ <tomcat.catalina.version>6.0.18</tomcat.catalina.version>
+ </properties>
+
+ <!-- Dependencies -->
+
+ <dependencies>
+
+ <!-- Build Dependencies -->
+ <dependency>
+ <groupId>org.apache.tomcat</groupId>
+ <artifactId>catalina</artifactId>
+ <version>${tomcat.catalina.version}</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <!-- Runtime Dependencies -->
+
+ </dependencies>
+
+ <!-- Project Information -->
+
+ <scm>
+
<connection>scm:svn:http://svn.apache.org/repos/asf/portals/applications/logging</connection>
+
<developerConnection>scm:svn:https://svn.apache.org/repos/asf/portals/applications/logging</developerConnection>
+
<url>http://svn.apache.org/viewcvs.cgi/portals/applications/logging/</url>
+ </scm>
+
+</project>
Added:
portals/applications/logging/trunk/src/main/java/org/apache/portals/applications/logging/tomcat/LoggingPropertiesServerListener.java
URL:
http://svn.apache.org/viewvc/portals/applications/logging/trunk/src/main/java/org/apache/portals/applications/logging/tomcat/LoggingPropertiesServerListener.java?rev=774021&view=auto
==============================================================================
---
portals/applications/logging/trunk/src/main/java/org/apache/portals/applications/logging/tomcat/LoggingPropertiesServerListener.java
(added)
+++
portals/applications/logging/trunk/src/main/java/org/apache/portals/applications/logging/tomcat/LoggingPropertiesServerListener.java
Tue May 12 19:05:38 2009
@@ -0,0 +1,130 @@
+/*
+ * 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.portals.applications.logging.tomcat;
+
+import java.io.File;
+
+import org.apache.catalina.Lifecycle;
+import org.apache.catalina.LifecycleEvent;
+import org.apache.catalina.LifecycleListener;
+
+/**
+ * Tomcat Catalina server Listener implementation used to initialize
+ * logging system properties before individual web applications are
+ * initialized and started.
+ *
+ * Set the logDir attribute for the Listener tag that initializes this
+ * listener in ${CATALINA_BASE}/conf/server.xml or define the
+ * org.apache.portals.logdir system property using CATALINA_OPTS on startup:
+ *
+ * > export CATALINA_OPTS=-Dorg.apache.portals.logdir=/var/log/portal
+ *
+ * @author <a href="mailto:[email protected]">Randy Watler</a>
+ * @version $Id:$
+ */
+public class LoggingPropertiesServerListener implements LifecycleListener
+{
+ public static final String CATALINA_BASE_PROPERTY_NAME = "catalina.base";
+ public static final String CATALINA_HOME_PROPERTY_NAME = "catalina.home";
+ public static final String CATALINA_LOGS_DIRECTORY_NAME = "logs";
+
+ public static final String LOG_DIR_PROPERTY_NAME =
"org.apache.portals.logdir";
+
+ private String logDir;
+
+ /* (non-Javadoc)
+ * @see
org.apache.catalina.LifecycleListener#lifecycleEvent(org.apache.catalina.LifecycleEvent)
+ */
+ public void lifecycleEvent(LifecycleEvent event)
+ {
+ if (Lifecycle.BEFORE_START_EVENT.equals(event.getType()))
+ {
+ // check for overridden logging directory from server environment
+ String logDirOverride = System.getProperty(LOG_DIR_PROPERTY_NAME);
+ if (logDirOverride == null)
+ {
+ // compute default logging directory if required
+ if (logDir == null)
+ {
+ // locate tomcat catalina base/home
+ String catalinaBase =
System.getProperty(CATALINA_BASE_PROPERTY_NAME);
+ if (catalinaBase == null)
+ {
+ catalinaBase =
System.getProperty(CATALINA_HOME_PROPERTY_NAME);
+ }
+ if (catalinaBase != null)
+ {
+ File catalinaLogsDirectoryFile = new
File(catalinaBase+File.separator+CATALINA_LOGS_DIRECTORY_NAME);
+ if (catalinaLogsDirectoryFile.isDirectory())
+ {
+ logDir =
catalinaLogsDirectoryFile.getAbsolutePath();
+ }
+ }
+ }
+ // set logging directory property if available
+ if (logDir != null)
+ {
+ // validate logging directory; create if necessary
+ File logDirFile = new File(logDir);
+ if (!logDirFile.isDirectory() && !logDirFile.exists())
+ {
+ logDirFile.mkdirs();
+ }
+ // set system property if logging directory exists
+ if (logDirFile.isDirectory())
+ {
+ System.out.println("Setting "+LOG_DIR_PROPERTY_NAME+"
= "+logDir);
+ System.setProperty(LOG_DIR_PROPERTY_NAME, logDir);
+ }
+ else
+ {
+ System.err.println("Unable to set
"+LOG_DIR_PROPERTY_NAME+": logDir attribute "+logDir+" does not exist and
cannot be created or is not a directory.");
+ }
+ }
+ else
+ {
+ System.err.println("Unable to set
"+LOG_DIR_PROPERTY_NAME+": logDir attribute not set and
"+CATALINA_BASE_PROPERTY_NAME+" or "+CATALINA_HOME_PROPERTY_NAME+" system
properties not available or "+CATALINA_LOGS_DIRECTORY_NAME+" directory
missing.");
+ }
+ }
+ else
+ {
+ logDir = logDirOverride;
+ System.out.println("Overridden "+LOG_DIR_PROPERTY_NAME+" =
"+logDir);
+ }
+ }
+ }
+
+ /**
+ * Get logging directory attribute.
+ *
+ * @return logging directory
+ */
+ public String getLogDir()
+ {
+ return logDir;
+ }
+
+ /**
+ * Set logging directory attribute.
+ *
+ * @param logDir logging directory
+ */
+ public void setLogDir(String logDir)
+ {
+ this.logDir = logDir;
+ }
+}
Added:
portals/applications/logging/trunk/src/main/java/org/apache/portals/applications/logging/tomcat/ServerXMLConfigurer.java
URL:
http://svn.apache.org/viewvc/portals/applications/logging/trunk/src/main/java/org/apache/portals/applications/logging/tomcat/ServerXMLConfigurer.java?rev=774021&view=auto
==============================================================================
---
portals/applications/logging/trunk/src/main/java/org/apache/portals/applications/logging/tomcat/ServerXMLConfigurer.java
(added)
+++
portals/applications/logging/trunk/src/main/java/org/apache/portals/applications/logging/tomcat/ServerXMLConfigurer.java
Tue May 12 19:05:38 2009
@@ -0,0 +1,357 @@
+/*
+ * 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.portals.applications.logging.tomcat;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.PrintWriter;
+
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.parsers.SAXParser;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * Tomcat Catalina server utility used to configure the server
+ * for the LoggingPropertiesServerListener server Listener.
+ *
+ * See Jetspeed 2 Deploy Maven Plugin for sample invocation: plugin
+ * expects a default constructor for editor class and the editing
+ * instance method to conform to the following signature:
+ *
+ * public void editMethodName(java.io.File file) throws Exception
+ *
+ * @author <a href="mailto:[email protected]">Randy Watler</a>
+ * @version $Id:$
+ */
+public class ServerXMLConfigurer
+{
+ private enum EditType {BEFORE, AFTER, WITHIN_FIRST, WITHIN_LAST};
+ private enum InsertType {BEFORE, AFTER, BETWEEN, ERROR};
+
+ private static final String EDIT_TARGET_TAG_QNAME = "Engine";
+ private static final EditType EDIT_TARGET_TYPE = EditType.WITHIN_LAST;
+ private static final String LISTENER_TAG_QNAME = "Listener";
+ private static final String LISTENER_TAG_CLASSNAME_ATTRIBUTE_NAME =
"className";
+ private static final String LISTENER_TAG_CLASSNAME =
"org.apache.portals.applications.logging.tomcat.LoggingPropertiesServerListener";
+
+ /**
+ * SAX parser handler for the server.xml configuration file.
+ */
+ private static class ServerXMLHandler extends DefaultHandler
+ {
+ private Locator locator;
+ private int indentLine = -1;
+ private String indent = "";
+ private String firstIndent = "";
+ private int firstCommentLine = -1;
+ private String firstCommentIndent = "";
+ private int commentLine = -1;
+ private String commentIndent = "";
+ private int tagLine = -1;
+ private int tagColumn = -1;
+ private String tagIndent = "";
+ private int previousTagLine = 0;
+ private String previousTagIndent = "";
+ private boolean tagFound;
+ private boolean endTagFound;
+ private int editLine = -1;
+ private InsertType editInsert = InsertType.ERROR;
+ private String editIndent = "";
+ private boolean listenerFound;
+
+ /* (non-Javadoc)
+ * @see
org.xml.sax.helpers.DefaultHandler#setDocumentLocator(org.xml.sax.Locator)
+ */
+ public void setDocumentLocator(Locator locator)
+ {
+ this.locator = locator;
+ }
+
+ /* (non-Javadoc)
+ * @see
org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String,
java.lang.String, java.lang.String, org.xml.sax.Attributes)
+ */
+ public void startElement(String uri, String localName, String qName,
Attributes attributes)
+ {
+ // locate insertion point relative to target tag
+ updateTagInfo();
+ if (qName.equals(EDIT_TARGET_TAG_QNAME))
+ {
+ tagFound = true;
+ if ((editLine == -1) && (EDIT_TARGET_TYPE == EditType.BEFORE))
+ {
+ editLine = (((commentLine != -1) && (commentLine <
tagLine) && tagIndent.equals(commentIndent)) ? commentLine : tagLine);
+ editInsert = InsertType.BEFORE;
+ editIndent = tagIndent;
+ }
+ }
+ else
+ {
+ if ((editLine == -1) && ((tagFound && (EDIT_TARGET_TYPE ==
EditType.WITHIN_FIRST)) ||
+ (endTagFound && (EDIT_TARGET_TYPE ==
EditType.AFTER))))
+ {
+ editLine = (((firstCommentLine != -1) && (firstCommentLine
< tagLine) && tagIndent.equals(firstCommentIndent)) ? firstCommentLine :
tagLine);
+ editInsert = InsertType.BEFORE;
+ editIndent = tagIndent;
+ }
+ tagFound = false;
+ }
+ endTagFound = false;
+ resetCommentInfo();
+
+ // find existing listener tag
+ if (qName.equals(LISTENER_TAG_QNAME))
+ {
+ String className =
attributes.getValue(LISTENER_TAG_CLASSNAME_ATTRIBUTE_NAME);
+ if ((className != null) &&
className.equals(LISTENER_TAG_CLASSNAME))
+ {
+ listenerFound = true;
+ }
+ }
+
+ // record first incremental indent
+ if ((firstIndent.length() == 0) && (tagIndent.length() > 0))
+ {
+ firstIndent = tagIndent;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see
org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String,
java.lang.String, java.lang.String)
+ */
+ public void endElement(String uri, String localName, String qName)
+ {
+ // locate insertion point relative to target tag
+ if ((tagLine != locator.getLineNumber()) || (tagColumn !=
locator.getColumnNumber()))
+ {
+ updateTagInfo();
+ }
+ if (qName.equals(EDIT_TARGET_TAG_QNAME))
+ {
+ if ((editLine == -1) && tagFound && (EDIT_TARGET_TYPE ==
EditType.WITHIN_FIRST))
+ {
+ editLine = tagLine;
+ editInsert = InsertType.BETWEEN;
+ editIndent = tagIndent+firstIndent;
+ }
+ endTagFound = true;
+ if ((editLine == -1) && (EDIT_TARGET_TYPE ==
EditType.WITHIN_LAST))
+ {
+ editLine = previousTagLine;
+ editInsert = InsertType.AFTER;
+ editIndent = previousTagIndent;
+ }
+ }
+ else
+ {
+ if ((editLine == -1) && endTagFound && (EDIT_TARGET_TYPE ==
EditType.AFTER))
+ {
+ editLine = previousTagLine;
+ editInsert = InsertType.AFTER;
+ editIndent = previousTagIndent;
+ }
+ endTagFound = false;
+ }
+ tagFound = false;
+ resetCommentInfo();
+ }
+
+ /* (non-Javadoc)
+ * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
+ */
+ public void characters(char[] chars, int start, int length)
+ {
+ // track comment and tag indentation
+ if (firstCommentLine == -1)
+ {
+ firstCommentLine = indentLine;
+ firstCommentIndent = indent;
+ }
+ commentLine = indentLine;
+ commentIndent = indent;
+ indentLine = locator.getLineNumber();
+ int indentChars = 0;
+ for (int i = start+length-1; (i >= start); i--)
+ {
+ if ((chars[i] == ' ') || (chars[i] == '\t'))
+ {
+ indentChars++;
+ }
+ else
+ {
+ break;
+ }
+ }
+ indent = new String(chars, start+length-indentChars, indentChars);
+ }
+
+ /**
+ * Save potential tag insertion point and indentation.
+ */
+ private void updateTagInfo()
+ {
+ previousTagLine = tagLine;
+ previousTagIndent = tagIndent;
+ tagLine = locator.getLineNumber();
+ tagColumn = locator.getColumnNumber();
+ tagIndent = indent;
+ }
+
+ /**
+ * Save comment indentation.
+ */
+ private void resetCommentInfo()
+ {
+ firstCommentLine = -1;
+ commentLine = -1;
+ indentLine = -1;
+ }
+
+ /**
+ * Get parsed tag insertion line.
+ *
+ * @return tag insertion line or -1 if none found.
+ */
+ private int getEditLine()
+ {
+ return editLine;
+ }
+
+ /**
+ * Get insertion edit type.
+ *
+ * @return insert type
+ */
+ private InsertType getEditInsert()
+ {
+ return editInsert;
+ }
+
+ /**
+ * Get parsed tag indentation.
+ *
+ * @return tag indentation.
+ */
+ private String getEditIndent()
+ {
+ return editIndent;
+ }
+
+ /**
+ * Get flag indicating whether existing listener tag found.
+ *
+ * @return found flag
+ */
+ private boolean isListenerFound()
+ {
+ return listenerFound;
+ }
+ }
+
+ /**
+ * Validate and configure Tomcat Catalina server for the
+ * LoggingPropertiesServerListener server Listener.
+ *
+ * @param serverXMLFile server.xml configuration file
+ * @throws Exception if exception thrown while parsing or configuring
server.xml
+ */
+ public void verifyAndConfigureServerXML(File serverXMLFile) throws
Exception
+ {
+ // parse server.xml configuration file, return if previously configured
+ SAXParserFactory factory = SAXParserFactory.newInstance();
+ SAXParser parser = factory.newSAXParser();
+ ServerXMLHandler serverXMLHandler = new ServerXMLHandler();
+ parser.parse(new FileInputStream(serverXMLFile), serverXMLHandler);
+ if (serverXMLHandler.isListenerFound())
+ {
+ return;
+ }
+ if (serverXMLHandler.getEditInsert() == InsertType.ERROR)
+ {
+ throw new RuntimeException("Unable to parse or find insertion edit
in "+serverXMLFile);
+ }
+
+ // copy original server.xml file by line, inserting new tag
+ // at before or after edit line with computed indent
+ BufferedReader serverXMLReader = new BufferedReader(new
FileReader(serverXMLFile));
+ File editServerXMLFile = new
File(serverXMLFile.getAbsolutePath()+".new");
+ PrintWriter serverXMLWriter = new PrintWriter(new
FileWriter(editServerXMLFile));
+ int lineNumber = 1;
+ String line = serverXMLReader.readLine();
+ while (line != null)
+ {
+ if (lineNumber == serverXMLHandler.getEditLine())
+ {
+ String listenerTagComment = "<!-- deployed Apache Portals
Jetspeed/APA listener to initialize logging directory system property -->";
+ String listenerTag = "<"+LISTENER_TAG_QNAME+"
"+LISTENER_TAG_CLASSNAME_ATTRIBUTE_NAME+"=\""+LISTENER_TAG_CLASSNAME+"\"/>";
+ String indent = serverXMLHandler.getEditIndent();
+ switch (serverXMLHandler.getEditInsert())
+ {
+ case BEFORE:
+ serverXMLWriter.println(indent+listenerTagComment);
+ serverXMLWriter.println(indent+listenerTag);
+ serverXMLWriter.println(indent);
+ serverXMLWriter.println(line);
+ break;
+ case BETWEEN:
+ serverXMLWriter.println(indent+listenerTagComment);
+ serverXMLWriter.println(indent+listenerTag);
+ serverXMLWriter.println(line);
+ break;
+ case AFTER:
+ serverXMLWriter.println(line);
+ serverXMLWriter.println(indent);
+ serverXMLWriter.println(indent+listenerTagComment);
+ serverXMLWriter.println(indent+listenerTag);
+ break;
+ case ERROR:
+ default :
+ serverXMLWriter.println(line);
+ break;
+ }
+ }
+ else
+ {
+ serverXMLWriter.println(line);
+ }
+ lineNumber++;
+ line = serverXMLReader.readLine();
+ }
+ serverXMLReader.close();
+ serverXMLWriter.flush();
+ serverXMLWriter.close();
+
+ // move new file to original file location
+ if (!editServerXMLFile.exists())
+ {
+ throw new RuntimeException("Configured file does not exist:
"+editServerXMLFile);
+ }
+ if (!serverXMLFile.delete())
+ {
+ throw new RuntimeException("Cannot remove file: "+serverXMLFile);
+ }
+ if (!editServerXMLFile.renameTo(serverXMLFile))
+ {
+ throw new RuntimeException("Cannot move file "+editServerXMLFile+"
to: "+serverXMLFile);
+ }
+ }
+}