blob: caa286f30d00ce37c8b1fa38d4d6617a79515253 [file] [log] [blame]
/********************************************************************************
* Copyright (c) 2015-2019 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
********************************************************************************/
package org.eclipse.mdm.apicopy.boundary;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.ws.rs.core.Response;
import org.eclipse.mdm.api.base.ConnectionException;
import org.eclipse.mdm.api.base.ServiceNotProvidedException;
import org.eclipse.mdm.api.dflt.ApplicationContext;
import org.eclipse.mdm.api.dflt.ApplicationContextFactory;
import org.eclipse.mdm.api.dflt.EntityManager;
import org.eclipse.mdm.api.dflt.model.Project;
import org.eclipse.mdm.apicopy.control.ApiCopyException;
import org.eclipse.mdm.apicopy.control.ApiCopyService;
import org.eclipse.mdm.apicopy.control.ApiCopyServiceImpl;
import org.eclipse.mdm.apicopy.entity.CopyStatusResponse;
import org.eclipse.mdm.apicopy.entity.CopyStatusResponse.State;
import org.eclipse.mdm.connector.boundary.ConnectorService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
/**
* Service for importing an ATFX file into a MDM datasource.
*
*/
@Stateless
public class ImportService {
private static final Logger LOG = LoggerFactory.getLogger(ImportService.class);
// TODO make temp path configurable
private static final Path TMP = Paths.get(System.getProperty("java.io.tmpdir"));
@Inject
private ConnectorService connectorService;
private ApiCopyService apiCopyService = new ApiCopyServiceImpl();
private final String atfxContextFactoryClassname = "org.eclipse.mdm.api.atfxadapter.ATFXContextFactory";
/**
* Default public constructor
*/
public ImportService() {
}
/**
* Imports an ATFX file into the provided datasource.
*
* @param atfxFileSupplier returns a {@link Path} to an ATFX file. Accompanying
* binary files are expected to be on the same folder.
* @param dstContextName target datasource of the import
* @return
*/
public Response importAtfx(Function<Path, Path> atfxFileSupplier, String dstContextName) {
ApplicationContext contextDst = connectorService.getContextByName(dstContextName);
ApplicationContext contextSrc = null;
Path tmpDir = null;
try {
tmpDir = Files.createTempDirectory(TMP, "atfximport");
Path atfxFile = atfxFileSupplier.apply(tmpDir);
Map<String, String> params = ImmutableMap.of("atfxfile", atfxFile.toFile().getAbsolutePath(),
"freetext.active", "false");
contextSrc = connectContext(atfxContextFactoryClassname, params);
List<Project> projects = contextSrc.getEntityManager()
.orElseThrow(() -> new ServiceNotProvidedException(EntityManager.class)).loadAll(Project.class);
apiCopyService.newApiCopyTask(contextSrc, contextDst).copy(projects);
CopyStatusResponse response = new CopyStatusResponse();
response.setState(State.OK);
return Response.ok(response).build();
} catch (ServiceNotProvidedException e) {
throw new ApiCopyException("Could not retrive all required services from ATFX application context!", e);
} catch (ConnectionException e) {
throw new ApiCopyException("Could not create ATFX application context!", e);
} catch (IOException e) {
throw new ApiCopyException("Cold not create temporary directory!", e);
} finally {
if (contextSrc != null) {
try {
contextSrc.close();
} catch (ConnectionException e) {
LOG.warn("Could not close application context!", e);
}
}
if (tmpDir != null) {
try {
deleteDirectory(tmpDir);
} catch (IOException e) {
LOG.warn("Could not delete temporary directory " + tmpDir.toFile().getAbsolutePath(), e);
}
}
}
}
/**
* Deletes a directory.
*
* @param pathToBeDeleted directory to delete
* @throws IOException
*/
private void deleteDirectory(java.nio.file.Path pathToBeDeleted) throws IOException {
Files.walk(pathToBeDeleted).sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete);
}
/**
* Connects to a {@link ApplicationContext}.
*
* @param contextFactoryClassname classname of the
* {@link ApplicationContextFactory}
* @param parameters connection parameters
* @return connected {@link ApplicationContext}
* @throws ConnectionException
*/
private ApplicationContext connectContext(String contextFactoryClassname, Map<String, String> parameters)
throws ConnectionException {
try {
Class<? extends ApplicationContextFactory> contextFactoryClass = Thread.currentThread()
.getContextClassLoader().loadClass(contextFactoryClassname)
.asSubclass(ApplicationContextFactory.class);
ApplicationContextFactory contextFactory = contextFactoryClass.newInstance();
return contextFactory.connect(parameters);
} catch (Exception e) {
throw new ConnectionException(
"failed to initialize entity manager using factory '" + contextFactoryClassname + "'", e);
}
}
}