/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. */ package com.liferay.portal.search.internal; import com.liferay.portal.instance.lifecycle.PortalInstanceLifecycleListener; import com.liferay.portal.kernel.backgroundtask.BackgroundTaskManager; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.module.framework.ModuleServiceLifecycle; import com.liferay.portal.kernel.search.BaseSearcher; import com.liferay.portal.kernel.search.IndexWriterHelper; import com.liferay.portal.kernel.search.Indexer; import com.liferay.portal.kernel.search.SearchEngine; import com.liferay.portal.kernel.util.GetterUtil; import com.liferay.portal.kernel.util.HashMapDictionary; import com.liferay.portal.kernel.util.Props; import com.liferay.portal.kernel.util.PropsKeys; import com.liferay.portal.kernel.util.Validator; import com.liferay.portal.search.internal.instance.lifecycle.IndexOnStartupPortalInstanceLifecycleListener; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; import org.osgi.framework.ServiceRegistration; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Deactivate; import org.osgi.service.component.annotations.Reference; import org.osgi.util.tracker.ServiceTracker; import org.osgi.util.tracker.ServiceTrackerCustomizer; /** * @author Michael C. Han */ @Component(immediate = true) public class IndexOnStartupIndexerServiceCustomizer implements ServiceTrackerCustomizer<Indexer, Indexer> { @Override public Indexer addingService(ServiceReference<Indexer> serviceReference) { Indexer<?> indexer = _bundleContext.getService(serviceReference); boolean indexerIndexOnStartup = GetterUtil.getBoolean( serviceReference.getProperty(PropsKeys.INDEX_ON_STARTUP), true); String className = indexer.getClassName(); if (!indexerIndexOnStartup || Validator.isNull(className) || isBaseSearcher(indexer.getClass())) { return indexer; } synchronized (_serviceRegistrations) { if (_serviceRegistrations.containsKey(className)) { if (_log.isInfoEnabled()) { _log.info( "Skip duplicate service registration for " + className); } return indexer; } PortalInstanceLifecycleListener portalInstanceLifecycleListener = new IndexOnStartupPortalInstanceLifecycleListener( _indexWriterHelper, _props, className); ServiceRegistration<PortalInstanceLifecycleListener> serviceRegistration = _bundleContext.registerService( PortalInstanceLifecycleListener.class, portalInstanceLifecycleListener, new HashMapDictionary<String, Object>()); _serviceRegistrations.put(className, serviceRegistration); } return indexer; } @Override public void modifiedService( ServiceReference<Indexer> serviceReference, Indexer indexer) { } @Override public void removedService( ServiceReference<Indexer> serviceReference, Indexer indexer) { synchronized (_serviceRegistrations) { ServiceRegistration<PortalInstanceLifecycleListener> serviceRegistration = _serviceRegistrations.remove( indexer.getClassName()); if (serviceRegistration != null) { serviceRegistration.unregister(); } } } @Activate protected void activate(BundleContext bundleContext) { _bundleContext = bundleContext; _serviceTracker = new ServiceTracker<>( bundleContext, Indexer.class, this); _serviceTracker.open(); } @Deactivate protected void deactivate() { Set<String> removedIndexerClassNames = new HashSet<>(); synchronized (_serviceRegistrations) { for (Map.Entry <String, ServiceRegistration <PortalInstanceLifecycleListener>> entry : _serviceRegistrations.entrySet()) { ServiceRegistration<?> serviceRegistration = entry.getValue(); serviceRegistration.unregister(); removedIndexerClassNames.add(entry.getKey()); } for (String removedIndexerClassName : removedIndexerClassNames) { _serviceRegistrations.remove(removedIndexerClassName); } } _bundleContext = null; if (_serviceTracker != null) { _serviceTracker.close(); } } protected boolean isBaseSearcher(Class indexerClass) { while ((indexerClass != null) && !Object.class.equals(indexerClass)) { if (indexerClass.equals(BaseSearcher.class)) { return true; } indexerClass = indexerClass.getSuperclass(); } return false; } @Reference(target = ModuleServiceLifecycle.PORTAL_INITIALIZED, unbind = "-") protected void setModuleServiceLifecycle( ModuleServiceLifecycle moduleServiceLifecycle) { } @Reference(target = "(search.engine.id=SYSTEM_ENGINE)", unbind = "-") protected void setSearchEngine(SearchEngine searchEngine) { } private static final Log _log = LogFactoryUtil.getLog( IndexOnStartupIndexerServiceCustomizer.class); @Reference private BackgroundTaskManager _backgroundTaskManager; private BundleContext _bundleContext; @Reference private IndexWriterHelper _indexWriterHelper; @Reference private Props _props; private final Map <String, ServiceRegistration<PortalInstanceLifecycleListener>> _serviceRegistrations = new HashMap<>(); private ServiceTracker<Indexer, Indexer> _serviceTracker; }