/** * 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.configuration.admin.web.internal.util; import com.liferay.configuration.admin.web.internal.model.ConfigurationModel; import com.liferay.portal.configuration.metatype.definitions.ExtendedMetaTypeInformation; import com.liferay.portal.configuration.metatype.definitions.ExtendedMetaTypeService; import com.liferay.portal.kernel.util.ArrayUtil; import com.liferay.portal.kernel.util.ReflectionUtil; import com.liferay.portal.kernel.util.StringBundler; import com.liferay.portal.kernel.util.StringPool; import com.liferay.portal.kernel.util.Validator; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; import org.osgi.framework.InvalidSyntaxException; import org.osgi.service.cm.Configuration; import org.osgi.service.cm.ConfigurationAdmin; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Reference; /** * @author Michael C. Han */ @Component(immediate = true, service = ConfigurationModelRetriever.class) public class ConfigurationModelRetrieverImpl implements ConfigurationModelRetriever { @Override public Map<String, Set<ConfigurationModel>> categorizeConfigurationModels( Map<String, ConfigurationModel> configurationModels) { Map<String, Set<ConfigurationModel>> categorizedConfigurationModels = new HashMap<>(); for (ConfigurationModel configurationModel : configurationModels.values()) { String configurationCategory = configurationModel.getCategory(); Set<ConfigurationModel> curConfigurationModels = categorizedConfigurationModels.get(configurationCategory); if (curConfigurationModels == null) { curConfigurationModels = new TreeSet<>( getConfigurationModelComparator()); categorizedConfigurationModels.put( configurationCategory, curConfigurationModels); } curConfigurationModels.add(configurationModel); } return categorizedConfigurationModels; } @Override public Configuration getConfiguration(String pid) { try { String pidFilter = getPidFilterString(pid, false); Configuration[] configurations = _configurationAdmin.listConfigurations(pidFilter); if (configurations != null) { return configurations[0]; } } catch (InvalidSyntaxException | IOException e) { ReflectionUtil.throwException(e); } return null; } @Override public List<String> getConfigurationCategories( Map<String, Set<ConfigurationModel>> categorizedConfigurationModels) { Set<String> configurationCategories = new TreeSet<>( getConfigurationCategoryComparator()); configurationCategories.addAll(categorizedConfigurationModels.keySet()); return new ArrayList<>(configurationCategories); } @Override public Map<String, ConfigurationModel> getConfigurationModels() { return getConfigurationModels((String)null); } @Override public Map<String, ConfigurationModel> getConfigurationModels( Bundle bundle) { Map<String, ConfigurationModel> configurationModels = new HashMap<>(); collectConfigurationModels(bundle, configurationModels, true, null); collectConfigurationModels(bundle, configurationModels, false, null); return configurationModels; } @Override public Map<String, ConfigurationModel> getConfigurationModels( String locale) { Map<String, ConfigurationModel> configurationModels = new HashMap<>(); Bundle[] bundles = _bundleContext.getBundles(); for (Bundle bundle : bundles) { if (bundle.getState() != Bundle.ACTIVE) { continue; } collectConfigurationModels( bundle, configurationModels, true, locale); collectConfigurationModels( bundle, configurationModels, false, locale); } return configurationModels; } @Override public List<ConfigurationModel> getFactoryInstances( ConfigurationModel factoryConfigurationModel) throws IOException { Configuration[] configurations = getFactoryConfigurations( factoryConfigurationModel.getFactoryPid()); if (configurations == null) { return Collections.emptyList(); } List<ConfigurationModel> factoryInstances = new ArrayList<>(); for (Configuration configuration : configurations) { ConfigurationModel curConfigurationModel = new ConfigurationModel( factoryConfigurationModel, configuration, factoryConfigurationModel.getBundleSymbolicName(), configuration.getBundleLocation(), false); factoryInstances.add(curConfigurationModel); } return factoryInstances; } @Activate protected void activate(BundleContext bundleContext) { _bundleContext = bundleContext; } protected void collectConfigurationModels( Bundle bundle, Map<String, ConfigurationModel> configurationModels, boolean factory, String locale) { ExtendedMetaTypeInformation extendedMetaTypeInformation = _extendedMetaTypeService.getMetaTypeInformation(bundle); if (extendedMetaTypeInformation == null) { return; } List<String> pids = new ArrayList<>(); if (factory) { Collections.addAll( pids, extendedMetaTypeInformation.getFactoryPids()); } else { Collections.addAll(pids, extendedMetaTypeInformation.getPids()); } for (String pid : pids) { ConfigurationModel configurationModel = getConfigurationModel( bundle, pid, factory, locale); if (configurationModel == null) { continue; } configurationModels.put(pid, configurationModel); } } protected Configuration getCompanyDefaultConfiguration(String factoryPid) { Configuration configuration = null; try { Configuration[] factoryConfigurations = getFactoryConfigurations( factoryPid, ConfigurationModel.PROPERTY_KEY_COMPANY_ID, ConfigurationModel.PROPERTY_VALUE_COMPANY_ID_DEFAULT); if (ArrayUtil.isNotEmpty(factoryConfigurations)) { configuration = factoryConfigurations[0]; } } catch (IOException ioe) { ReflectionUtil.throwException(ioe); } return configuration; } protected Comparator<String> getConfigurationCategoryComparator() { return new ConfigurationCategoryComparator(); } protected ConfigurationModel getConfigurationModel( Bundle bundle, String pid, boolean factory, String locale) { ExtendedMetaTypeInformation metaTypeInformation = _extendedMetaTypeService.getMetaTypeInformation(bundle); if (metaTypeInformation == null) { return null; } ConfigurationModel configurationModel = new ConfigurationModel( metaTypeInformation.getObjectClassDefinition(pid, locale), getConfiguration(pid), bundle.getSymbolicName(), StringPool.QUESTION, factory); if (configurationModel.isCompanyFactory()) { Configuration configuration = getCompanyDefaultConfiguration(pid); configurationModel = new ConfigurationModel( configurationModel.getExtendedObjectClassDefinition(), configuration, bundle.getSymbolicName(), StringPool.QUESTION, configurationModel.isFactory()); } return configurationModel; } protected Comparator<ConfigurationModel> getConfigurationModelComparator() { return new ConfigurationModelComparator(); } protected Configuration[] getFactoryConfigurations(String factoryPid) throws IOException { return getFactoryConfigurations(factoryPid, null, null); } protected Configuration[] getFactoryConfigurations( String factoryPid, String property, String value) throws IOException { Configuration[] configurations = null; StringBundler sb = new StringBundler(13); if (Validator.isNotNull(property) && Validator.isNotNull(value)) { sb.append(StringPool.OPEN_PARENTHESIS); sb.append(StringPool.AMPERSAND); } sb.append(StringPool.OPEN_PARENTHESIS); sb.append(ConfigurationAdmin.SERVICE_FACTORYPID); sb.append(StringPool.EQUAL); sb.append(factoryPid); sb.append(StringPool.CLOSE_PARENTHESIS); if (Validator.isNotNull(property) && Validator.isNotNull(value)) { sb.append(StringPool.OPEN_PARENTHESIS); sb.append(property); sb.append(StringPool.EQUAL); sb.append(value); sb.append(StringPool.CLOSE_PARENTHESIS); sb.append(StringPool.CLOSE_PARENTHESIS); } try { configurations = _configurationAdmin.listConfigurations( sb.toString()); } catch (InvalidSyntaxException ise) { ReflectionUtil.throwException(ise); } return configurations; } protected String getPidFilterString(String pid, boolean factory) { StringBundler sb = new StringBundler(5); sb.append(StringPool.OPEN_PARENTHESIS); if (factory) { sb.append(ConfigurationAdmin.SERVICE_FACTORYPID); } else { sb.append(Constants.SERVICE_PID); } sb.append(StringPool.EQUAL); sb.append(pid); sb.append(StringPool.CLOSE_PARENTHESIS); return sb.toString(); } private BundleContext _bundleContext; @Reference private ConfigurationAdmin _configurationAdmin; @Reference private ExtendedMetaTypeService _extendedMetaTypeService; private static class ConfigurationCategoryComparator implements Comparator<String> { @Override public int compare( String configurationCategory1, String configurationCategory2) { if (configurationCategory1.equals("other")) { return 1; } else if (configurationCategory1.equals("web-experience")) { return -1; } else if (configurationCategory1.equals("collaboration")) { if (configurationCategory2.equals("web-experience")) { return 1; } else { return -1; } } else if (configurationCategory1.equals("productivity")) { if (configurationCategory2.equals("collaboration") || configurationCategory2.equals("web-experience")) { return 1; } else { return -1; } } return configurationCategory1.compareTo(configurationCategory2); } } private static class ConfigurationModelComparator implements Comparator<ConfigurationModel> { @Override public int compare( ConfigurationModel configurationModel1, ConfigurationModel configurationModel2) { String name1 = configurationModel1.getName(); String name2 = configurationModel2.getName(); return name1.compareTo(name2); } } }