1 19 package org.netbeans.modules.java.editor.codegen.ui; 20 21 22 import java.awt.Image ; 23 import java.awt.event.ActionEvent ; 24 import java.util.ArrayList ; 25 import java.util.Iterator ; 26 import java.util.List ; 27 import java.util.Set ; 28 import javax.lang.model.element.Element; 29 import javax.lang.model.element.ElementKind; 30 import javax.lang.model.element.ExecutableElement; 31 import javax.lang.model.element.Modifier; 32 import javax.lang.model.element.TypeElement; 33 import javax.lang.model.element.TypeParameterElement; 34 import javax.lang.model.element.VariableElement; 35 import javax.lang.model.type.ArrayType; 36 import javax.lang.model.type.DeclaredType; 37 import javax.lang.model.type.TypeKind; 38 import javax.lang.model.type.TypeMirror; 39 import javax.lang.model.type.TypeVariable; 40 import javax.lang.model.type.WildcardType; 41 import javax.swing.AbstractAction ; 42 import javax.swing.Action ; 43 import org.netbeans.api.java.source.ElementHandle; 44 import org.netbeans.api.java.source.UiUtils; 45 import org.netbeans.modules.java.editor.codegen.ui.ElementNode.Description; 46 import org.openide.nodes.AbstractNode; 47 import org.openide.nodes.Children; 48 import org.openide.nodes.Node; 49 import org.openide.util.Utilities; 50 import org.openide.util.lookup.Lookups; 51 52 56 public class ElementNode extends AbstractNode { 57 58 private Description description; 59 private boolean singleSelection; 60 61 62 public ElementNode(Description description) { 63 super(description.subs == null ? Children.LEAF: new ElementChilren(description.subs), Lookups.singleton(description)); 64 this.description = description; 65 description.node = this; 66 setDisplayName(description.name); 67 } 68 69 public void setSingleSelection( boolean singleSelection ) { 70 this.singleSelection = singleSelection; 71 } 72 73 @Override 74 public Image getIcon(int type) { 75 if (description.elementHandle == null) 76 return super.getIcon(type); 77 return Utilities.icon2Image(UiUtils.getElementIcon(description.elementHandle.getKind(), description.modifiers)); 78 } 79 80 @Override 81 public Image getOpenedIcon(int type) { 82 return getIcon(type); 83 } 84 85 @Override 86 public java.lang.String getDisplayName() { 87 return description.name; 88 } 89 90 @Override 91 public String getHtmlDisplayName() { 92 return description.htmlHeader; 93 } 94 95 public void assureSingleSelection() { 96 Node pn = getParentNode(); 97 if (pn == null && singleSelection ) { 98 description.deepSetSelected( false ); 99 } 100 else if ( pn != null ) { 101 Description d = pn.getLookup().lookup(Description.class); 102 if ( d != null ) { 103 d.node.assureSingleSelection(); 104 } 105 } 106 } 107 108 private static final class ElementChilren extends Children.Keys<Description> { 109 110 public ElementChilren(List <Description> descriptions) { 111 setKeys(descriptions); 112 } 113 114 protected Node[] createNodes(Description key) { 115 return new Node[] {new ElementNode(key)}; 116 } 117 } 118 119 121 public static class Description { 122 123 private ElementNode node; 124 125 private String name; 126 private ElementHandle<? extends Element> elementHandle; 127 private Set <Modifier> modifiers; 128 private List <Description> subs; 129 private String htmlHeader; 130 private boolean isSelected; 131 private boolean isSelectable; 132 133 public static Description create(List <Description> subs) { 134 return new Description("<root>", null, null, subs, null, false, false); } 136 137 public static Description create(Element element, List <Description> subs, boolean isSelectable, boolean isSelected ) { 138 String htmlHeader = null; 139 switch (element.getKind()) { 140 case ANNOTATION_TYPE: 141 case CLASS: 142 case ENUM: 143 case INTERFACE: 144 htmlHeader = createHtmlHeader((TypeElement)element); 145 break; 146 case ENUM_CONSTANT: 147 case FIELD: 148 htmlHeader = createHtmlHeader((VariableElement)element); 149 break; 150 case CONSTRUCTOR: 151 case METHOD: 152 htmlHeader = createHtmlHeader((ExecutableElement)element); 153 break; 154 } 155 return new Description(element.getSimpleName().toString(), 156 ElementHandle.create(element), 157 element.getModifiers(), 158 subs, 159 htmlHeader, 160 isSelectable, 161 isSelected); 162 } 163 164 private Description(String name, ElementHandle<? extends Element> elementHandle, 165 Set <Modifier> modifiers, List <Description> subs, String htmlHeader, 166 boolean isSelectable, boolean isSelected ) { 167 this.name = name; 168 this.elementHandle = elementHandle; 169 this.modifiers = modifiers; 170 this.subs = subs; 171 this.htmlHeader = htmlHeader; 172 this.isSelectable = isSelectable; 173 this.isSelected = isSelected; 174 } 175 176 public boolean isSelectable() { 177 return isSelectable; 178 } 179 180 public boolean isSelected() { 181 return isSelected; 182 } 183 184 public List <Description> getSubs() { 185 return subs; 186 } 187 188 public void setSelected( boolean selected ) { 189 190 if ( selected == true && node != null) { 191 node.assureSingleSelection(); 192 } 193 194 this.isSelected = selected; 195 if ( node != null ) { node.fireDisplayNameChange(null, null); 197 } 198 } 199 200 public void deepSetSelected( boolean value ) { 201 202 if ( isSelectable() && value != isSelected() ) { 203 setSelected(value); 204 } 205 206 if ( subs != null ) { 207 for( Description s : subs ) { 208 s.deepSetSelected(value); 209 } 210 } 211 } 212 213 public ElementHandle<? extends Element> getElementHandle() { 214 return elementHandle; 215 } 216 217 @Override 218 public boolean equals(Object o) { 219 if (!(o instanceof Description)) 220 return false; 221 Description d = (Description)o; 222 if (!this.name.equals(d.name)) 223 return false; 224 if (this.elementHandle != d.elementHandle) { 225 if (this.elementHandle == null || d.elementHandle == null) 226 return false; 227 if (this.elementHandle.getKind() != d.elementHandle.getKind()) 228 return false; 229 if (!this.elementHandle.signatureEquals(d.elementHandle)) 230 return false; 231 } 232 return true; 233 } 234 235 @Override 236 public int hashCode() { 237 int hash = 7; 238 hash = 29 * hash + (this.name != null ? this.name.hashCode() : 0); 239 hash = 29 * hash + (this.elementHandle != null ? this.elementHandle.getKind().hashCode() : 0); 240 return hash; 241 } 242 243 public static Description deepCopy( Description d ) { 244 245 List <Description> subsCopy; 246 247 if ( d.subs == null ) { 248 subsCopy = null; 249 } 250 else { 251 subsCopy = new ArrayList <Description>( d.subs.size() ); 252 for( Description s : d.subs ) { 253 subsCopy.add( deepCopy(s) ); 254 } 255 } 256 257 return new Description( d.name, d.elementHandle, d.modifiers, subsCopy, 258 d.htmlHeader, d.isSelectable, d.isSelected ); 259 260 } 261 262 263 264 private static String createHtmlHeader(ExecutableElement e) { 265 StringBuilder sb = new StringBuilder (); 266 if (e.getKind() == ElementKind.CONSTRUCTOR) { 267 sb.append(e.getEnclosingElement().getSimpleName()); 268 } else { 269 sb.append(e.getSimpleName()); 270 } 271 sb.append("("); for(Iterator <? extends VariableElement> it = e.getParameters().iterator(); it.hasNext(); ) { 273 VariableElement param = it.next(); 274 sb.append(print(param.asType())); 275 sb.append(" "); sb.append(param.getSimpleName()); 277 if (it.hasNext()) { 278 sb.append(", "); } 280 } 281 sb.append(")"); if ( e.getKind() != ElementKind.CONSTRUCTOR ) { 283 TypeMirror rt = e.getReturnType(); 284 if ( rt.getKind() != TypeKind.VOID ) { 285 sb.append(" : "); sb.append(print(e.getReturnType())); 287 } 288 } 289 return sb.toString(); 290 } 291 292 private static String createHtmlHeader(VariableElement e) { 293 StringBuilder sb = new StringBuilder (); 294 sb.append(e.getSimpleName()); 295 if ( e.getKind() != ElementKind.ENUM_CONSTANT ) { 296 sb.append( " : " ); sb.append(print(e.asType())); 298 } 299 return sb.toString(); 300 } 301 302 private static String createHtmlHeader(TypeElement e) { 303 StringBuilder sb = new StringBuilder (); 304 sb.append(e.getSimpleName()); 305 List <? extends TypeParameterElement> typeParams = e.getTypeParameters(); 306 if (typeParams != null && !typeParams.isEmpty()) { 307 sb.append("<"); for(Iterator <? extends TypeParameterElement> it = typeParams.iterator(); it.hasNext();) { 309 TypeParameterElement tp = it.next(); 310 sb.append(tp.getSimpleName()); 311 try { 312 List <? extends TypeMirror> bounds = tp.getBounds(); 313 if (!bounds.isEmpty()) { 314 sb.append(printBounds(bounds)); 315 } 316 } 317 catch (NullPointerException npe) { 318 } 319 if (it.hasNext()) { 320 sb.append(", "); } 322 } 323 sb.append(">"); } 325 return sb.toString(); 326 } 327 328 private static String printBounds(List <? extends TypeMirror> bounds) { 329 if (bounds.size() == 1 && "java.lang.Object".equals(bounds.get(0).toString())) return ""; 331 StringBuilder sb = new StringBuilder (); 332 sb.append(" extends "); for (Iterator <? extends TypeMirror> it = bounds.iterator(); it.hasNext();) { 334 TypeMirror bound = it.next(); 335 sb.append(print(bound)); 336 if (it.hasNext()) { 337 sb.append(" & "); } 339 } 340 return sb.toString(); 341 } 342 343 private static String print( TypeMirror tm ) { 344 StringBuilder sb; 345 switch (tm.getKind()) { 346 case DECLARED: 347 DeclaredType dt = (DeclaredType)tm; 348 sb = new StringBuilder (dt.asElement().getSimpleName().toString()); 349 List <? extends TypeMirror> typeArgs = dt.getTypeArguments(); 350 if (!typeArgs.isEmpty()) { 351 sb.append("<"); for (Iterator <? extends TypeMirror> it = typeArgs.iterator(); it.hasNext();) { 353 TypeMirror ta = it.next(); 354 sb.append(print(ta)); 355 if (it.hasNext()) { 356 sb.append(", "); } 358 } 359 sb.append(">"); } 361 return sb.toString(); 362 case TYPEVAR: 363 TypeVariable tv = (TypeVariable)tm; 364 sb = new StringBuilder (tv.asElement().getSimpleName().toString()); 365 return sb.toString(); 366 case ARRAY: 367 ArrayType at = (ArrayType)tm; 368 sb = new StringBuilder (print(at.getComponentType())); 369 sb.append("[]"); return sb.toString(); 371 case WILDCARD: 372 WildcardType wt = (WildcardType)tm; 373 sb = new StringBuilder ("?"); if (wt.getExtendsBound() != null) { 375 sb.append(" extends "); sb.append(print(wt.getExtendsBound())); 377 } 378 if (wt.getSuperBound() != null) { 379 sb.append(" super "); sb.append(print(wt.getSuperBound())); 381 } 382 return sb.toString(); 383 default: 384 return tm.toString(); 385 } 386 } 387 388 } 389 } 390 | Popular Tags |