/** * Copyright OPS4J * * 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.wicket.internal; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.wicket.Page; import org.ops4j.pax.wicket.api.PaxWicketMountPoint; import org.ops4j.pax.wicket.api.support.DefaultPageMounter; import org.ops4j.pax.wicket.internal.extender.ExtendedBundle; import org.ops4j.pax.wicket.internal.injection.BundleDelegatingComponentInstanciationListener; import org.osgi.framework.BundleContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * The behavior of this Delegating Resolver is different from the {@link org.ops4j.pax.wicket.internal.BundleDelegatingClassResolver} or * {@link org.ops4j.pax.wicket.internal.injection.BundleDelegatingComponentInstanciationListener}. In this case the bundles are not only scanned during the real * operation but rather services are exported directly at the pax-wicket bundle for the application to register the * right mount points. * * @author nmw * @version $Id: $Id */ public class BundleDelegatingPageMounter implements InternalBundleDelegationProvider { private static final Logger LOGGER = LoggerFactory.getLogger(BundleDelegatingPageMounter.class); private final String applicationName; private final BundleContext paxWicketContext; private final Map<String, List<DefaultPageMounter>> mountPointRegistrations = new HashMap<String, List<DefaultPageMounter>>(); /** * <p>Constructor for BundleDelegatingPageMounter.</p> * * @param applicationName a {@link java.lang.String} object. * @param paxWicketContext a {@link org.osgi.framework.BundleContext} object. */ public BundleDelegatingPageMounter(String applicationName, BundleContext paxWicketContext) { this.applicationName = applicationName; this.paxWicketContext = paxWicketContext; } /** * <p>Getter for the field <code>applicationName</code>.</p> * * @return a {@link java.lang.String} object. */ public String getApplicationName() { return applicationName; } /** * <p>start.</p> */ public void start() { // not required for this class } /** * <p>stop.</p> */ public void stop() { Collection<List<DefaultPageMounter>> values; synchronized (mountPointRegistrations) { values = new ArrayList<List<DefaultPageMounter>>(mountPointRegistrations.values()); mountPointRegistrations.clear(); } for (List<DefaultPageMounter> bundleMounters : values) { for (DefaultPageMounter pageMounter : bundleMounters) { pageMounter.dispose(); } } } /** {@inheritDoc} */ public void addBundle(ExtendedBundle bundle) { String symbolicName = bundle.getBundle().getSymbolicName(); if (bundle.isRelevantForMountPointAnnotations()) { LOGGER.trace("Scanning bundle {} for PaxWicketMountPoint annotations", symbolicName); ArrayList<DefaultPageMounter> pageMounter = new ArrayList<DefaultPageMounter>(); Collection<Class<?>> allClasses = bundle.getAllClasses(); for (Class<?> clazz : allClasses) { PaxWicketMountPoint mountPoint = clazz.getAnnotation(PaxWicketMountPoint.class); if (mountPoint != null) { if (!Page.class.isAssignableFrom(clazz)) { LOGGER .warn( "ignore PaxWicketMountPoint annotated class {} since it is no page class or has unresolved optional dependencies...", clazz.getName()); continue; } DefaultPageMounter mountPointRegistration = new DefaultPageMounter(applicationName, paxWicketContext); // We have checked this before... @SuppressWarnings("unchecked") Class<? extends Page> pageClass = (Class<? extends Page>) clazz; mountPointRegistration.addMountPoint(mountPoint.mountPoint(), pageClass); mountPointRegistration.register(); pageMounter.add(mountPointRegistration); LOGGER.info("Mounting page {} at {}", clazz.getName(), mountPoint.mountPoint()); } } synchronized (mountPointRegistrations) { if (mountPointRegistrations.containsKey(symbolicName)) { removeBundle(bundle); } mountPointRegistrations.put(bundle.getID(), pageMounter); } } else { LOGGER.debug("Ignore bundle " + symbolicName + " for PageMounting."); } } /** {@inheritDoc} */ public void removeBundle(ExtendedBundle bundle) { List<DefaultPageMounter> registrations; synchronized (mountPointRegistrations) { registrations = mountPointRegistrations.remove(bundle.getID()); } if (registrations == null) { return; } for (DefaultPageMounter pageMounter : registrations) { pageMounter.dispose(); } } }