All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.sonar.graph.Dsm Maven / Gradle / Ivy

/*
 * Sonar, open source software quality management tool.
 * Copyright (C) 2009 SonarSource SA
 * mailto:contact AT sonarsource DOT com
 *
 * Sonar is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * Sonar is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with Sonar; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
 */
package org.sonar.graph;

import java.util.Collection;
import java.util.Collections;
import java.util.Set;

public class Dsm {

  private V[] vertices;
  private DsmCell[][] cells;
  private int dimension;
  private DirectedGraphAccessor> graph;

  public Dsm(DirectedGraphAccessor> graph, Collection vertices, Set feedbackEdges) {
    this.graph = graph;
    this.dimension = vertices.size();
    this.cells = new DsmCell[dimension][dimension];
    initVertices(vertices);
    initCells(feedbackEdges);
  }

  public Dsm(DirectedGraphAccessor> acyclicGraph, Set feedbackEdges) {
    this(acyclicGraph, acyclicGraph.getVertices(), feedbackEdges);
  }

  public Dsm(DirectedGraphAccessor> acyclicGraph) {
    this(acyclicGraph, acyclicGraph.getVertices(), Collections.emptySet());
  }

  private void initCells(Set feedbackEdges) {
    for (int x = 0; x < dimension; x++) {
      for (int y = 0; y < dimension; y++) {
        V from = vertices[x];
        V to = vertices[y];

        Edge edge = graph.getEdge(from, to);
        boolean isFeedbackEdge = (edge != null && feedbackEdges.contains(edge));
        DsmCell cell = new DsmCell(edge, isFeedbackEdge);
        cells[x][y] = cell;
      }
    }
  }

  private void initVertices(Collection verticesCol) {
    this.vertices = (V[]) new Object[dimension];
    int i = 0;
    for (V vertex : verticesCol) {
      vertices[i] = vertex;
      i++;
    }
  }

  public V getVertex(int rowIndex) {
    return vertices[rowIndex];
  }

  public int getDimension() {
    return dimension;
  }

  public void permute(int fromIndex, int toIndex) {
    if (fromIndex != toIndex) {
      checkIndicesBoudaries(fromIndex, toIndex);
      permuteVertice(fromIndex, toIndex);
      permuteColumns(fromIndex, toIndex);
      permuteRows(fromIndex, toIndex);
    }
  }

  private void checkIndicesBoudaries(int... indices) {
    for (int index : indices) {
      if (index < 0 || index >= dimension) {
        StringBuilder builder = new StringBuilder("DSM contains the following vertices : ");
        for (V vertex : vertices) {
          builder.append(vertex.toString()).append(" | ");
        }
        builder.append(". Trying to reach index ").append(index);
        throw new ArrayIndexOutOfBoundsException(builder.toString());
      }
    }
  }

  private void permuteVertice(int fromIndex, int toIndex) {
    V fromVertex = vertices[fromIndex];
    V toVertex = vertices[toIndex];
    vertices[fromIndex] = toVertex;
    vertices[toIndex] = fromVertex;
  }

  private void permuteRows(int fromYIndex, int toYIndex) {
    for (int x = 0; x < dimension; x++) {
      permuteCells(x, fromYIndex, x, toYIndex);
    }
  }

  private void permuteColumns(int fromXIndex, int toXIndex) {
    for (int y = 0; y < dimension; y++) {
      permuteCells(fromXIndex, y, toXIndex, y);
    }
  }

  private void permuteCells(int fromXIndex, int fromYIndex, int toXIndex, int toYIndex) {
    DsmCell fromCell = cells[fromXIndex][fromYIndex];
    DsmCell toCell = cells[toXIndex][toYIndex];
    cells[toXIndex][toYIndex] = fromCell;
    cells[fromXIndex][fromYIndex] = toCell;
  }

  public int getNumberOfIncomingEdges(int y, int from, int to) {
    int incomingEdges = 0;
    for (int x = from; x <= to; x++) {
      DsmCell cell = cells[x][y];
      if (cell.getWeight() != 0 && !cell.isFeedbackEdge()) {
        incomingEdges++;
      }
    }
    return incomingEdges;
  }

  public int getNumberOfOutgoingEdges(int x, int from, int to) {
    int outgoingEdges = 0;
    for (int y = from; y <= to; y++) {
      DsmCell cell = cells[x][y];
      if (cell.getWeight() != 0 && !cell.isFeedbackEdge()) {
        outgoingEdges++;
      }
    }
    return outgoingEdges;
  }

  public DsmCell getCell(int x, int y) {
    return cells[x][y];
  }

  public V[] getVertices() {
    V[] verticesCopy = (V[]) new Object[vertices.length];
    System.arraycopy(vertices, 0, verticesCopy, 0, vertices.length);
    return verticesCopy;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy