analysis: Move plugins to their own sub-directory
[deliverable/tracecompass.git] / org.eclipse.tracecompass.tmf.remote.ui / src / org / eclipse / tracecompass / internal / tmf / remote / ui / wizards / fetch / model / RemoteGenerateManifestOperation.java
CommitLineData
417a4110
BH
1/*******************************************************************************
2 * Copyright (c) 2015 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Bernd Hufmann - Initial API and implementation
11 *******************************************************************************/
12
13package org.eclipse.tracecompass.internal.tmf.remote.ui.wizards.fetch.model;
14
15import java.util.ArrayList;
16import java.util.HashSet;
17import java.util.List;
18import java.util.Map.Entry;
19import java.util.Set;
20import java.util.regex.Pattern;
21
22import org.eclipse.core.filesystem.EFS;
23import org.eclipse.core.filesystem.IFileInfo;
24import org.eclipse.core.filesystem.IFileStore;
25import org.eclipse.core.runtime.CoreException;
26import org.eclipse.core.runtime.IPath;
27import org.eclipse.core.runtime.IProgressMonitor;
28import org.eclipse.core.runtime.IStatus;
29import org.eclipse.core.runtime.Path;
30import org.eclipse.core.runtime.Status;
31import org.eclipse.core.runtime.SubMonitor;
32import org.eclipse.jface.operation.ModalContext;
33import org.eclipse.osgi.util.NLS;
34import org.eclipse.remote.core.IRemoteFileService;
35import org.eclipse.tracecompass.internal.tmf.remote.ui.Activator;
36import org.eclipse.tracecompass.internal.tmf.remote.ui.messages.RemoteMessages;
37import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageElement;
38import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageTraceElement;
39import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceCoreUtils;
40import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType;
41import org.eclipse.tracecompass.tmf.remote.core.proxy.RemoteSystemProxy;
42
43/**
44 * An operation that generates the manifest based on a profile and the content
45 * of a remote node.
46 *
47 * @author Bernd Hufmann
48 */
49public class RemoteGenerateManifestOperation extends AbstractGenerateManifestOperation {
50
51 // ------------------------------------------------------------------------
52 // Attributes
53 // ------------------------------------------------------------------------
54 private RemoteImportProfileElement fProfile;
55 private Set<IPath> fDirectoryTraces = new HashSet<>();
56
57 // ------------------------------------------------------------------------
58 // Constructor(s)
59 // ------------------------------------------------------------------------
60 /**
61 * Constructs a new import operation for generating the manifest
62 *
63 * @param profile
64 * the input profile element
65 */
66 public RemoteGenerateManifestOperation(RemoteImportProfileElement profile) {
67 super(profile.getText());
68 fProfile = profile;
69 }
70
71 // ------------------------------------------------------------------------
72 // Operation(s)
73 // ------------------------------------------------------------------------
74 @Override
75 public void run(IProgressMonitor monitor) {
76 try {
77 monitor.worked(1);
78 String root = null;
79 List<TracePackageElement> resultElementList = new ArrayList<>();
80 SubMonitor subMonitor = SubMonitor.convert(monitor, fProfile.getChildren().length * 2);
81
82 List<RemoteImportConnectionNodeElement> connectionNodes = fProfile.getConnectionNodeElements();
83 for (RemoteImportConnectionNodeElement connectionNode : connectionNodes) {
84 RemoteSystemProxy proxy = connectionNode.getRemoteSystemProxy();
85 // create new element to decouple from input element
86 RemoteImportConnectionNodeElement outputConnectionNode =
87 new RemoteImportConnectionNodeElement(null, connectionNode.getName(), connectionNode.getURI());
88 resultElementList.add(outputConnectionNode);
89 for (TracePackageElement element : connectionNode.getChildren()) {
90 if (element instanceof RemoteImportTraceGroupElement) {
91 ModalContext.checkCanceled(monitor);
92 RemoteImportTraceGroupElement traceGroup = (RemoteImportTraceGroupElement) element;
93 root = traceGroup.getRootImportPath();
94 TracePackageElement[] traceElements = traceGroup.getChildren();
95 fTemplatePatternsToTraceElements = generatePatterns(traceElements);
33d432d5 96 IRemoteFileService fs = proxy.getRemoteConnection().getService(IRemoteFileService.class);
417a4110
BH
97 if (fs == null) {
98 continue;
99 }
100
101 final IFileStore remoteFolder = fs.getResource(root);
102
103 // make sure that remote directory is read and not cached
104 int recursionLevel = 0;
105 // create new element to decouple from input element
106 RemoteImportTraceGroupElement outputTraceGroup =
107 new RemoteImportTraceGroupElement(outputConnectionNode, traceGroup.getRootImportPath());
108 outputTraceGroup.setRecursive(traceGroup.isRecursive());
109 generateElementsFromArchive(outputTraceGroup, outputTraceGroup, remoteFolder, recursionLevel, subMonitor.newChild(1));
110 filterElements(outputTraceGroup);
111 }
112 }
113 }
114 setResultElements(resultElementList.toArray(new TracePackageElement[0]));
115 setStatus(Status.OK_STATUS);
116 } catch (InterruptedException e) {
117 setStatus(Status.CANCEL_STATUS);
118 } catch (Exception e) {
119 setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, NLS.bind(RemoteMessages.RemoteGenerateManifest_GenerateProfileManifestError, fProfile.getText()), e));
120 }
121 }
122
123 // ------------------------------------------------------------------------
124 // Helper methods
125 // ------------------------------------------------------------------------
126 /**
127 * Scan traceFolder for files that match the patterns specified in the
128 * template file. When there is a match, the trace package element is used
129 * to determine the trace name and trace type.
130 *
131 * @param traceGroup
132 * The parent trace group element
133 * @param parentElement
134 * The immediate parent trace group or folder element
135 * @param traceFolder
136 * The folder to scan
137 * @param recursionLevel
138 * The recursion level (needed to find directory traces under the traceFolder
139 * @param monitor
140 * The progress monitor
141 * @throws CoreException
142 * Thrown by the file system implementation
143 * @throws InterruptedException
144 * Thrown if operation was cancelled
145 */
146 private void generateElementsFromArchive(
147 final RemoteImportTraceGroupElement traceGroup,
148 final TracePackageElement parentElement,
149 final IFileStore traceFolder,
150 final int recursionLevel,
151 IProgressMonitor monitor)
152 throws CoreException, InterruptedException {
153
154 int localRecursionLevel = recursionLevel + 1;
155 IFileStore[] sources = traceFolder.childStores(EFS.NONE, monitor);
156
157 for (int i = 0; i < sources.length; i++) {
158 ModalContext.checkCanceled(monitor);
159 SubMonitor subMonitor = SubMonitor.convert(monitor, sources.length);
160
161 IFileStore fileStore = sources[i];
162 IPath fullArchivePath = TmfTraceCoreUtils.newSafePath(fileStore.toURI().getPath());
163
164 IFileInfo sourceInfo = fileStore.fetchInfo();
165 if (!sourceInfo.isDirectory()) {
166
167 String rootPathString = traceGroup.getRootImportPath();
168 IPath rootPath = TmfTraceCoreUtils.newSafePath(rootPathString);
169 IPath relativeTracePath = Path.EMPTY;
170 if (rootPath.isPrefixOf(fullArchivePath)) {
171 relativeTracePath = fullArchivePath.makeRelativeTo(rootPath);
172 }
173 Entry<Pattern, TracePackageTraceElement> matchingTemplateEntry = getMatchingTemplateElement(relativeTracePath);
174 if (matchingTemplateEntry != null) {
175 TracePackageTraceElement matchingTemplateElement = matchingTemplateEntry.getValue();
176 String traceType = matchingTemplateElement.getTraceType();
177
178 // If a single file is part of a directory trace, use the parent directory instead
179 TracePackageElement parent = parentElement;
180 if (matchesDirectoryTrace(relativeTracePath, matchingTemplateEntry)) {
181 fullArchivePath = fullArchivePath.removeLastSegments(1);
182 fDirectoryTraces.add(fullArchivePath);
183 fileStore = fileStore.getParent();
184 parent = parentElement.getParent();
185 // Let the auto-detection choose the best trace type
186 traceType = null;
187 } else if ((localRecursionLevel > 1) && (!traceGroup.isRecursive())) {
188 // Don't consider file traces on level 2 if it's not recursive
189 continue;
190 }
191 String traceName = fullArchivePath.lastSegment();
192 String fileName = fileStore.getName();
193 // create new elements to decouple from input elements
194 TracePackageTraceElement traceElement = new TracePackageTraceElement(parent, traceName, traceType);
195 RemoteImportTraceFilesElement tracePackageFilesElement = new RemoteImportTraceFilesElement(traceElement, fileName, fileStore);
196 tracePackageFilesElement.setVisible(false);
197 }
198 } else {
199 if (traceGroup.isRecursive() || localRecursionLevel < 2) {
200 RemoteImportFolderElement folder = new RemoteImportFolderElement(parentElement, fileStore.getName());
201 generateElementsFromArchive(traceGroup, folder, fileStore, localRecursionLevel, subMonitor);
202 }
203 }
204 }
205 }
206
207 /*
208 * Filter elements to avoid having files of directory traces listed as
209 * separate traces.
210 */
211 private void filterElements(TracePackageElement parentElement) {
212 for (TracePackageElement childElement : parentElement.getChildren()) {
213 filterElements(childElement);
214 if (childElement instanceof TracePackageTraceElement) {
215 // no need to do length check here
216 RemoteImportTraceFilesElement filesElement = (RemoteImportTraceFilesElement) childElement.getChildren()[0];
217 IFileStore parentFile = filesElement.getRemoteFile().getParent();
218 if (fDirectoryTraces.contains(TmfTraceCoreUtils.newSafePath(parentFile.toURI().getPath()))) {
219 removeChild(childElement, parentElement);
220 continue;
221 }
222 IFileStore grandParentFile = parentFile.getParent();
223 if (grandParentFile != null && fDirectoryTraces.contains(TmfTraceCoreUtils.newSafePath(grandParentFile.toURI().getPath()))) {
224 // ignore file if grandparent is a directory trace
225 // for example: file is a index file of a LTTng kernel trace
226 parentElement.removeChild(childElement);
227 if (parentElement.getChildren().length == 0) {
228 TracePackageElement grandParentElement = parentElement.getParent();
229 removeChild(parentElement, grandParentElement);
230 }
231 continue;
232 }
233 } else if (childElement instanceof RemoteImportFolderElement) {
234 if (childElement.getChildren().length == 0) {
235 parentElement.removeChild(childElement);
236 }
237 }
238 }
239 }
240
241 private static void removeChild(TracePackageElement childElement, TracePackageElement parentElement) {
242 parentElement.removeChild(childElement);
243 if (parentElement.getChildren().length == 0) {
244 if (parentElement.getParent() != null) {
245 parentElement.getParent().removeChild(parentElement);
246 }
247 }
248 }
249
250 /**
251 * This method takes the auto-detection case into consideration.
252 *
253 * {@inheritDoc}
254 */
255 @Override
256 protected Entry<Pattern, TracePackageTraceElement> getMatchingTemplateElement(IPath fullArchivePath) {
257 for (Entry<Pattern, TracePackageTraceElement> entry : fTemplatePatternsToTraceElements.entrySet()) {
258 // Check for CTF trace (metadata)
259 String traceType = entry.getValue().getTraceType();
260 // empty string is for auto-detection
261 if ((traceType.isEmpty() || TmfTraceType.isDirectoryTraceType(traceType)) &&
262 (matchesDirectoryTrace(fullArchivePath, entry))) {
263 return entry;
264 } else if (entry.getKey().matcher(TmfTraceCoreUtils.safePathToString(fullArchivePath.toString())).matches()) {
265 return entry;
266 }
267 }
268
269 return null;
270 }
271
272 /**
273 * This method takes the auto-detection case into consideration.
274 *
275 * {@inheritDoc}
276 */
277 @Override
278 protected boolean matchesDirectoryTrace(IPath archivePath, Entry<Pattern, TracePackageTraceElement> entry) {
279 if (METADATA_FILE_NAME.equals(archivePath.lastSegment())) {
280 IPath archiveParentPath = archivePath.removeLastSegments(1);
281 String parentPathString = TmfTraceCoreUtils.safePathToString(archiveParentPath.toString());
282 if (entry.getKey().matcher(parentPathString).matches()) {
283 String traceType = entry.getValue().getTraceType();
284 // empty string is for auto-detection
285 if (traceType.isEmpty() || TmfTraceType.isDirectoryTraceType(traceType)) {
286 return true;
287 }
288 }
289 }
290 return false;
291 }
292}
This page took 0.03981 seconds and 5 git commands to generate.