1 19 package org.netbeans.modules.java.editor.codegen; 20 21 import com.sun.source.tree.ClassTree; 22 import com.sun.source.tree.Tree; 23 import com.sun.source.util.SourcePositions; 24 import com.sun.source.util.TreePath; 25 import java.awt.Dialog ; 26 import java.io.IOException ; 27 import java.util.ArrayList ; 28 import java.util.Collections ; 29 import java.util.LinkedHashSet ; 30 import java.util.List ; 31 import java.util.Set ; 32 import javax.lang.model.element.Element; 33 import javax.lang.model.element.ElementKind; 34 import javax.lang.model.element.ExecutableElement; 35 import javax.lang.model.element.TypeElement; 36 import javax.lang.model.element.VariableElement; 37 import javax.lang.model.type.DeclaredType; 38 import javax.lang.model.util.ElementFilter; 39 import javax.swing.text.JTextComponent ; 40 import org.netbeans.api.java.source.CancellableTask; 41 import org.netbeans.api.java.source.CompilationController; 42 import org.netbeans.api.java.source.ElementHandle; 43 import org.netbeans.api.java.source.JavaSource; 44 import org.netbeans.api.java.source.WorkingCopy; 45 import org.netbeans.modules.editor.java.Utilities; 46 import org.netbeans.modules.java.editor.codegen.ui.ConstructorPanel; 47 import org.netbeans.modules.java.editor.codegen.ui.ElementNode; 48 import org.openide.DialogDescriptor; 49 import org.openide.DialogDisplayer; 50 import org.openide.util.Exceptions; 51 import org.openide.util.NbBundle; 52 53 57 public class ConstructorGenerator implements CodeGenerator { 58 59 public static class Factory implements CodeGenerator.Factory { 60 61 Factory() { 62 } 63 64 public Iterable <? extends CodeGenerator> create(CompilationController controller, TreePath path) throws IOException { 65 path = Utilities.getPathElementOfKind(Tree.Kind.CLASS, path); 66 if (path == null) 67 return Collections.emptySet(); 68 controller.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED); 69 TypeElement typeElement = (TypeElement)controller.getTrees().getElement(path); 70 if (!typeElement.getKind().isClass()) 71 return Collections.emptySet(); 72 final Set <VariableElement> initializedFields = new LinkedHashSet <VariableElement>(); 73 final Set <VariableElement> uninitializedFields = new LinkedHashSet <VariableElement>(); 74 final List <ExecutableElement> constructors = new ArrayList <ExecutableElement>(); 75 final List <ExecutableElement> inheritedConstructors = new ArrayList <ExecutableElement>(); 76 TypeElement superClass = (TypeElement)((DeclaredType)typeElement.getSuperclass()).asElement(); 77 for (ExecutableElement executableElement : ElementFilter.constructorsIn(superClass.getEnclosedElements())) { 78 inheritedConstructors.add(executableElement); 79 } 80 GeneratorUtils.scanForFieldsAndConstructors(controller, path, initializedFields, uninitializedFields, constructors); 81 ElementHandle<? extends Element> constructorHandle = null; 82 ElementNode.Description constructorDescription = null; 83 if (typeElement.getKind() != ElementKind.ENUM && inheritedConstructors.size() == 1) { 84 constructorHandle = ElementHandle.create(inheritedConstructors.get(0)); 85 } else if (inheritedConstructors.size() > 1) { 86 List <ElementNode.Description> constructorDescriptions = new ArrayList <ElementNode.Description>(); 87 for (ExecutableElement constructorElement : inheritedConstructors) 88 constructorDescriptions.add(ElementNode.Description.create(constructorElement, null, true, false)); 89 constructorDescription = ElementNode.Description.create(superClass, constructorDescriptions, false, false); 90 } 91 ElementNode.Description fieldsDescription = null; 92 if (!uninitializedFields.isEmpty()) { 93 List <ElementNode.Description> fieldDescriptions = new ArrayList <ElementNode.Description>(); 94 for (VariableElement variableElement : uninitializedFields) 95 fieldDescriptions.add(ElementNode.Description.create(variableElement, null, true, false)); 96 fieldsDescription = ElementNode.Description.create(typeElement, fieldDescriptions, false, false); 97 } 98 if (constructorHandle == null && constructorDescription == null && fieldsDescription == null) 99 return Collections.emptySet(); 100 return Collections.singleton(new ConstructorGenerator(constructorHandle, constructorDescription, fieldsDescription)); 101 } 102 } 103 104 private ElementHandle<? extends Element> constructorHandle; 105 private ElementNode.Description constructorDescription; 106 private ElementNode.Description fieldsDescription; 107 108 109 private ConstructorGenerator(ElementHandle<? extends Element> constructorHandle, ElementNode.Description constructorDescription, ElementNode.Description fieldsDescription) { 110 this.constructorHandle = constructorHandle; 111 this.constructorDescription = constructorDescription; 112 this.fieldsDescription = fieldsDescription; 113 } 114 115 public String getDisplayName() { 116 return org.openide.util.NbBundle.getMessage(ConstructorGenerator.class, "LBL_constructor"); } 118 119 public void invoke(JTextComponent component) { 120 final List <ElementHandle<? extends Element>> fieldHandles; 121 if (constructorDescription != null || fieldsDescription != null) { 122 ConstructorPanel panel = new ConstructorPanel(constructorDescription, fieldsDescription); 123 DialogDescriptor dialogDescriptor = new DialogDescriptor(panel, NbBundle.getMessage(ConstructorGenerator.class, "LBL_generate_constructor")); Dialog dialog = DialogDisplayer.getDefault().createDialog(dialogDescriptor); 125 dialog.setVisible(true); 126 if (dialogDescriptor.getValue() != DialogDescriptor.OK_OPTION) 127 return; 128 if (constructorHandle == null) 129 constructorHandle = panel.getInheritedConstructor(); 130 fieldHandles = panel.getVariablesToInitialize(); 131 } else { 132 fieldHandles = null; 133 } 134 JavaSource js = JavaSource.forDocument(component.getDocument()); 135 if (js != null) { 136 try { 137 final int caretOffset = component.getCaretPosition(); 138 js.runModificationTask(new CancellableTask<WorkingCopy>() { 139 public void cancel() { 140 } 141 public void run(WorkingCopy copy) throws IOException { 142 copy.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED); 143 TreePath path = copy.getTreeUtilities().pathFor(caretOffset); 144 path = Utilities.getPathElementOfKind(Tree.Kind.CLASS, path); 145 int idx = 0; 146 SourcePositions sourcePositions = copy.getTrees().getSourcePositions(); 147 for (Tree tree : ((ClassTree)path.getLeaf()).getMembers()) { 148 if (sourcePositions.getStartPosition(path.getCompilationUnit(), tree) < caretOffset) 149 idx++; 150 else 151 break; 152 } 153 ArrayList <VariableElement> variableElements = new ArrayList <VariableElement>(); 154 if (fieldHandles != null) { 155 for (ElementHandle<? extends Element> elementHandle : fieldHandles) 156 variableElements.add((VariableElement)elementHandle.resolve(copy)); 157 } 158 GeneratorUtils.generateConstructor(copy, path, variableElements, constructorHandle != null ? (ExecutableElement)constructorHandle.resolve(copy) : null, idx); 159 } 160 }).commit(); 161 } catch (IOException ex) { 162 Exceptions.printStackTrace(ex); 163 } 164 } 165 } 166 } 167 | Popular Tags |