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    }