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 */
020 package org.sonar.batch.phases;
021
022 import com.tinkerpop.blueprints.Graph;
023 import org.apache.commons.io.IOUtils;
024 import org.sonar.api.component.Perspective;
025 import org.sonar.batch.index.ScanPersister;
026 import org.sonar.core.component.ComponentVertex;
027 import org.sonar.core.component.GraphPerspectiveBuilder;
028 import org.sonar.core.component.PerspectiveBuilder;
029 import org.sonar.core.component.ScanGraph;
030 import org.sonar.core.graph.SubGraph;
031 import org.sonar.core.graph.graphson.GraphsonMode;
032 import org.sonar.core.graph.graphson.GraphsonWriter;
033 import org.sonar.core.graph.jdbc.GraphDto;
034 import org.sonar.core.graph.jdbc.GraphDtoMapper;
035 import org.sonar.core.persistence.DbSession;
036 import org.sonar.core.persistence.MyBatis;
037
038 import java.io.StringWriter;
039
040 public class GraphPersister implements ScanPersister {
041 private final MyBatis myBatis;
042 private final ScanGraph projectGraph;
043 private final GraphPerspectiveBuilder[] builders;
044
045 public GraphPersister(MyBatis myBatis, ScanGraph projectGraph, GraphPerspectiveBuilder[] builders) {
046 this.myBatis = myBatis;
047 this.projectGraph = projectGraph;
048 this.builders = builders;
049 }
050
051 public void persist() {
052 DbSession session = myBatis.openSession(true);
053 GraphDtoMapper mapper = session.getMapper(GraphDtoMapper.class);
054 try {
055 for (ComponentVertex component : projectGraph.getComponents()) {
056 persistComponentGraph(mapper, component);
057 }
058 session.commit();
059 } finally {
060 session.close();
061 }
062 }
063
064 private void persistComponentGraph(GraphDtoMapper mapper, ComponentVertex component) {
065 Long snapshotId = (Long) component.element().getProperty("sid");
066 if (snapshotId != null) {
067 for (PerspectiveBuilder builder : builders) {
068 GraphPerspectiveBuilder graphPerspectiveBuilder = (GraphPerspectiveBuilder) builder;
069 Perspective perspective = graphPerspectiveBuilder.getPerspectiveLoader().load(component);
070 if (perspective != null) {
071 serializePerspectiveData(mapper, component, snapshotId, graphPerspectiveBuilder);
072 }
073 }
074 }
075 }
076
077 private void serializePerspectiveData(GraphDtoMapper mapper, ComponentVertex component, Long snapshotId,
078 GraphPerspectiveBuilder builder) {
079 Graph subGraph = SubGraph.extract(component.element(), builder.path());
080 String data = write(subGraph);
081 mapper.insert(new GraphDto()
082 .setData(data)
083 .setFormat("graphson")
084 .setPerspective(builder.getPerspectiveLoader().getPerspectiveKey())
085 .setVersion(1)
086 .setResourceId((Long) component.element().getProperty("rid"))
087 .setSnapshotId(snapshotId)
088 .setRootVertexId(component.element().getId().toString())
089 );
090 }
091
092 private String write(Graph graph) {
093 StringWriter output = new StringWriter();
094 try {
095 new GraphsonWriter().write(graph, output, GraphsonMode.EXTENDED);
096 return output.toString();
097 } finally {
098 IOUtils.closeQuietly(output);
099 }
100 }
101 }