package org.springframework.roo.uaa;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.osgi.framework.BundleContext;
import org.osgi.service.component.ComponentContext;
import org.springframework.roo.metadata.MetadataLogger;
import org.springframework.roo.metadata.MetadataTimingStatistic;
import org.springframework.roo.support.osgi.BundleFindingUtils;
/**
* Regularly polls {@link MetadataLogger#getTimings()} and incorporates all
* timings into UAA feature use statistics.
*
* @author Ben Alex
* @since 1.1.1
*/
@Component(enabled = true)
public class MetadataPollingUaaRegistrationFacility {
private class MetadataTimerTask extends TimerTask {
@Override
public void run() {
// Try..catch used to avoid unexpected problems terminating the
// timer thread
try {
// Deal with modules being used via the add-on infrastructure
for (final MetadataTimingStatistic stat : metadataLogger
.getTimings()) {
final String typeName = stat.getName();
String bundleSymbolicName = typeToBsnMap.get(typeName);
if (bundleSymbolicName == null) {
// Try to look it up and cache the outcome
bundleSymbolicName = BundleFindingUtils
.findFirstBundleForTypeName(bundleContext,
typeName);
if (bundleSymbolicName == null) {
bundleSymbolicName = NOT_FOUND;
}
// Cache to avoid the lookup cost in the future
typeToBsnMap.put(typeName, bundleSymbolicName);
}
if (NOT_FOUND.equals(bundleSymbolicName)) {
continue;
}
// Only notify the UAA service if we haven't previously told
// it about this BSN (UAA service handles buffering
// internally)
if (!previouslyNotifiedBsns.contains(bundleSymbolicName)) {
// UaaRegistrationService deals with determining if the
// BSN is public (non-public BSNs are not registered)
uaaRegistrationService.registerBundleSymbolicNameUse(
bundleSymbolicName, null);
previouslyNotifiedBsns.add(bundleSymbolicName);
}
}
}
catch (final RuntimeException ignored) {
}
}
}
private static final String NOT_FOUND = "___NOT_FOUND___";
private BundleContext bundleContext;
@Reference private MetadataLogger metadataLogger;
private final Set<String> previouslyNotifiedBsns = new HashSet<String>();
private final Timer timer = new Timer();
private final Map<String, String> typeToBsnMap = new HashMap<String, String>();
@Reference private UaaRegistrationService uaaRegistrationService;
protected void activate(final ComponentContext context) {
bundleContext = context.getBundleContext();
timer.scheduleAtFixedRate(new MetadataTimerTask(), 0, 5 * 1000);
}
protected void deactivate(final ComponentContext context) {
timer.cancel();
}
}