1 11 package org.eclipse.jdt.ui.actions; 12 13 import java.lang.reflect.InvocationTargetException ; 14 import java.util.ArrayList ; 15 import java.util.Arrays ; 16 import java.util.List ; 17 18 import org.eclipse.core.runtime.CoreException; 19 20 import org.eclipse.jface.dialogs.MessageDialog; 21 import org.eclipse.jface.operation.IRunnableContext; 22 import org.eclipse.jface.viewers.IStructuredSelection; 23 import org.eclipse.jface.window.Window; 24 25 import org.eclipse.jface.text.IRewriteTarget; 26 import org.eclipse.jface.text.ITextSelection; 27 28 import org.eclipse.ui.IEditorPart; 29 import org.eclipse.ui.IWorkbenchSite; 30 import org.eclipse.ui.PlatformUI; 31 32 import org.eclipse.jdt.core.Flags; 33 import org.eclipse.jdt.core.ICompilationUnit; 34 import org.eclipse.jdt.core.IField; 35 import org.eclipse.jdt.core.IJavaElement; 36 import org.eclipse.jdt.core.IType; 37 import org.eclipse.jdt.core.JavaModelException; 38 import org.eclipse.jdt.core.ToolFactory; 39 import org.eclipse.jdt.core.compiler.IScanner; 40 import org.eclipse.jdt.core.compiler.ITerminalSymbols; 41 import org.eclipse.jdt.core.dom.CompilationUnit; 42 import org.eclipse.jdt.core.dom.IMethodBinding; 43 import org.eclipse.jdt.core.dom.ITypeBinding; 44 import org.eclipse.jdt.core.dom.IVariableBinding; 45 46 import org.eclipse.jdt.internal.corext.codemanipulation.AddCustomConstructorOperation; 47 import org.eclipse.jdt.internal.corext.codemanipulation.CodeGenerationSettings; 48 import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility2; 49 import org.eclipse.jdt.internal.corext.dom.Bindings; 50 import org.eclipse.jdt.internal.corext.dom.TokenScanner; 51 import org.eclipse.jdt.internal.corext.util.JavaModelUtil; 52 import org.eclipse.jdt.internal.corext.util.JdtFlags; 53 54 import org.eclipse.jdt.ui.JavaUI; 55 56 import org.eclipse.jdt.internal.ui.IJavaHelpContextIds; 57 import org.eclipse.jdt.internal.ui.JavaPlugin; 58 import org.eclipse.jdt.internal.ui.actions.ActionMessages; 59 import org.eclipse.jdt.internal.ui.actions.ActionUtil; 60 import org.eclipse.jdt.internal.ui.actions.GenerateConstructorUsingFieldsContentProvider; 61 import org.eclipse.jdt.internal.ui.actions.GenerateConstructorUsingFieldsSelectionDialog; 62 import org.eclipse.jdt.internal.ui.actions.GenerateConstructorUsingFieldsValidator; 63 import org.eclipse.jdt.internal.ui.actions.SelectionConverter; 64 import org.eclipse.jdt.internal.ui.actions.WorkbenchRunnableAdapter; 65 import org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor; 66 import org.eclipse.jdt.internal.ui.preferences.JavaPreferencesSettings; 67 import org.eclipse.jdt.internal.ui.util.BusyIndicatorRunnableContext; 68 import org.eclipse.jdt.internal.ui.util.ElementValidator; 69 import org.eclipse.jdt.internal.ui.util.ExceptionHandler; 70 import org.eclipse.jdt.internal.ui.viewsupport.BindingLabelProvider; 71 72 89 public class GenerateNewConstructorUsingFieldsAction extends SelectionDispatchAction { 90 91 private CompilationUnitEditor fEditor; 92 93 99 public GenerateNewConstructorUsingFieldsAction(CompilationUnitEditor editor) { 100 this(editor.getEditorSite()); 101 fEditor= editor; 102 setEnabled(checkEnabledEditor()); 103 } 104 105 112 public GenerateNewConstructorUsingFieldsAction(IWorkbenchSite site) { 113 super(site); 114 setText(ActionMessages.GenerateConstructorUsingFieldsAction_label); 115 setDescription(ActionMessages.GenerateConstructorUsingFieldsAction_description); 116 setToolTipText(ActionMessages.GenerateConstructorUsingFieldsAction_tooltip); 117 118 PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.CREATE_NEW_CONSTRUCTOR_ACTION); 119 } 120 121 private boolean canEnable(IStructuredSelection selection) throws JavaModelException { 122 if (getSelectedFields(selection) != null) 123 return true; 124 125 if ((selection.size() == 1) && (selection.getFirstElement() instanceof IType)) { 126 IType type= (IType) selection.getFirstElement(); 127 return type.getCompilationUnit() != null && !type.isInterface() && !type.isAnnotation(); 128 } 129 130 if ((selection.size() == 1) && (selection.getFirstElement() instanceof ICompilationUnit)) 131 return true; 132 133 return false; 134 } 135 136 private boolean canRunOn(IField[] fields) throws JavaModelException { 137 if (fields != null && fields.length > 0) { 138 for (int index= 0; index < fields.length; index++) { 139 if (JdtFlags.isEnum(fields[index])) { 140 MessageDialog.openInformation(getShell(), ActionMessages.GenerateConstructorUsingFieldsAction_error_title, ActionMessages.GenerateConstructorUsingFieldsAction_enum_not_applicable); 141 return false; 142 } 143 } 144 return true; 145 } 146 return false; 147 } 148 149 private boolean checkEnabledEditor() { 150 return fEditor != null && SelectionConverter.canOperateOn(fEditor); 151 } 152 153 157 private IField[] getSelectedFields(IStructuredSelection selection) { 158 List elements= selection.toList(); 159 if (elements.size() > 0) { 160 IField[] fields= new IField[elements.size()]; 161 ICompilationUnit unit= null; 162 for (int index= 0; index < elements.size(); index++) { 163 if (elements.get(index) instanceof IField) { 164 IField field= (IField) elements.get(index); 165 if (index == 0) { 166 unit= field.getCompilationUnit(); 168 if (unit == null) { 169 return null; 170 } 171 } else if (!unit.equals(field.getCompilationUnit())) { 172 return null; 174 } 175 try { 176 final IType declaringType= field.getDeclaringType(); 177 if (declaringType.isInterface() || declaringType.isAnnotation()) 178 return null; 179 } catch (JavaModelException exception) { 180 JavaPlugin.log(exception); 181 return null; 182 } 183 fields[index]= field; 184 } else { 185 return null; 186 } 187 } 188 return fields; 189 } 190 return null; 191 } 192 193 private IType getSelectedType(IStructuredSelection selection) throws JavaModelException { 194 Object [] elements= selection.toArray(); 195 if (elements.length == 1 && (elements[0] instanceof IType)) { 196 IType type= (IType) elements[0]; 197 if (type.getCompilationUnit() != null && !type.isInterface() && !type.isAnnotation()) { 198 return type; 199 } 200 } else if (elements[0] instanceof ICompilationUnit) { 201 ICompilationUnit unit= (ICompilationUnit) elements[0]; 202 IType type= unit.findPrimaryType(); 203 if (type != null && !type.isInterface() && !type.isAnnotation()) 204 return type; 205 } else if (elements[0] instanceof IField) { 206 return ((IField) elements[0]).getCompilationUnit().findPrimaryType(); 207 } 208 return null; 209 } 210 211 214 public void run(IStructuredSelection selection) { 215 try { 216 IType selectionType= getSelectedType(selection); 217 if (selectionType == null) { 218 MessageDialog.openInformation(getShell(), ActionMessages.GenerateConstructorUsingFieldsAction_error_title, ActionMessages.GenerateConstructorUsingFieldsAction_not_applicable); 219 notifyResult(false); 220 return; 221 } 222 223 IField[] selectedFields= getSelectedFields(selection); 224 225 if (canRunOn(selectedFields)) { 226 run(selectedFields[0].getDeclaringType(), selectedFields, false); 227 return; 228 } 229 Object firstElement= selection.getFirstElement(); 230 231 if (firstElement instanceof IType) { 232 run((IType) firstElement, new IField[0], false); 233 } else if (firstElement instanceof ICompilationUnit) { 234 IType type= ((ICompilationUnit) firstElement).findPrimaryType(); 235 if (type.isAnnotation()) { 236 MessageDialog.openInformation(getShell(), ActionMessages.GenerateConstructorUsingFieldsAction_error_title, ActionMessages.GenerateConstructorUsingFieldsAction_annotation_not_applicable); 237 notifyResult(false); 238 return; 239 } else if (type.isInterface()) { 240 MessageDialog.openInformation(getShell(), ActionMessages.GenerateConstructorUsingFieldsAction_error_title, ActionMessages.GenerateConstructorUsingFieldsAction_interface_not_applicable); 241 notifyResult(false); 242 return; 243 } else 244 run(((ICompilationUnit) firstElement).findPrimaryType(), new IField[0], false); 245 } 246 } catch (CoreException exception) { 247 ExceptionHandler.handle(exception, getShell(), ActionMessages.GenerateConstructorUsingFieldsAction_error_title, ActionMessages.GenerateConstructorUsingFieldsAction_error_actionfailed); 248 } 249 } 250 251 254 public void run(ITextSelection selection) { 255 if (!ActionUtil.isProcessable(fEditor)) { 256 notifyResult(false); 257 return; 258 } 259 try { 260 IJavaElement[] elements= SelectionConverter.codeResolveForked(fEditor, true); 261 if (elements.length == 1 && (elements[0] instanceof IField)) { 262 IField field= (IField) elements[0]; 263 run(field.getDeclaringType(), new IField[] { field}, false); 264 return; 265 } 266 IJavaElement element= SelectionConverter.getElementAtOffset(fEditor); 267 if (element != null) { 268 IType type= (IType) element.getAncestor(IJavaElement.TYPE); 269 if (type != null) { 270 if (type.getFields().length > 0) { 271 run(type, new IField[0], true); 272 } else { 273 MessageDialog.openInformation(getShell(), ActionMessages.GenerateConstructorUsingFieldsAction_error_title, ActionMessages.GenerateConstructorUsingFieldsAction_typeContainsNoFields_message); 274 } 275 return; 276 } 277 } 278 MessageDialog.openInformation(getShell(), ActionMessages.GenerateConstructorUsingFieldsAction_error_title, ActionMessages.GenerateConstructorUsingFieldsAction_not_applicable); 279 } catch (CoreException exception) { 280 ExceptionHandler.handle(exception, getShell(), ActionMessages.GenerateConstructorUsingFieldsAction_error_title, ActionMessages.GenerateConstructorUsingFieldsAction_error_actionfailed); 281 } catch (InvocationTargetException exception) { 282 ExceptionHandler.handle(exception, getShell(), ActionMessages.GenerateConstructorUsingFieldsAction_error_title, ActionMessages.GenerateConstructorUsingFieldsAction_error_actionfailed); 283 } catch (InterruptedException e) { 284 } 286 } 287 288 290 void run(IType type, IField[] selected, boolean activated) throws CoreException { 291 if (!ElementValidator.check(type, getShell(), ActionMessages.GenerateConstructorUsingFieldsAction_error_title, activated)) { 292 notifyResult(false); 293 return; 294 } 295 if (!ActionUtil.isEditable(fEditor, getShell(), type)) { 296 notifyResult(false); 297 return; 298 } 299 if (type.getCompilationUnit() == null) { 300 MessageDialog.openInformation(getShell(), ActionMessages.GenerateConstructorUsingFieldsAction_error_title, ActionMessages.GenerateNewConstructorUsingFieldsAction_error_not_a_source_file); 301 notifyResult(false); 302 return; 303 304 } 305 306 IField[] candidates= type.getFields(); 307 ArrayList fields= new ArrayList (); 308 for (int index= 0; index < candidates.length; index++) { 309 boolean isStatic= Flags.isStatic(candidates[index].getFlags()); 310 boolean isFinal= Flags.isFinal(candidates[index].getFlags()); 311 if (!isStatic) { 312 if (isFinal) { 313 try { 314 IScanner scanner= ToolFactory.createScanner(true, false, false, false); 316 scanner.setSource(candidates[index].getSource().toCharArray()); 317 TokenScanner tokenScanner= new TokenScanner(scanner); 318 tokenScanner.getTokenStartOffset(ITerminalSymbols.TokenNameEQUAL, 0); 319 } catch (JavaModelException e) { 320 } catch (CoreException e) { 321 fields.add(candidates[index]); 322 } 323 } else 324 fields.add(candidates[index]); 325 } 326 } 327 if (fields.isEmpty()) { 328 MessageDialog.openInformation(getShell(), ActionMessages.GenerateConstructorUsingFieldsAction_error_title, ActionMessages.GenerateConstructorUsingFieldsAction_typeContainsNoFields_message); 329 notifyResult(false); 330 return; 331 } 332 final GenerateConstructorUsingFieldsContentProvider provider= new GenerateConstructorUsingFieldsContentProvider(type, fields, Arrays.asList(selected)); 333 IMethodBinding[] bindings= null; 334 final ITypeBinding provided= provider.getType(); 335 if (provided.isAnonymous()) { 336 MessageDialog.openInformation(getShell(), ActionMessages.GenerateConstructorUsingFieldsAction_error_title, ActionMessages.GenerateConstructorUsingFieldsAction_error_anonymous_class); 337 notifyResult(false); 338 return; 339 } 340 if (provided.isEnum()) { 341 bindings= new IMethodBinding[] {getObjectConstructor(provider.getCompilationUnit())}; 342 } else { 343 bindings= StubUtility2.getVisibleConstructors(provided, false, true); 344 if (bindings.length == 0) { 345 MessageDialog.openInformation(getShell(), ActionMessages.GenerateConstructorUsingFieldsAction_error_title, ActionMessages.GenerateConstructorUsingFieldsAction_error_nothing_found); 346 notifyResult(false); 347 return; 348 } 349 } 350 351 GenerateConstructorUsingFieldsSelectionDialog dialog= new GenerateConstructorUsingFieldsSelectionDialog(getShell(), new BindingLabelProvider(), provider, fEditor, type, bindings); 352 dialog.setCommentString(ActionMessages.SourceActionDialog_createConstructorComment); 353 dialog.setTitle(ActionMessages.GenerateConstructorUsingFieldsAction_dialog_title); 354 dialog.setInitialSelections(provider.getInitiallySelectedElements()); 355 dialog.setContainerMode(true); 356 dialog.setSize(60, 18); 357 dialog.setInput(new Object ()); 358 dialog.setMessage(ActionMessages.GenerateConstructorUsingFieldsAction_dialog_label); 359 dialog.setValidator(new GenerateConstructorUsingFieldsValidator(dialog, provided, fields.size())); 360 361 final int dialogResult= dialog.open(); 362 if (dialogResult == Window.OK) { 363 Object [] elements= dialog.getResult(); 364 if (elements == null) { 365 notifyResult(false); 366 return; 367 } 368 ArrayList result= new ArrayList (elements.length); 369 for (int index= 0; index < elements.length; index++) { 370 if (elements[index] instanceof IVariableBinding) 371 result.add(elements[index]); 372 } 373 IVariableBinding[] variables= new IVariableBinding[result.size()]; 374 result.toArray(variables); 375 IEditorPart editor= JavaUI.openInEditor(type.getCompilationUnit()); 376 CodeGenerationSettings settings= JavaPreferencesSettings.getCodeGenerationSettings(type.getJavaProject()); 377 settings.createComments= dialog.getGenerateComment(); 378 IMethodBinding constructor= dialog.getSuperConstructorChoice(); 379 IRewriteTarget target= editor != null ? (IRewriteTarget) editor.getAdapter(IRewriteTarget.class) : null; 380 if (target != null) 381 target.beginCompoundChange(); 382 try { 383 AddCustomConstructorOperation operation= new AddCustomConstructorOperation(type, dialog.getElementPosition(), provider.getCompilationUnit(), variables, constructor, settings, true, false); 384 operation.setVisibility(dialog.getVisibilityModifier()); 385 if (constructor.getParameterTypes().length == 0) 386 operation.setOmitSuper(dialog.isOmitSuper()); 387 IRunnableContext context= JavaPlugin.getActiveWorkbenchWindow(); 388 if (context == null) 389 context= new BusyIndicatorRunnableContext(); 390 PlatformUI.getWorkbench().getProgressService().runInUI(context, new WorkbenchRunnableAdapter(operation, operation.getSchedulingRule()), operation.getSchedulingRule()); 391 } catch (InvocationTargetException exception) { 392 ExceptionHandler.handle(exception, getShell(), ActionMessages.GenerateConstructorUsingFieldsAction_error_title, ActionMessages.GenerateConstructorUsingFieldsAction_error_actionfailed); 393 } catch (InterruptedException exception) { 394 } finally { 396 if (target != null) { 397 target.endCompoundChange(); 398 } 399 } 400 } 401 notifyResult(dialogResult == Window.OK); 402 } 403 404 private IMethodBinding getObjectConstructor(CompilationUnit compilationUnit) { 405 final ITypeBinding binding= compilationUnit.getAST().resolveWellKnownType("java.lang.Object"); return Bindings.findMethodInType(binding, "Object", new ITypeBinding[0]); } 408 409 412 public void selectionChanged(IStructuredSelection selection) { 413 try { 414 setEnabled(canEnable(selection)); 415 } catch (JavaModelException e) { 416 if (JavaModelUtil.isExceptionToBeLogged(e)) 418 JavaPlugin.log(e); 419 setEnabled(false); 420 } 421 } 422 423 425 428 public void selectionChanged(ITextSelection selection) { 429 } 430 } 431 | Popular Tags |