32545bee156a9b42f51cf075e020250e82970de0
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.analysis.xml.ui / src / org / eclipse / tracecompass / tmf / analysis / xml / ui / module / XmlAnalysisModuleSource.java
1 /*******************************************************************************
2 * Copyright (c) 2014, 2015 École Polytechnique de Montréal and others
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 * Geneviève Bastien - Initial API and implementation
11 * Bernd Hufmann - Ensure backwards compatibility to Linux Tools
12 *******************************************************************************/
13
14 package org.eclipse.tracecompass.tmf.analysis.xml.ui.module;
15
16 import java.io.File;
17 import java.io.FileInputStream;
18 import java.io.FileNotFoundException;
19 import java.io.FileOutputStream;
20 import java.io.IOException;
21 import java.net.URL;
22 import java.nio.channels.FileChannel;
23 import java.util.ArrayList;
24 import java.util.List;
25
26 import javax.xml.parsers.DocumentBuilder;
27 import javax.xml.parsers.DocumentBuilderFactory;
28 import javax.xml.parsers.ParserConfigurationException;
29
30 import org.eclipse.core.runtime.FileLocator;
31 import org.eclipse.core.runtime.IConfigurationElement;
32 import org.eclipse.core.runtime.IPath;
33 import org.eclipse.core.runtime.ISafeRunnable;
34 import org.eclipse.core.runtime.Platform;
35 import org.eclipse.core.runtime.SafeRunner;
36 import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.Activator;
37 import org.eclipse.tracecompass.tmf.analysis.xml.core.module.Messages;
38 import org.eclipse.tracecompass.tmf.analysis.xml.core.module.XmlUtils;
39 import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.TmfXmlStrings;
40 import org.eclipse.tracecompass.tmf.analysis.xml.ui.module.TmfAnalysisModuleHelperXml.XmlAnalysisModuleType;
41 import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModuleHelper;
42 import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModuleSource;
43 import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisManager;
44 import org.osgi.framework.Bundle;
45 import org.w3c.dom.Document;
46 import org.w3c.dom.Element;
47 import org.w3c.dom.NodeList;
48 import org.xml.sax.SAXException;
49
50 /**
51 * Analysis module source who creates helpers for the analysis modules described
52 * in the imported XML files
53 *
54 * @author Geneviève Bastien
55 */
56 public class XmlAnalysisModuleSource implements IAnalysisModuleSource {
57
58 /** Extension point ID */
59 private static final String TMF_XML_BUILTIN_ID = "org.eclipse.linuxtools.tmf.analysis.xml.core.files"; //$NON-NLS-1$
60 private static final String XML_FILE_ELEMENT = "xmlfile"; //$NON-NLS-1$
61
62 private static final String XML_FILE_ATTRIB = "file"; //$NON-NLS-1$
63
64 /*
65 * Legacy (Linux Tools) XML directory.
66 * TODO Remove once we feel the transition phase is over.
67 */
68 private static final IPath XML_DIRECTORY_LEGACY =
69 Activator.getDefault().getStateLocation().removeLastSegments(1)
70 .append("org.eclipse.linuxtools.tmf.analysis.xml.core") //$NON-NLS-1$
71 .append("xml_files"); //$NON-NLS-1$
72
73 private static List<IAnalysisModuleHelper> fModules = null;
74
75 /**
76 * Constructor. It adds the new module listener to the analysis manager.
77 */
78 public XmlAnalysisModuleSource() {
79 TmfAnalysisManager.addNewModuleListener(new TmfXmlAnalysisOutputSource());
80 }
81
82 @Override
83 public synchronized Iterable<IAnalysisModuleHelper> getAnalysisModules() {
84 if (fModules == null) {
85 fModules = new ArrayList<>();
86 populateBuiltinModules();
87 populateAnalysisModules();
88 }
89 return fModules;
90 }
91
92 private static void processFile(File xmlFile) {
93 if (!XmlUtils.xmlValidate(xmlFile).isOK()) {
94 return;
95 }
96
97 try {
98 /* Load the XML File */
99 DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
100 DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
101 Document doc = dBuilder.parse(xmlFile);
102 doc.getDocumentElement().normalize();
103
104 /* get State Providers modules */
105 NodeList stateproviderNodes = doc.getElementsByTagName(TmfXmlStrings.STATE_PROVIDER);
106 for (int i = 0; i < stateproviderNodes.getLength(); i++) {
107 Element node = (Element) stateproviderNodes.item(i);
108
109 IAnalysisModuleHelper helper = new TmfAnalysisModuleHelperXml(xmlFile, node, XmlAnalysisModuleType.STATE_SYSTEM);
110 fModules.add(helper);
111 }
112 } catch (ParserConfigurationException | SAXException | IOException e) {
113 Activator.logError("Error opening XML file", e); //$NON-NLS-1$
114 }
115 }
116
117 private static void populateBuiltinModules() {
118 /* Get the XML files advertised through the extension point */
119 IConfigurationElement[] elements = Platform.getExtensionRegistry().getConfigurationElementsFor(TMF_XML_BUILTIN_ID);
120 for (IConfigurationElement element : elements) {
121 if (element.getName().equals(XML_FILE_ELEMENT)) {
122 final String filename = element.getAttribute(XML_FILE_ATTRIB);
123 final String name = element.getContributor().getName();
124 // Run this in a safe runner in case there is an exception
125 // (IOException, FileNotFoundException, NPE, etc).
126 // This makes sure other extensions are not prevented from
127 // working if one is faulty.
128 SafeRunner.run(new ISafeRunnable() {
129
130 @Override
131 public void run() throws Exception {
132 if (name != null) {
133 Bundle bundle = Platform.getBundle(name);
134 if (bundle != null) {
135 URL xmlUrl = bundle.getResource(filename);
136 if (xmlUrl == null) {
137 throw new FileNotFoundException(filename);
138 }
139 URL locatedURL = FileLocator.toFileURL(xmlUrl);
140 processFile(new File(locatedURL.getFile()));
141 }
142 }
143 }
144
145 @Override
146 public void handleException(Throwable exception) {
147 // Handled sufficiently in SafeRunner
148 }
149 });
150 }
151 }
152 }
153
154 private static void populateAnalysisModules() {
155 IPath pathToFiles = XmlUtils.getXmlFilesPath();
156 File fFolder = pathToFiles.toFile();
157 if (!(fFolder.isDirectory() && fFolder.exists())) {
158 return;
159 }
160
161 /*
162 * Transfer files from Linux Tools directory.
163 */
164 File fOldFolder = XML_DIRECTORY_LEGACY.toFile();
165 if ((fOldFolder.isDirectory() && fOldFolder.exists())) {
166 for (File fromFile : fOldFolder.listFiles()) {
167 File toFile = pathToFiles.append(fromFile.getName()).toFile();
168 if (!toFile.exists() && !fromFile.isDirectory()) {
169 try (FileInputStream fis = new FileInputStream(fromFile);
170 FileOutputStream fos = new FileOutputStream(toFile);
171 FileChannel source = fis.getChannel();
172 FileChannel destination = fos.getChannel();) {
173 destination.transferFrom(source, 0, source.size());
174 } catch (IOException e) {
175 String error = Messages.XmlUtils_ErrorCopyingFile;
176 Activator.logError(error, e);
177 }
178 }
179 }
180 }
181
182 for (File xmlFile : fFolder.listFiles()) {
183 processFile(xmlFile);
184 }
185 }
186
187 /**
188 * Notifies the main XML analysis module that the executable modules list
189 * may have changed and needs to be refreshed.
190 */
191 public static void notifyModuleChange() {
192 fModules = null;
193 TmfAnalysisManager.refreshModules();
194 }
195
196 }
This page took 0.035868 seconds and 4 git commands to generate.