001////////////////////////////////////////////////////////////////////////////////
002// checkstyle: Checks Java source code for adherence to a set of rules.
003// Copyright (C) 2001-2014  Oliver Burn
004//
005// This library is free software; you can redistribute it and/or
006// modify it under the terms of the GNU Lesser General Public
007// License as published by the Free Software Foundation; either
008// version 2.1 of the License, or (at your option) any later version.
009//
010// This library is distributed in the hope that it will be useful,
011// but WITHOUT ANY WARRANTY; without even the implied warranty of
012// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013// Lesser General Public License for more details.
014//
015// You should have received a copy of the GNU Lesser General Public
016// License along with this library; if not, write to the Free Software
017// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
018////////////////////////////////////////////////////////////////////////////////
019package com.puppycrawl.tools.checkstyle.checks.coding;
020
021import com.google.common.collect.Sets;
022import com.puppycrawl.tools.checkstyle.api.DetailAST;
023import com.puppycrawl.tools.checkstyle.api.FullIdent;
024import com.puppycrawl.tools.checkstyle.api.TokenTypes;
025import java.util.Set;
026
027/**
028 * Throwing java.lang.Error or java.lang.RuntimeException
029 * is almost never acceptable.
030 * @author Oliver Burn
031 */
032public final class IllegalThrowsCheck extends AbstractIllegalCheck
033{
034
035    /** Default ignored method names. */
036    private static final String[] DEFAULT_IGNORED_METHOD_NAMES = {
037        "finalize",
038    };
039
040    /** methods which should be ignored. */
041    private final Set<String> mIgnoredMethodNames = Sets.newHashSet();
042
043    /** Creates new instance of the check. */
044    public IllegalThrowsCheck()
045    {
046        super(new String[] {"Error",
047                            "RuntimeException", "Throwable",
048                            "java.lang.Error",
049                            "java.lang.RuntimeException",
050                            "java.lang.Throwable",
051        });
052        setIgnoredMethodNames(DEFAULT_IGNORED_METHOD_NAMES);
053    }
054
055    @Override
056    public int[] getDefaultTokens()
057    {
058        return new int[] {TokenTypes.LITERAL_THROWS};
059    }
060
061    @Override
062    public int[] getRequiredTokens()
063    {
064        return getDefaultTokens();
065    }
066
067    @Override
068    public void visitToken(DetailAST aDetailAST)
069    {
070        DetailAST token = aDetailAST.getFirstChild();
071        // Check if the method with the given name should be ignored.
072        if (!(shouldIgnoreMethod(aDetailAST.getParent().findFirstToken(
073                                     TokenTypes.IDENT).getText())))
074        {
075            while (token != null) {
076                if (token.getType() != TokenTypes.COMMA) {
077                    final FullIdent ident = FullIdent.createFullIdent(token);
078                    if (isIllegalClassName(ident.getText())) {
079                        log(token, "illegal.throw", ident.getText());
080                    }
081                }
082                token = token.getNextSibling();
083            }
084        }
085    }
086
087    /**
088     * Check if the method is specified in the ignore method list
089     * @param aName the name to check
090     * @return whether the method with the passed name should be ignored
091     */
092    private boolean shouldIgnoreMethod(String aName)
093    {
094        return mIgnoredMethodNames.contains(aName);
095    }
096
097    /**
098     * Set the list of ignore method names.
099     * @param aMethodNames array of ignored method names
100     */
101    public void setIgnoredMethodNames(String[] aMethodNames)
102    {
103        mIgnoredMethodNames.clear();
104        for (String element : aMethodNames) {
105            mIgnoredMethodNames.add(element);
106        }
107    }
108}