Рубрики
Без рубрики

Обнаружение Циклических Ссылок В Проекте Java

По мере роста Java-проектов, над которыми работают несколько разработчиков, это может привести к тому, что код будет циркулировать… Помеченный java, статический анализ кода, качество кода, циклические ссылки.

По мере роста проектов Java, над которыми работают несколько разработчиков, это может привести к тому, что код будет иметь циклические ссылки. Трудно сериализовать объекты с циклическими ссылками. Я создал инструмент для обнаружения циклических ссылок в проекте Java: Детектор циклических ссылок Исходный код Gitlab . Ниже приведены шаги, предпринятые для обнаружения циклических ссылок в проекте Java.

Цель программы

  • Ввод : Путь к исходным файлам проекта Java.
  • Вывод : Папка, содержащая файлы изображений циклических графиков для каждого класса, имеющего циклические ссылки.

Шаги

  • Используя Синтаксический анализатор Java , проанализируйте каждый файл Java в данном исходном каталоге и соберите ссылки на класс в ориентированном графе с помощью JGraphT
  • Определите циклы для каждой вершины в графике с помощью JGraphT Детектор циклов
  • Храните графики в виде файлов PNG с помощью библиотеки jgrapht-ext

Фрагменты Кода

Проанализируйте файлы Java в исходном каталоге и добавьте ссылки на классы в график.
Graph classReferencesGraph = new DefaultDirectedGraph<>(DefaultEdge.class);
try (Stream filesStream = Files.walk(Paths.get(srcDirectory))) {
    filesStream             
    .filter(path -> path.getFileName().toString().endsWith(".java"))
    .forEach(path ->{
        Set instanceVarTypes = getInstanceVarTypes(path.toFile());
        if( ! instanceVarTypes.isEmpty()) {                     
            String className = getClassName(path.getFileName().toString());
            classReferencesGraph.addVertex(className);
            instanceVarTypes.forEach(classReferencesGraph::addVertex);
            instanceVarTypes.forEach( var -> classReferencesGraph.addEdge(className, var));
        }
    });
}
Сбор переменных экземпляра класса с помощью синтаксического анализатора Java
CompilationUnit compilationUnit = StaticJavaParser.parse(javaSrcFile);      
List instanceVarTypes = compilationUnit.findAll(FieldDeclaration.class)
    .stream()
    .map(f -> f.getVariables().get(0).getType())
    .filter(v -> !v.isPrimitiveType())
    .map( Object::toString)
    .collect(Collectors.toSet());
Создание ориентированного графика с помощью Карты
Graph graph = new DefaultDirectedGraph<>(DefaultEdge.class);       
//add vertices
classNametoInstanceVarTypesMap.keySet().forEach(className ->{           
  graph.addVertex(className);
});
//add edges
classNametoInstanceVarTypesMap
  .forEach((className , instanceVariableTypes) -> {
      instanceVariableTypes.forEach( instVar -> {
        if (classNametoInstanceVarTypesMap.containsKey(instVar)){
          graph.addEdge(className, instVar);
        }           
    });
});
Определите циклы для каждой вершины графика с помощью графического детектора циклов и добавьте циклы на карту.
Map> cyclesForEveryVertexMap = new HashMap<>();
CycleDetector cycleDetector = new CycleDetector<>(classReferencesGraph);
cycleDetector.findCycles().forEach(v -> {
    AsSubgraph subGraph = new AsSubgraph<>(classReferencesGraph,
            cycleDetector.findCyclesContainingVertex(v));
    cyclesForEveryVertexMap.put(v,subGraph);
});
  • найти циклы, содержащие вершину (вершина) возвращает набор вершин, участвующих в цикле для вершины. Создайте подграф основного графа, используя эти вершины.
Создайте изображение графика в формате PNG с помощью библиотеки jgrapht-ext.
new File(outputDirectoryPath).mkdirs();
File imgFile = new File(outputDirectoryPath+"/graph" + imageName + ".png");
if(imgFile.createNewFile()) {
    JGraphXAdapter graphAdapter = new JGraphXAdapter<>(subGraph);
    mxIGraphLayout layout = new mxCircleLayout(graphAdapter);
    layout.execute(graphAdapter.getDefaultParent());

    BufferedImage image = mxCellRenderer.createBufferedImage(graphAdapter, null, 2, Color.WHITE, true, null);
    if (image != null) {
        ImageIO.write(image, "PNG", imgFile);
    }
}
Пример Выходного Графического Изображения

Рекомендации

Оригинал: “https://dev.to/nikhilpereira1793/detecting-circular-references-in-a-java-project-32fd”