diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index fd677f9d3d..a62e448365 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -5,10 +5,12 @@ on: branches: [ "master" ] paths: - 'scr/**' + - 'log/**' pull_request: branches: [ "master" ] paths: - 'scr/**' + - 'log/**' permissions: {} @@ -26,9 +28,11 @@ jobs: - name: Set up Maven uses: stCarolas/setup-maven@d6af6abeda15e98926a57b5aa970a96bb37f97d1 # v5 with: - maven-version: 3.9.7 + maven-version: 3.9.9 - name: Felix SCR run: mvn -B -V -Dstyle.color=always --file scr/pom.xml clean verify + - name: Felix Log + run: mvn -B -V -Dstyle.color=always --file log/pom.xml clean verify - name: Upload Test Results if: always() uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 diff --git a/eventadmin/bridge.configuration/pom.xml b/eventadmin/bridge.configuration/pom.xml index 094213ee4f..6ae2346009 100644 --- a/eventadmin/bridge.configuration/pom.xml +++ b/eventadmin/bridge.configuration/pom.xml @@ -20,7 +20,7 @@ org.apache.felix felix-parent - 4 + 9 ../../pom/pom.xml 4.0.0 @@ -39,14 +39,14 @@ - 6 + 7 org.osgi - org.osgi.core - 5.0.0 + osgi.core + 7.0.0 provided @@ -68,7 +68,7 @@ org.apache.felix maven-bundle-plugin - 3.2.0 + 6.0.0 true diff --git a/eventadmin/bridge.upnp/pom.xml b/eventadmin/bridge.upnp/pom.xml index 5f3f8d8542..7ec4e343f0 100644 --- a/eventadmin/bridge.upnp/pom.xml +++ b/eventadmin/bridge.upnp/pom.xml @@ -19,8 +19,8 @@ org.apache.felix - felix - 1.0.4 + felix-parent + 9 ../../pom/pom.xml 4.0.0 diff --git a/eventadmin/bridge.useradmin/pom.xml b/eventadmin/bridge.useradmin/pom.xml index 6d2446fb45..1ba1cd0c61 100644 --- a/eventadmin/bridge.useradmin/pom.xml +++ b/eventadmin/bridge.useradmin/pom.xml @@ -19,8 +19,8 @@ org.apache.felix - felix - 1.0.4 + felix-parent + 9 ../../pom/pom.xml 4.0.0 diff --git a/eventadmin/bridge.wireadmin/pom.xml b/eventadmin/bridge.wireadmin/pom.xml index 9e43b04015..f5677a5cf5 100644 --- a/eventadmin/bridge.wireadmin/pom.xml +++ b/eventadmin/bridge.wireadmin/pom.xml @@ -19,8 +19,8 @@ org.apache.felix - felix - 1.0.4 + felix-parent + 9 ../../pom/pom.xml 4.0.0 diff --git a/eventadmin/impl/pom.xml b/eventadmin/impl/pom.xml index d90614cf80..e4be41c859 100644 --- a/eventadmin/impl/pom.xml +++ b/eventadmin/impl/pom.xml @@ -20,7 +20,7 @@ org.apache.felix felix-parent - 7 + 9 ../../pom/pom.xml 4.0.0 @@ -53,7 +53,7 @@ org.osgi osgi.core - 6.0.0 + 7.0.0 provided @@ -71,7 +71,7 @@ org.osgi org.osgi.service.log - 1.3.0 + 1.4.0 provided @@ -96,38 +96,38 @@ org.slf4j slf4j-simple - 1.7.5 + 1.7.36 test org.ops4j.pax.exam pax-exam-container-forked - 4.13.1 + 4.13.4 test org.ops4j.pax.exam pax-exam-junit4 - 4.13.1 + 4.13.4 test org.ops4j.pax.exam pax-exam-link-mvn - 4.13.1 + 4.13.4 test org.ops4j.pax.url pax-url-aether - 2.6.2 + 2.6.14 test org.ops4j.pax.url pax-url-wrap - 2.6.2 + 2.6.14 test @@ -139,7 +139,7 @@ org.apache.felix org.apache.felix.framework - 6.0.3 + 7.0.5 test @@ -153,7 +153,7 @@ org.apache.felix maven-bundle-plugin - 4.2.1 + 6.0.0 true @@ -180,10 +180,10 @@ --> org.osgi.service.metatype;version="[1.1,2)";resolution:=optional, - - org.osgi.service.log;version="[1.3,2)";resolution:=optional, + + org.osgi.service.log;version="[1.3,2)";resolution:=optional, * diff --git a/eventadmin/impl/src/main/java/org/apache/felix/eventadmin/impl/Configuration.java b/eventadmin/impl/src/main/java/org/apache/felix/eventadmin/impl/Configuration.java index 25b21fc275..aa31dd3d93 100644 --- a/eventadmin/impl/src/main/java/org/apache/felix/eventadmin/impl/Configuration.java +++ b/eventadmin/impl/src/main/java/org/apache/felix/eventadmin/impl/Configuration.java @@ -25,11 +25,6 @@ import java.util.Hashtable; import java.util.StringTokenizer; -import org.apache.felix.eventadmin.impl.adapter.AbstractAdapter; -import org.apache.felix.eventadmin.impl.adapter.BundleEventAdapter; -import org.apache.felix.eventadmin.impl.adapter.FrameworkEventAdapter; -import org.apache.felix.eventadmin.impl.adapter.LogEventAdapter; -import org.apache.felix.eventadmin.impl.adapter.ServiceEventAdapter; import org.apache.felix.eventadmin.impl.handler.EventAdminImpl; import org.apache.felix.eventadmin.impl.security.SecureEventAdminFactory; import org.apache.felix.eventadmin.impl.tasks.DefaultThreadPool; @@ -172,9 +167,6 @@ public class Configuration // The registration of the mbean private volatile ServiceRegistration m_mbeanreg; - // all adapters - private AbstractAdapter[] m_adapters; - private ServiceRegistration m_managedServiceReg; // the access control context @@ -431,9 +423,6 @@ private void startOrUpdate() m_requireTopic, m_ignoreTopics); - // Finally, adapt the outside events to our kind of events as per spec - adaptEvents(m_admin); - // register the admin wrapped in a service factory (SecureEventAdminFactory) // that hands-out the m_admin object wrapped in a decorator that checks // appropriated permissions of each calling bundle @@ -463,14 +452,6 @@ public void destroy() { synchronized ( this ) { - if ( m_adapters != null ) - { - for(int i=0;iFelix Project Team - */ -public abstract class AbstractAdapter -{ - private volatile EventAdmin m_admin; - - /** - * The constructor of the adapter. - * - * @param admin The {@code EventAdmin} to use for posting events. - */ - public AbstractAdapter(final EventAdmin admin) - { - if (null == admin) - { - throw new NullPointerException("EventAdmin must not be null"); - } - - m_admin = admin; - } - - protected EventAdmin getEventAdmin() - { - return m_admin; - } - - public abstract void destroy(final BundleContext bundleContext); -} diff --git a/eventadmin/impl/src/main/java/org/apache/felix/eventadmin/impl/adapter/BundleEventAdapter.java b/eventadmin/impl/src/main/java/org/apache/felix/eventadmin/impl/adapter/BundleEventAdapter.java deleted file mode 100644 index 0a5f380b0c..0000000000 --- a/eventadmin/impl/src/main/java/org/apache/felix/eventadmin/impl/adapter/BundleEventAdapter.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * 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.felix.eventadmin.impl.adapter; - -import java.util.Dictionary; -import java.util.Hashtable; - -import org.osgi.framework.BundleContext; -import org.osgi.framework.BundleEvent; -import org.osgi.framework.BundleListener; -import org.osgi.service.event.Event; -import org.osgi.service.event.EventAdmin; -import org.osgi.service.event.EventConstants; - -/** - * This class registers itself as a listener for bundle events and posts them via - * the EventAdmin as specified in 113.6.4 OSGi R4 compendium. - * - * @author Felix Project Team - */ -public class BundleEventAdapter extends AbstractAdapter implements BundleListener -{ - /** - * The constructor of the adapter. This will register the adapter with the given - * context as a {@code BundleListener} and subsequently, will post received - * events via the given EventAdmin. - * - * @param context The bundle context with which to register as a listener. - * @param admin The {@code EventAdmin} to use for posting events. - */ - public BundleEventAdapter(final BundleContext context, final EventAdmin admin) - { - super(admin); - context.addBundleListener(this); - } - - @Override - public void destroy(BundleContext context) { - context.removeBundleListener(this); - } - - /** - * Once a bundle event is received this method assembles and posts an event via - * the {@code EventAdmin} as specified in 113.6.4 OSGi R4 compendium. - * - * @param event The event to adapt. - */ - @Override - public void bundleChanged(final BundleEvent event) - { - final Dictionary properties = new Hashtable(); - - properties.put(EventConstants.EVENT, event); - - properties.put("bundle.id", event.getBundle().getBundleId()); - - final String symbolicName = event.getBundle().getSymbolicName(); - - if (null != symbolicName) - { - properties.put(EventConstants.BUNDLE_SYMBOLICNAME, - symbolicName); - } - - properties.put("bundle", event.getBundle()); - - final StringBuilder topic = new StringBuilder(BundleEvent.class - .getName().replace('.', '/')).append('/'); - - switch (event.getType()) - { - case BundleEvent.INSTALLED: - topic.append("INSTALLED"); - break; - case BundleEvent.STARTED: - topic.append("STARTED"); - break; - case BundleEvent.STOPPED: - topic.append("STOPPED"); - break; - case BundleEvent.UPDATED: - topic.append("UPDATED"); - break; - case BundleEvent.UNINSTALLED: - topic.append("UNINSTALLED"); - break; - case BundleEvent.RESOLVED: - topic.append("RESOLVED"); - break; - case BundleEvent.UNRESOLVED: - topic.append("UNRESOLVED"); - break; - default: - return; // IGNORE EVENT - } - - try { - getEventAdmin().postEvent(new Event(topic.toString(), properties)); - } catch (IllegalStateException e) { - // This is o.k. - indicates that we are stopped. - } - } -} diff --git a/eventadmin/impl/src/main/java/org/apache/felix/eventadmin/impl/adapter/FrameworkEventAdapter.java b/eventadmin/impl/src/main/java/org/apache/felix/eventadmin/impl/adapter/FrameworkEventAdapter.java deleted file mode 100644 index 5edfe0cf68..0000000000 --- a/eventadmin/impl/src/main/java/org/apache/felix/eventadmin/impl/adapter/FrameworkEventAdapter.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * 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.felix.eventadmin.impl.adapter; - -import java.util.Dictionary; -import java.util.Hashtable; - -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; -import org.osgi.framework.FrameworkEvent; -import org.osgi.framework.FrameworkListener; -import org.osgi.service.event.Event; -import org.osgi.service.event.EventAdmin; -import org.osgi.service.event.EventConstants; - -/** - * This class registers itself as a listener for framework events and posts them via - * the EventAdmin as specified in 113.6.3 OSGi R4 compendium. - * - * @author Felix Project Team - */ -public class FrameworkEventAdapter extends AbstractAdapter implements FrameworkListener -{ - /** - * The constructor of the adapter. This will register the adapter with the - * given context as a {@code FrameworkListener} and subsequently, will - * post received events via the given EventAdmin. - * - * @param context The bundle context with which to register as a listener. - * @param admin The {@code EventAdmin} to use for posting events. - */ - public FrameworkEventAdapter(final BundleContext context, final EventAdmin admin) - { - super(admin); - - context.addFrameworkListener(this); - } - - @Override - public void destroy(BundleContext context) { - context.removeFrameworkListener(this); - } - - /** - * Once a framework event is received this method assembles and posts an event - * via the {@code EventAdmin} as specified in 113.6.3 OSGi R4 compendium. - * - * @param event The event to adapt. - */ - @Override - public void frameworkEvent(final FrameworkEvent event) - { - final Dictionary properties = new Hashtable<>(); - - properties.put(EventConstants.EVENT, event); - - final Bundle bundle = event.getBundle(); - - if (null != bundle) - { - properties.put("bundle.id", bundle.getBundleId()); - - final String symbolicName = bundle.getSymbolicName(); - - if (null != symbolicName) - { - properties.put(EventConstants.BUNDLE_SYMBOLICNAME, - symbolicName); - } - - properties.put("bundle", bundle); - } - - final Throwable thrown = event.getThrowable(); - - if (null != thrown) - { - properties.put(EventConstants.EXCEPTION_CLASS, - thrown.getClass().getName()); - - final String message = thrown.getMessage(); - - if (null != message) - { - properties.put(EventConstants.EXCEPTION_MESSAGE, - message); - } - - properties.put(EventConstants.EXCEPTION, thrown); - } - - final StringBuilder topic = new StringBuilder( - FrameworkEvent.class.getName().replace('.', '/')) - .append('/'); - - switch (event.getType()) - { - case FrameworkEvent.STARTED: - topic.append("STARTED"); - break; - case FrameworkEvent.ERROR: - topic.append("ERROR"); - break; - case FrameworkEvent.PACKAGES_REFRESHED: - topic.append("PACKAGES_REFRESHED"); - break; - case FrameworkEvent.STARTLEVEL_CHANGED: - topic.append("STARTLEVEL_CHANGED"); - break; - case FrameworkEvent.WARNING: - topic.append("WARNING"); - break; - case FrameworkEvent.INFO: - topic.append("INFO"); - break; - default: - return; // IGNORE EVENT - } - - try { - getEventAdmin().postEvent(new Event(topic.toString(), properties)); - } catch(IllegalStateException e) { - // This is o.k. - indicates that we are stopped. - } - } -} diff --git a/eventadmin/impl/src/main/java/org/apache/felix/eventadmin/impl/adapter/LogEventAdapter.java b/eventadmin/impl/src/main/java/org/apache/felix/eventadmin/impl/adapter/LogEventAdapter.java deleted file mode 100644 index 8a11a937ee..0000000000 --- a/eventadmin/impl/src/main/java/org/apache/felix/eventadmin/impl/adapter/LogEventAdapter.java +++ /dev/null @@ -1,254 +0,0 @@ -/* - * 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.felix.eventadmin.impl.adapter; - -import java.util.Dictionary; -import java.util.Hashtable; - -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; -import org.osgi.framework.Constants; -import org.osgi.framework.InvalidSyntaxException; -import org.osgi.framework.ServiceEvent; -import org.osgi.framework.ServiceListener; -import org.osgi.framework.ServiceReference; -import org.osgi.service.event.Event; -import org.osgi.service.event.EventAdmin; -import org.osgi.service.event.EventConstants; - -/** - * This class registers itself as a listener for {@code LogReaderService} services - * with the framework and subsequently, a {@code LogListener} callback with any - * currently available {@code LogReaderService}. Any received log event is then - * posted via the EventAdmin as specified in 113.6.6 OSGi R4 compendium. - * Note that this class does not create a hard dependency on the org.osgi.service.log - * packages. The adaption only takes place if it is present or once it becomes - * available hence, combined with a DynamicImport-Package no hard dependency is - * needed. - * - * @author Felix Project Team - */ -public class LogEventAdapter extends AbstractAdapter implements ServiceListener -{ - // The internal lock for this object used instead synchronized(this) - private final Object m_lock = new Object(); - - private BundleContext m_context; - - // A singleton instance of the used log listener that is the adapter - private Object m_logListener; - - /** - * The constructor of the adapter. This will register the adapter with the - * given context as a listener for {@code LogReaderService} services and - * subsequently, a {@code LogListener} callback with any currently available - * {@code LogReaderService}. Any received log event is then posted via the given - * EventAdmin. - * - * @param context The bundle context with which to register as a listener. - * @param admin The {@code EventAdmin} to use for posting events. - */ - public LogEventAdapter(final BundleContext context, final EventAdmin admin) - { - super(admin); - m_context = context; - - try - { - m_context.addServiceListener(this, "(" + Constants.OBJECTCLASS - + "=org.osgi.service.log.LogReaderService)"); - - final ServiceReference[] refs; - - refs = m_context.getServiceReferences( - "org.osgi.service.log.LogReaderService", null); - - if (null != refs) - { - for (int i = 0; i < refs.length; i++) - { - final org.osgi.service.log.LogReaderService logReader = - (org.osgi.service.log.LogReaderService) m_context - .getService(refs[i]); - - if (null != logReader) - { - logReader.addLogListener((org.osgi.service.log.LogListener) - getLogListener()); - } - } - } - } catch (InvalidSyntaxException e) - { - // This never happens - } - } - - @Override - public void destroy(BundleContext context) { - context.removeServiceListener(this); - } - - /** - * Once a {@code LogReaderService} register event is received this method - * registers a {@code LogListener} with the received service that assembles - * and posts any log event via the {@code EventAdmin} as specified in - * 113.6.6 OSGi R4 compendium. - * - * @param event The event to adapt. - */ - @Override - public void serviceChanged(final ServiceEvent event) - { - if (ServiceEvent.REGISTERED == event.getType()) - { - final org.osgi.service.log.LogReaderService logReader = - (org.osgi.service.log.LogReaderService) m_context - .getService(event.getServiceReference()); - - if (null != logReader) - { - logReader.addLogListener((org.osgi.service.log.LogListener) - getLogListener()); - } - } - } - - /* - * Constructs a LogListener that assembles and posts any log event via the - * EventAdmin as specified in 113.6.6 OSGi R4 compendium. Note that great - * care is taken to not create a hard dependency on the org.osgi.service.log - * package. - */ - private Object getLogListener() - { - synchronized (m_lock) - { - if (null != m_logListener) - { - return m_logListener; - } - - m_logListener = new org.osgi.service.log.LogListener() - { - @Override - public void logged(final org.osgi.service.log.LogEntry entry) - { - // This is where the assembly as specified in 133.6.6 OSGi R4 - // compendium is taking place (i.e., the log entry is adapted to - // an event and posted via the EventAdmin) - - final Dictionary properties = new Hashtable(); - - final Bundle bundle = entry.getBundle(); - - if (null != bundle) - { - properties.put("bundle.id", bundle.getBundleId()); - - final String symbolicName = bundle.getSymbolicName(); - if (null != symbolicName) - { - properties.put(EventConstants.BUNDLE_SYMBOLICNAME, - symbolicName); - } - - properties.put("bundle", bundle); - } - - properties.put("log.level", entry.getLevel()); - - properties.put(EventConstants.MESSAGE, - (entry.getMessage()) != null ? entry.getMessage() : "" ); - - properties.put(EventConstants.TIMESTAMP, entry.getTime()); - - properties.put("log.entry", entry); - - final Throwable exception = entry.getException(); - - if (null != exception) - { - properties.put(EventConstants.EXCEPTION_CLASS, - exception.getClass().getName()); - - final String message = exception.getMessage(); - - if (null != message) - { - properties.put(EventConstants.EXCEPTION_MESSAGE, - message); - } - - properties.put(EventConstants.EXCEPTION, exception); - } - - final ServiceReference service = entry.getServiceReference(); - - if (null != service) - { - properties.put(EventConstants.SERVICE, service); - properties.put(EventConstants.SERVICE_ID, service.getProperty(EventConstants.SERVICE_ID)); - properties.put( - EventConstants.SERVICE_OBJECTCLASS, - service.getProperty(Constants.OBJECTCLASS)); - - final Object pid = service.getProperty(EventConstants.SERVICE_PID); - if (null != pid) - { - properties.put(EventConstants.SERVICE_PID, pid); - } - - } - - final StringBuilder topic = new StringBuilder( - org.osgi.service.log.LogEntry.class.getName().replace( - '.', '/')).append('/'); - - switch (entry.getLevel()) - { - case org.osgi.service.log.LogService.LOG_ERROR: - topic.append("LOG_ERROR"); - break; - case org.osgi.service.log.LogService.LOG_WARNING: - topic.append("LOG_WARNING"); - break; - case org.osgi.service.log.LogService.LOG_INFO: - topic.append("LOG_INFO"); - break; - case org.osgi.service.log.LogService.LOG_DEBUG: - topic.append("LOG_DEBUG"); - break; - default: - topic.append("LOG_OTHER"); - break; - } - - try { - getEventAdmin().postEvent(new Event(topic.toString(), properties)); - } catch(IllegalStateException e) { - // This is o.k. - indicates that we are stopped. - } - } - }; - - return m_logListener; - } - } -} diff --git a/eventadmin/impl/src/main/java/org/apache/felix/eventadmin/impl/adapter/ServiceEventAdapter.java b/eventadmin/impl/src/main/java/org/apache/felix/eventadmin/impl/adapter/ServiceEventAdapter.java deleted file mode 100644 index 3dfff931f4..0000000000 --- a/eventadmin/impl/src/main/java/org/apache/felix/eventadmin/impl/adapter/ServiceEventAdapter.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * 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.felix.eventadmin.impl.adapter; - -import java.util.Dictionary; -import java.util.Hashtable; - -import org.osgi.framework.BundleContext; -import org.osgi.framework.Constants; -import org.osgi.framework.ServiceEvent; -import org.osgi.framework.ServiceListener; -import org.osgi.service.event.Event; -import org.osgi.service.event.EventAdmin; -import org.osgi.service.event.EventConstants; - -/** - * This class registers itself as a listener for service events and posts them via - * the EventAdmin as specified in 113.6.5 OSGi R4 compendium. - * - * @author Felix Project Team - */ -public class ServiceEventAdapter extends AbstractAdapter implements ServiceListener -{ - /** - * The constructor of the adapter. This will register the adapter with the - * given context as a {@code ServiceListener} and subsequently, will - * post received events via the given EventAdmin. - * - * @param context The bundle context with which to register as a listener. - * @param admin The {@code EventAdmin} to use for posting events. - */ - public ServiceEventAdapter(final BundleContext context, final EventAdmin admin) - { - super(admin); - - context.addServiceListener(this); - } - - @Override - public void destroy(BundleContext context) { - context.removeServiceListener(this); - } - - /** - * Once a Service event is received this method assembles and posts an event - * via the {@code EventAdmin} as specified in 113.6.5 OSGi R4 compendium. - * - * @param event The event to adapt. - */ - @Override - public void serviceChanged(final ServiceEvent event) - { - final Dictionary properties = new Hashtable(); - - properties.put(EventConstants.EVENT, event); - - properties.put(EventConstants.SERVICE, event.getServiceReference()); - - properties.put(EventConstants.SERVICE_ID, - event.getServiceReference().getProperty(EventConstants.SERVICE_ID)); - - properties.put(EventConstants.SERVICE_OBJECTCLASS, - event.getServiceReference().getProperty(Constants.OBJECTCLASS)); - - final Object pid = event.getServiceReference().getProperty( - EventConstants.SERVICE_PID); - if (null != pid) - { - properties.put(EventConstants.SERVICE_PID, pid); - } - - final StringBuilder topic = new StringBuilder(ServiceEvent.class - .getName().replace('.', '/')).append('/'); - - switch (event.getType()) - { - case ServiceEvent.REGISTERED: - topic.append("REGISTERED"); - break; - case ServiceEvent.MODIFIED: - topic.append("MODIFIED"); - break; - case ServiceEvent.UNREGISTERING: - topic.append("UNREGISTERING"); - break; - default: - return; // IGNORE - } - - try { - getEventAdmin().postEvent(new Event(topic.toString(), properties)); - } catch(IllegalStateException e) { - // This is o.k. - indicates that we are stopped. - } - } -} diff --git a/eventadmin/pom.xml b/eventadmin/pom.xml index 22655c65d7..601e3d2a7c 100644 --- a/eventadmin/pom.xml +++ b/eventadmin/pom.xml @@ -23,8 +23,8 @@ org.apache.felix - felix - 1.0.4 + felix-parent + 9 ../pom/pom.xml diff --git a/log/itests/base.bndrun b/log/itests/base.bndrun new file mode 100644 index 0000000000..1c461aa21d --- /dev/null +++ b/log/itests/base.bndrun @@ -0,0 +1,8 @@ +-resolve.effective: resolve, active + +-runstartlevel: \ + order=leastdependenciesfirst,\ + begin=-1 + +-noimportjava: true +-reproducible: true diff --git a/log/itests/log-events/itest.bndrun b/log/itests/log-events/itest.bndrun new file mode 100644 index 0000000000..a1b7728e1e --- /dev/null +++ b/log/itests/log-events/itest.bndrun @@ -0,0 +1,17 @@ +-include: ../base.bndrun + +-runfw: org.apache.felix.framework + +-runrequires:\ + osgi.identity;filter:='(osgi.identity=org.apache.felix.log)',\ + osgi.identity;filter:='(osgi.identity=org.apache.felix.log.itests.logevents)' + +-runbundles: \ + org.apache.felix.configadmin;version='[1.9.22,1.9.23)',\ + org.apache.felix.log;version='[1.3.1,1.3.2)',\ + org.apache.felix.eventadmin;version='[1.6.4,1.6.5)',\ + org.apache.servicemix.bundles.junit;version='[4.13.2,4.13.3)',\ + org.osgi.service.event;version='[1.4.1,1.4.2)',\ + org.apache.felix.log.itests.logevents;version='[1.0.0,1.0.1)' + +#-runjdb: 8000 diff --git a/log/itests/log-events/pom.xml b/log/itests/log-events/pom.xml new file mode 100644 index 0000000000..eb88be53be --- /dev/null +++ b/log/itests/log-events/pom.xml @@ -0,0 +1,50 @@ + + + + org.apache.felix + org.apache.felix.log.itests.reactor + 1.0.0-SNAPSHOT + + 4.0.0 + + org.apache.felix.log.itests.logevents + jar + + + + org.apache.felix + org.apache.felix.eventadmin + + + + + + + biz.aQute.bnd + bnd-resolver-maven-plugin + + + biz.aQute.bnd + bnd-testing-maven-plugin + + + + + \ No newline at end of file diff --git a/log/itests/log-events/src/main/java/org/apache/felix/log/itests/log/events/LogEventsTest.java b/log/itests/log-events/src/main/java/org/apache/felix/log/itests/log/events/LogEventsTest.java new file mode 100644 index 0000000000..d583c27bae --- /dev/null +++ b/log/itests/log-events/src/main/java/org/apache/felix/log/itests/log/events/LogEventsTest.java @@ -0,0 +1,110 @@ +/* + * 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.felix.log.itests.log.events; + +import java.util.ArrayList; +import java.util.Dictionary; +import java.util.Hashtable; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import org.junit.Assert; +import org.junit.Test; +import org.osgi.annotation.bundle.Requirement; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; +import org.osgi.framework.ServiceRegistration; +import org.osgi.namespace.service.ServiceNamespace; +import org.osgi.resource.Namespace; +import org.osgi.service.event.Event; +import org.osgi.service.event.EventAdmin; +import org.osgi.service.event.EventConstants; +import org.osgi.service.event.EventHandler; +import org.osgi.service.log.Logger; + +@Requirement(namespace = ServiceNamespace.SERVICE_NAMESPACE, + filter = "(objectClass=org.osgi.service.event.EventAdmin)", + effective = Namespace.EFFECTIVE_ACTIVE) +public class LogEventsTest { + public static org.osgi.service.log.Logger getLogger(Class clazz) { + BundleContext bundleContext = FrameworkUtil.getBundle(clazz).getBundleContext(); + ServiceReference serviceReference = + bundleContext.getServiceReference(org.osgi.service.log.LoggerFactory.class); + org.osgi.service.log.LoggerFactory loggerFactory = bundleContext.getService(serviceReference); + final Logger logger = loggerFactory.getLogger(clazz); + Assert.assertNotNull(logger); + return logger; + } + + public static EventAdmin getEventAdmin() { + final Bundle bundle = FrameworkUtil.getBundle(LogEventsTest.class); + final BundleContext bundleContext = bundle.getBundleContext(); + final ServiceReference eventAdminRef = bundleContext.getServiceReference(EventAdmin.class); + final EventAdmin eventAdmin = bundleContext.getService(eventAdminRef); + Assert.assertNotNull(eventAdmin); + return eventAdmin; + } + + static class LogEventHandler implements EventHandler { + private final List events = new ArrayList<>(1); + private final CountDownLatch latch = new CountDownLatch(1); + + public synchronized List getEvents() { + return new ArrayList<>(events); + } + + public CountDownLatch getLatch() { + return latch; + } + + @Override + public synchronized void handleEvent(Event event) { + events.add(event); + latch.countDown(); + } + } + + @Test + public void test() throws InterruptedException { + final Bundle bundle = FrameworkUtil.getBundle(LogEventsTest.class); + final BundleContext bundleContext = bundle.getBundleContext(); + final LogEventHandler handler = new LogEventHandler(); + Dictionary handlerProps = new Hashtable<>(2); + handlerProps.put(EventConstants.EVENT_TOPIC, "org/osgi/service/log/LogEntry/LOG_ERROR"); + handlerProps.put(EventConstants.EVENT_FILTER, "(bundle.symbolicName=org.apache.felix.log.itests.logevents)" ); + ServiceRegistration eventHandlerRegistration + = bundleContext.registerService(EventHandler.class.getName(), handler, handlerProps); + try { + final org.osgi.service.log.Logger logger = getLogger(LogEventsTest.class); + logger.error("test"); + handler.getLatch().await(1, TimeUnit.SECONDS); + eventHandlerRegistration.unregister(); + eventHandlerRegistration = null; + final List events = handler.getEvents(); + Assert.assertEquals("Expecting one event", 1, events.size()); + } finally { + if (eventHandlerRegistration != null) { + eventHandlerRegistration.unregister(); + } + } + } +} diff --git a/log/itests/pom.xml b/log/itests/pom.xml new file mode 100644 index 0000000000..a29dd51525 --- /dev/null +++ b/log/itests/pom.xml @@ -0,0 +1,241 @@ + + + + org.apache.felix + felix-parent + 9 + + + 4.0.0 + + pom + Felix Log integration tests root + org.apache.felix.log.itests.reactor + 1.0.0-SNAPSHOT + + + 6.0.0 + + true + true + true + true + + + + + + org.apache.felix + org.apache.felix.log + 1.3.1-SNAPSHOT + + + org.osgi + osgi.core + 7.0.0 + + + junit + junit + 4.13.2 + + + org.osgi + org.osgi.service.cm + 1.6.1 + + + org.osgi + org.osgi.namespace.service + 1.0.0 + + + org.apache.servicemix.bundles + org.apache.servicemix.bundles.junit + 4.13.2_1 + + + org.apache.felix + org.apache.felix.framework + 7.0.5 + + + org.apache.felix + org.apache.felix.configadmin + 1.9.22 + + + org.apache.felix + org.apache.felix.eventadmin + 1.6.4 + + + + + + + org.osgi + osgi.core + provided + + + org.apache.felix + org.apache.felix.log + + + org.osgi + org.osgi.namespace.service + + + org.apache.servicemix.bundles + org.apache.servicemix.bundles.junit + + + org.apache.felix + org.apache.felix.framework + runtime + + + org.apache.felix + org.apache.felix.configadmin + runtime + + + + + log-events + + + + + + + biz.aQute.bnd + bnd-maven-plugin + + + + + + + org.apache.maven.plugins + maven-antrun-plugin + 3.1.0 + + + props + + run + + + + + + + + + + + + + + biz.aQute.bnd + bnd-maven-plugin + ${bnd.version} + + + bnd-process + + bnd-process + + + + + + biz.aQute.bnd + bnd-resolver-maven-plugin + ${bnd.version} + + false + false + + + compile + runtime + test + + + + + resolve + + resolve + + package + + + + + biz.aQute.bnd + bnd-testing-maven-plugin + ${bnd.version} + + false + false + + + compile + runtime + test + + + + + testing + + testing + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.4.2 + + + ${project.build.outputDirectory}/META-INF/MANIFEST.MF + + + + + + + \ No newline at end of file diff --git a/log/pom.xml b/log/pom.xml index 70b132a877..4b7297094f 100644 --- a/log/pom.xml +++ b/log/pom.xml @@ -20,7 +20,7 @@ org.apache.felix felix-parent - 6 + 9 ../pom/pom.xml 4.0.0 @@ -48,37 +48,59 @@ org.osgi osgi.core - 6.0.0 + 7.0.0 + provided + + + org.osgi + org.osgi.service.cm + 1.6.0 + provided org.osgi org.osgi.service.log 1.5.0 + + org.osgi + org.osgi.service.event + 1.4.1 + + + org.osgi + osgi.annotation + 8.1.0 + provided + + + org.osgi + org.osgi.namespace.service + 1.0.0 + provided + + + org.osgi + org.osgi.service.component.annotations + 1.5.1 + provided + org.apache.felix maven-bundle-plugin - 3.5.0 + 5.1.9 true org.osgi.service.log,org.osgi.service.log.admin - org.apache.felix.log - ${pom.artifactId} - ${pom.artifactId}.Activator + ${project.artifactId} The Apache Software Foundation META-INF/LICENSE=LICENSE,META-INF/NOTICE=NOTICE,META-INF/DEPENDENCIES=DEPENDENCIES - - ="org.osgi.service.log.LogReaderService";uses:="org.osgi.service.log,org.osgi.service.log.admin", - osgi.service;objectClass:List="org.osgi.service.log.LogService,org.osgi.service.log.LoggerFactory";uses:="org.osgi.service.log,org.osgi.service.log.admin", - osgi.service;objectClass:List="org.osgi.service.log.admin.LoggerAdmin";uses:="org.osgi.service.log,org.osgi.service.log.admin" - ]]> + <_reproducible>true + <_noimportjava>true diff --git a/log/src/main/java/org/apache/felix/log/Activator.java b/log/src/main/java/org/apache/felix/log/Activator.java index b1c0a50033..2674a922e0 100644 --- a/log/src/main/java/org/apache/felix/log/Activator.java +++ b/log/src/main/java/org/apache/felix/log/Activator.java @@ -21,10 +21,14 @@ import java.util.Dictionary; import java.util.Hashtable; +import org.osgi.annotation.bundle.Header; +import org.osgi.annotation.bundle.Requirement; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; import org.osgi.framework.ServiceRegistration; +import org.osgi.namespace.service.ServiceNamespace; +import org.osgi.resource.Namespace; import org.osgi.service.log.LogLevel; import org.osgi.service.log.LogReaderService; import org.osgi.service.log.LogService; @@ -54,6 +58,10 @@ * the historic log information. The default value is false. * */ +@Header(name = Constants.BUNDLE_ACTIVATOR, value = "${@class}") +@Requirement(namespace = ServiceNamespace.SERVICE_NAMESPACE, + filter = "(objectClass=org.osgi.service.cm.ConfigurationAdmin)", + effective = Namespace.EFFECTIVE_ACTIVE) public final class Activator implements BundleActivator { /** The name of the property that defines the maximum size of the log. */ @@ -108,7 +116,7 @@ private static boolean getStoreDebug(final BundleContext context) String storeDebugPropValue = context.getProperty(STORE_DEBUG_PROPERTY); if (storeDebugPropValue != null) { - storeDebug = Boolean.valueOf(storeDebugPropValue).booleanValue(); + storeDebug = Boolean.parseBoolean(storeDebugPropValue); } return storeDebug; @@ -133,7 +141,7 @@ private static String getDefaultLogLevel(final BundleContext context) { public void start(final BundleContext context) throws Exception { // create the log instance - m_log = new Log(getMaxSize(context), getStoreDebug(context)); + m_log = new Log(context, getMaxSize(context), getStoreDebug(context)); // create the LoggerAdmin instance m_loggerAdmin = new LoggerAdminImpl(getDefaultLogLevel(context), m_log); diff --git a/log/src/main/java/org/apache/felix/log/ConfigurationListenerImpl.java b/log/src/main/java/org/apache/felix/log/ConfigurationListenerImpl.java index 489cc74145..729f1b389f 100644 --- a/log/src/main/java/org/apache/felix/log/ConfigurationListenerImpl.java +++ b/log/src/main/java/org/apache/felix/log/ConfigurationListenerImpl.java @@ -52,7 +52,7 @@ public class ConfigurationListenerImpl { final Log m_log; final LoggerAdminImpl m_loggerAdmin; - public ConfigurationListenerImpl(final BundleContext context, final Log log, final LoggerAdminImpl loggerAdmin) throws Exception { + ConfigurationListenerImpl(final BundleContext context, final Log log, final LoggerAdminImpl loggerAdmin) throws Exception { m_context = context; m_log = log; m_loggerAdmin = loggerAdmin; diff --git a/log/src/main/java/org/apache/felix/log/FormatterLoggerImpl.java b/log/src/main/java/org/apache/felix/log/FormatterLoggerImpl.java index dda2667733..0ff256bf9d 100644 --- a/log/src/main/java/org/apache/felix/log/FormatterLoggerImpl.java +++ b/log/src/main/java/org/apache/felix/log/FormatterLoggerImpl.java @@ -26,12 +26,13 @@ public class FormatterLoggerImpl extends LoggerImpl implements FormatterLogger { - public FormatterLoggerImpl( + FormatterLoggerImpl( final String name, final Bundle bundle, final Log log, final LoggerAdminImpl loggerAdmin) { super(name, bundle, log, loggerAdmin); } + @Override String format(String format, LogParameters logParameters) { StringBuilder sb = new StringBuilder(); diff --git a/log/src/main/java/org/apache/felix/log/Log.java b/log/src/main/java/org/apache/felix/log/Log.java index a92f596f7c..be61a623f5 100644 --- a/log/src/main/java/org/apache/felix/log/Log.java +++ b/log/src/main/java/org/apache/felix/log/Log.java @@ -18,19 +18,32 @@ */ package org.apache.felix.log; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; +import org.osgi.annotation.bundle.Requirement; import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; import org.osgi.framework.BundleEvent; import org.osgi.framework.BundleListener; +import org.osgi.framework.Constants; import org.osgi.framework.FrameworkEvent; import org.osgi.framework.FrameworkListener; import org.osgi.framework.ServiceEvent; import org.osgi.framework.ServiceListener; import org.osgi.framework.ServiceReference; +import org.osgi.namespace.implementation.ImplementationNamespace; +import org.osgi.service.event.EventConstants; import org.osgi.service.log.LogEntry; import org.osgi.service.log.LogLevel; import org.osgi.service.log.LogListener; +import org.osgi.util.tracker.ServiceTracker; +import org.osgi.util.tracker.ServiceTrackerCustomizer; /** * Class used to represent the log. This class is used by the implementations @@ -39,8 +52,16 @@ * @see org.osgi.service.log.LogService * @see org.osgi.service.log.LogReaderService */ +@Requirement(namespace = ImplementationNamespace.IMPLEMENTATION_NAMESPACE, + name = EventConstants.EVENT_ADMIN_IMPLEMENTATION, + version = EventConstants.EVENT_ADMIN_SPECIFICATION_VERSION, + resolution = Requirement.Resolution.OPTIONAL) final class Log implements BundleListener, FrameworkListener, ServiceListener { + private static final String EVENT_ADMIN_CLASS = "org.osgi.service.event.EventAdmin"; + private static final String EVENT_CLASS = "org.osgi.service.event.Event"; + private static final String POST_EVENT_METHOD = "postEvent"; + /** The first log entry. */ private volatile LogNode m_head; /** The last log entry. */ @@ -55,16 +76,111 @@ final class Log implements BundleListener, FrameworkListener, ServiceListener private final boolean m_storeDebug; /** Active flag */ private volatile boolean active = true; + /** Bundle context */ + private final BundleContext m_context; + /** Service tracker for EventAdmin */ + private final ServiceTracker m_eventAdminTracker; + + static class EventAdminServiceInfo { + final Constructor m_eventClassCtor; + final Method m_postEventMethod; + final Object m_service; + + EventAdminServiceInfo(Constructor eventClassCtor, Method postEventMethod, Object service) { + this.m_eventClassCtor = eventClassCtor; + this.m_postEventMethod = postEventMethod; + this.m_service = service; + } + } + + static class EAProxy { + final AtomicReference m_info = new AtomicReference<>(); + + public EAProxy(ServiceReference reference, Object service) { + setServiceInfo(reference, service); + } + + final void setServiceInfo(ServiceReference reference, Object service) { + final Bundle bundle = reference.getBundle(); + try { + Class eventClass = bundle.loadClass(EVENT_CLASS); + final Constructor eventConstructor = eventClass.getConstructor(String.class, Map.class); + Class eventAdminClass = bundle.loadClass(EVENT_ADMIN_CLASS); + final Method postMethod = eventAdminClass.getMethod(POST_EVENT_METHOD, eventClass); + this.m_info.set(new EventAdminServiceInfo(eventConstructor, postMethod, service)); + } catch (ClassNotFoundException | NoSuchMethodException | SecurityException e) { + throw new IllegalStateException( + "Failure reflecting over API from Event Admin service bundle", e); + } + } + + void resetServiceInfo() { + this.m_info.set(null); + } + + void postEvent(LogEntry entry) { + final EventAdminServiceInfo eventAdminServiceInfo = this.m_info.get(); + if (eventAdminServiceInfo == null) { + return; + } + + try { + final LogLevel logLevel = entry.getLogLevel(); + final String topic; + if (logLevel == LogLevel.TRACE) { + topic = "org/osgi/service/log/LogEntry/LOG_OTHER"; + } else { + topic = "org/osgi/service/log/LogEntry/LOG_" + logLevel.name(); + } + final Map props = new HashMap<>(10); + final Bundle bundle = entry.getBundle(); + props.put(EventConstants.BUNDLE_ID, bundle.getBundleId()); + props.put(EventConstants.BUNDLE_SYMBOLICNAME, bundle.getSymbolicName()); + props.put(EventConstants.BUNDLE, bundle); + props.put("log.level", entry.getLogLevel()); + props.put("log.loggername", entry.getLoggerName()); + props.put("log.threadinfo", entry.getThreadInfo()); + props.put("log.loglevel", logLevel); + props.put(EventConstants.MESSAGE, entry.getMessage()); + props.put(EventConstants.TIMESTAMP, entry.getTime()); + props.put("log.entry", entry); + final Throwable exception = entry.getException(); + if (exception != null) { + props.put(EventConstants.EXCEPTION_CLASS, exception.getClass().getName()); + props.put(EventConstants.EXCEPTION_MESSAGE, exception.getMessage()); + props.put(EventConstants.EXCEPTION, exception); + } + final ServiceReference serviceReference = entry.getServiceReference(); + if (serviceReference != null) { + props.put(EventConstants.SERVICE, serviceReference); + props.put(EventConstants.SERVICE_ID, serviceReference.getProperty(Constants.SERVICE_ID)); + final Object servicePid = serviceReference.getProperty(Constants.SERVICE_PID); + if (servicePid != null) { + props.put(EventConstants.SERVICE_PID, servicePid); + } + props.put(EventConstants.SERVICE_OBJECTCLASS, serviceReference.getProperty(Constants.OBJECTCLASS)); + } + final Object event = eventAdminServiceInfo.m_eventClassCtor.newInstance(topic, props); + eventAdminServiceInfo.m_postEventMethod.invoke(eventAdminServiceInfo.m_service, event); + } catch (IllegalAccessException | InvocationTargetException | InstantiationException e) { + throw new RuntimeException(e); + } + } + } /** * Create a new instance. * @param maxSize the maximum size for the log * @param storeDebug whether or not to store debug messages */ - Log(final int maxSize, final boolean storeDebug) + Log(final BundleContext context, final int maxSize, final boolean storeDebug) { + this.m_context = context; this.m_maxSize = maxSize; this.m_storeDebug = storeDebug; + this.m_eventAdminTracker = new ServiceTracker<>(context, EVENT_ADMIN_CLASS, + new EAProxyServiceTrackerCustomizer()); + this.m_eventAdminTracker.open(); } /** @@ -78,6 +194,7 @@ synchronized void close() listenerThread.shutdown(); listenerThread = null; } + m_eventAdminTracker.close(); m_head = null; m_tail = null; @@ -151,6 +268,12 @@ synchronized void addEntry(final LogEntry entry) { listenerThread.addEntry(entry); } + + final EAProxy eaProxy = this.m_eventAdminTracker.getService(); + if (eaProxy != null) + { + eaProxy.postEvent(entry); + } } /** @@ -206,7 +329,7 @@ synchronized Enumeration getEntries() "FrameworkEvent STARTED", "FrameworkEvent ERROR", "FrameworkEvent PACKAGES REFRESHED", - "FrameworkEvent STARTLEVEL CHANGED", + "FrameworkEvent STARTLEVEL CHANGED", "FrameworkEvent WARNING", "FrameworkEvent INFO" }; @@ -330,4 +453,21 @@ public void serviceChanged(final ServiceEvent event) message, null); } + + private class EAProxyServiceTrackerCustomizer implements ServiceTrackerCustomizer { + @Override + public EAProxy addingService(ServiceReference reference) { + return new EAProxy(reference, m_context.getService(reference)); + } + + @Override + public void modifiedService(ServiceReference reference, EAProxy proxy) { + proxy.setServiceInfo(reference, m_context.getService(reference)); + } + + @Override + public void removedService(ServiceReference reference, EAProxy proxy) { + proxy.resetServiceInfo(); + } + } } \ No newline at end of file diff --git a/log/src/main/java/org/apache/felix/log/LogEntryImpl.java b/log/src/main/java/org/apache/felix/log/LogEntryImpl.java index 2d98b9298e..2198e97765 100644 --- a/log/src/main/java/org/apache/felix/log/LogEntryImpl.java +++ b/log/src/main/java/org/apache/felix/log/LogEntryImpl.java @@ -143,6 +143,7 @@ final class LogEntryImpl implements LogEntry * @return the bundle that created this LogEntry object;null if no * bundle is associated with this LogEntry object */ + @Override public Bundle getBundle() { return m_bundle; @@ -155,6 +156,7 @@ public Bundle getBundle() * this LogEntry object; null if no {@link ServiceReference} object * was provided */ + @Override public ServiceReference getServiceReference() { return m_serviceReference; @@ -171,6 +173,7 @@ public ServiceReference getServiceReference() * @see org.osgi.service.LogService#LOG_INFO * @see org.osgi.service.LogService#LOG_DEBUG */ + @Override public int getLevel() { if (m_legacyLevel != m_level.ordinal()) { @@ -184,6 +187,7 @@ public int getLevel() * Returns the human readable message associated with this LogEntry object. * @return a string containing the message associated with this LogEntry object */ + @Override public String getMessage() { return m_message; @@ -202,6 +206,7 @@ public String getMessage() * @return throwable object of the exception associated with this LogEntry; * null if no exception is associated with this LogEntry object */ + @Override public Throwable getException() { return m_exception; @@ -213,6 +218,7 @@ public Throwable getException() * @return the system time in milliseconds when this LogEntry object was created * @see System#currentTimeMillis() */ + @Override public long getTime() { return m_time; diff --git a/log/src/main/java/org/apache/felix/log/LogListenerThread.java b/log/src/main/java/org/apache/felix/log/LogListenerThread.java index 588f1e739a..34ee75ad7d 100644 --- a/log/src/main/java/org/apache/felix/log/LogListenerThread.java +++ b/log/src/main/java/org/apache/felix/log/LogListenerThread.java @@ -106,6 +106,7 @@ void shutdown() * The main method of the thread: waits for new messages to be receieved * and then delivers them to any registered log listeners. */ + @Override public void run() { while (!isInterrupted()) @@ -138,10 +139,10 @@ public void run() { // Take a snapshot of all current listeners and deliver all // pending messages to them... - List listeners = new ArrayList<>(); + List listeners; synchronized (m_listeners) { - listeners.addAll(m_listeners); + listeners = new ArrayList<>(m_listeners); } Iterator entriesIt = entriesToDeliver.iterator(); diff --git a/log/src/main/java/org/apache/felix/log/LogNodeEnumeration.java b/log/src/main/java/org/apache/felix/log/LogNodeEnumeration.java index 39f067e973..8560b71e5c 100644 --- a/log/src/main/java/org/apache/felix/log/LogNodeEnumeration.java +++ b/log/src/main/java/org/apache/felix/log/LogNodeEnumeration.java @@ -48,6 +48,7 @@ final class LogNodeEnumeration implements Enumeration * Determines whether there are any more elements to return. * @return true if there are more elements; false otherwise */ + @Override public boolean hasMoreElements() { return m_next != null; @@ -57,6 +58,7 @@ public boolean hasMoreElements() * Returns the current element and moves onto the next element. * @return the current element */ + @Override public LogEntry nextElement() { LogEntry result = null; diff --git a/log/src/main/java/org/apache/felix/log/LogReaderServiceFactory.java b/log/src/main/java/org/apache/felix/log/LogReaderServiceFactory.java index 12677ba35e..5193c66704 100644 --- a/log/src/main/java/org/apache/felix/log/LogReaderServiceFactory.java +++ b/log/src/main/java/org/apache/felix/log/LogReaderServiceFactory.java @@ -47,6 +47,7 @@ final class LogReaderServiceFactory implements ServiceFactory * @param registration the service registration * @return the log reader service implementation for the specified bundle */ + @Override public LogReaderService getService(final Bundle bundle, final ServiceRegistration registration) { @@ -60,6 +61,7 @@ public LogReaderService getService(final Bundle bundle, * @param registration the service registration * @param service the service to release */ + @Override public void ungetService(final Bundle bundle, final ServiceRegistration registration, final LogReaderService service) diff --git a/log/src/main/java/org/apache/felix/log/LogReaderServiceImpl.java b/log/src/main/java/org/apache/felix/log/LogReaderServiceImpl.java index d5ce5f4823..46547df7a4 100644 --- a/log/src/main/java/org/apache/felix/log/LogReaderServiceImpl.java +++ b/log/src/main/java/org/apache/felix/log/LogReaderServiceImpl.java @@ -23,6 +23,8 @@ import java.util.List; import java.util.Vector; +import org.osgi.annotation.bundle.Capability; +import org.osgi.namespace.service.ServiceNamespace; import org.osgi.service.log.LogEntry; import org.osgi.service.log.LogListener; import org.osgi.service.log.LogReaderService; @@ -37,6 +39,11 @@ * notifications about {@link org.osgi.service.log.LogEntry} objects when they are created * through the {@link org.osgi.service.log.LogService}. */ +@Capability( + namespace = ServiceNamespace.SERVICE_NAMESPACE, + attribute = { "objectClass:List=\"org.osgi.service.log.LogReaderService\"" }, + uses = { LogReaderServiceImpl.class, LogReaderService.class } +) final class LogReaderServiceImpl implements LogReaderService { /** The log implementation. */ diff --git a/log/src/main/java/org/apache/felix/log/LogServiceFactory.java b/log/src/main/java/org/apache/felix/log/LogServiceFactory.java index 132f386b5d..210d1ee7ef 100644 --- a/log/src/main/java/org/apache/felix/log/LogServiceFactory.java +++ b/log/src/main/java/org/apache/felix/log/LogServiceFactory.java @@ -34,7 +34,7 @@ final class LogServiceFactory implements ServiceFactory /** * Create a new instance. - * @param log the log to associate the service implementations with., + * @param loggerAdminImpl */ LogServiceFactory(final LoggerAdminImpl loggerAdminImpl) { diff --git a/log/src/main/java/org/apache/felix/log/LogServiceImpl.java b/log/src/main/java/org/apache/felix/log/LogServiceImpl.java index 7a9acf3282..21219a4323 100644 --- a/log/src/main/java/org/apache/felix/log/LogServiceImpl.java +++ b/log/src/main/java/org/apache/felix/log/LogServiceImpl.java @@ -18,14 +18,23 @@ */ package org.apache.felix.log; +import org.osgi.annotation.bundle.Capability; import org.osgi.framework.Bundle; import org.osgi.framework.ServiceReference; +import org.osgi.namespace.service.ServiceNamespace; import org.osgi.service.log.LogService; import org.osgi.service.log.Logger; +import org.osgi.service.log.LoggerFactory; +import org.osgi.service.log.admin.LoggerAdmin; /** * Implementation of the OSGi {@link LogService}. */ +@Capability( + namespace = ServiceNamespace.SERVICE_NAMESPACE, + attribute = { "objectClass:List=\"org.osgi.service.log.LogService,org.osgi.service.log.LoggerFactory\"" }, + uses = { LogServiceImpl.class, LogService.class, LoggerFactory.class, LoggerAdmin.class } +) final class LogServiceImpl implements LogService { /** The bundle associated with this implementation. */ @@ -35,9 +44,8 @@ final class LogServiceImpl implements LogService /** * Create a new instance. - * @param log the log implementation * @param bundle the bundle associated with this implementation - * @param serviceReference + * @param loggerAdminImpl */ LogServiceImpl(final Bundle bundle, final LoggerAdminImpl loggerAdminImpl) { diff --git a/log/src/main/java/org/apache/felix/log/LoggerAdminImpl.java b/log/src/main/java/org/apache/felix/log/LoggerAdminImpl.java index aa53e37f8d..0d6bfbb3fe 100644 --- a/log/src/main/java/org/apache/felix/log/LoggerAdminImpl.java +++ b/log/src/main/java/org/apache/felix/log/LoggerAdminImpl.java @@ -24,12 +24,19 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import org.osgi.annotation.bundle.Capability; import org.osgi.framework.Bundle; +import org.osgi.namespace.service.ServiceNamespace; import org.osgi.service.log.FormatterLogger; import org.osgi.service.log.Logger; import org.osgi.service.log.admin.LoggerAdmin; import org.osgi.service.log.admin.LoggerContext; +@Capability( + namespace = ServiceNamespace.SERVICE_NAMESPACE, + attribute = { "objectClass:List=\"org.osgi.service.log.admin.LoggerAdmin\"" }, + uses = { LoggerAdminImpl.class, LoggerAdmin.class } +) public class LoggerAdminImpl implements LoggerAdmin { private final Log m_log; @@ -37,7 +44,7 @@ public class LoggerAdminImpl implements LoggerAdmin { private final ConcurrentMap m_contexts = new ConcurrentHashMap<>(); private final ConcurrentMap _loggers = new ConcurrentHashMap<>(); - public LoggerAdminImpl(final String defaultLogLevelString, final Log log) { + LoggerAdminImpl(final String defaultLogLevelString, final Log log) { m_rootContext = new RootLoggerContextImpl(defaultLogLevelString, this); m_log = log; } diff --git a/log/src/main/java/org/apache/felix/log/LoggerContextImpl.java b/log/src/main/java/org/apache/felix/log/LoggerContextImpl.java index d26889e95d..36a9b206ad 100644 --- a/log/src/main/java/org/apache/felix/log/LoggerContextImpl.java +++ b/log/src/main/java/org/apache/felix/log/LoggerContextImpl.java @@ -47,17 +47,19 @@ public LoggerContextImpl(String name, LoggerAdminImpl loggerAdminImpl, LoggerCon _rootContext = rootLoggerContext; } + @Override public String getName() { return _name; } + @Override public LogLevel getEffectiveLogLevel(String name) { _lock.lock(); try { if (_levels != null && !_levels.isEmpty()) { String copy = name; LogLevel level; - while (copy.length() > 0) { + while (!copy.isEmpty()) { level = _levels.get(copy); if (level != null) { return level; @@ -74,6 +76,7 @@ public LogLevel getEffectiveLogLevel(String name) { } } + @Override public Map getLogLevels() { _lock.lock(); try { @@ -87,6 +90,7 @@ public Map getLogLevels() { } } + @Override public void setLogLevels(Map logLevels) { _lock.lock(); try { @@ -98,6 +102,7 @@ public void setLogLevels(Map logLevels) { } } + @Override public void clear() { _lock.lock(); try { @@ -108,6 +113,7 @@ public void clear() { } } + @Override public boolean isEmpty() { _lock.lock(); try { diff --git a/log/src/main/java/org/apache/felix/log/LoggerImpl.java b/log/src/main/java/org/apache/felix/log/LoggerImpl.java index a9879f1603..055bc50914 100644 --- a/log/src/main/java/org/apache/felix/log/LoggerImpl.java +++ b/log/src/main/java/org/apache/felix/log/LoggerImpl.java @@ -36,10 +36,10 @@ public class LoggerImpl implements Logger { protected final String m_name; protected final Bundle m_bundle; - protected final Log m_log; + final Log m_log; protected final LoggerAdminImpl m_loggerAdmin; - public LoggerImpl(final String name, final Bundle bundle, final Log log, final LoggerAdminImpl loggerAdmin) { + LoggerImpl(final String name, final Bundle bundle, final Log log, final LoggerAdminImpl loggerAdmin) { m_name = name; m_bundle = bundle; m_log = log; diff --git a/log/src/main/java/org/apache/felix/log/RootLoggerContextImpl.java b/log/src/main/java/org/apache/felix/log/RootLoggerContextImpl.java index 3ec792b2fd..11e8f5c64c 100644 --- a/log/src/main/java/org/apache/felix/log/RootLoggerContextImpl.java +++ b/log/src/main/java/org/apache/felix/log/RootLoggerContextImpl.java @@ -19,9 +19,6 @@ package org.apache.felix.log; -import java.util.Dictionary; -import java.util.Map; - import org.osgi.service.log.LogLevel; import org.osgi.service.log.Logger; @@ -45,12 +42,13 @@ public RootLoggerContextImpl(String defaultLogLevelString, LoggerAdminImpl logge _defaultLevel = defaultLogLevel; } + @Override public LogLevel getEffectiveLogLevel(String name) { _lock.lock(); try { if (_levels != null && !_levels.isEmpty()) { LogLevel level; - while (name.length() > 0) { + while (!name.isEmpty()) { level = _levels.get(name); if (level != null) { return level; @@ -67,16 +65,6 @@ public LogLevel getEffectiveLogLevel(String name) { } } - @Override - public void setLogLevels(Map logLevels) { - super.setLogLevels(logLevels); - } - - @Override - void updateLoggerContext(Dictionary properties) { - super.updateLoggerContext(properties); - } - private LogLevel getEffectiveRootLogLevel() { if (_levels == null) return _defaultLevel; LogLevel logLevel = _levels.get(Logger.ROOT_LOGGER_NAME); diff --git a/pom/pom.xml b/pom/pom.xml index 4f7723da20..e8c6451f30 100644 --- a/pom/pom.xml +++ b/pom/pom.xml @@ -22,7 +22,7 @@ org.apache apache - 31 + 33 diff --git a/scr/src/main/java/org/apache/felix/scr/impl/ComponentCommands.java b/scr/src/main/java/org/apache/felix/scr/impl/ComponentCommands.java index 08d9184487..c7d5945277 100644 --- a/scr/src/main/java/org/apache/felix/scr/impl/ComponentCommands.java +++ b/scr/src/main/java/org/apache/felix/scr/impl/ComponentCommands.java @@ -462,16 +462,14 @@ else if (value instanceof byte[]) valueStr = Arrays.toString((byte[]) value); else if (value instanceof short[]) valueStr = Arrays.toString((short[]) value); - else if (value instanceof byte[]) - valueStr = Arrays.toString((byte[]) value); else if (value instanceof char[]) valueStr = Arrays.toString((char[]) value); else if (value instanceof boolean[]) valueStr = Arrays.toString((boolean[]) value); else if (value instanceof float[]) - valueStr = Arrays.toString((boolean[]) value); + valueStr = Arrays.toString((float[]) value); else if (value instanceof double[]) - valueStr = Arrays.toString((boolean[]) value); + valueStr = Arrays.toString((double[]) value); else if (value instanceof Object[]) valueStr = Arrays.deepToString((Object[]) value); else