/** * */ package ecologylab.bigsemantics.collecting; import java.lang.reflect.Field; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import ecologylab.bigsemantics.metadata.builtins.Document; import ecologylab.bigsemantics.metadata.scalar.MetadataParsedURL; import ecologylab.net.ParsedURL; /** * Monitors document downloading. Any object can * * @author quyin * */ public class DocumentDownloadingMonitor { private SemanticsGlobalScope semanticsScope; private ConcurrentMap<ParsedURL, Set<DocumentDownloadedEventHandler>> handlers; DocumentDownloadingMonitor(SemanticsGlobalScope semanticsScope) { this.semanticsScope = semanticsScope; this.handlers = new ConcurrentHashMap<ParsedURL, Set<DocumentDownloadedEventHandler>>(); } public SemanticsGlobalScope getSemanticsScope() { return semanticsScope; } /** * * @param hostObject * The object that is holding the Document that may change. * @param location * The location that is listened for downloading. * @param field * The Field that corresponds to the document to be downloaded, in hostObject. * @param listener * The handler object that will actually handle the document downloaded event. */ public void listenForDocumentDownloading(Object hostObject, ParsedURL location, Field field, DocumentDownloadedEventHandler listener) { if (location != null) { listener.hostObject = hostObject; listener.location = location; listener.field = field; Set<DocumentDownloadedEventHandler> listenerSet = handlers.get(location); if (listenerSet == null) { synchronized (handlers) { listenerSet = handlers.get(location); if (listenerSet == null) { listenerSet = new HashSet<DocumentDownloadedEventHandler>(); handlers.put(location, listenerSet); } } } synchronized (listenerSet) { listenerSet.add(listener); } } } public Set<DocumentDownloadedEventHandler> getListenersForDocument(Document downloadedDoc) { Set<DocumentDownloadedEventHandler> result = null; ParsedURL location = downloadedDoc.getLocation(); result = getListenersForLocation(location, result); List<MetadataParsedURL> additionalLocations = downloadedDoc.getAdditionalLocations(); if (additionalLocations != null && additionalLocations.size() > 0) { for (MetadataParsedURL mpurl : additionalLocations) { result = getListenersForLocation(mpurl.getValue(), result); } } return result; } public Set<DocumentDownloadedEventHandler> getListenersForLocation(ParsedURL purl, Set<DocumentDownloadedEventHandler> result) { Set<DocumentDownloadedEventHandler> newResult = handlers.get(purl); if (newResult != null) { synchronized (handlers) { handlers.remove(purl); } if (result == null) return newResult; else synchronized (newResult) { result.addAll(newResult); } } return result; } }