/******************************************************************************* * 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.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.IField; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IMember; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.ISourceRange; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaModelException; 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.jdt.ui.wizards.NewTypeWizardPage.ImportsManager; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.dialogs.FilteredItemsSelectionDialog; import org.jboss.tools.cdi.core.CDIConstants; import org.jboss.tools.cdi.core.CDICorePlugin; 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.core.IQualifier; import org.jboss.tools.cdi.ui.CDIUIMessages; import org.jboss.tools.common.java.IParametedType; import org.jboss.tools.common.java.generation.JavaBeanGenerator; import org.jboss.tools.common.ui.widget.editor.ButtonFieldEditor; import org.jboss.tools.common.ui.widget.editor.ButtonFieldEditor.ButtonPressedAction; 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.LabelFieldEditor; import org.jboss.tools.common.ui.widget.editor.TextFieldEditor; /** * * @author Viacheslav Kabanovich * */ public class NewAnnotationLiteralWizardPage extends NewClassWizardPage { protected QualifierSelectionProvider qualifiersProvider = new QualifierSelectionProvider(); CompositeEditor qualifiers = null; String defaultTypeName = null; protected StatusInfo qualifierStatus = new StatusInfo(); public NewAnnotationLiteralWizardPage() { setTitle(CDIUIMessages.NEW_ANNOTATION_LITERAL_WIZARD_PAGE_NAME); setDescription(CDIUIMessages.NEW_ANNOTATION_LITERAL_WIZARD_DESCRIPTION); setImageDescriptor(CDIImages.getImageDescriptor(CDIImages.CDI_ANNOTATION_IMAGE)); qualifiersProvider.setMulti(false); } public void init(IStructuredSelection selection) { super.init(selection); defaultTypeName = null; if (!selection.isEmpty()) { Object o = selection.iterator().next(); IType type = null; if (o instanceof IType) { type = (IType) o; } else if (o instanceof ICompilationUnit) { ICompilationUnit cu = (ICompilationUnit) o; try { IType[] ts = cu.getTypes(); if (ts != null && ts.length > 0) type = ts[0]; } catch (JavaModelException e) { CDICorePlugin.getDefault().logError(e); } } boolean isInterface = false; try { isInterface = type != null && type.isInterface(); } catch (JavaModelException e) { CDICorePlugin.getDefault().logError(e); } if (isInterface) { String name = ""; try { name = type.getFullyQualifiedParameterizedName(); } catch (JavaModelException e) { name = type.getFullyQualifiedName(); } IPackageFragmentRoot r = getPackageFragmentRoot(); if(r != null) { ICDIProject cdi = NewCDIAnnotationWizardPage.getCDIProject(r.getJavaProject()); IQualifier q = cdi != null ? cdi.getQualifier(name) : null; if(q != null) { selected = q; ArrayList<String> interfacesNames = new ArrayList<String>(); interfacesNames.add(name); setSuperInterfaces(interfacesNames, true); superInterfacesChanged(); setSuperClass(CDIConstants.ANNOTATION_LITERAL_TYPE_NAME + "<" + type.getElementName() + ">", false); setDefaultTypeName(name); } } } } doStatusUpdate(); } void setDefaultTypeName(String interfaceName) { int d = interfaceName.lastIndexOf('.'); int b = interfaceName.indexOf('<'); if (b < 0) b = interfaceName.length(); String elementName = interfaceName.substring(d + 1, b); String typeName = elementName + "Literal"; typeName += interfaceName.substring(b); String currentTypeName = getTypeName(); boolean isDefault = currentTypeName == null || currentTypeName.length() == 0 || currentTypeName.equals(defaultTypeName); if(isDefault) { setTypeName(typeName, true); typeNameChanged(); } defaultTypeName = typeName; } 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); onQualifiersChange(); 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(); buf.replace(range.getOffset(), 0, sb.toString()); boolean isDefault = modifyMethodContent(newType, imports, monitor, lineDelimiter); if(isDefault) { createInstanceField(newType, imports, monitor, lineDelimiter); } } protected void createCustomFields(Composite composite) { createQualifierField(composite); } protected void createQualifierField(Composite composite) { qualifiers = (CompositeEditor)createQualifierCompositeEditor("qualifiers", CDIUIMessages.FIELD_EDITOR_QUALIFIER_LABEL, ""); // qualifiers.setProvider(qualifiersProvider); // qualifiersProvider.setEditorField(qualifiers); qualifiers.doFillIntoGrid(composite); setQualifiers(getPackageFragmentRoot()); qualifiers.addPropertyChangeListener(new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { Object o = evt.getNewValue(); validateQualifierSelection(o); }}); } void validateQualifierSelection(Object value) { boolean done = false; if(value != null) { String name = value.toString(); IPackageFragmentRoot r = getPackageFragmentRoot(); if(r != null) { ICDIProject cdi = NewCDIAnnotationWizardPage.getCDIProject(r.getJavaProject()); selected = cdi != null ? cdi.getQualifier(name) : null; if(selected != null) { ArrayList<String> interfacesNames = new ArrayList<String>(); interfacesNames.add(name); setSuperInterfaces(interfacesNames, true); superInterfacesChanged(); setSuperClass(CDIConstants.ANNOTATION_LITERAL_TYPE_NAME + "<" + selected.getSourceType().getElementName() + ">", false); setDefaultTypeName(name); done = true; } } } if(!done) { selected = null; setSuperInterfaces(new ArrayList<String>(), true); superInterfacesChanged(); } } public void setPackageFragmentRoot(IPackageFragmentRoot root, boolean canBeModified) { super.setPackageFragmentRoot(root, canBeModified); setQualifiers(root); if(qualifiers != null) { validateQualifierSelection(qualifiers.getValue()); } } void setQualifiers(IPackageFragmentRoot root) { qualifiersProvider.setProject(null); if(root != null) { IJavaProject jp = root.getJavaProject(); ICDIProject cdi = NewCDIAnnotationWizardPage.getCDIProject(jp); if(cdi != null) { qualifiersProvider.setProject(cdi); } } } protected IField createInstanceField(IType type, ImportsManager imports, IProgressMonitor monitor, String lineDelimiter) throws CoreException { imports.addImport(CDIConstants.ANNOTATION_LITERAL_TYPE_NAME); IType fieldType = selected.getSourceType(); imports.addImport(fieldType.getFullyQualifiedName()); String access = "public static final "; String initialization = "new " + type.getElementName() + "()"; IJavaElement[] cs = type.getChildren(); IJavaElement sibling = cs == null || cs.length == 0 ? null : cs[0]; IField m = createField(type, sibling, imports, "INSTANCE", fieldType.getElementName(), access, initialization, monitor, lineDelimiter); return m; } protected IField createField(IType type, IJavaElement sibling, ImportsManager imports, String name, String fieldType, String access, String initialization, IProgressMonitor monitor, String lineDelimiter) throws CoreException { ICompilationUnit cu = type.getCompilationUnit(); JavaModelUtil.reconcile(cu); CodeGenerationSettings settings = JavaPreferencesSettings .getCodeGenerationSettings(type.getJavaProject()); settings.createComments = isAddComments(); String fieldHeader = access + " " + fieldType + " " + name; if(initialization != null) { fieldHeader += "= " + initialization; } fieldHeader += ";" + lineDelimiter; //$NON-NLS-1$ //$NON-NLS-2$ IField m = type.createField(fieldHeader, sibling, true, null); editField(cu, m, fieldType, fieldHeader, lineDelimiter); return m; } void editField(ICompilationUnit cu, IField m, String javatype, String fieldHeader, 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 fieldComment = CodeGeneration.getFieldComment(cu, javatype, m.getElementName(), lineDelimiter); sb.append(fieldComment).append(lineDelimiter); } sb.append(fieldHeader); 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); } protected IStatus superInterfacesChanged() { List list = getSuperInterfaces(); if(list != null && !list.isEmpty()) { setDefaultTypeName(list.get(0).toString()); } StatusInfo result = (StatusInfo) super.superInterfacesChanged(); if (!result.isError()) { if (list == null || list.isEmpty()) { result.setError("Please select qualifier."); } } return result; } 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 + 1]; // System.arraycopy(status, 0, ns, 0, status.length); // ns[status.length] = qualifierStatus; // status = ns; updateStatus(StatusUtil.getMostSevere(status)); } void onQualifiersChange() { // qualifierStatus = new StatusInfo(); // if(((List)qualifiers.getValue()).isEmpty()) { // qualifierStatus.setWarning(CDIUIMessages.MESSAGE_QUALIFIER_NOT_SET); // } } public IFieldEditor createQualifierCompositeEditor(String name, String label, String defaultValue) { if(selected != null) { defaultValue = selected.getSourceType().getFullyQualifiedName(); } CompositeEditor editor = new CompositeEditor(name, label, defaultValue); editor.addFieldEditors(new IFieldEditor[]{new LabelFieldEditor(name,label), new TextFieldEditor(name,label, defaultValue), new ButtonFieldEditor(name,createSelectAction(), "")}); return editor; } ButtonPressedAction createSelectAction() { return new ButtonPressedAction("Browse") { public void run() { selected = (ICDIAnnotation)runAddAction(); if(selected != null) { qualifiers.setValue(selected.getSourceType().getFullyQualifiedName()); } } }; } ICDIAnnotation selected = null; protected Object runAddAction() { if(qualifiersProvider != null) { FilteredItemsSelectionDialog dialog = qualifiersProvider.createSelectionDialog(); int result = dialog.open(); if(result == FilteredItemsSelectionDialog.OK) { Object[] os = dialog.getResult(); if(os != null) { for (Object o: os) { Object v = qualifiersProvider.getSelected(o); if(v != null) { return v; } } } } } return null; } public void setQualifier(String type) { qualifiers.setValue(type); } protected boolean modifyMethodContent(IType type, ImportsManager imports, IProgressMonitor monitor, String lineDelimiter) throws CoreException { IMethod[] ms = type.getMethods(); IMethod sibling = null; List<String[]> fields = new ArrayList<String[]>(); IMethod constructor = null; for (int i = 0; i < ms.length; i++) { if(ms[i].isConstructor()) { constructor = ms[i]; continue; } if(sibling == null) { sibling = ms[i]; } ICompilationUnit cu = type.getCompilationUnit(); synchronized (cu) { cu.reconcile(ICompilationUnit.NO_AST, true, null, null); } IBuffer buf = cu.getBuffer(); ISourceRange range = ms[i].getSourceRange(); int start = -1; int end = -1; StringBuffer sb = new StringBuffer(); if("void".equals(ms[i].getReturnType()) || "V".equals(ms[i].getReturnType())) { end = buf.getContents().indexOf("}", range.getOffset()); if(end < 0) continue; end = buf.getContents().lastIndexOf(lineDelimiter, end); if(end < 0 || end < range.getOffset()) continue; // end += lineDelimiter.length(); start = end; } else { start = buf.getContents().indexOf("return", range.getOffset()); if(start < 0 || start > range.getOffset() + range.getLength()) continue; start += 7; end = buf.getContents().indexOf(";", start); if(end < 0) continue; end++; } String methodName = ms[i].getElementName(); String fieldName = "" + methodName; sb.append(fieldName).append(";"); buf.replace(start, end - start, sb.toString()); fields.add(new String[]{ms[i].getReturnType(), fieldName}); } for (int i = 0; i < fields.size(); i++) { String[] data = fields.get(i); String fieldType = data[0]; String fieldName = data[1]; IParametedType t = NewCDIAnnotationWizardPage.getCDIProject(getPackageFragmentRoot().getJavaProject()).getNature().getTypeFactory().getParametedType(type, fieldType); if(t != null) { data[0] = t.getSimpleName(); createField(type, constructor, imports, fieldName, t.getSimpleName(), "private final", null, monitor, lineDelimiter); } } if(constructor != null) { constructor.delete(true, monitor); } if(!fields.isEmpty()) { String constructorContents = "public " + type.getElementName() + "("; String comments = "/**" + lineDelimiter; for (int i = 0; i < fields.size(); i++) { String[] data = fields.get(i); String fieldType = data[0]; String fieldName = data[1]; comments += " * @param " + fieldName + lineDelimiter; if(i > 0) constructorContents += ", "; constructorContents += fieldType + " " + fieldName; } comments += "*/" + lineDelimiter; constructorContents += ") {" + lineDelimiter; for (int i = 0; i < fields.size(); i++) { String[] data = fields.get(i); String fieldName = data[1]; constructorContents += "this." + fieldName + " = " + fieldName + ";" + lineDelimiter; } constructorContents += "}" + lineDelimiter; if(isAddComments()) { constructorContents = comments + constructorContents; } IMethod m = type.createMethod(constructorContents, sibling, true, monitor); } return fields.isEmpty(); } }