SLING-4839 - Allow to configure logger additivity via OSGi Config UI

git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1692840 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/java/org/apache/sling/commons/log/logback/internal/SlingLogPanel.java b/src/main/java/org/apache/sling/commons/log/logback/internal/SlingLogPanel.java
index 71fcf7e..0dfd9c6 100644
--- a/src/main/java/org/apache/sling/commons/log/logback/internal/SlingLogPanel.java
+++ b/src/main/java/org/apache/sling/commons/log/logback/internal/SlingLogPanel.java
@@ -162,9 +162,10 @@
                 String logger = req.getParameter("logger");
                 String logLevel = req.getParameter("loglevel");
                 String logFile = req.getParameter("logfile");
+                String additive = req.getParameter("logAdditive");
                 String[] loggers = req.getParameterValues("logger");
                 if (null != logger) {
-                    configureLogger(pid, logLevel, loggers, logFile);
+                    configureLogger(pid, logLevel, loggers, logFile, additive);
                 }
             }
         } catch (ConfigurationException e) {
@@ -229,6 +230,7 @@
         pw.println("<thead class='ui-widget-header'>");
         pw.println("<tr>");
         pw.println("<th>Log Level</th>");
+        pw.println("<th>Additive</th>");
         pw.println("<th>Log File</th>");
         pw.println("<th>Logger</th>");
         pw.print("<th width=\"20%\">");
@@ -250,6 +252,11 @@
             pw.print("\">");
             pw.print(getLevelStr(logConfig));
             pw.println("</span></td>");
+            pw.print("<td><span class=\"logAdditive\" data-currentAdditivity=\"");
+            pw.print(Boolean.toString(logConfig.isAdditive()));
+            pw.print("\">");
+            pw.print(Boolean.toString(logConfig.isAdditive()));
+            pw.println("</span></td>");
             pw.print("<td><span class=\"logFile\">");
             pw.print( XmlUtil.escapeXml(getPath(logConfig.getLogWriterName(), rootPath, shortenPaths)));
             pw.println("</span></td>");
@@ -287,6 +294,7 @@
         }
 
         pw.println("\"></span></td>");
+        pw.print("<td><span class=\"logAdditive\" data-currentAdditivity=\"false\"></span></td>");
         pw.print("<td><span id=\"defaultLogfile\" data-defaultlogfile=\"");
         pw.print( XmlUtil.escapeXml(getPath(configManager.getDefaultWriter().getFileName(), rootPath, shortenPaths)));
         pw.println("\" class=\"logFile\"></span></td>");
@@ -645,10 +653,11 @@
      * @param logLevel the log level to set
      * @param loggers  list of logger categories to set
      * @param logFile  log file (relative path is ok)
+     * @param additive logger additivity
      * @throws IOException            when an existing configuration couldn't be updated or a configuration couldn't be created.
      * @throws ConfigurationException when mandatory parameters where not specified
      */
-    private void configureLogger(final String pid, final String logLevel, final String[] loggers, final String logFile)
+    private void configureLogger(final String pid, final String logLevel, final String[] loggers, final String logFile, String additive)
             throws IOException, ConfigurationException {
         // try to get the configadmin service reference
         ServiceReference sr = this.bundleContext
@@ -682,6 +691,12 @@
                         dict.put(LogConfigManager.LOG_LEVEL, logLevel.toLowerCase());
                         dict.put(LogConfigManager.LOG_LOGGERS, loggers);
                         dict.put(LogConfigManager.LOG_FILE, logFile);
+
+                        if (additive == null){
+                            dict.put(LogConfigManager.LOG_ADDITIV, "false");
+                        } else {
+                            dict.put(LogConfigManager.LOG_ADDITIV, "true");
+                        }
                         config.update(dict);
                     }
                 }
diff --git a/src/main/resources/OSGI-INF/metatype/metatype.properties b/src/main/resources/OSGI-INF/metatype/metatype.properties
index 328d9d7..c4f9b71 100644
--- a/src/main/resources/OSGI-INF/metatype/metatype.properties
+++ b/src/main/resources/OSGI-INF/metatype/metatype.properties
@@ -85,6 +85,10 @@
   If set to true  and if appenders are not closed properly when your application exits, then \
   logging events not yet written to disk may be lost. See http://logback.qos.ch/manual/encoders.html#immediateFlush
 
+log.additiv.name = Additivity
+log.additiv.description = If set to false then logs from these loggers would not be sent \
+   to any appender attached higher in the hierarchy
+
 log.config.maxOldFileCountInDump.name = Max Count of files in dump
 log.config.maxOldFileCountInDump.description = Maximum number of old rolled over files for each \
   active file to be included while generating the dump as part of Status zip support
diff --git a/src/main/resources/OSGI-INF/metatype/metatype.xml b/src/main/resources/OSGI-INF/metatype/metatype.xml
index b88f3d5..a44645e 100644
--- a/src/main/resources/OSGI-INF/metatype/metatype.xml
+++ b/src/main/resources/OSGI-INF/metatype/metatype.xml
@@ -134,6 +134,10 @@
         <metatype:AD id="webconsole.configurationFactory.nameHint"
             type="String"
             default="{org.apache.sling.commons.log.file}: {org.apache.sling.commons.log.level}"/>
+        <metatype:AD id="org.apache.sling.commons.log.additiv"
+             name="%log.additiv.name"
+             description="%log.additiv.description"
+             type="Boolean" />
     </metatype:OCD>
     <metatype:Designate
         pid="org.apache.sling.commons.log.LogManager.factory.config"
diff --git a/src/main/resources/res/ui/slinglog.js b/src/main/resources/res/ui/slinglog.js
index 707994a..3eb5d55 100644
--- a/src/main/resources/res/ui/slinglog.js
+++ b/src/main/resources/res/ui/slinglog.js
@@ -19,6 +19,7 @@
  */
 function removeEditor(row) {
     $(row).find(".loggers").toggle();
+	$(row).find(".logAdditive").toggle();
 	$(row).find(".logLevels").toggle();
 	$(row).find(".logFile").toggle();
 	$(row).find(".configureLink").toggle();
@@ -73,6 +74,22 @@
 }
 
 /**
+ * Make checkbox for additive field
+ */
+function addAdditive(row) {
+	var additiveElement = $(row).find(".logAdditive");
+	var currentAdditivity = additiveElement.attr("data-currentAdditivity");
+	if(!currentAdditivity) {
+		// default additivity is false
+		currentAdditivity = "false";
+	}
+
+	var checked = currentAdditivity == "true" ? "checked" : "";
+	additiveElement.after('<input class="editElement ui-state-default" type="checkbox" name="logAdditive" value="true" '+ checked +' />')
+	additiveElement.toggle();
+}
+
+/**
  * Turns the logger elements into inputfields (with controls).
  */
 function addLoggers(row) {
@@ -119,6 +136,7 @@
 	row.addClass("currentEditor");
 	// add the editables
     addLogLevelSelect(row);
+    addAdditive(row);
 	addLoggers(row);
     addLogFile(row);
     // add controls