Lines 41-47
Link Here
|
41 |
* Version 2 license, then the option applies only if the new code is |
41 |
* Version 2 license, then the option applies only if the new code is |
42 |
* made subject to such option by the copyright holder. |
42 |
* made subject to such option by the copyright holder. |
43 |
*/ |
43 |
*/ |
44 |
|
|
|
45 |
package org.netbeans.modules.j2ee.jpa.verification.rules.entity; |
44 |
package org.netbeans.modules.j2ee.jpa.verification.rules.entity; |
46 |
|
45 |
|
47 |
import java.util.ArrayList; |
46 |
import java.util.ArrayList; |
Lines 49-75
Link Here
|
49 |
import java.util.List; |
48 |
import java.util.List; |
50 |
import java.util.ListResourceBundle; |
49 |
import java.util.ListResourceBundle; |
51 |
import java.util.Locale; |
50 |
import java.util.Locale; |
52 |
import java.util.Map; |
|
|
53 |
import java.util.MissingResourceException; |
51 |
import java.util.MissingResourceException; |
54 |
import java.util.ResourceBundle; |
52 |
import java.util.ResourceBundle; |
55 |
import java.util.logging.Level; |
53 |
import java.util.logging.Level; |
56 |
import javax.lang.model.element.AnnotationMirror; |
|
|
57 |
import javax.lang.model.element.AnnotationValue; |
58 |
import javax.lang.model.element.ExecutableElement; |
59 |
import javax.lang.model.element.TypeElement; |
54 |
import javax.lang.model.element.TypeElement; |
60 |
import org.eclipse.persistence.jpa.internal.jpql.JPQLQueryProblemResourceBundle; |
55 |
import org.eclipse.persistence.jpa.internal.jpql.JPQLQueryProblemResourceBundle; |
61 |
import org.eclipse.persistence.jpa.jpql.JPQLQueryHelper; |
56 |
import org.eclipse.persistence.jpa.jpql.JPQLQueryHelper; |
62 |
import org.eclipse.persistence.jpa.jpql.JPQLQueryProblem; |
57 |
import org.eclipse.persistence.jpa.jpql.JPQLQueryProblem; |
63 |
import org.netbeans.api.project.FileOwnerQuery; |
58 |
import org.netbeans.api.project.FileOwnerQuery; |
64 |
import org.netbeans.api.project.Project; |
59 |
import org.netbeans.api.project.Project; |
65 |
import org.netbeans.modules.j2ee.jpa.model.JPAAnnotations; |
|
|
66 |
import org.netbeans.modules.j2ee.jpa.verification.CancelListener; |
60 |
import org.netbeans.modules.j2ee.jpa.verification.CancelListener; |
67 |
import org.netbeans.modules.j2ee.jpa.verification.JPAClassRule; |
61 |
import org.netbeans.modules.j2ee.jpa.verification.JPAClassRule; |
68 |
import org.netbeans.modules.j2ee.jpa.verification.JPAClassRule.ClassConstraints; |
62 |
import org.netbeans.modules.j2ee.jpa.verification.JPAClassRule.ClassConstraints; |
69 |
import org.netbeans.modules.j2ee.jpa.verification.JPAProblemContext; |
63 |
import org.netbeans.modules.j2ee.jpa.verification.JPAProblemContext; |
70 |
import org.netbeans.modules.j2ee.jpa.verification.JPAProblemFinder; |
64 |
import org.netbeans.modules.j2ee.jpa.verification.JPAProblemFinder; |
71 |
import org.netbeans.modules.j2ee.jpa.verification.common.ProblemContext; |
65 |
import org.netbeans.modules.j2ee.jpa.verification.common.ProblemContext; |
72 |
import org.netbeans.modules.j2ee.jpa.verification.common.Utilities; |
|
|
73 |
import org.netbeans.modules.j2ee.persistence.api.metadata.orm.Entity; |
66 |
import org.netbeans.modules.j2ee.persistence.api.metadata.orm.Entity; |
74 |
import org.netbeans.modules.j2ee.persistence.api.metadata.orm.NamedQuery; |
67 |
import org.netbeans.modules.j2ee.persistence.api.metadata.orm.NamedQuery; |
75 |
import org.netbeans.modules.j2ee.persistence.spi.jpql.ManagedTypeProvider; |
68 |
import org.netbeans.modules.j2ee.persistence.spi.jpql.ManagedTypeProvider; |
Lines 78-179
Link Here
|
78 |
import org.netbeans.spi.editor.hints.Severity; |
71 |
import org.netbeans.spi.editor.hints.Severity; |
79 |
|
72 |
|
80 |
/** |
73 |
/** |
81 |
* Verify content of @NamedQuery query |
74 |
* Verify content of |
82 |
* TODO: good to move warning to query level instead of class level |
75 |
* |
|
|
76 |
* @NamedQuery query TODO: good to move warning to query level instead of class |
77 |
* level |
83 |
*/ |
78 |
*/ |
84 |
public class JPQLValidation extends JPAClassRule implements CancelListener{ |
79 |
public class JPQLValidation extends JPAClassRule implements CancelListener { |
85 |
|
80 |
|
86 |
private ManagedTypeProvider mtp;//need to store as jpql validation may be too long and need to be cancelled if required |
81 |
private ManagedTypeProvider mtp;//need to store as jpql validation may be too long and need to be cancelled if required |
87 |
private JPQLQueryHelper helper; |
82 |
private JPQLQueryHelper helper; |
88 |
/** Creates a new instance of NonFinalClass */ |
83 |
|
|
|
84 |
/** |
85 |
* Creates a new instance of NonFinalClass |
86 |
*/ |
89 |
public JPQLValidation() { |
87 |
public JPQLValidation() { |
90 |
setClassContraints(Arrays.asList(ClassConstraints.ENTITY, |
88 |
setClassContraints(Arrays.asList(ClassConstraints.ENTITY, |
91 |
ClassConstraints.EMBEDDABLE, |
89 |
ClassConstraints.EMBEDDABLE, |
92 |
ClassConstraints.MAPPED_SUPERCLASS)); |
90 |
ClassConstraints.MAPPED_SUPERCLASS)); |
93 |
} |
91 |
} |
94 |
|
92 |
|
95 |
@Override public ErrorDescription[] apply(TypeElement subject, ProblemContext ctx){ |
93 |
@Override |
96 |
JPAProblemContext jpaCtx = (JPAProblemContext)ctx; |
94 |
public ErrorDescription[] apply(TypeElement subject, ProblemContext ctx) { |
|
|
95 |
JPAProblemContext jpaCtx = (JPAProblemContext) ctx; |
97 |
jpaCtx.addCancelListener(this); |
96 |
jpaCtx.addCancelListener(this); |
98 |
Object modEl = ctx.getModelElement(); |
97 |
Object modEl = ctx.getModelElement(); |
99 |
Entity entity = (Entity) (modEl instanceof Entity ? modEl : null); |
98 |
Entity entity = (Entity) (modEl instanceof Entity ? modEl : null); |
100 |
List<AnnotationMirror> first = Utilities.findAnnotations(subject, JPAAnnotations.NAMED_QUERY); |
|
|
101 |
ArrayList<String> values = new ArrayList<String>(); |
102 |
ArrayList<String> names = new ArrayList<String>(); |
103 |
if(first == null || first.size()==0){ |
104 |
AnnotationMirror qs = Utilities.findAnnotation(subject, JPAAnnotations.NAMED_QUERIES); |
105 |
if(qs != null){ |
106 |
Map<? extends ExecutableElement, ? extends AnnotationValue> maps = qs.getElementValues(); |
107 |
for(AnnotationValue vl:maps.values()){ |
108 |
List lst = (List) vl.getValue(); |
109 |
for(Object val:lst){ |
110 |
if(val instanceof AnnotationMirror){ |
111 |
AnnotationMirror am = (AnnotationMirror) val; |
112 |
if(JPAAnnotations.NAMED_QUERY.equals(am.getAnnotationType().toString())){ |
113 |
AnnotationValue qAttrValue = Utilities.getAnnotationAttrValue(am, "query"); |
114 |
AnnotationValue nmAttrValue = Utilities.getAnnotationAttrValue(am, "name"); |
115 |
if(qAttrValue != null){ |
116 |
values.add(qAttrValue.getValue().toString()); |
117 |
names.add(nmAttrValue == null ? "" : nmAttrValue.getValue().toString()); |
118 |
} |
119 |
} |
120 |
} |
121 |
} |
122 |
} |
123 |
} |
124 |
} |
125 |
else { |
126 |
for(AnnotationMirror mr:first){ |
127 |
AnnotationValue qAttrValue = Utilities.getAnnotationAttrValue(mr, "query"); |
128 |
AnnotationValue nmAttrValue = Utilities.getAnnotationAttrValue(mr, "name"); |
129 |
if(qAttrValue != null){ |
130 |
values.add(qAttrValue.getValue().toString()); |
131 |
names.add(nmAttrValue == null ? "" : nmAttrValue.getValue().toString()); |
132 |
} |
133 |
} |
134 |
} |
135 |
helper = new JPQLQueryHelper(); |
99 |
helper = new JPQLQueryHelper(); |
136 |
Project project = FileOwnerQuery.getOwner(ctx.getFileObject()); |
100 |
Project project = FileOwnerQuery.getOwner(ctx.getFileObject()); |
137 |
List<JPQLQueryProblem> problems = new ArrayList<JPQLQueryProblem>(); |
101 |
List<JPQLQueryProblem> problems = new ArrayList<JPQLQueryProblem>(); |
138 |
mtp = new ManagedTypeProvider(project, jpaCtx.getMetaData(), jpaCtx.getCompilationInfo().getElements()); |
102 |
mtp = new ManagedTypeProvider(project, jpaCtx.getMetaData(), jpaCtx.getCompilationInfo().getElements()); |
139 |
for(int index=0;index<values.size() && !ctx.isCancelled();index++){ |
103 |
if (entity != null) { |
140 |
String value = values.get(index); |
104 |
for (NamedQuery nq : entity.getNamedQuery()) { |
141 |
String qName = names.get(index); |
105 |
helper.setQuery(new Query(nq, nq.getQuery(), mtp)); |
142 |
NamedQuery nq = null; |
106 |
List<JPQLQueryProblem> tmp = null; |
143 |
if(entity != null) { |
107 |
try { |
144 |
nq = entity.newNamedQuery(); |
108 |
tmp = helper.validate(); |
145 |
nq.setQuery(value); |
109 |
} catch (UnsupportedOperationException ex) { |
146 |
nq.setName(qName); |
110 |
JPAProblemFinder.LOG.log(Level.INFO, "Unsupported jpql validation case: " + ex.getMessage(), ex); |
|
|
111 |
} catch (NullPointerException ex) { |
112 |
JPAProblemFinder.LOG.log(Level.INFO, "NPE in jpql validation: " + ex.getMessage(), ex); |
113 |
} |
114 |
if (tmp != null && tmp.size() > 0) { |
115 |
problems.addAll(tmp); |
116 |
} |
117 |
helper.dispose(); |
147 |
} |
118 |
} |
148 |
helper.setQuery(new Query(nq, value, mtp)); |
|
|
149 |
List<JPQLQueryProblem> tmp = null; |
150 |
try{ |
151 |
tmp = helper.validate(); |
152 |
} catch (UnsupportedOperationException ex) { |
153 |
JPAProblemFinder.LOG.log(Level.INFO, "Unsupported jpql validation case: " + ex.getMessage(), ex); |
154 |
}catch (NullPointerException ex) { |
155 |
JPAProblemFinder.LOG.log(Level.INFO, "NPE in jpql validation: " + ex.getMessage(), ex); |
156 |
} |
157 |
if(tmp!=null && tmp.size()>0)problems.addAll(tmp); |
158 |
helper.dispose(); |
159 |
} |
119 |
} |
160 |
ErrorDescription[] ret = null; |
120 |
ErrorDescription[] ret = null; |
161 |
if (!ctx.isCancelled() && problems != null && problems.size()>0){ |
121 |
if (!ctx.isCancelled() && problems != null && problems.size() > 0) { |
162 |
ret = new ErrorDescription[problems.size()]; |
122 |
ret = new ErrorDescription[problems.size()]; |
163 |
for(int i=0;i<ret.length;i++){ |
123 |
for (int i = 0; i < ret.length; i++) { |
164 |
ListResourceBundle msgBundle = null; |
124 |
ListResourceBundle msgBundle = null; |
165 |
try{ |
125 |
try { |
166 |
msgBundle = (ListResourceBundle) ResourceBundle.getBundle(JPQLQueryProblemResourceBundle.class.getName());//NOI18N |
126 |
msgBundle = (ListResourceBundle) ResourceBundle.getBundle(JPQLQueryProblemResourceBundle.class.getName());//NOI18N |
167 |
} catch (MissingResourceException ex) {//default en |
127 |
} catch (MissingResourceException ex) {//default en |
168 |
msgBundle = (ListResourceBundle) ResourceBundle.getBundle(JPQLQueryProblemResourceBundle.class.getName(), Locale.ENGLISH);//NOI18N |
128 |
msgBundle = (ListResourceBundle) ResourceBundle.getBundle(JPQLQueryProblemResourceBundle.class.getName(), Locale.ENGLISH);//NOI18N |
169 |
} |
129 |
} |
170 |
String message = java.text.MessageFormat.format(msgBundle.getString(problems.get(i).getMessageKey()), (Object[]) problems.get(i).getMessageArguments()); |
130 |
String message = java.text.MessageFormat.format(msgBundle.getString(problems.get(i).getMessageKey()), (Object[]) problems.get(i).getMessageArguments()); |
171 |
String pos = "["+problems.get(i).getStartPosition() + ";"+problems.get(i).getEndPosition()+"]"; |
131 |
String pos = "[" + problems.get(i).getStartPosition() + ";" + problems.get(i).getEndPosition() + "]"; |
172 |
Query q = (Query) problems.get(i).getQuery(); |
132 |
Query q = (Query) problems.get(i).getQuery(); |
173 |
if(q.getNamedQuery() != null && q.getNamedQuery().getName()!=null){ |
133 |
if (q.getNamedQuery() != null && q.getNamedQuery().getName() != null) { |
174 |
pos = q.getNamedQuery().getName()+pos; |
134 |
pos = q.getNamedQuery().getName() + pos; |
175 |
} |
135 |
} |
176 |
ret[i] = createProblem(subject, ctx, pos + ": " + message , Severity.WARNING); |
136 |
ret[i] = createProblem(subject, ctx, pos + ": " + message, Severity.WARNING); |
177 |
} |
137 |
} |
178 |
} |
138 |
} |
179 |
jpaCtx.removeCancelListener(this); |
139 |
jpaCtx.removeCancelListener(this); |
Lines 181-196
Link Here
|
181 |
helper = null; |
141 |
helper = null; |
182 |
return ret; |
142 |
return ret; |
183 |
} |
143 |
} |
184 |
|
144 |
|
185 |
@Override protected boolean isApplicable(TypeElement subject, ProblemContext ctx) { |
145 |
@Override |
186 |
JPAProblemContext jpaCtx = (JPAProblemContext)ctx; |
146 |
protected boolean isApplicable(TypeElement subject, ProblemContext ctx) { |
187 |
|
147 |
JPAProblemContext jpaCtx = (JPAProblemContext) ctx; |
|
|
148 |
|
188 |
return (jpaCtx.isEntity() || jpaCtx.isMappedSuperClass()); |
149 |
return (jpaCtx.isEntity() || jpaCtx.isMappedSuperClass()); |
189 |
} |
150 |
} |
190 |
|
151 |
|
191 |
@Override |
152 |
@Override |
192 |
public void cancelled() { |
153 |
public void cancelled() { |
193 |
if(mtp != null)mtp.invalidate(); |
154 |
if (mtp != null) { |
194 |
if(helper != null)helper.dispose(); |
155 |
mtp.invalidate(); |
|
|
156 |
} |
157 |
if (helper != null) { |
158 |
helper.dispose(); |
159 |
} |
195 |
} |
160 |
} |
196 |
} |
161 |
} |