1 /* |
|
2 * Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 * Header engine manages the trace header file that is included into source code |
|
17 * |
|
18 */ |
|
19 package com.nokia.tracecompiler.engine.header; |
|
20 |
|
21 import java.io.File; |
|
22 import java.io.IOException; |
|
23 import java.util.ArrayList; |
|
24 import java.util.Iterator; |
|
25 |
|
26 import com.nokia.tracecompiler.engine.LocationListBase; |
|
27 import com.nokia.tracecompiler.engine.LocationProperties; |
|
28 import com.nokia.tracecompiler.engine.TraceCompilerEngineBase; |
|
29 import com.nokia.tracecompiler.engine.TraceCompilerEngineEvents; |
|
30 import com.nokia.tracecompiler.engine.TraceCompilerEngineGlobals; |
|
31 import com.nokia.tracecompiler.engine.TraceCompilerEngineErrorCodes.TraceCompilerErrorCode; |
|
32 import com.nokia.tracecompiler.engine.project.ProjectEngine; |
|
33 import com.nokia.tracecompiler.file.FileCompareOutputStream; |
|
34 import com.nokia.tracecompiler.model.Trace; |
|
35 import com.nokia.tracecompiler.model.TraceCompilerException; |
|
36 import com.nokia.tracecompiler.model.TraceGroup; |
|
37 import com.nokia.tracecompiler.model.TraceModel; |
|
38 import com.nokia.tracecompiler.plugin.TraceHeaderContribution; |
|
39 import com.nokia.tracecompiler.plugin.TraceHeaderContribution.TraceHeaderContributionType; |
|
40 import com.nokia.tracecompiler.project.ProjectUtils; |
|
41 import com.nokia.tracecompiler.project.TraceProjectAPI; |
|
42 import com.nokia.tracecompiler.source.SourceUtils; |
|
43 |
|
44 /** |
|
45 * Header engine manages the trace header file that is included into source |
|
46 * code. This implements the plug-in interface to get notifications about |
|
47 * project file opening and closing |
|
48 * |
|
49 */ |
|
50 public final class HeaderEngine extends TraceCompilerEngineBase { |
|
51 |
|
52 /** |
|
53 * Trace model |
|
54 */ |
|
55 private TraceModel model; |
|
56 |
|
57 /** |
|
58 * Constructor |
|
59 * |
|
60 * @param model |
|
61 * trace model |
|
62 */ |
|
63 public HeaderEngine(TraceModel model) { |
|
64 this.model = model; |
|
65 } |
|
66 |
|
67 /* |
|
68 * (non-Javadoc) |
|
69 * |
|
70 * @see com.nokia.tracecompiler.engine.TraceCompilerEngine#projectOpened() |
|
71 */ |
|
72 @Override |
|
73 public void projectOpened() { |
|
74 TraceHeader header = model.getExtension(TraceHeader.class); |
|
75 if (header == null) { |
|
76 String fileName = null; |
|
77 try { |
|
78 fileName = ProjectUtils.getLocationForFile(model, |
|
79 ProjectEngine.traceFolderName, |
|
80 HeaderConstants.TRACE_HEADER_NAME, false); |
|
81 } catch (TraceCompilerException e) { |
|
82 // Model should always be open when traceProjectOpened is called |
|
83 } |
|
84 if (fileName != null) { |
|
85 header = new TraceHeader(fileName, false); |
|
86 model.addExtension(header); |
|
87 } else { |
|
88 String msg = Messages |
|
89 .getString("HeaderEngine.FailedToAttachHeader"); //$NON-NLS-1$ |
|
90 TraceCompilerEngineGlobals.getEvents().postErrorMessage(msg, null, true); |
|
91 } |
|
92 } |
|
93 } |
|
94 |
|
95 /* |
|
96 * (non-Javadoc) |
|
97 * |
|
98 * @see com.nokia.tracecompiler.engin.TraceCompilererEngine#projectClosing() |
|
99 */ |
|
100 @Override |
|
101 public void projectClosed() { |
|
102 model.removeExtensions(TraceHeader.class); |
|
103 } |
|
104 |
|
105 /** |
|
106 * Gets the name for the trace header file based on given source |
|
107 * |
|
108 * @param sourceFile |
|
109 * the source file name |
|
110 * @return the header file name |
|
111 */ |
|
112 public String getHeaderFileName(String sourceFile) { |
|
113 String retval = null; |
|
114 if (model != null) { |
|
115 // The header file name is the source file name with extension |
|
116 // replaced by Traces.h |
|
117 File f = new File(sourceFile); |
|
118 retval = removeFileExtension(f.getName()) |
|
119 + HeaderConstants.TRACE_HEADER_EXTENSION; |
|
120 } |
|
121 return retval; |
|
122 } |
|
123 |
|
124 /* |
|
125 * (non-Javadoc) |
|
126 * |
|
127 * @see com.nokia.tracecompiler.engi.TraceCompilerlerEngine#projectExporting() |
|
128 */ |
|
129 @Override |
|
130 public void exportProject() throws TraceCompilerException { |
|
131 if (model.isValid() && model.hasTraces()) { |
|
132 TraceHeader header = model.getExtension(TraceHeader.class); |
|
133 if (header != null) { |
|
134 // Headers for each source are written first |
|
135 String path = header.getPath(); |
|
136 ArrayList<String> fileNames = new ArrayList<String>(); |
|
137 collectSourceFilesFromTraces(fileNames); |
|
138 for (String fileName : fileNames) { |
|
139 String target = path + File.separator + fileName; |
|
140 writeHeaderFile(target); |
|
141 } |
|
142 // The main header is written after everything else succeeds |
|
143 writeMainHeaderFile(header); |
|
144 } |
|
145 } |
|
146 } |
|
147 |
|
148 /** |
|
149 * Collects the source file names from traces |
|
150 * |
|
151 * @param fileNames |
|
152 * the file names |
|
153 */ |
|
154 private void collectSourceFilesFromTraces(ArrayList<String> fileNames) { |
|
155 for (TraceGroup group : model) { |
|
156 for (Trace trace : group) { |
|
157 Iterator<LocationListBase> itr = trace |
|
158 .getExtensions(LocationListBase.class); |
|
159 while (itr.hasNext()) { |
|
160 LocationListBase base = itr.next(); |
|
161 for (LocationProperties loc : base) { |
|
162 String locFileName = loc.getFileName(); |
|
163 if (locFileName != null) { |
|
164 addFileToList(fileNames, locFileName); |
|
165 } |
|
166 } |
|
167 } |
|
168 } |
|
169 } |
|
170 } |
|
171 |
|
172 /** |
|
173 * Adds a file to list if it does not exist |
|
174 * |
|
175 * @param fileNames |
|
176 * the list |
|
177 * @param locFileName |
|
178 * the file |
|
179 */ |
|
180 private void addFileToList(ArrayList<String> fileNames, String locFileName) { |
|
181 locFileName = removeFileExtension(locFileName); |
|
182 if (!fileNames.contains(locFileName)) { |
|
183 fileNames.add(locFileName); |
|
184 } |
|
185 } |
|
186 |
|
187 /** |
|
188 * Removes the file extension from file name |
|
189 * |
|
190 * @param fileName |
|
191 * the file name |
|
192 * @return name without extension |
|
193 */ |
|
194 private String removeFileExtension(String fileName) { |
|
195 int index = fileName.lastIndexOf('.'); |
|
196 int sep1 = fileName.lastIndexOf('/'); |
|
197 int sep2 = fileName.lastIndexOf('\\'); |
|
198 if (index > sep1 && index > sep2) { |
|
199 fileName = fileName.substring(0, index); |
|
200 } |
|
201 return fileName; |
|
202 } |
|
203 |
|
204 /** |
|
205 * Writes the header to given target |
|
206 * |
|
207 * @param target |
|
208 * the target file |
|
209 * @throws TraceCompilerException |
|
210 * if writing fails |
|
211 */ |
|
212 private void writeHeaderFile(String target) throws TraceCompilerException { |
|
213 // The TraceHeader stored into the model is not used when writing |
|
214 // headers, since a separate header is written for each source file |
|
215 TraceHeader header = new TraceHeader(target, true); |
|
216 try { |
|
217 header.setOwner(model); |
|
218 TraceHeaderWriter writer = new TraceHeaderWriter(header); |
|
219 TraceCompilerEngineEvents events = TraceCompilerEngineGlobals.getEvents(); |
|
220 if (writer.write()) { |
|
221 header.postFileWrittenEvent(header.getAbsolutePath()); |
|
222 } else { |
|
223 String msg = Messages |
|
224 .getString("HeaderEngine.TraceHeaderNotChangedPrefix"); //$NON-NLS-1$ |
|
225 events.postInfoMessage(msg + header.getAbsolutePath(), null); |
|
226 } |
|
227 } finally { |
|
228 // The header owner must be reset to null, since that makes |
|
229 // unregisters it from the model |
|
230 header.setOwner(null); |
|
231 } |
|
232 } |
|
233 |
|
234 /** |
|
235 * Writes the main header file to given target |
|
236 * |
|
237 * @param header |
|
238 * the header |
|
239 * @throws TraceCompilerException |
|
240 * if writing fails |
|
241 */ |
|
242 private void writeMainHeaderFile(TraceHeader header) |
|
243 throws TraceCompilerException { |
|
244 // The TraceHeader stored into the model is not used when writing |
|
245 // headers, since a separate header is written for each source file |
|
246 TraceCompilerEngineEvents events = TraceCompilerEngineGlobals.getEvents(); |
|
247 String path = header.getAbsolutePath(); |
|
248 try { |
|
249 if (writeMainHeader(path)) { |
|
250 header.postFileWrittenEvent(path); |
|
251 } else { |
|
252 String msg = Messages |
|
253 .getString("HeaderEngine.TraceHeaderNotChangedPrefix"); //$NON-NLS-1$ |
|
254 events.postInfoMessage(msg + path, null); |
|
255 } |
|
256 } catch (IOException e) { |
|
257 throw new TraceCompilerException( |
|
258 TraceCompilerErrorCode.CANNOT_WRITE_PROJECT_FILE, e); |
|
259 } |
|
260 } |
|
261 |
|
262 /** |
|
263 * Writes the main header to given target |
|
264 * |
|
265 * @param target |
|
266 * the target |
|
267 * @return true if written, false if the file already had the same content |
|
268 * @throws IOException |
|
269 * if writing fails |
|
270 */ |
|
271 private boolean writeMainHeader(String target) throws IOException { |
|
272 File f = new File(target); |
|
273 FileCompareOutputStream stream = new FileCompareOutputStream(f); |
|
274 String licence = TraceCompilerEngineGlobals.getDefaultLicence(true); |
|
275 if (licence != null) { |
|
276 stream.write(licence.getBytes()); |
|
277 } |
|
278 stream.write(SourceUtils.createHeaderGuard(f.getName()).getBytes()); |
|
279 TraceProjectAPI api = model.getExtension(TraceProjectAPI.class); |
|
280 if (api instanceof TraceHeaderContribution) { |
|
281 String[] content = ((TraceHeaderContribution) api) |
|
282 .getContribution(TraceHeaderContributionType.MAIN_HEADER_CONTENT); |
|
283 if (content != null && content.length == 1) { |
|
284 stream.write(content[0].getBytes()); |
|
285 } |
|
286 } |
|
287 return stream.writeFile(); |
|
288 } |
|
289 } |
|