/* * 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.impl; import java.io.IOException; import java.net.URI; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import eu.esdihumboldt.hale.common.align.io.AlignmentIO; import eu.esdihumboldt.hale.common.align.io.AlignmentReader; import eu.esdihumboldt.hale.common.align.model.Alignment; import eu.esdihumboldt.hale.common.codelist.io.CodeListReader; import eu.esdihumboldt.hale.common.codelist.service.CodeListRegistry; import eu.esdihumboldt.hale.common.core.io.IOAdvisor; import eu.esdihumboldt.hale.common.core.io.IOProvider; import eu.esdihumboldt.hale.common.core.io.Value; import eu.esdihumboldt.hale.common.core.io.impl.AbstractIOAdvisor; import eu.esdihumboldt.hale.common.core.io.project.FixedProjectInfoService; import eu.esdihumboldt.hale.common.core.io.project.ProjectInfoService; import eu.esdihumboldt.hale.common.core.io.project.ProjectReader; import eu.esdihumboldt.hale.common.core.io.project.extension.internal.ActionProjectFile; import eu.esdihumboldt.hale.common.core.io.project.model.IOConfiguration; import eu.esdihumboldt.hale.common.core.io.project.model.Project; import eu.esdihumboldt.hale.common.core.io.project.model.ProjectFile; import eu.esdihumboldt.hale.common.core.io.project.util.LocationUpdater; import eu.esdihumboldt.hale.common.core.report.ReportHandler; import eu.esdihumboldt.hale.common.core.service.ServiceProvider; import eu.esdihumboldt.hale.common.headless.HeadlessIO; import eu.esdihumboldt.hale.common.instance.io.InstanceIO; import eu.esdihumboldt.hale.common.schema.SchemaSpaceID; import eu.esdihumboldt.hale.common.schema.io.SchemaIO; import eu.esdihumboldt.hale.common.schema.model.SchemaSpace; /** * Advisor for loading a project headless. Only loads schemas and alignment, and * stores them in the advisor. As such an advisor instance may be used only once * to load a single project. * * @author Simon Templer */ @SuppressWarnings("restriction") public class HeadlessProjectAdvisor extends AbstractIOAdvisor<ProjectReader> { /** * Loads an alignment. */ public class LoadAlignment extends AbstractIOAdvisor<AlignmentReader> { private Alignment alignment; @Override public void prepareProvider(AlignmentReader provider) { super.prepareProvider(provider); provider.setPathUpdater(updater); provider.setSourceSchema(sourceSchemaAdvisor.getSchema()); provider.setTargetSchema(targetSchemaAdvisor.getSchema()); } /** * @see AbstractIOAdvisor#handleResults(IOProvider) */ @Override public void handleResults(AlignmentReader provider) { alignment = provider.getAlignment(); } /** * Get the loaded alignment. * * @return the alignment */ public Alignment getAlignment() { return alignment; } } /** * Updater for project paths. */ private LocationUpdater updater; /** * Action IDs mapped to responsible advisors. */ private final Map<String, IOAdvisor<?>> advisors; /** * Advisor for loading source schemas. */ private final LoadSchemaAdvisor sourceSchemaAdvisor; /** * Advisor for loading target schemas. */ private final LoadSchemaAdvisor targetSchemaAdvisor; /** * Advisor for loading the alignment. */ private final LoadAlignment alignmentAdvisor = new LoadAlignment(); /** * The loaded project */ private Project project; /** * The report handler */ private final ReportHandler reportHandler; private final CodeListAdvisor codeListRegistry; private URI projectLocation; /** * Default constructor * * @param reportHandler the report handler to use when executing contained * I/O configurations, may be <code>null</code> * @param serviceProvider the service provider in the current context */ public HeadlessProjectAdvisor(ReportHandler reportHandler, ServiceProvider serviceProvider) { this(reportHandler, serviceProvider, null); } /** * Default constructor * * @param reportHandler the report handler to use when executing contained * I/O configurations, may be <code>null</code> * @param serviceProvider the service provider in the current context * @param additionalAdvisors a map with additional I/O advisors, action ID * mapped to advisor, may be <code>null</code> */ public HeadlessProjectAdvisor(ReportHandler reportHandler, ServiceProvider serviceProvider, Map<String, IOAdvisor<?>> additionalAdvisors) { super(); setServiceProvider(serviceProvider); this.reportHandler = reportHandler; advisors = new HashMap<String, IOAdvisor<?>>(); if (additionalAdvisors != null) { advisors.putAll(additionalAdvisors); } sourceSchemaAdvisor = new LoadSchemaAdvisor(SchemaSpaceID.SOURCE); sourceSchemaAdvisor.setServiceProvider(this); advisors.put(SchemaIO.ACTION_LOAD_SOURCE_SCHEMA, sourceSchemaAdvisor); targetSchemaAdvisor = new LoadSchemaAdvisor(SchemaSpaceID.TARGET); targetSchemaAdvisor.setServiceProvider(this); advisors.put(SchemaIO.ACTION_LOAD_TARGET_SCHEMA, targetSchemaAdvisor); codeListRegistry = new CodeListAdvisor(); codeListRegistry.setServiceProvider(this); advisors.put(CodeListReader.ACTION_ID, codeListRegistry); } @Override public void updateConfiguration(ProjectReader provider) { super.updateConfiguration(provider); // Map<String, ProjectFile> projectFiles = ProjectIO.createDefaultProjectFiles(); Map<String, ProjectFile> projectFiles = new HashMap<String, ProjectFile>(); // create only alignment project file projectFiles.put(AlignmentIO.PROJECT_FILE_ALIGNMENT, new ActionProjectFile(AlignmentIO.ACTION_LOAD_ALIGNMENT, // null, // auto-detect provider for loading new HashMap<String, Value>(), // no parameters givens null, null, null, this) // give null for save related // parts // (should not be called) { @Override protected IOAdvisor<?> getLoadAdvisor(String loadActionId, ServiceProvider serviceProvider) { return alignmentAdvisor; } }); provider.setProjectFiles(projectFiles); } @Override public void handleResults(ProjectReader provider) { project = provider.getProject(); projectLocation = provider.getSource().getLocation(); updater = new LocationUpdater(project, projectLocation); // no need to keep relative paths in the headless environment updater.updateProject(false); // inject project into advisors (mappable types) sourceSchemaAdvisor.setProject(project); targetSchemaAdvisor.setProject(project); // execute loaded I/O configurations List<IOConfiguration> confs = new ArrayList<IOConfiguration>(project.getResources()); // but remove source data actions first Iterator<IOConfiguration> it = confs.iterator(); while (it.hasNext()) { if (InstanceIO.ACTION_LOAD_SOURCE_DATA.equals(it.next().getActionId())) { it.remove(); } } try { HeadlessIO.executeConfigurations(confs, advisors, reportHandler, this); } catch (IOException e) { throw new RuntimeException(e.getMessage(), e); } Map<String, ProjectFile> projectFiles = provider.getProjectFiles(); // apply remaining project files for (ProjectFile file : projectFiles.values()) { file.apply(); } } @SuppressWarnings("unchecked") @Override public <X> X getService(Class<X> serviceInterface) { if (ProjectInfoService.class.equals(serviceInterface) && project != null) { return (X) new FixedProjectInfoService(project, projectLocation); } return super.getService(serviceInterface); } /** * Get the loaded project. Can be retrieved after the project was * successfully loaded. * * @return the project */ public Project getProject() { return project; } /** * Get the alignment between source and target schemas. Can be retrieved * after the project was successfully loaded. * * @return the alignment */ public Alignment getAlignment() { return alignmentAdvisor.getAlignment(); } /** * Get the source schemas. Can be retrieved after the project was * successfully loaded. * * @return the source schemas */ public SchemaSpace getSourceSchema() { return sourceSchemaAdvisor.getSchema(); } /** * Get the target schemas. Can be retrieved after the project was * successfully loaded. * * @return the target schemas */ public SchemaSpace getTargetSchema() { return targetSchemaAdvisor.getSchema(); } /** * Get the registry of code lists loaded in the project. * * @return the code list registry */ public CodeListRegistry getCodeListRegistry() { return codeListRegistry; } }