/* * Copyright (c) 2012 Data Harmonisation Panel * * All rights reserved. This program and the accompanying materials are made * available under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution. If not, see <http://www.gnu.org/licenses/>. * * Contributors: * Data Harmonisation Panel <http://www.dhpanel.eu> */ package eu.esdihumboldt.hale.common.headless; import java.io.IOException; import java.text.MessageFormat; import java.util.List; import java.util.Map; import de.fhg.igd.eclipse.util.extension.ExtensionObjectFactoryCollection; import de.fhg.igd.eclipse.util.extension.FactoryFilter; import de.fhg.igd.slf4jplus.ALogger; import de.fhg.igd.slf4jplus.ALoggerFactory; import de.fhg.igd.slf4jplus.ATransaction; import eu.esdihumboldt.hale.common.core.io.CachingImportProvider; import eu.esdihumboldt.hale.common.core.io.IOAdvisor; import eu.esdihumboldt.hale.common.core.io.IOProvider; import eu.esdihumboldt.hale.common.core.io.ProgressIndicator; import eu.esdihumboldt.hale.common.core.io.extension.IOAdvisorExtension; import eu.esdihumboldt.hale.common.core.io.extension.IOAdvisorFactory; import eu.esdihumboldt.hale.common.core.io.extension.IOProviderDescriptor; import eu.esdihumboldt.hale.common.core.io.extension.IOProviderExtension; import eu.esdihumboldt.hale.common.core.io.project.model.IOConfiguration; import eu.esdihumboldt.hale.common.core.io.report.IOReport; import eu.esdihumboldt.hale.common.core.io.report.IOReporter; import eu.esdihumboldt.hale.common.core.report.ReportHandler; import eu.esdihumboldt.hale.common.core.service.ServiceProvider; import eu.esdihumboldt.hale.common.headless.impl.ProjectTransformationEnvironment; /** * Utilities for headless execution of I/O configurations and providers. * * @author Simon Templer */ public abstract class HeadlessIO { private static final ALogger log = ALoggerFactory .getLogger(ProjectTransformationEnvironment.class); /** * Execute a set of I/O configurations. Configurations for which no advisor * is provided are ignored. * * @param configurations the I/O configurations * @param advisors map of advisors, action ID mapped to responsible advisor * @param reportHandler the report handler, may be <code>null</code> * @param serviceProvider the service provider * @throws IOException if an error occurs executing a configuration */ public static void executeConfigurations(final List<IOConfiguration> configurations, Map<String, IOAdvisor<?>> advisors, ReportHandler reportHandler, ServiceProvider serviceProvider) throws IOException { // TODO sort by dependencies? for (IOConfiguration conf : configurations) { executeConfiguration(conf, advisors, reportHandler, serviceProvider); } } /** * Execute a single I/O configuration. If no matching advisor is given for * the configuration, first the extension point is queried for an advisor, * if not found it is ignored. * * @param conf the I/O configuration * @param advisors map of advisors, action ID mapped to responsible advisor * @param reportHandler the report handler, may be <code>null</code> * @param serviceProvider the service provider * @throws IOException if an error occurs executing a configuration */ public static void executeConfiguration(IOConfiguration conf, Map<String, IOAdvisor<?>> advisors, ReportHandler reportHandler, ServiceProvider serviceProvider) throws IOException { // get advisor ... final String actionId = conf.getActionId(); IOAdvisor<?> advisor = advisors.get(actionId); if (advisor == null) { // try to find registered advisor for action (e.g. lookup) List<IOAdvisorFactory> regAdvisors = IOAdvisorExtension.getInstance() .getFactories(new FactoryFilter<IOAdvisor<?>, IOAdvisorFactory>() { @Override public boolean acceptFactory(IOAdvisorFactory factory) { return factory.getActionID().equals(actionId); } @Override public boolean acceptCollection( ExtensionObjectFactoryCollection<IOAdvisor<?>, IOAdvisorFactory> collection) { return true; } }); if (regAdvisors != null && !regAdvisors.isEmpty()) { try { advisor = regAdvisors.get(0).createAdvisor(serviceProvider); log.info(MessageFormat.format( "No advisor for action {0} given, using advisor registered through extension point.", actionId)); } catch (Exception e) { log.error(MessageFormat .format("Failed to load registered advisor for action {0}.", actionId)); if (advisor != null) { // shouldn't happen, but seems to happen anyway log.error("Advisor is set in spite of error", e); } } } } if (advisor == null) { log.info(MessageFormat.format( "No advisor for action {0} given, I/O configuration is ignored.", actionId)); // ignore this configuration return; } // ... and provider IOProvider provider = loadProvider(conf); if (provider != null) { if (serviceProvider != null) { // set service provider, just in case the advisor does not do it provider.setServiceProvider(serviceProvider); } // execute provider executeProvider(provider, advisor, null, reportHandler); // XXX progress?!! } else { throw new IOException(MessageFormat.format( "Could not execute I/O configuration, provider with ID {0} not found.", conf.getProviderId())); } } /** * Load and configure the I/O provider specified by the given I/O * configuration. * * @param conf the I/O configuration * @return the provider or <code>null</code> if it was not found or could * not be created */ public static IOProvider loadProvider(IOConfiguration conf) { IOProvider provider = null; IOProviderDescriptor descriptor = IOProviderExtension.getInstance() .getFactory(conf.getProviderId()); if (descriptor != null) { try { provider = descriptor.createExtensionObject(); // configure settings provider.loadConfiguration(conf.getProviderConfiguration()); if (provider instanceof CachingImportProvider) { ((CachingImportProvider) provider).setCache(conf.getCache()); } } catch (Exception e) { log.error("Could not instantiate I/O provider.", e); } } return provider; } /** * Execute the given I/O provider with the given I/O advisor. * * @param provider the I/O provider * @param advisor the I/O advisor * @param progress the progress indicator, may be <code>null</code> * @param reportHandler the report handler, may be <code>null</code> * @throws IOException if executing the provider fails */ @SuppressWarnings("unchecked") public static void executeProvider(final IOProvider provider, @SuppressWarnings("rawtypes") final IOAdvisor advisor, ProgressIndicator progress, ReportHandler reportHandler) throws IOException { IOReporter reporter = provider.createReporter(); ATransaction trans = log.begin(reporter.getTaskName()); try { // use advisor to configure provider advisor.prepareProvider(provider); advisor.updateConfiguration(provider); // execute IOReport report = provider.execute(progress); if (reportHandler != null) { reportHandler.publishReport(report); } // handle results if (report.isSuccess()) { advisor.handleResults(provider); } else { throw new IOException( "Executing I/O provider not successful: " + report.getSummary()); } } catch (Exception e) { throw new IOException("Error executing an I/O provider.", e); } finally { trans.end(); } } }