/** * 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.configuration.extender.internal; import com.liferay.osgi.felix.util.AbstractExtender; import com.liferay.portal.configuration.extender.BundleStorage; import com.liferay.portal.configuration.extender.ConfigurationDescriptionFactory; import com.liferay.portal.configuration.extender.NamedConfigurationContent; import com.liferay.portal.configuration.extender.NamedConfigurationContentFactory; import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.Collection; import java.util.Dictionary; import java.util.Enumeration; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import org.apache.felix.utils.extender.Extension; import org.apache.felix.utils.log.Logger; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; 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.Deactivate; import org.osgi.service.component.annotations.Reference; import org.osgi.service.component.annotations.ReferenceCardinality; import org.osgi.service.component.annotations.ReferencePolicy; import org.osgi.service.component.annotations.ReferencePolicyOption; /** * @author Carlos Sierra Andrés * @author Miguel Pastor */ @Component(immediate = true) public class ConfiguratorExtender extends AbstractExtender { @Activate protected void activate(BundleContext bundleContext) throws Exception { _logger = new Logger(bundleContext); start(bundleContext); } @Reference( cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY, unbind = "removeConfigurationDescriptionFactory" ) protected void addConfigurationDescriptionFactory( ConfigurationDescriptionFactory configurationDescriptionFactory) { _configurationDescriptionFactories.add(configurationDescriptionFactory); } @Reference( cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY, unbind = "removeNamedConfigurationContentFactory" ) protected void addNamedConfigurationContentFactory( NamedConfigurationContentFactory namedConfigurationContentFactory) { _namedConfigurationContentFactories.add( namedConfigurationContentFactory); } @Deactivate protected void deactivate(BundleContext bundleContext) throws Exception { stop(bundleContext); } @Override protected void debug(Bundle bundle, String s) { _logger.log(Logger.LOG_DEBUG, "[" + bundle + "] " + s); } @Override protected Extension doCreateExtension(Bundle bundle) throws Exception { Collection<NamedConfigurationContent> namedConfigurationContents = new ArrayList<>(); for (NamedConfigurationContentFactory namedConfigurationContentFactory : _namedConfigurationContentFactories) { try { List<NamedConfigurationContent> contents = namedConfigurationContentFactory.create( new BundleStorageImpl(bundle)); if (contents != null) { namedConfigurationContents.addAll(contents); } } catch (Throwable t) { _logger.log(Logger.LOG_INFO, t.getMessage(), t); } } if (namedConfigurationContents.isEmpty()) { return null; } return new ConfiguratorExtension( _configurationAdmin, new Logger(bundle.getBundleContext()), bundle.getSymbolicName(), namedConfigurationContents, _configurationDescriptionFactories); } @Override protected void error(String s, Throwable throwable) { _logger.log(Logger.LOG_ERROR, s, throwable); } protected void removeConfigurationDescriptionFactory( ConfigurationDescriptionFactory configurationDescriptionFactory) { _configurationDescriptionFactories.remove( configurationDescriptionFactory); } protected void removeNamedConfigurationContentFactory( NamedConfigurationContentFactory namedConfigurationContentFactory) { _namedConfigurationContentFactories.remove( namedConfigurationContentFactory); } @Reference(unbind = "-") protected void setConfigurationAdmin( ConfigurationAdmin configurationAdmin) { _configurationAdmin = configurationAdmin; } @Override protected void warn(Bundle bundle, String s, Throwable throwable) { _logger.log(Logger.LOG_WARNING, "[" + bundle + "] " + s); } private ConfigurationAdmin _configurationAdmin; private final Collection<ConfigurationDescriptionFactory> _configurationDescriptionFactories = new CopyOnWriteArrayList<>(); private Logger _logger; private final Collection<NamedConfigurationContentFactory> _namedConfigurationContentFactories = new CopyOnWriteArrayList<>(); private static class BundleStorageImpl implements BundleStorage { public BundleStorageImpl(Bundle bundle) { _bundle = bundle; } @Override public Enumeration<URL> findEntries( String root, String pattern, boolean recurse) { return _bundle.findEntries(root, pattern, recurse); } @Override public long getBundleId() { return _bundle.getBundleId(); } @Override public URL getEntry(String name) { return _bundle.getEntry(name); } @Override public Enumeration<String> getEntryPaths(String name) { return _bundle.getEntryPaths(name); } @Override public Dictionary<String, String> getHeaders() { return _bundle.getHeaders(); } @Override public String getLocation() { return _bundle.getLocation(); } @Override public URL getResource(String name) { return _bundle.getResource(name); } @Override public Enumeration<URL> getResources(String name) throws IOException { return _bundle.getResources(name); } @Override public String getSymbolicName() { return _bundle.getSymbolicName(); } private final Bundle _bundle; } }