/******************************************************************************* * Copyright (c) 2016 ARM Ltd. and others * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * ARM Ltd and ARM Germany GmbH - Initial API and implementation *******************************************************************************/ package com.arm.cmsis.pack.installer.jobs; import java.io.File; import java.io.IOException; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubMonitor; import org.eclipse.osgi.util.NLS; import com.arm.cmsis.pack.CpPlugIn; import com.arm.cmsis.pack.ICpPackInstaller; import com.arm.cmsis.pack.common.CmsisConstants; import com.arm.cmsis.pack.data.CpPack; import com.arm.cmsis.pack.data.ICpPack; import com.arm.cmsis.pack.data.ICpPackCollection; import com.arm.cmsis.pack.events.RteEvent; import com.arm.cmsis.pack.installer.Messages; import com.arm.cmsis.pack.parser.ICpXmlParser; import com.arm.cmsis.pack.parser.PdscParser; import com.arm.cmsis.pack.utils.Utils; /** * Job of importing packs from a folder */ public class CpPackImportFolderJob extends CpPackJob { protected final String fRootPath; protected final Set<String> fPackFolders; public CpPackImportFolderJob(String name, ICpPackInstaller packInstaller, String jobId, String rootPath) { super(name, packInstaller, jobId); fRootPath = rootPath; fPackFolders = new HashSet<>(); } @Override protected IStatus run(IProgressMonitor monitor) { File rootFile = new File(fRootPath); if (!rootFile.exists()) { fResult.setSuccess(false); fResult.setErrorString(NLS.bind(Messages.CpPackImportFolderJob_FolderNotExist, fRootPath)); fPackInstaller.jobFinished(CmsisConstants.EMPTY_STRING, RteEvent.PACK_IMPORT_FOLDER_JOB_FINISHED, fResult); return Status.OK_STATUS; } SubMonitor progress = SubMonitor.convert(monitor, Utils.countFiles(rootFile)); progress.setTaskName(NLS.bind(Messages.CpPackImportFolderJob_ImportingPacksFrom, fRootPath)); try { if (importFolderPacks(rootFile, new HashSet<String>(), progress)) { fResult.setSuccess(true); } } catch (IOException e) { fResult.setSuccess(false); fResult.setErrorString(e.getMessage()); } fPackInstaller.jobFinished(fJobId, RteEvent.PACK_IMPORT_FOLDER_JOB_FINISHED, fResult); return Status.OK_STATUS; } protected boolean importFolderPacks(File parentFolder, Set<String> copiedFolder, IProgressMonitor progress) throws IOException { for (File folder : parentFolder.listFiles()) { if (progress.isCanceled()) { fPackFolders.stream().forEach(path -> Utils.deleteFolderRecursive(new File(path))); fResult.setSuccess(false); fResult.setErrorString(Messages.CpPackJob_CancelledByUser); return false; } if (folder.isDirectory()) { if (!importFolderPacks(folder, copiedFolder, progress)) { // first import child folder packs return false; } } } List<String> files = new LinkedList<String>(); Utils.findPdscFiles(parentFolder, files, 0); if (files.isEmpty()) { // this is a normal folder return true; } ICpXmlParser parser = new PdscParser(); ICpPack pack = (ICpPack) parser.parseFile(files.get(0)); if (pack == null) { fResult.setSuccess(false); fResult.setErrorString(String.join("\n", parser.getErrorStrings())); //$NON-NLS-1$ return false; } ICpPackCollection installedPacks = CpPlugIn.getPackManager().getInstalledPacks(); if (installedPacks != null && installedPacks.getPack(pack.getId()) != null) { // pack already installed copiedFolder.add(parentFolder.getAbsolutePath()); return true; } progress.subTask(NLS.bind(Messages.CpPackImportFolderJob_ImportingPack, pack.getId())); String relativeDir = CpPack.getPackRelativeInstallDir(pack.getId()); IPath dstFolder = new Path(CpPlugIn.getPackManager().getCmsisPackRootDirectory()).append(relativeDir); for (File file : parentFolder.listFiles()) { if (file.isFile()) { Utils.copy(file, dstFolder.append(file.getName()).toFile()); progress.worked(1); } else if (file.isDirectory() && !copiedFolder.contains(file.getAbsolutePath())) { Utils.copyDirectoryWithProgress(file, dstFolder.append(file.getName()).toFile(), copiedFolder, progress); } } fPackFolders.add(dstFolder.toOSString()); copiedFolder.add(parentFolder.getAbsolutePath()); // this folder has been copied, will not enter any subfolders return true; } }