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.io.File;
023 import java.util.ArrayList;
024 import java.util.Collection;
025 import java.util.HashSet;
026 import java.util.List;
027 import java.util.Set;
028
029 import org.picocontainer.DefaultPicoContainer;
030 import org.picocontainer.MutablePicoContainer;
031 import org.sonar.squid.api.CodeScanner;
032 import org.sonar.squid.api.CodeVisitor;
033 import org.sonar.squid.api.SourceCode;
034 import org.sonar.squid.api.SourceProject;
035 import org.sonar.squid.api.SquidConfiguration;
036 import org.sonar.squid.indexer.Query;
037 import org.sonar.squid.indexer.SquidIndex;
038
039 public class Squid {
040
041 private MutablePicoContainer pico;
042 private SourceProject project;
043 private SquidIndex squidIndex;
044
045 public Squid(SquidConfiguration conf) {
046 pico = new DefaultPicoContainer();
047 pico.addComponent(conf);
048 project = new SourceProject("Project");
049 squidIndex = new SquidIndex();
050 squidIndex.index(project);
051 pico.addComponent(squidIndex);
052 }
053
054 public Squid() {
055 this(new SquidConfiguration());
056 }
057
058 public void scanDir(Class<? extends CodeScanner> codeScanner, File dirToAnalyse) {
059 if (dirToAnalyse == null) {
060 throw new IllegalStateException("There is no directory to analyze as the File object is null.");
061 }
062 scanFiles(codeScanner, traverse(dirToAnalyse));
063 }
064
065 public void scanFile(Class<? extends CodeScanner> codeScanner, File fileToAnalyse) {
066 if (fileToAnalyse == null) {
067 throw new IllegalStateException("There is no file to analyze as the File object is null.");
068 }
069 Set<File> files = new HashSet<File>();
070 files.add(fileToAnalyse);
071 scanFiles(codeScanner, files);
072 }
073
074 public void scanFiles(Class<? extends CodeScanner> codeScanner, Collection<File> filesToAnalyse) {
075 addToPicocontainer(codeScanner);
076 CodeScanner scanner = (CodeScanner) pico.getComponent(codeScanner);
077 for (Class<? extends CodeVisitor> visitorClasses : scanner.getVisitors()) {
078 addToPicocontainer(visitorClasses);
079 scanner.accept(pico.getComponent(visitorClasses));
080 }
081 scanner.scanCode(project, filesToAnalyse);
082 }
083
084 public SourceCode computeMeasures() {
085 project.computeMeasures();
086 return project;
087 }
088
089 private void addToPicocontainer(Class classToExpose) {
090 if (pico.getComponent(classToExpose) == null) {
091 pico.addComponent(classToExpose);
092 }
093 }
094
095 public SourceCode search(String key) {
096 return squidIndex.search(key);
097 }
098
099 public Collection<SourceCode> search(Query... query) {
100 return squidIndex.search(query);
101 }
102
103 private static List<File> traverse(File aNode) {
104 List<File> files = new ArrayList<File>();
105 if (aNode.canRead()) {
106 if (aNode.isDirectory()) {
107 final File[] nodes = aNode.listFiles();
108 for (File node : nodes) {
109 files.addAll(traverse(node));
110 }
111 } else if (aNode.isFile()) {
112 files.add(aNode);
113 }
114 }
115 return files;
116 }
117 }