/******************************************************************************* * Copyright (c) 2010 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.cdi.ui.wizard; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.List; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.SubProgressMonitor; import org.eclipse.jdt.core.IBuffer; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.ISourceRange; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.formatter.CodeFormatter; import org.eclipse.jdt.internal.corext.codemanipulation.CodeGenerationSettings; import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility; import org.eclipse.jdt.internal.corext.util.JavaConventionsUtil; import org.eclipse.jdt.internal.corext.util.JavaModelUtil; import org.eclipse.jdt.internal.ui.IJavaHelpContextIds; import org.eclipse.jdt.internal.ui.dialogs.StatusInfo; import org.eclipse.jdt.internal.ui.dialogs.StatusUtil; import org.eclipse.jdt.internal.ui.preferences.JavaPreferencesSettings; import org.eclipse.jdt.ui.CodeGeneration; import org.eclipse.jdt.ui.wizards.NewClassWizardPage; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.PlatformUI; import org.jboss.tools.cdi.core.CDIConstants; import org.jboss.tools.cdi.core.CDIImages; import org.jboss.tools.cdi.core.ICDIAnnotation; import org.jboss.tools.cdi.core.ICDIProject; import org.jboss.tools.cdi.ui.CDIUIMessages; import org.jboss.tools.cdi.xml.beans.model.CDIBeansConstants; import org.jboss.tools.common.java.generation.JavaBeanGenerator; import org.jboss.tools.common.ui.widget.editor.CompositeEditor; import org.jboss.tools.common.ui.widget.editor.IFieldEditor; import org.jboss.tools.common.ui.widget.editor.IFieldEditorFactory; import org.jboss.tools.common.ui.widget.editor.LabelFieldEditor; import org.jboss.tools.common.ui.widget.editor.ListFieldEditor; /** * * @author Viacheslav Kabanovich * */ public class NewInterceptorWizardPage extends NewClassWizardPage { protected InterceptorBindingSelectionProvider interceptorBindingsProvider = new InterceptorBindingSelectionProvider(); protected ListFieldEditor interceptorBindings = null; IFieldEditor methodName = null; protected StatusInfo methodNameStatus = new StatusInfo(); protected StatusInfo interceptorBindingsStatus = new StatusInfo(); protected boolean mayBeRegisteredInBeansXML = true; protected BeansXMLAccess registerInBeansXML = new BeansXMLAccess(this, "Interceptors", CDIBeansConstants.ENT_CDI_CLASS, CDIBeansConstants.ATTR_CLASS); public void setMayBeRegisteredInBeansXML(boolean b) { mayBeRegisteredInBeansXML = b; } public NewInterceptorWizardPage() { setTitle(CDIUIMessages.NEW_INTERCEPTOR_WIZARD_PAGE_NAME); setDescription(CDIUIMessages.NEW_INTERCEPTOR_WIZARD_DESCRIPTION); setImageDescriptor(CDIImages.getImageDescriptor(CDIImages.CDI_CLASS_IMAGE)); } public void init(IStructuredSelection selection) { super.init(selection); } public void addInterceptorBinding(ICDIAnnotation a) { Object o = interceptorBindings.getValue(); List list = o instanceof List ? (List)o : new ArrayList(); if(list.contains(a)) return; list.add(a); interceptorBindings.setValue(new ArrayList(list)); } public void createControl(Composite parent) { initializeDialogUnits(parent); Composite composite= new Composite(parent, SWT.NONE); composite.setFont(parent.getFont()); int nColumns= 4; GridLayout layout= new GridLayout(); layout.numColumns= nColumns; composite.setLayout(layout); // pick & choose the wanted UI components createContainerControls(composite, nColumns); createPackageControls(composite, nColumns); // createEnclosingTypeControls(composite, nColumns); createSeparator(composite, nColumns); createTypeNameControls(composite, nColumns); // createModifierControls(composite, nColumns); createSuperClassControls(composite, nColumns); // createSuperInterfacesControls(composite, nColumns); // createMethodStubSelectionControls(composite, nColumns); createCustomFields(composite); createCommentControls(composite, nColumns); enableCommentControl(true); setControl(composite); Dialog.applyDialogFont(composite); PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, IJavaHelpContextIds.NEW_CLASS_WIZARD_PAGE); onInterceptorBindingChange(); doStatusUpdate(); } protected void createTypeMembers(IType newType, final ImportsManager imports, IProgressMonitor monitor) throws CoreException { createInheritedMethods(newType, true, true, imports, new SubProgressMonitor(monitor, 1)); ISourceRange range = newType.getSourceRange(); IBuffer buf = newType.getCompilationUnit().getBuffer(); String lineDelimiter = StubUtility.getLineDelimiterUsed(newType.getJavaProject()); StringBuffer sb = new StringBuffer(); addAnnotations(imports, sb, lineDelimiter); buf.replace(range.getOffset(), 0, sb.toString()); //TODO add method createAroundInvokeMethod(newType, imports, monitor, lineDelimiter); } void addAnnotations(ImportsManager imports, StringBuffer sb, String lineDelimiter) { addInterceptorBindingAnnotations(imports, sb, lineDelimiter); addInterceptorAnnotation(imports, sb, lineDelimiter); } protected void addInterceptorAnnotation(ImportsManager imports, StringBuffer sb, String lineDelimiter) { NewCDIAnnotationWizardPage.addAnnotation(CDIConstants.INTERCEPTOR_ANNOTATION_TYPE_NAME, imports, sb, lineDelimiter); } protected void addInterceptorBindingAnnotations(ImportsManager imports, StringBuffer sb, String lineDelimiter) { if(interceptorBindings != null) { List list = (List)interceptorBindings.getValue(); for (Object o: list) { if(o instanceof ICDIAnnotation) { ICDIAnnotation a = (ICDIAnnotation)o; String typeName = a.getSourceType().getFullyQualifiedName(); NewCDIAnnotationWizardPage.addAnnotation(typeName, imports, sb, lineDelimiter); } } } } protected void createCustomFields(Composite composite) { createInterceptorBindingField(composite); createMethodNameField(composite); createRegisterInBeansXML(composite); } protected void createInterceptorBindingField(Composite composite) { interceptorBindings = new ListFieldEditor("interceptorBindings", CDIUIMessages.FIELD_EDITOR_INTERCEPTOR_BINDINGS_LABEL, new ArrayList<Object>()); interceptorBindings.setProvider(interceptorBindingsProvider); interceptorBindingsProvider.setEditorField(interceptorBindings); interceptorBindings.doFillIntoGrid(composite); setInterceptorBindings(getPackageFragmentRoot()); interceptorBindings.addPropertyChangeListener(new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { onInterceptorBindingChange(); doStatusUpdate(); } }); } void onInterceptorBindingChange() { interceptorBindingsStatus = new StatusInfo(); if(((List)interceptorBindings.getValue()).isEmpty()) { interceptorBindingsStatus.setWarning(CDIUIMessages.MESSAGE_INTERCEPTOR_BINDINGS_EMPTY); } } protected void createMethodNameField(Composite composite) { String label = "Around Invoke Method Name:"; methodName = IFieldEditorFactory.INSTANCE.createTextEditor("methodName", label, "aroundInvoke"); ((CompositeEditor)methodName).addFieldEditors(new IFieldEditor[]{new LabelFieldEditor("methodName", "")}); methodName.doFillIntoGrid(composite); methodName.addPropertyChangeListener(new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { onMethodNameChange(); doStatusUpdate(); } }); } protected void createRegisterInBeansXML(Composite composite) { if(!mayBeRegisteredInBeansXML) return; registerInBeansXML.create(composite); } void setInterceptorBindings(IPackageFragmentRoot root) { interceptorBindingsProvider.setProject(null); if(root != null) { IJavaProject jp = root.getJavaProject(); ICDIProject cdi = NewCDIAnnotationWizardPage.getCDIProject(jp); if(cdi != null) { interceptorBindingsProvider.setProject(cdi); } } interceptorBindingsProvider.setPackageFragment(getPackageFragment()); } void onMethodNameChange() { String methodName = this.methodName.getValueAsString(); methodNameStatus = new StatusInfo(); if(methodName.length() == 0) { methodNameStatus.setError(CDIUIMessages.MESSAGE_METHOD_NAME_EMPTY); return; } IStatus val = JavaConventionsUtil.validateMethodName(methodName, null); if(val != null && val.getSeverity() == IStatus.ERROR) { methodNameStatus.setError(NLS.bind(CDIUIMessages.MESSAGE_METHOD_NAME_NOT_VALID, val.getMessage())); } } protected IMethod createAroundInvokeMethod(IType type, ImportsManager imports, IProgressMonitor monitor, String lineDelimiter) throws CoreException { String methodName = "" + this.methodName.getValue(); imports.addImport("javax.interceptor.InvocationContext"); imports.addImport("javax.interceptor.AroundInvoke"); final ICompilationUnit cu= type.getCompilationUnit(); JavaModelUtil.reconcile(cu); CodeGenerationSettings settings = JavaPreferencesSettings.getCodeGenerationSettings(type.getJavaProject()); settings.createComments = isAddComments(); String access = "public"; String javatype = "Object"; String methodHeader = "@AroundInvoke" + lineDelimiter + access + " " + javatype + " " + methodName + "(InvocationContext ic) throws Exception"; //$NON-NLS-1$ //$NON-NLS-2$ String stub = null; if(!type.isInterface()) { methodHeader += " {" + lineDelimiter; //$NON-NLS-1$ stub = methodHeader + "}" + lineDelimiter; //$NON-NLS-1$ } else { methodHeader += ";" + lineDelimiter; //$NON-NLS-1$ stub = methodHeader; } IMethod m = type.createMethod(stub, null, true, null); editMethod(cu, m, methodHeader, "return null;", lineDelimiter); return m; } void editMethod(ICompilationUnit cu, IMethod m, String methodHeader, String methodContent, String lineDelimiter) throws CoreException { synchronized(cu) { cu.reconcile(ICompilationUnit.NO_AST, true, null, null); } ISourceRange range = m.getSourceRange(); IBuffer buf = cu.getBuffer(); StringBuffer sb = new StringBuffer(lineDelimiter); if(isAddComments()) { String methodComment = CodeGeneration.getMethodComment(m, null, lineDelimiter); sb.append(methodComment); } sb.append(methodHeader); if(methodContent != null) { sb.append(methodContent).append("}").append(lineDelimiter); //$NON-NLS-1$ } String formattedContent = JavaBeanGenerator.codeFormat2(CodeFormatter.K_CLASS_BODY_DECLARATIONS, sb.toString(), 1, lineDelimiter, cu.getJavaProject()); if(formattedContent != null && formattedContent.startsWith("\t")) { //$NON-NLS-1$ formattedContent = formattedContent.substring(1); } buf.replace(range.getOffset(), range.getLength(), formattedContent); } private void doStatusUpdate() { // status of all used components IStatus[] status= new IStatus[] { fContainerStatus, isEnclosingTypeSelected() ? fEnclosingTypeStatus : fPackageStatus, fTypeNameStatus, fModifierStatus, fSuperClassStatus, fSuperInterfacesStatus }; // the mode severe status will be displayed and the OK button enabled/disabled. updateStatus(status); } protected void updateStatus(IStatus[] status) { IStatus[] ns = new IStatus[status.length + 2]; System.arraycopy(status, 0, ns, 0, status.length); ns[status.length] = methodNameStatus; ns[status.length + 1] = interceptorBindingsStatus; status = ns; updateStatus(StatusUtil.getMostSevere(status)); } protected IStatus packageChanged() { IStatus result = super.packageChanged(); if(result != null && result.isOK()) { interceptorBindingsProvider.setPackageFragment(getPackageFragment()); } registerInBeansXML.validate(); return result; } public boolean isToBeRegisteredInBeansXML() { return registerInBeansXML.isSelected(); } protected IStatus typeNameChanged() { IStatus result = super.typeNameChanged(); registerInBeansXML.validate(); return result; } }