001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.websvc.core;
043:
044: import com.sun.source.tree.ClassTree;
045: import com.sun.source.util.TreePathScanner;
046: import java.util.ArrayList;
047: import java.util.List;
048: import java.util.Map;
049: import java.util.Map.Entry;
050: import javax.lang.model.element.AnnotationMirror;
051: import javax.lang.model.element.AnnotationValue;
052: import javax.lang.model.element.Element;
053: import javax.lang.model.element.ExecutableElement;
054: import javax.lang.model.element.Modifier;
055: import javax.lang.model.element.TypeElement;
056: import javax.lang.model.util.ElementFilter;
057: import org.netbeans.api.java.source.CompilationInfo;
058:
059: /**
060: *
061: * @author rico
062: */
063: public class MethodVisitor {
064:
065: private String operationName;
066: private ExecutableElement method;
067: private CompilationInfo info;
068: private boolean hasWebMethod;
069: private boolean hasPublicMethod;
070: private List<ExecutableElement> publicMethods;
071:
072: /** Creates a new instance of MethodLocator */
073: public MethodVisitor(CompilationInfo info) {
074: this .info = info;
075: }
076:
077: public ExecutableElement getMethod(String operationName) {
078: this .operationName = operationName;
079: new JavaMethodVisitor().scan(info.getCompilationUnit(), null);
080: return method;
081: }
082:
083: public boolean hasWebMethod() {
084: new WebMethodVisitor().scan(info.getCompilationUnit(), null);
085: return hasWebMethod;
086: }
087:
088: public List<ExecutableElement> getPublicMethods() {
089: new PublicMethodVisitor().scan(info.getCompilationUnit(), null);
090: return publicMethods;
091: }
092:
093: public boolean hasPublicMethod() {
094: new PublicMethodVisitor().scan(info.getCompilationUnit(), null);
095: return hasPublicMethod;
096: }
097:
098: private class PublicMethodVisitor extends
099: TreePathScanner<Void, Void> {
100: public PublicMethodVisitor() {
101: publicMethods = new ArrayList<ExecutableElement>();
102: }
103:
104: @Override
105: public Void visitClass(ClassTree t, Void v) {
106: Element el = info.getTrees().getElement(getCurrentPath());
107: if (el != null) {
108: TypeElement te = (TypeElement) el;
109: List<ExecutableElement> methods = ElementFilter
110: .methodsIn(te.getEnclosedElements());
111: for (ExecutableElement m : methods) {
112: if (m.getModifiers().contains(Modifier.PUBLIC)) {
113: hasPublicMethod = true;
114: publicMethods.add(m);
115: }
116:
117: }
118: }
119: return null;
120: }
121: }
122:
123: private class WebMethodVisitor extends TreePathScanner<Void, Void> {
124: @Override
125: public Void visitClass(ClassTree t, Void v) {
126: Element el = info.getTrees().getElement(getCurrentPath());
127: if (el != null) {
128: TypeElement te = (TypeElement) el;
129: List<ExecutableElement> methods = ElementFilter
130: .methodsIn(te.getEnclosedElements());
131: for (ExecutableElement m : methods) {
132: if (hasWebMethodAnnotation(m)) {
133: hasWebMethod = true;
134: break;
135: }
136: }
137: }
138: return null;
139: }
140: }
141:
142: private class JavaMethodVisitor extends TreePathScanner<Void, Void> {
143:
144: public JavaMethodVisitor() {
145:
146: }
147:
148: @Override
149: public Void visitClass(ClassTree t, Void v) {
150: Element el = info.getTrees().getElement(getCurrentPath());
151: if (el != null) {
152: TypeElement te = (TypeElement) el;
153: List<ExecutableElement> methods = ElementFilter
154: .methodsIn(te.getEnclosedElements());
155: for (ExecutableElement m : methods) {
156: if (isMethodFor(m, operationName)) {
157: method = m;
158: break;
159: }
160:
161: }
162: }
163: return null;
164: }
165: }
166:
167: /**
168: * Determines if the method has a WebMethod annotation and if it does
169: * that the exclude attribute is not set
170: */
171: private boolean hasWebMethodAnnotation(ExecutableElement method) {
172: boolean isWebMethod = false;
173: TypeElement methodAnotationEl = info.getElements()
174: .getTypeElement("javax.jws.WebMethod"); //NOI18N
175: List<? extends AnnotationMirror> methodAnnotations = method
176: .getAnnotationMirrors();
177: for (AnnotationMirror anMirror : methodAnnotations) {
178: if (info.getTypes().isSameType(methodAnotationEl.asType(),
179: anMirror.getAnnotationType())) {
180: //WebMethod found, set boolean to true
181: isWebMethod = true;
182: //Now determine if "exclude" is present and set to true
183: Map<? extends ExecutableElement, ? extends AnnotationValue> expressions = anMirror
184: .getElementValues();
185: for (Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : expressions
186: .entrySet()) {
187: if (entry.getKey().getSimpleName().contentEquals(
188: "exclude")) { //NOI18N
189: String value = (String) expressions.get(
190: entry.getKey()).getValue();
191: if ("true".equals(value)) {
192: isWebMethod = false;
193: break;
194: }
195: }
196: }
197: }
198: break;
199: }
200: return isWebMethod;
201: }
202:
203: /**
204: * Determines if the WSDL operation is the corresponding Java method
205: */
206: private boolean isMethodFor(ExecutableElement method,
207: String operationName) {
208: if (method.getSimpleName().toString().equals(operationName)) {
209: return true;
210: }
211:
212: //if method name is not the same as the operation name, look at WebMethod annotation
213: TypeElement methodAnotationEl = info.getElements()
214: .getTypeElement("javax.jws.WebMethod"); //NOI18N
215: List<? extends AnnotationMirror> methodAnnotations = method
216: .getAnnotationMirrors();
217: for (AnnotationMirror anMirror : methodAnnotations) {
218: if (info.getTypes().isSameType(methodAnotationEl.asType(),
219: anMirror.getAnnotationType())) {
220: Map<? extends ExecutableElement, ? extends AnnotationValue> expressions = anMirror
221: .getElementValues();
222: for (Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : expressions
223: .entrySet()) {
224: if (entry.getKey().getSimpleName().contentEquals(
225: "operationName")) { //NOI18N
226: String name = (String) expressions.get(
227: entry.getKey()).getValue();
228: if (operationName.equals(name)) {
229: return true;
230: }
231: }
232: }
233: }
234: }
235: return false;
236: }
237: }
|