2 * Copyright 2003-2008 Dave Griffith, Bas Leijdekkers
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com
.siyeh
.ig
.resources
;
18 import com
.intellij
.psi
.*;
19 import com
.siyeh
.InspectionGadgetsBundle
;
20 import com
.siyeh
.ig
.BaseInspectionVisitor
;
21 import com
.siyeh
.ig
.psiutils
.TypeUtils
;
22 import org
.jetbrains
.annotations
.NonNls
;
23 import org
.jetbrains
.annotations
.NotNull
;
25 public class JNDIResourceInspection
extends ResourceInspection
{
28 public String
getID(){
29 return "JNDIResourceOpenedButNotSafelyClosed";
33 public String
getDisplayName(){
34 return InspectionGadgetsBundle
.message(
35 "jndi.resource.opened.not.closed.display.name");
39 public String
buildErrorString(Object
... infos
){
40 final PsiExpression expression
= (PsiExpression
) infos
[0];
41 final PsiType type
= expression
.getType();
43 final String text
= type
.getPresentableText();
44 return InspectionGadgetsBundle
.message(
45 "resource.opened.not.closed.problem.descriptor", text
);
48 public BaseInspectionVisitor
buildVisitor(){
49 return new JNDIResourceVisitor();
52 private static class JNDIResourceVisitor
extends BaseInspectionVisitor
{
54 @NonNls private static final String LIST
= "list";
55 @NonNls private static final String LIST_BINDING
= "listBindings";
56 @NonNls private static final String GET_ALL
= "getAll";
58 @Override public void visitMethodCallExpression(
59 @NotNull PsiMethodCallExpression expression
){
60 super.visitMethodCallExpression(expression
);
61 if(!isJNDIFactoryMethod(expression
)){
64 final PsiElement parent
= getExpressionParent(expression
);
65 if(parent
instanceof PsiReturnStatement
){
68 final PsiVariable boundVariable
= getVariable(parent
);
69 if(isSafelyClosed(boundVariable
, expression
)){
72 if(isResourceEscapedFromMethod(boundVariable
, expression
)){
75 registerError(expression
, expression
);
79 @Override public void visitNewExpression(
80 @NotNull PsiNewExpression expression
){
81 super.visitNewExpression(expression
);
82 if(!isJNDIResource(expression
)){
85 final PsiElement parent
= getExpressionParent(expression
);
86 if (parent
instanceof PsiReturnStatement
) {
89 final PsiVariable boundVariable
= getVariable(parent
);
90 if (isSafelyClosed(boundVariable
, expression
)) {
93 if(isResourceEscapedFromMethod(boundVariable
, expression
)){
96 registerError(expression
, expression
);
99 private static boolean isJNDIResource(PsiNewExpression expression
){
100 return TypeUtils
.expressionHasTypeOrSubtype(expression
,
101 "javax.naming.InitialContext");
104 private static boolean isJNDIFactoryMethod(
105 PsiMethodCallExpression expression
){
106 final PsiReferenceExpression methodExpression
=
107 expression
.getMethodExpression();
108 final String methodName
= methodExpression
.getReferenceName();
109 if (LIST
.equals(methodName
) || LIST_BINDING
.equals(methodName
)) {
110 final PsiExpression qualifier
=
111 methodExpression
.getQualifierExpression();
112 if (qualifier
== null) {
115 return TypeUtils
.expressionHasTypeOrSubtype(qualifier
,
116 "javax.naming.Context");
117 } else if (GET_ALL
.equals(methodName
)) {
118 final PsiExpression qualifier
=
119 methodExpression
.getQualifierExpression();
120 if (qualifier
== null) {
123 return TypeUtils
.expressionHasTypeOrSubtype(qualifier
,
124 "javax.naming.directory.Attribute") ||
125 TypeUtils
.expressionHasTypeOrSubtype(qualifier
,
126 "javax.naming.directory.Attributes");