001 /*
002 * Sonar, open source software quality management tool.
003 * Copyright (C) 2009 SonarSource SA
004 * mailto:contact AT sonarsource DOT com
005 *
006 * Sonar 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 * Sonar 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
017 * License along with Sonar; if not, write to the Free Software
018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
019 */
020 package org.sonar.squid;
021
022 import java.util.Collection;
023 import java.util.List;
024 import java.util.Set;
025
026 import org.picocontainer.MutablePicoContainer;
027 import org.picocontainer.containers.TransientPicoContainer;
028 import org.sonar.squid.api.CodeScanner;
029 import org.sonar.squid.api.CodeVisitor;
030 import org.sonar.squid.api.Query;
031 import org.sonar.squid.api.SourceCode;
032 import org.sonar.squid.api.SourceCodeEdge;
033 import org.sonar.squid.api.SourceCodeSearchEngine;
034 import org.sonar.squid.api.SourceProject;
035 import org.sonar.squid.api.SquidConfiguration;
036 import org.sonar.graph.DirectedGraph;
037 import org.sonar.graph.DirectedGraphAccessor;
038 import org.sonar.squid.indexer.SquidIndex;
039
040 public class Squid implements DirectedGraphAccessor<SourceCode, SourceCodeEdge>, SourceCodeSearchEngine {
041
042 private MutablePicoContainer pico;
043 private SourceProject project;
044 private SquidIndex squidIndex;
045 private DirectedGraph<SourceCode, SourceCodeEdge> graph = new DirectedGraph<SourceCode, SourceCodeEdge>();
046
047 public Squid(SquidConfiguration conf) {
048 pico = new TransientPicoContainer();
049 pico.addComponent(conf);
050 project = new SourceProject("Project");
051 squidIndex = new SquidIndex();
052 squidIndex.index(project);
053 pico.addComponent(squidIndex);
054 pico.addComponent(project);
055 pico.addComponent(graph);
056 }
057
058 public Squid() {
059 this(new SquidConfiguration());
060 }
061
062 public <SCANNER extends CodeScanner> SCANNER register(Class<SCANNER> scannerClass) {
063 addToPicocontainer(scannerClass);
064 SCANNER scanner = pico.getComponent(scannerClass);
065 for (Object clazz : scanner.getVisitorClasses()) {
066 addToPicocontainer((Class) clazz);
067 scanner.accept(pico.<CodeVisitor> getComponent((Class) clazz));
068 }
069 return scanner;
070 }
071
072 public SourceProject aggregate() {
073 project.computeMeasures();
074 return project;
075 }
076
077 public SourceProject getProject() {
078 return project;
079 }
080
081 private void addToPicocontainer(Class classToExpose) {
082 if (pico.getComponent(classToExpose) == null) {
083 pico.addComponent(classToExpose);
084 }
085 }
086
087 public SourceCode search(String key) {
088 return squidIndex.search(key);
089 }
090
091 public Collection<SourceCode> search(Query... query) {
092 return squidIndex.search(query);
093 }
094
095 public SourceCodeEdge getEdge(SourceCode from, SourceCode to) {
096 return graph.getEdge(from, to);
097 }
098
099 public Collection<SourceCodeEdge> getIncomingEdges(SourceCode to) {
100 return graph.getIncomingEdges(to);
101 }
102
103 public Collection<SourceCodeEdge> getOutgoingEdges(SourceCode from) {
104 return graph.getOutgoingEdges(from);
105 }
106
107 public Set<SourceCode> getVertices() {
108 return graph.getVertices();
109 }
110
111 public List<SourceCodeEdge> getEdges(Collection<SourceCode> vertices) {
112 return graph.getEdges(vertices);
113 }
114
115 public boolean hasEdge(SourceCode from, SourceCode to) {
116 return graph.hasEdge(from, to);
117 }
118
119 public void flush() {
120 graph = null;
121 pico = null;
122 }
123 }