001/*
002 * SonarQube, open source software quality management tool.
003 * Copyright (C) 2008-2014 SonarSource
004 * mailto:contact AT sonarsource DOT com
005 *
006 * SonarQube is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 3 of the License, or (at your option) any later version.
010 *
011 * SonarQube is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014 * Lesser General Public License for more details.
015 *
016 * You should have received a copy of the GNU Lesser General Public License
017 * along with this program; if not, write to the Free Software Foundation,
018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
019 */
020package org.sonar.batch.protocol.output;
021
022import java.io.BufferedOutputStream;
023import java.io.File;
024import java.io.FileOutputStream;
025import java.io.OutputStream;
026import org.sonar.core.util.ContextException;
027import org.sonar.core.util.Protobuf;
028
029public class BatchReportWriter {
030
031  private final FileStructure fileStructure;
032
033  public BatchReportWriter(File dir) {
034    if (!dir.exists() && !dir.mkdirs()) {
035      throw new IllegalStateException("Unable to create directory: " + dir);
036    }
037    this.fileStructure = new FileStructure(dir);
038  }
039
040  public FileStructure getFileStructure() {
041    return fileStructure;
042  }
043
044  public boolean hasComponentData(FileStructure.Domain domain, int componentRef) {
045    File file = fileStructure.fileFor(domain, componentRef);
046    return file.exists() && file.isFile();
047  }
048
049  /**
050   * Metadata is mandatory
051   */
052  public File writeMetadata(BatchReport.Metadata metadata) {
053    Protobuf.write(metadata, fileStructure.metadataFile());
054    return fileStructure.metadataFile();
055  }
056
057  public File writeActiveRules(Iterable<BatchReport.ActiveRule> activeRules) {
058    Protobuf.writeStream(activeRules, fileStructure.activeRules(), false);
059    return fileStructure.metadataFile();
060  }
061
062  public File writeComponent(BatchReport.Component component) {
063    File file = fileStructure.fileFor(FileStructure.Domain.COMPONENT, component.getRef());
064    Protobuf.write(component, file);
065    return file;
066  }
067
068  public File writeComponentIssues(int componentRef, Iterable<BatchReport.Issue> issues) {
069    File file = fileStructure.fileFor(FileStructure.Domain.ISSUES, componentRef);
070    Protobuf.writeStream(issues, file, false);
071    return file;
072  }
073
074  public void appendComponentIssue(int componentRef, BatchReport.Issue issue) {
075    File file = fileStructure.fileFor(FileStructure.Domain.ISSUES, componentRef);
076    try (OutputStream out = new BufferedOutputStream(new FileOutputStream(file, true))) {
077      issue.writeDelimitedTo(out);
078    } catch (Exception e) {
079      throw ContextException.of("Unable to write issue", e).addContext("file", file);
080    }
081  }
082
083  public File writeComponentMeasures(int componentRef, Iterable<BatchReport.Measure> measures) {
084    File file = fileStructure.fileFor(FileStructure.Domain.MEASURES, componentRef);
085    Protobuf.writeStream(measures, file, false);
086    return file;
087  }
088
089  public File writeComponentChangesets(BatchReport.Changesets changesets) {
090    File file = fileStructure.fileFor(FileStructure.Domain.CHANGESETS, changesets.getComponentRef());
091    Protobuf.write(changesets, file);
092    return file;
093  }
094
095  public File writeComponentDuplications(int componentRef, Iterable<BatchReport.Duplication> duplications) {
096    File file = fileStructure.fileFor(FileStructure.Domain.DUPLICATIONS, componentRef);
097    Protobuf.writeStream(duplications, file, false);
098    return file;
099  }
100
101  public File writeComponentSymbols(int componentRef, Iterable<BatchReport.Symbol> symbols) {
102    File file = fileStructure.fileFor(FileStructure.Domain.SYMBOLS, componentRef);
103    Protobuf.writeStream(symbols, file, false);
104    return file;
105  }
106
107  public File writeComponentSyntaxHighlighting(int componentRef, Iterable<BatchReport.SyntaxHighlighting> syntaxHighlightingRules) {
108    File file = fileStructure.fileFor(FileStructure.Domain.SYNTAX_HIGHLIGHTINGS, componentRef);
109    Protobuf.writeStream(syntaxHighlightingRules, file, false);
110    return file;
111  }
112
113  public File writeComponentCoverage(int componentRef, Iterable<BatchReport.Coverage> coverageList) {
114    File file = fileStructure.fileFor(FileStructure.Domain.COVERAGES, componentRef);
115    Protobuf.writeStream(coverageList, file, false);
116    return file;
117  }
118
119  public File writeTests(int componentRef, Iterable<BatchReport.Test> tests) {
120    File file = fileStructure.fileFor(FileStructure.Domain.TESTS, componentRef);
121    Protobuf.writeStream(tests, file, false);
122    return file;
123  }
124
125  public File writeCoverageDetails(int componentRef, Iterable<BatchReport.CoverageDetail> tests) {
126    File file = fileStructure.fileFor(FileStructure.Domain.COVERAGE_DETAILS, componentRef);
127    Protobuf.writeStream(tests, file, false);
128    return file;
129  }
130
131  public File getSourceFile(int componentRef) {
132    return fileStructure.fileFor(FileStructure.Domain.SOURCE, componentRef);
133  }
134
135}