/*
 * Copyright 2011 Avid Technology, Inc.
 *
 * 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.ops4j.pax.logging.logback.appender;

import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.UnsynchronizedAppenderBase;
import org.ops4j.pax.logging.logback.internal.PaxAppenderProxy;
import org.ops4j.pax.logging.logback.internal.PaxLoggingEventForLogback;
import org.osgi.framework.BundleContext;

/**
 * <p>
 * This is a Logback appender that forwards log messages to any services registered with OSGi with the interface
 * org.ops4j.pax.logging.spi.PaxAppender. That list of appender services is possibly filtered by the paxname setting.
 * </p>
 * <p>
 * For example, you can use it like this in your logback.xml file:
 * <pre>
 *   &lt;appender name="OSGI" class="org.ops4j.pax.logging.logback.appender.PaxAppenderDelegate"&gt;
 *       &lt;paxname&gt;*&lt;/paxname&gt;
 *   &lt;/appender&gt;
 * </pre>
 * The paxname argument is a filter for the bundle property "org.ops4j.pax.logging.appender.name". In this example,
 * the "*" means to accept all delegatees.
 * </p>
 * <p>
 * This class is inspired by PaxLoggingConfigurator.parseAppender(), PaxAppenderProxy and AppenderBridgeImpl in the
 * log4j implementation.
 * </p>
 * 
 * @author Chris Dolan
 * @since 6/14/11 9:32 AM
 */
public class PaxAppenderDelegate extends UnsynchronizedAppenderBase<ILoggingEvent> {
    private final Object lifeCycleLock = new Object();
    private PaxAppenderProxy proxy;
    private String paxname = "*";

    /**
     * Allows filtering on OSGi services on the bundle property "org.ops4j.pax.logging.appender.name"
     * @param paxname defaults to "*", can be any string that works as a value in {@link org.osgi.framework.Filter}.
     */
    public void setPaxname(String paxname) {
        if (null == paxname)
            throw new IllegalArgumentException("paxname cannot be null");
        this.paxname = paxname;
    }

    @Override
    public void start() {
        synchronized (lifeCycleLock) {
            if (isStarted())
                return;
            BundleContext bundleContext = (BundleContext) getContext().getObject("org.ops4j.pax.logging.logback.bundlecontext");
            if (bundleContext == null)
                throw new IllegalArgumentException("missing BundleContext, expected in org.ops4j.pax.logging.logback.bundlecontext");
            super.start();
            proxy = new PaxAppenderProxy(bundleContext, paxname);
        }
    }

    @Override
    public void stop() {
        synchronized (lifeCycleLock) {
            if (!isStarted())
                return;
            if (proxy != null) {
                proxy.close();
                proxy = null;
            }
            super.stop();
        }
    }

    @Override
    protected void append(ILoggingEvent event) {
        PaxAppenderProxy p = proxy;
        if (p != null) {
            p.doAppend(new PaxLoggingEventForLogback(event));
        }
    }
}

@@ -937,23 +937,98 @@
 k.Bundle
-Context
+;%0Aimport org.osgi.framework.BundleContext;%0Aimport org.osgi.framework.FrameworkUtil
 ;%0A%0A/**%0A 
@@ -2843,17 +2843,256 @@
 == null)
+ %7B
 %0A
+                Bundle bundle = FrameworkUtil.getBundle(getClass());%0A                if (bundle != null) %7B%0A                    bundleContext = bundle.getBundleContext();%0A                %7D%0A                if (bundleContext == null) %7B%0A    
         
@@ -3209,32 +3209,65 @@
 undlecontext%22);%0A
+                %7D%0A            %7D%0A%0A
             supe

Support automatic lookup of containing bundlecontext when running in static/legacy mode