/**
* 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.upgrade.registry;
import com.liferay.osgi.util.ServiceTrackerFactory;
import com.liferay.portal.kernel.module.framework.ModuleServiceLifecycle;
import com.liferay.portal.kernel.upgrade.UpgradeStep;
import com.liferay.portal.kernel.util.ArrayUtil;
import com.liferay.portal.upgrade.registry.UpgradeStepRegistrator.Registry;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.List;
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 Carlos Sierra Andrés
*/
@Component(immediate = true)
public class UpgradeStepRegistratorTracker {
public static List<ServiceRegistration<UpgradeStep>> register(
BundleContext bundleContext, String bundleSymbolicName,
String fromSchemaVersionString, String toSchemaVersionString,
Dictionary<String, Object> properties, UpgradeStep... upgradeSteps) {
List<ServiceRegistration<UpgradeStep>> serviceRegistrations =
new ArrayList<>();
List<UpgradeInfo> upgradeInfos = createUpgradeInfos(
fromSchemaVersionString, toSchemaVersionString, upgradeSteps);
for (UpgradeInfo upgradeInfo : upgradeInfos) {
ServiceRegistration<UpgradeStep> serviceRegistration = _register(
bundleContext, bundleSymbolicName, upgradeInfo, properties);
serviceRegistrations.add(serviceRegistration);
}
return serviceRegistrations;
}
public static List<ServiceRegistration<UpgradeStep>> register(
BundleContext bundleContext, String bundleSymbolicName,
String fromSchemaVersionString, String toSchemaVersionString,
UpgradeStep... upgradeSteps) {
return register(
bundleContext, bundleSymbolicName, fromSchemaVersionString,
toSchemaVersionString, new Hashtable<String, Object>(),
upgradeSteps);
}
protected static List<UpgradeInfo> createUpgradeInfos(
String fromSchemaVersionString, String toSchemaVersionString,
UpgradeStep... upgradeSteps) {
if (ArrayUtil.isEmpty(upgradeSteps)) {
return Collections.emptyList();
}
List<UpgradeInfo> upgradeInfos = new ArrayList<>();
String upgradeInfoFromSchemaVersionString = fromSchemaVersionString;
for (int i = 0; i < upgradeSteps.length - 1; i++) {
UpgradeStep upgradeStep = upgradeSteps[i];
String upgradeInfoToSchemaVersionString =
toSchemaVersionString + "-step" + (i - upgradeSteps.length + 1);
UpgradeInfo upgradeInfo = new UpgradeInfo(
upgradeInfoFromSchemaVersionString,
upgradeInfoToSchemaVersionString, upgradeStep);
upgradeInfos.add(upgradeInfo);
upgradeInfoFromSchemaVersionString =
upgradeInfoToSchemaVersionString;
}
UpgradeInfo upgradeInfo = new UpgradeInfo(
upgradeInfoFromSchemaVersionString, toSchemaVersionString,
upgradeSteps[upgradeSteps.length - 1]);
upgradeInfos.add(upgradeInfo);
return upgradeInfos;
}
@Activate
protected void activate(BundleContext bundleContext) {
_bundleContext = bundleContext;
_serviceTracker = ServiceTrackerFactory.open(
bundleContext, UpgradeStepRegistrator.class,
new UpgradeStepRegistratorServiceTrackerCustomizer());
}
protected List<UpgradeInfo> createUpgradeInfos(
String fromSchemaVersionString, String toSchemaVersionString,
Collection<UpgradeStep> upgradeSteps) {
return createUpgradeInfos(
fromSchemaVersionString, toSchemaVersionString,
upgradeSteps.toArray(new UpgradeStep[upgradeSteps.size()]));
}
@Deactivate
protected void deactivate() {
_serviceTracker.close();
}
@Reference(target = ModuleServiceLifecycle.DATABASE_INITIALIZED)
protected ModuleServiceLifecycle moduleServiceLifecycle;
private static ServiceRegistration<UpgradeStep> _register(
BundleContext bundleContext, String bundleSymbolicName,
UpgradeInfo upgradeInfo, Dictionary<String, Object> properties) {
properties.put("upgrade.bundle.symbolic.name", bundleSymbolicName);
properties.put("upgrade.db.type", "any");
properties.put(
"upgrade.from.schema.version",
upgradeInfo.getFromSchemaVersionString());
properties.put(
"upgrade.to.schema.version",
upgradeInfo.getToSchemaVersionString());
return bundleContext.registerService(
UpgradeStep.class, upgradeInfo.getUpgradeStep(), properties);
}
private BundleContext _bundleContext;
private ServiceTracker
<UpgradeStepRegistrator, Collection<ServiceRegistration<UpgradeStep>>>
_serviceTracker;
private class UpgradeStepRegistratorServiceTrackerCustomizer
implements ServiceTrackerCustomizer
<UpgradeStepRegistrator,
Collection<ServiceRegistration<UpgradeStep>>> {
@Override
public Collection<ServiceRegistration<UpgradeStep>> addingService(
ServiceReference<UpgradeStepRegistrator> serviceReference) {
UpgradeStepRegistrator upgradeStepRegistrator =
_bundleContext.getService(serviceReference);
if (upgradeStepRegistrator == null) {
return null;
}
Collection<ServiceRegistration<UpgradeStep>> serviceRegistrations =
new ArrayList<>();
upgradeStepRegistrator.register(
new UpgradeStepRegistry(serviceRegistrations));
return serviceRegistrations;
}
@Override
public void modifiedService(
ServiceReference<UpgradeStepRegistrator> serviceReference,
Collection<ServiceRegistration<UpgradeStep>> serviceRegistrations) {
removedService(serviceReference, serviceRegistrations);
addingService(serviceReference);
}
@Override
public void removedService(
ServiceReference<UpgradeStepRegistrator> serviceReference,
Collection<ServiceRegistration<UpgradeStep>> serviceRegistrations) {
for (ServiceRegistration<UpgradeStep> serviceRegistration :
serviceRegistrations) {
serviceRegistration.unregister();
}
}
private class UpgradeStepRegistry implements Registry {
public UpgradeStepRegistry(
Collection<ServiceRegistration<UpgradeStep>>
serviceRegistrations) {
_serviceRegistrations = serviceRegistrations;
}
@Override
public void register(
final String bundleSymbolicName, String fromSchemaVersionString,
String toSchemaVersionString, UpgradeStep... upgradeSteps) {
List<UpgradeInfo> upgradeInfos = createUpgradeInfos(
fromSchemaVersionString, toSchemaVersionString,
upgradeSteps);
for (UpgradeInfo upgradeInfo : upgradeInfos) {
ServiceRegistration<UpgradeStep> serviceRegistration =
_register(
_bundleContext, bundleSymbolicName, upgradeInfo,
new Hashtable<String, Object>());
_serviceRegistrations.add(serviceRegistration);
}
}
private final Collection<ServiceRegistration<UpgradeStep>>
_serviceRegistrations;
}
}
}