001/*
002 * Sonar, open source software quality management tool.
003 * Copyright (C) 2008-2012 SonarSource
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 */
020package org.sonar.java.ast;
021
022import com.puppycrawl.tools.checkstyle.api.Check;
023import com.puppycrawl.tools.checkstyle.api.DetailAST;
024import org.slf4j.Logger;
025import org.slf4j.LoggerFactory;
026import org.sonar.api.resources.InputFile;
027import org.sonar.java.ast.visitor.JavaAstVisitor;
028import org.sonar.squid.text.Source;
029
030/**
031 * Delegate from Checkstyle {@link Check} to {@link JavaAstVisitor}s.
032 */
033public class CheckstyleSquidBridge extends Check {
034
035  private static Logger logger = LoggerFactory.getLogger(CheckstyleSquidBridge.class);
036
037  private static CheckstyleSquidBridgeContext bridgeContext;
038
039  /**
040   * @see CheckstyleSquidBridgeContext
041   */
042  static void setContext(CheckstyleSquidBridgeContext context) {
043    bridgeContext = context;
044  }
045
046  @Override
047  public int[] getDefaultTokens() {
048    return bridgeContext.getAllTokens();
049  }
050
051  @Override
052  public void beginTree(DetailAST ast) {
053    try {
054      String filename = getFileContents().getFilename();
055      Source source = createSource();
056      InputFile inputFile = bridgeContext.getInputFile(new java.io.File(filename));
057      for (JavaAstVisitor visitor : bridgeContext.getVisitors()) {
058        visitor.setFileContents(getFileContents());
059        visitor.setSource(source);
060        visitor.setInputFile(inputFile);
061        visitor.visitFile(ast);
062      }
063    } catch (RuntimeException e) {
064      logAndThrowException(e);
065    }
066  }
067
068  private Source createSource() {
069    return new Source(getFileContents().getLines(), bridgeContext.getCodeRecognizer());
070  }
071
072  @Override
073  public void visitToken(DetailAST ast) {
074    try {
075      for (JavaAstVisitor visitor : bridgeContext.getVisitors()) {
076        if (visitor.getWantedTokens().contains(ast.getType())) {
077          visitor.visitToken(ast);
078        }
079      }
080    } catch (RuntimeException e) {
081      logAndThrowException(e);
082    }
083  }
084
085  @Override
086  public void leaveToken(DetailAST ast) {
087    JavaAstVisitor[] visitors = bridgeContext.getVisitors();
088    try {
089      for (int i = visitors.length - 1; i >= 0; i--) {
090        JavaAstVisitor visitor = visitors[i];
091        if (visitor.getWantedTokens().contains(ast.getType())) {
092          visitor.leaveToken(ast);
093        }
094      }
095    } catch (RuntimeException e) {
096      logAndThrowException(e);
097    }
098  }
099
100  @Override
101  public void finishTree(DetailAST ast) {
102    JavaAstVisitor[] visitors = bridgeContext.getVisitors();
103    try {
104      for (int i = visitors.length - 1; i >= 0; i--) {
105        JavaAstVisitor visitor = visitors[i];
106        visitor.leaveFile(ast);
107      }
108    } catch (RuntimeException e) {
109      logAndThrowException(e);
110    }
111  }
112
113  private void logAndThrowException(RuntimeException e) {
114    logger.error("Squid Error occurs when analysing :" + getFileContents().getFilename(), e);
115    throw e;
116  }
117
118}