/* * Copyright (c) 2013 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.server.templates; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import java.util.Properties; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.Multimap; import eu.esdihumboldt.hale.common.align.io.AlignmentIO; import eu.esdihumboldt.hale.common.align.io.impl.internal.JaxbToAlignment; import eu.esdihumboldt.hale.common.align.io.impl.internal.generated.AlignmentType; import eu.esdihumboldt.hale.common.align.io.impl.internal.generated.CellType; import eu.esdihumboldt.hale.common.core.io.project.model.IOConfiguration; import eu.esdihumboldt.hale.common.core.io.project.model.IOConfigurationResource; import eu.esdihumboldt.hale.common.core.io.project.model.Project; import eu.esdihumboldt.hale.common.core.io.project.model.Resource; import eu.esdihumboldt.hale.common.core.io.project.util.LocationUpdater; import eu.esdihumboldt.hale.common.headless.report.ReportFile; import eu.esdihumboldt.hale.common.headless.scavenger.ProjectReference; /** * Template project reference. * * @author Simon Templer */ @SuppressWarnings("restriction") public class TemplateProject extends ProjectReference<Void> { private boolean valid; private String notValidMessage; private int definedRelations = 0; private final Multimap<String, Resource> resources = ArrayListMultimap.create(); /** * @see ProjectReference#ProjectReference(File, String, String, Properties) */ public TemplateProject(File projectFolder, String overrideProjectFile, String projectId, Properties defaultSettings) throws IOException { super(projectFolder, overrideProjectFile, projectId, defaultSettings); } /** * @return the resources */ public Multimap<String, Resource> getResources() { return ImmutableMultimap.copyOf(resources); } /** * States if the template is valid. * * @return <code>true</code> if the template is valid, <code>false</code> * otherwise */ public boolean isValid() { return getProjectInfo() != null && valid; } /** * @return the notValidMessage */ public String getNotValidMessage() { return notValidMessage; } /** * @return the number defined relations, not necessarily exact, zero may * mean unknown */ public int getDefinedRelations() { return definedRelations; } @Override protected void onSuccess(Void context, String projectId, File projectFile, Project project, ReportFile reportFile) { super.onSuccess(context, projectId, projectFile, project, reportFile); // update locations in project file LocationUpdater updater = new LocationUpdater(project, projectFile.toURI()); updater.updateProject(false); resources.clear(); List<Path> invalidSources = new ArrayList<>(); Path projectFolder = getProjectFolder().toPath(); // validate resources for (IOConfiguration config : project.getResources()) { Resource resource = new IOConfigurationResource(config, getProjectFile().toURI()); // check if file URIs are valid and inside project folder URI source = resource.getSource(); if (source != null) { Path path = null; if (source.getScheme() == null) { // is a relative URI path = projectFile.toPath().resolve(source.toString()).normalize(); } else if ("file".equals(source.getScheme())) { // is a file URI path = Paths.get(source).normalize(); } if (path != null) { // only file references are validated if (!path.startsWith(projectFolder) || !Files.exists(path)) { // invalid source invalidSources.add(path); } } } resources.put(resource.getActionId(), resource); } valid = invalidSources.isEmpty(); if (!valid) { StringBuilder builder = new StringBuilder( "Files referenced by the project could not be found: "); for (int i = 0; i < invalidSources.size(); i++) { if (i > 0) builder.append(", "); Path path = invalidSources.get(i); builder.append(path.getFileName().toString()); } notValidMessage = builder.toString(); } else { notValidMessage = ""; } // additionally, try to find out cell count definedRelations = 0; // check if default alignment file exists try { File defAlignmentFile = new File(URI.create(projectFile.toURI().toASCIIString() + "." + AlignmentIO.PROJECT_FILE_ALIGNMENT)); if (defAlignmentFile.exists()) { // check alignment size try (InputStream in = new BufferedInputStream(new FileInputStream(defAlignmentFile))) { /* * Try loading the file with JAXB - only supports 2.6+ * projects. */ AlignmentType alignment = JaxbToAlignment.load(in, null); // XXX ignoring base alignments int count = 0; for (Object element : alignment.getCellOrModifier()) { if (element instanceof CellType) { count++; } } definedRelations = count; } catch (Exception e) { // ignore } } } catch (Exception e) { // ignore } } @Override protected void onFailure(Void context, String projectId) { super.onFailure(context, projectId); valid = false; notValidMessage = "Project could not be loaded"; definedRelations = 0; resources.clear(); } @Override protected void onNotAvailable(Void context, String projectId) { super.onNotAvailable(context, projectId); valid = false; notValidMessage = "No project file found"; definedRelations = 0; resources.clear(); } }