1 19 package org.netbeans.modules.form; 20 21 import com.sun.source.tree.ClassTree; 22 import com.sun.source.tree.Tree; 23 import com.sun.source.tree.VariableTree; 24 import com.sun.source.util.SourcePositions; 25 import com.sun.source.util.TreePath; 26 import com.sun.source.util.TreeScanner; 27 import java.beans.Introspector ; 28 import java.io.IOException ; 29 import java.util.ArrayList ; 30 import java.util.Collections ; 31 import java.util.List ; 32 import java.util.logging.Level ; 33 import java.util.logging.Logger ; 34 import javax.lang.model.element.Element; 35 import javax.lang.model.element.ElementKind; 36 import javax.lang.model.element.ExecutableElement; 37 import javax.lang.model.element.TypeElement; 38 import javax.lang.model.type.TypeMirror; 39 import org.netbeans.api.editor.guards.SimpleSection; 40 import org.netbeans.api.java.classpath.ClassPath; 41 import org.netbeans.api.java.source.CancellableTask; 42 import org.netbeans.api.java.source.CompilationController; 43 import org.netbeans.api.java.source.JavaSource; 44 import org.netbeans.modules.form.project.ClassPathUtils; 45 import org.openide.filesystems.FileObject; 46 47 53 public class FormJavaSource { 54 55 private final FormDataObject formDataObject; 56 private List <String > fields = null; 57 private static final String [] PROPERTY_PREFIXES = new String [] {"get", "is"}; 60 public FormJavaSource(FormDataObject formDataObject) { 61 this.formDataObject = formDataObject; 62 } 63 64 public void refresh() { 65 this.fields = Collections.<String >emptyList(); 66 runUserActionTask(new CancellableTask<CompilationController>() { 67 public void cancel() { 68 } 69 public void run(CompilationController controller) throws Exception { 70 controller.toPhase(JavaSource.Phase.PARSED); 71 FormJavaSource.this.fields = getFieldNames(controller); 72 } 73 }); 74 75 } 76 77 private void runUserActionTask(CancellableTask<CompilationController> task) { 78 FileObject javaFileObject = formDataObject.getPrimaryFile(); 79 JavaSource js = JavaSource.forFileObject(javaFileObject); 80 if (js != null) { 81 try { 82 js.runUserActionTask(task, true); 83 } catch (IOException ex) { 84 Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex); 85 } 86 } 87 } 88 89 public boolean containsField(String name, boolean refresh) { 90 if(refresh) { 91 refresh(); 92 } 93 return fields != null && fields.contains(name); 94 } 95 96 private ClassTree findClassTree(CompilationController controller) { 97 String fileName = formDataObject.getPrimaryFile().getName(); 98 99 for (Tree t: controller.getCompilationUnit().getTypeDecls()) { 100 if (t.getKind() == Tree.Kind.CLASS && 101 fileName.equals(((ClassTree) t).getSimpleName().toString())) { 102 return (ClassTree) t; 103 } 104 } 105 return null; 106 } 107 108 private List <String > findMethodsByReturnType(CompilationController controller, TypeElement celem, Class returnType) { 109 List <String > methods = new ArrayList <String >(); 110 String returnTypeName = returnType.getName(); 111 TypeElement returnTypeElm = controller.getElements().getTypeElement(returnTypeName); 112 for (Element el: celem.getEnclosedElements()) { 113 if (el.getKind() == ElementKind.METHOD) { 114 ExecutableElement method = (ExecutableElement) el; 115 TypeMirror methodRT = method.getReturnType(); 116 if (controller.getTypes().isAssignable(returnTypeElm.asType(), methodRT)) { 117 methods.add(method.getSimpleName().toString()); 118 } 119 } 120 } 121 return methods; 122 } 123 126 public String [] getMethodNames(final Class returnType) { 127 final Object [] result = new Object [1]; 128 129 runUserActionTask(new CancellableTask<CompilationController>() { 130 public void cancel() { 131 } 132 public void run(CompilationController controller) throws Exception { 133 controller.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED); 134 135 ClassTree ct = findClassTree(controller); 136 if (ct != null) { 137 TreePath cpath = controller.getTrees().getPath(controller.getCompilationUnit(), ct); 138 TypeElement celem = (TypeElement) controller.getTrees().getElement(cpath); 139 List <String > names = findMethodsByReturnType(controller, celem, returnType); 140 result[0] = toArray(names); 141 } 142 143 } 144 }); 145 146 return result[0] == null? new String [0]: (String []) result[0]; 147 } 148 149 153 public String [] getPropertyReadMethodNames(Class returnType) { 154 String [] names = getMethodNames(returnType); 155 List <String > result = new ArrayList <String >(names.length); 156 for (String name: names) { 157 if(!FormJavaSource.extractPropertyName(name).equals("")) { result.add(name); 160 } 161 162 } 163 164 return toArray(result); 165 166 } 167 168 171 public static String extractPropertyName(String methodName) { 172 for (int i = 0; i < PROPERTY_PREFIXES.length; i++) { 173 if(methodName.startsWith(PROPERTY_PREFIXES[i]) && 174 methodName.length() > PROPERTY_PREFIXES[i].length()) 175 { 176 return Introspector.decapitalize(methodName.substring(PROPERTY_PREFIXES[i].length())); 177 } 178 } 179 return ""; } 181 182 private List <String > getFieldNames(final CompilationController controller) { 183 SimpleSection variablesSection = 184 formDataObject.getFormEditorSupport().getVariablesSection(); 185 186 if(variablesSection==null) { 187 return null; 188 } 189 190 final int genVariablesStartOffset = variablesSection.getStartPosition().getOffset(); 191 final int genVariablesEndOffset = variablesSection.getEndPosition().getOffset(); 192 193 final SourcePositions positions = controller.getTrees().getSourcePositions(); 194 195 TreeScanner scan = new TreeScanner<Void , List <String >>() { 196 @Override 197 public Void visitClass(ClassTree node, List <String > p) { 198 long startOffset = positions.getStartPosition(controller.getCompilationUnit(), node); 199 long endOffset = positions.getEndPosition(controller.getCompilationUnit(), node); 200 if (genVariablesStartOffset > startOffset && genVariablesEndOffset < endOffset) { 201 for (Tree tree: node.getMembers()) { 202 if (tree.getKind() == Tree.Kind.VARIABLE) { 203 testVariable((VariableTree) tree, p); 204 } 205 } 206 } 207 return null; 208 } 209 210 private void testVariable(VariableTree node, List <String > p) { 211 long startOffset = positions.getStartPosition(controller.getCompilationUnit(), node); 212 if (startOffset >= genVariablesEndOffset || 213 startOffset <= genVariablesStartOffset) { 214 p.add(node.getName().toString()); 215 } 216 } 217 }; 218 219 List <String > fields = new ArrayList <String >(); 220 scan.scan(controller.getCompilationUnit(), fields); 221 222 return fields; 223 } 224 225 private boolean isAssignableFrom(String typeName, Class returnType) { 226 Class clazz = getClassByName(typeName); 227 return clazz!=null ? returnType.isAssignableFrom(clazz) : false; 228 } 229 230 private Class getClassByName(String className) { 231 Class clazz = null; 232 try { 233 clazz = ClassPathUtils.loadClass(className, formDataObject.getPrimaryFile()); 234 } 235 catch (Exception ex) { 236 ex.printStackTrace(); 238 } 239 catch (LinkageError ex) { 240 ex.printStackTrace(); 241 } 242 return clazz; 243 } 244 245 private static String [] toArray(List list) { 246 return (String [])list.toArray(new String [list.size()]); 247 } 248 249 public static boolean isInDefaultPackage(FormModel formModel) { 250 FileObject fdo = FormEditor.getFormDataObject(formModel).getPrimaryFile(); 251 ClassPath cp = ClassPath.getClassPath(fdo, ClassPath.SOURCE); 252 String name = cp.getResourceName(fdo); 253 return name.indexOf('/') < 0; 254 } 255 256 } 257 | Popular Tags |