diff -r a151135b0cf9 -r aa2539c91954 tracesrv/tracecompiler/src/com.nokia.tracecompiler/src/com/nokia/tracecompiler/engine/header/HeaderEngine.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tracesrv/tracecompiler/src/com.nokia.tracecompiler/src/com/nokia/tracecompiler/engine/header/HeaderEngine.java Fri Oct 08 14:56:39 2010 +0300 @@ -0,0 +1,289 @@ +/* +* Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +* Header engine manages the trace header file that is included into source code +* +*/ +package com.nokia.tracecompiler.engine.header; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; + +import com.nokia.tracecompiler.engine.LocationListBase; +import com.nokia.tracecompiler.engine.LocationProperties; +import com.nokia.tracecompiler.engine.TraceCompilerEngineBase; +import com.nokia.tracecompiler.engine.TraceCompilerEngineEvents; +import com.nokia.tracecompiler.engine.TraceCompilerEngineGlobals; +import com.nokia.tracecompiler.engine.TraceCompilerEngineErrorCodes.TraceCompilerErrorCode; +import com.nokia.tracecompiler.engine.project.ProjectEngine; +import com.nokia.tracecompiler.file.FileCompareOutputStream; +import com.nokia.tracecompiler.model.Trace; +import com.nokia.tracecompiler.model.TraceCompilerException; +import com.nokia.tracecompiler.model.TraceGroup; +import com.nokia.tracecompiler.model.TraceModel; +import com.nokia.tracecompiler.plugin.TraceHeaderContribution; +import com.nokia.tracecompiler.plugin.TraceHeaderContribution.TraceHeaderContributionType; +import com.nokia.tracecompiler.project.ProjectUtils; +import com.nokia.tracecompiler.project.TraceProjectAPI; +import com.nokia.tracecompiler.source.SourceUtils; + +/** + * Header engine manages the trace header file that is included into source + * code. This implements the plug-in interface to get notifications about + * project file opening and closing + * + */ +public final class HeaderEngine extends TraceCompilerEngineBase { + + /** + * Trace model + */ + private TraceModel model; + + /** + * Constructor + * + * @param model + * trace model + */ + public HeaderEngine(TraceModel model) { + this.model = model; + } + + /* + * (non-Javadoc) + * + * @see com.nokia.tracecompiler.engine.TraceCompilerEngine#projectOpened() + */ + @Override + public void projectOpened() { + TraceHeader header = model.getExtension(TraceHeader.class); + if (header == null) { + String fileName = null; + try { + fileName = ProjectUtils.getLocationForFile(model, + ProjectEngine.traceFolderName, + HeaderConstants.TRACE_HEADER_NAME, false); + } catch (TraceCompilerException e) { + // Model should always be open when traceProjectOpened is called + } + if (fileName != null) { + header = new TraceHeader(fileName, false); + model.addExtension(header); + } else { + String msg = Messages + .getString("HeaderEngine.FailedToAttachHeader"); //$NON-NLS-1$ + TraceCompilerEngineGlobals.getEvents().postErrorMessage(msg, null, true); + } + } + } + + /* + * (non-Javadoc) + * + * @see com.nokia.tracecompiler.engin.TraceCompilererEngine#projectClosing() + */ + @Override + public void projectClosed() { + model.removeExtensions(TraceHeader.class); + } + + /** + * Gets the name for the trace header file based on given source + * + * @param sourceFile + * the source file name + * @return the header file name + */ + public String getHeaderFileName(String sourceFile) { + String retval = null; + if (model != null) { + // The header file name is the source file name with extension + // replaced by Traces.h + File f = new File(sourceFile); + retval = removeFileExtension(f.getName()) + + HeaderConstants.TRACE_HEADER_EXTENSION; + } + return retval; + } + + /* + * (non-Javadoc) + * + * @see com.nokia.tracecompiler.engi.TraceCompilerlerEngine#projectExporting() + */ + @Override + public void exportProject() throws TraceCompilerException { + if (model.isValid() && model.hasTraces()) { + TraceHeader header = model.getExtension(TraceHeader.class); + if (header != null) { + // Headers for each source are written first + String path = header.getPath(); + ArrayList fileNames = new ArrayList(); + collectSourceFilesFromTraces(fileNames); + for (String fileName : fileNames) { + String target = path + File.separator + fileName; + writeHeaderFile(target); + } + // The main header is written after everything else succeeds + writeMainHeaderFile(header); + } + } + } + + /** + * Collects the source file names from traces + * + * @param fileNames + * the file names + */ + private void collectSourceFilesFromTraces(ArrayList fileNames) { + for (TraceGroup group : model) { + for (Trace trace : group) { + Iterator itr = trace + .getExtensions(LocationListBase.class); + while (itr.hasNext()) { + LocationListBase base = itr.next(); + for (LocationProperties loc : base) { + String locFileName = loc.getFileName(); + if (locFileName != null) { + addFileToList(fileNames, locFileName); + } + } + } + } + } + } + + /** + * Adds a file to list if it does not exist + * + * @param fileNames + * the list + * @param locFileName + * the file + */ + private void addFileToList(ArrayList fileNames, String locFileName) { + locFileName = removeFileExtension(locFileName); + if (!fileNames.contains(locFileName)) { + fileNames.add(locFileName); + } + } + + /** + * Removes the file extension from file name + * + * @param fileName + * the file name + * @return name without extension + */ + private String removeFileExtension(String fileName) { + int index = fileName.lastIndexOf('.'); + int sep1 = fileName.lastIndexOf('/'); + int sep2 = fileName.lastIndexOf('\\'); + if (index > sep1 && index > sep2) { + fileName = fileName.substring(0, index); + } + return fileName; + } + + /** + * Writes the header to given target + * + * @param target + * the target file + * @throws TraceCompilerException + * if writing fails + */ + private void writeHeaderFile(String target) throws TraceCompilerException { + // The TraceHeader stored into the model is not used when writing + // headers, since a separate header is written for each source file + TraceHeader header = new TraceHeader(target, true); + try { + header.setOwner(model); + TraceHeaderWriter writer = new TraceHeaderWriter(header); + TraceCompilerEngineEvents events = TraceCompilerEngineGlobals.getEvents(); + if (writer.write()) { + header.postFileWrittenEvent(header.getAbsolutePath()); + } else { + String msg = Messages + .getString("HeaderEngine.TraceHeaderNotChangedPrefix"); //$NON-NLS-1$ + events.postInfoMessage(msg + header.getAbsolutePath(), null); + } + } finally { + // The header owner must be reset to null, since that makes + // unregisters it from the model + header.setOwner(null); + } + } + + /** + * Writes the main header file to given target + * + * @param header + * the header + * @throws TraceCompilerException + * if writing fails + */ + private void writeMainHeaderFile(TraceHeader header) + throws TraceCompilerException { + // The TraceHeader stored into the model is not used when writing + // headers, since a separate header is written for each source file + TraceCompilerEngineEvents events = TraceCompilerEngineGlobals.getEvents(); + String path = header.getAbsolutePath(); + try { + if (writeMainHeader(path)) { + header.postFileWrittenEvent(path); + } else { + String msg = Messages + .getString("HeaderEngine.TraceHeaderNotChangedPrefix"); //$NON-NLS-1$ + events.postInfoMessage(msg + path, null); + } + } catch (IOException e) { + throw new TraceCompilerException( + TraceCompilerErrorCode.CANNOT_WRITE_PROJECT_FILE, e); + } + } + + /** + * Writes the main header to given target + * + * @param target + * the target + * @return true if written, false if the file already had the same content + * @throws IOException + * if writing fails + */ + private boolean writeMainHeader(String target) throws IOException { + File f = new File(target); + FileCompareOutputStream stream = new FileCompareOutputStream(f); + String licence = TraceCompilerEngineGlobals.getDefaultLicence(true); + if (licence != null) { + stream.write(licence.getBytes()); + } + stream.write(SourceUtils.createHeaderGuard(f.getName()).getBytes()); + TraceProjectAPI api = model.getExtension(TraceProjectAPI.class); + if (api instanceof TraceHeaderContribution) { + String[] content = ((TraceHeaderContribution) api) + .getContribution(TraceHeaderContributionType.MAIN_HEADER_CONTENT); + if (content != null && content.length == 1) { + stream.write(content[0].getBytes()); + } + } + return stream.writeFile(); + } +}