diff options
author | itrimble | 2012-01-31 19:33:23 +0000 |
---|---|---|
committer | itrimble | 2012-01-31 19:33:23 +0000 |
commit | 79e267761c76431fe217bcaebf24e47e6876914d (patch) | |
tree | 1d311f169f6d3b1d870fcead5b6acbe4905b1297 | |
parent | 8f82e4e7f078eb141e8009289af74ffbd437c26c (diff) | |
download | webtools.jsf-79e267761c76431fe217bcaebf24e47e6876914d.tar.gz webtools.jsf-79e267761c76431fe217bcaebf24e47e6876914d.tar.xz webtools.jsf-79e267761c76431fe217bcaebf24e47e6876914d.zip |
Bug 307562 - Java EE 6 CDI support is needed for JSF 2.0 EE 6 web applications
4 files changed, 264 insertions, 10 deletions
diff --git a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/jsfappconfig/AnnotationJSFAppConfigProvider.java b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/jsfappconfig/AnnotationJSFAppConfigProvider.java index 99bb9560f..92af67f6c 100644 --- a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/jsfappconfig/AnnotationJSFAppConfigProvider.java +++ b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/jsfappconfig/AnnotationJSFAppConfigProvider.java @@ -48,12 +48,20 @@ public class AnnotationJSFAppConfigProvider extends AbstractJSFAppConfigProvider static final String FACES_RENDERER_ANNOTATION_CLASS = "javax.faces.render.FacesRenderer"; //$NON-NLS-1$ static final String FACES_VALIDATOR_ANNOTATION_CLASS = "javax.faces.validator.FacesValidator"; //$NON-NLS-1$ - static final String VIEW_SCOPED_ANNOTATION_CLASS = "javax.faces.bean.ViewScoped"; //$NON-NLS-1$ - static final String APPLICATION_SCOPED_ANNOTATION_CLASS = "javax.faces.bean.ApplicationScoped"; //$NON-NLS-1$ static final String NONE_SCOPED_ANNOTATION_CLASS = "javax.faces.bean.NoneScoped"; //$NON-NLS-1$ + static final String VIEW_SCOPED_ANNOTATION_CLASS = "javax.faces.bean.ViewScoped"; //$NON-NLS-1$ static final String SESSION_SCOPED_ANNOTATION_CLASS = "javax.faces.bean.SessionScoped"; //$NON-NLS-1$ + static final String APPLICATION_SCOPED_ANNOTATION_CLASS = "javax.faces.bean.ApplicationScoped"; //$NON-NLS-1$ static final String CUSTOM_SCOPED_ANNOTATION_CLASS = "javax.faces.bean.CustomScoped"; //$NON-NLS-1$ + static final String CDI_NAMED_BEAN_ANNOTATION_CLASS = "javax.inject.Named"; //$NON-NLS-1$ + static final String CDI_MODEL_BEAN_ANNOTATION_CLASS = "javax.enterprise.inject.Model"; //$NON-NLS-1$ + + static final String CDI_REQUEST_SCOPED_ANNOTATION_CLASS = "javax.enterprise.context.RequestScoped"; //$NON-NLS-1$ + static final String CDI_CONVERSATION_SCOPED_ANNOTATION_CLASS = "javax.enterprise.context.ConversationScoped"; //$NON-NLS-1$ + static final String CDI_SESSION_SCOPED_ANNOTATION_CLASS = "javax.enterprise.context.SessionScoped"; //$NON-NLS-1$ + static final String CDI_APPLICATION_SCOPED_ANNOTATION_CLASS = "javax.enterprise.context.ApplicationScoped"; //$NON-NLS-1$ + /** * Cached {@link FacesConfigType} instance. */ @@ -109,6 +117,8 @@ public class AnnotationJSFAppConfigProvider extends AbstractJSFAppConfigProvider pattern = orPattern(pattern, jProject.findType(FACES_CONVERTER_ANNOTATION_CLASS)); pattern = orPattern(pattern, jProject.findType(FACES_RENDERER_ANNOTATION_CLASS)); pattern = orPattern(pattern, jProject.findType(FACES_VALIDATOR_ANNOTATION_CLASS)); + pattern = orPattern(pattern, jProject.findType(CDI_NAMED_BEAN_ANNOTATION_CLASS)); + pattern = orPattern(pattern, jProject.findType(CDI_MODEL_BEAN_ANNOTATION_CLASS)); if (pattern != null) { SearchEngine engine = new SearchEngine(); diff --git a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/jsfappconfig/AnnotationSearchRequestor.java b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/jsfappconfig/AnnotationSearchRequestor.java index f015b7f59..79f3889a4 100644 --- a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/jsfappconfig/AnnotationSearchRequestor.java +++ b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/jsfappconfig/AnnotationSearchRequestor.java @@ -17,12 +17,21 @@ import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvid import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.FACES_CONVERTER_ANNOTATION_CLASS; import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.FACES_RENDERER_ANNOTATION_CLASS; import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.FACES_VALIDATOR_ANNOTATION_CLASS; -import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.VIEW_SCOPED_ANNOTATION_CLASS; -import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.APPLICATION_SCOPED_ANNOTATION_CLASS; + import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.NONE_SCOPED_ANNOTATION_CLASS; +import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.VIEW_SCOPED_ANNOTATION_CLASS; import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.SESSION_SCOPED_ANNOTATION_CLASS; +import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.APPLICATION_SCOPED_ANNOTATION_CLASS; import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.CUSTOM_SCOPED_ANNOTATION_CLASS; +import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.CDI_NAMED_BEAN_ANNOTATION_CLASS; +import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.CDI_MODEL_BEAN_ANNOTATION_CLASS; + +import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.CDI_REQUEST_SCOPED_ANNOTATION_CLASS; +import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.CDI_CONVERSATION_SCOPED_ANNOTATION_CLASS; +import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.CDI_SESSION_SCOPED_ANNOTATION_CLASS; +import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.CDI_APPLICATION_SCOPED_ANNOTATION_CLASS; + import org.eclipse.core.runtime.CoreException; import org.eclipse.emf.common.util.EList; import org.eclipse.jdt.core.IAnnotation; @@ -97,7 +106,11 @@ public class AnnotationSearchRequestor extends SearchRequestor { addRenderer(annotations[i], type); } else if (FACES_VALIDATOR_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) { addValidator(annotations[i], type); - } + } else if (CDI_NAMED_BEAN_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) { + addCDINamedBean(annotations[i], type); + } else if (CDI_MODEL_BEAN_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) { + addCDIModelBean(type); + } } } } @@ -168,14 +181,14 @@ public class AnnotationSearchRequestor extends SearchRequestor { String[][] resolvedAnnotationTypes = beanType.resolveType(annotationType); if (resolvedAnnotationTypes != null) { String resolvedAnnotationClassName = new StringBuffer(resolvedAnnotationTypes[0][0]).append('.').append(resolvedAnnotationTypes[0][1]).toString(); - if (APPLICATION_SCOPED_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) { - beanScopeString = "application"; //$NON-NLS-1$ + if (NONE_SCOPED_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) { + beanScopeString = "none"; //$NON-NLS-1$ } else if (VIEW_SCOPED_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) { beanScopeString = "view"; //$NON-NLS-1$ - } else if (NONE_SCOPED_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) { - beanScopeString = "none"; //$NON-NLS-1$ } else if (SESSION_SCOPED_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) { beanScopeString = "session"; //$NON-NLS-1$ + } else if (APPLICATION_SCOPED_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) { + beanScopeString = "application"; //$NON-NLS-1$ } else if (CUSTOM_SCOPED_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) { IMemberValuePair[] scopePairs = annotations[i].getMemberValuePairs(); if (scopePairs != null && scopePairs.length == 1 && scopePairs[0].getValueKind() == IMemberValuePair.K_STRING) { @@ -199,6 +212,7 @@ public class AnnotationSearchRequestor extends SearchRequestor { beanScope.setTextContent(beanScopeString); bean.setManagedBeanScope(beanScope); bean.setEager(isBeanEager.booleanValue()); + JSFAppConfigUtils.setManagedBeanSource(bean, JSFAppConfigUtils.MANAGEDBEAN_SOURCE_JSF_ANNOTATION); facesConfig.getManagedBean().add(bean); } } @@ -357,4 +371,113 @@ public class AnnotationSearchRequestor extends SearchRequestor { facesConfig.getComponent().add(component); } } + + private void addCDINamedBean(IAnnotation beanAnnotation, IType beanType) throws JavaModelException { + IMemberValuePair[] pairs = beanAnnotation.getMemberValuePairs(); + + String beanNameString = null; + if (pairs != null) { + for (IMemberValuePair pair : pairs) { + if ("value".equals(pair.getMemberName()) && pair.getValueKind() == IMemberValuePair.K_STRING) { //$NON-NLS-1$ + beanNameString = (String)pair.getValue(); + } + } + } + if (beanNameString == null || beanNameString.length() < 1) { + beanNameString = beanType.getElementName(); + if (beanNameString != null && beanNameString.length() > 0) { + StringBuffer casedName = new StringBuffer(String.valueOf(beanNameString.charAt(0)).toLowerCase()); + beanNameString = casedName.append(beanNameString.substring(1)).toString(); + } + } + + String beanClassName = beanType.getFullyQualifiedName(); + + String beanScopeString = "dependent"; //$NON-NLS-1$ + IAnnotation[] annotations = beanType.getAnnotations(); + if (annotations != null) { + for (int i = 0, k = annotations.length; i < k; i++) { + if (annotations[i].exists()) { + String annotationType = annotations[i].getElementName(); + String[][] resolvedAnnotationTypes = beanType.resolveType(annotationType); + if (resolvedAnnotationTypes != null) { + String resolvedAnnotationClassName = new StringBuffer(resolvedAnnotationTypes[0][0]).append('.').append(resolvedAnnotationTypes[0][1]).toString(); + if (CDI_REQUEST_SCOPED_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) { + beanScopeString = "request"; //$NON-NLS-1$ + } else if (CDI_CONVERSATION_SCOPED_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) { + beanScopeString = "conversation"; //$NON-NLS-1$ + } else if (CDI_SESSION_SCOPED_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) { + beanScopeString = "session"; //$NON-NLS-1$ + } else if (CDI_APPLICATION_SCOPED_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) { + beanScopeString = "application"; //$NON-NLS-1$ + } + } + } + } + } + + if (beanNameString != null && beanClassName != null) { + ManagedBeanType bean = FacesConfigFactory.eINSTANCE.createManagedBeanType(); + ManagedBeanNameType beanName = FacesConfigFactory.eINSTANCE.createManagedBeanNameType(); + beanName.setTextContent(beanNameString); + bean.setManagedBeanName(beanName); + ManagedBeanClassType beanClass = FacesConfigFactory.eINSTANCE.createManagedBeanClassType(); + beanClass.setTextContent(beanClassName); + bean.setManagedBeanClass(beanClass); + ManagedBeanScopeType beanScope = FacesConfigFactory.eINSTANCE.createManagedBeanScopeType(); + beanScope.setTextContent(beanScopeString); + bean.setManagedBeanScope(beanScope); + bean.setEager(false); + JSFAppConfigUtils.setManagedBeanSource(bean, JSFAppConfigUtils.MANAGEDBEAN_SOURCE_CDI_ANNOTATION); + facesConfig.getManagedBean().add(bean); + } + } + + private void addCDIModelBean(IType beanType) throws JavaModelException { + String beanNameString = beanType.getElementName(); + if (beanNameString != null && beanNameString.length() > 0) { + StringBuffer casedName = new StringBuffer(String.valueOf(beanNameString.charAt(0)).toLowerCase()); + beanNameString = casedName.append(beanNameString.substring(1)).toString(); + } + + String beanClassName = beanType.getFullyQualifiedName(); + + String beanScopeString = "request"; //$NON-NLS-1$ + IAnnotation[] annotations = beanType.getAnnotations(); + if (annotations != null) { + for (int i = 0, k = annotations.length; i < k; i++) { + if (annotations[i].exists()) { + String annotationType = annotations[i].getElementName(); + String[][] resolvedAnnotationTypes = beanType.resolveType(annotationType); + if (resolvedAnnotationTypes != null) { + String resolvedAnnotationClassName = new StringBuffer(resolvedAnnotationTypes[0][0]).append('.').append(resolvedAnnotationTypes[0][1]).toString(); + if (CDI_CONVERSATION_SCOPED_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) { + beanScopeString = "conversation"; //$NON-NLS-1$ + } else if (CDI_SESSION_SCOPED_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) { + beanScopeString = "session"; //$NON-NLS-1$ + } else if (CDI_APPLICATION_SCOPED_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) { + beanScopeString = "application"; //$NON-NLS-1$ + } + } + } + } + } + + if (beanNameString != null && beanClassName != null) { + ManagedBeanType bean = FacesConfigFactory.eINSTANCE.createManagedBeanType(); + ManagedBeanNameType beanName = FacesConfigFactory.eINSTANCE.createManagedBeanNameType(); + beanName.setTextContent(beanNameString); + bean.setManagedBeanName(beanName); + ManagedBeanClassType beanClass = FacesConfigFactory.eINSTANCE.createManagedBeanClassType(); + beanClass.setTextContent(beanClassName); + bean.setManagedBeanClass(beanClass); + ManagedBeanScopeType beanScope = FacesConfigFactory.eINSTANCE.createManagedBeanScopeType(); + beanScope.setTextContent(beanScopeString); + bean.setManagedBeanScope(beanScope); + bean.setEager(false); + JSFAppConfigUtils.setManagedBeanSource(bean, JSFAppConfigUtils.MANAGEDBEAN_SOURCE_CDI_ANNOTATION); + facesConfig.getManagedBean().add(bean); + } + } + }
\ No newline at end of file diff --git a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/jsfappconfig/JSFAppConfigUtils.java b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/jsfappconfig/JSFAppConfigUtils.java index 73c8004dd..43b045526 100644 --- a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/jsfappconfig/JSFAppConfigUtils.java +++ b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/jsfappconfig/JSFAppConfigUtils.java @@ -52,6 +52,9 @@ import org.eclipse.jst.jsf.common.internal.componentcore.AbstractVirtualComponen import org.eclipse.jst.jsf.core.IJSFCoreConstants; import org.eclipse.jst.jsf.core.internal.JSFCorePlugin; import org.eclipse.jst.jsf.core.internal.Messages; +import org.eclipse.jst.jsf.facesconfig.emf.FacesConfigFactory; +import org.eclipse.jst.jsf.facesconfig.emf.ManagedBeanExtensionType; +import org.eclipse.jst.jsf.facesconfig.emf.ManagedBeanType; import org.eclipse.osgi.util.NLS; import org.eclipse.wst.common.componentcore.resources.IVirtualFolder; import org.eclipse.wst.common.project.facet.core.IFacetedProject; @@ -79,6 +82,14 @@ public class JSFAppConfigUtils { */ public static final String FACES_CONFIG_IN_JAR_PATH = "META-INF/faces-config.xml"; //$NON-NLS-1$ + /** ID of managed bean's description instance to indicate content identifies bean's "source" **/ + public static final String MANAGEDBEAN_SOURCE_ID = "MANAGEDBEAN_SOURCE_ID"; //$NON-NLS-1$ + /** Indicates that a managed bean was defined in a faces-config file **/ + public static final String MANAGEDBEAN_SOURCE_FACES_CONFIG_FILE = "FACES_CONFIG_FILE"; //$NON-NLS-1$ + /** Indicates that a managed bean was defined by a JSF annotation **/ + public static final String MANAGEDBEAN_SOURCE_JSF_ANNOTATION = "JSF_ANNOTATION"; //$NON-NLS-1$ + /** Indicates that a managed bean was defined by a CDI annotation **/ + public static final String MANAGEDBEAN_SOURCE_CDI_ANNOTATION = "CDI_ANNOTATION"; //$NON-NLS-1$ /** * @param project @@ -402,6 +413,116 @@ public class JSFAppConfigUtils { return files; } + /** + * Sets the "source" (one of the MANAGEDBEAN_SOURCE_* constants) of the managed bean. + * @param managedBean Managed bean instance. + * @param source "Source" of the managed bean. + */ + public static void setManagedBeanSource(final ManagedBeanType managedBean, final String source) { + if (managedBean != null) { + ManagedBeanExtensionType extension = getManagedBeanSourceExtension(managedBean); + if (extension == null) { + extension = FacesConfigFactory.eINSTANCE.createManagedBeanExtensionType(); + extension.setId(MANAGEDBEAN_SOURCE_ID); + managedBean.getManagedBeanExtension().add(extension); + } + final String content = extension.getTextContent(); + if (content != null) { + if (!content.trim().equals(source)) { + extension.setTextContent(source); + } + } else { + extension.setTextContent(source); + } + } + } + + /** + * Gets the "source" (one of the MANAGEDBEAN_SOURCE_* constants) of the managed bean. + * @param managedBean Managed bean instance. + * @return "Source" of the managed bean (assumes MANAGEDBEAN_SOURCE_FACES_CONFIG_FILE if not + * set on the managed bean). + */ + public static String getManagedBeanSource(final ManagedBeanType managedBean) { + String source = MANAGEDBEAN_SOURCE_FACES_CONFIG_FILE; + final ManagedBeanExtensionType extension = getManagedBeanSourceExtension(managedBean); + if (extension != null) { + source = extension.getTextContent().trim(); + } + return source; + } + + /** + * Gets the managed bean instance's extension object that has ID of MANAGEDBEAN_SOURCE_ID. + * @param managedBean Managed bean instance. + * @return The managed bean's extension object that has ID of MANAGEDBEAN_SOURCE_ID. + */ + public static ManagedBeanExtensionType getManagedBeanSourceExtension(final ManagedBeanType managedBean) { + ManagedBeanExtensionType extension = null; + if (managedBean != null) { + final EList extensions = managedBean.getManagedBeanExtension(); + for (final Object curExtObj: extensions) { + if (curExtObj instanceof ManagedBeanExtensionType) { + final ManagedBeanExtensionType curExt = (ManagedBeanExtensionType) curExtObj; + final String id = curExt.getId(); + if (id != null && id.equals(MANAGEDBEAN_SOURCE_ID)) { + extension = curExt; + break; + } + } + } + } + return extension; + } + + /** + * Returns <code>true</code> if the managed bean is defined in a faces-config file. + * @param managedBean Managed bean instance to test. + * @return <code>true</code> if the managed bean is defined in a faces-config file, else + * <code>false</code>. + */ + public static boolean isDefinedInFacesConfigFile(final ManagedBeanType managedBean) { + boolean ret = false; + if (managedBean != null) { + ret = !isDefinedByJSFAnnotation(managedBean) && !isDefinedByCDIAnnotation(managedBean); + } + return ret; + } + + /** + * Returns <code>true</code> if the managed bean is defined by a JSF annotation. + * @param managedBean Managed bean instance to test. + * @return <code>true</code> if the managed bean is defined by a JSF annotation, else + * <code>false</code>. + */ + public static boolean isDefinedByJSFAnnotation(final ManagedBeanType managedBean) { + boolean ret = false; + if (managedBean != null) { + final String source = getManagedBeanSource(managedBean); + if (source != null && source.equals(MANAGEDBEAN_SOURCE_JSF_ANNOTATION)) { + ret = true; + } + } + return ret; + } + + /** + * Returns <code>true</code> if the managed bean is defined by a CDI annotation. + * @param managedBean Managed bean instance to test. + * @return <code>true</code> if the managed bean is defined by a CDI annotation, else + * <code>false</code>. + */ + public static boolean isDefinedByCDIAnnotation(final ManagedBeanType managedBean) { + boolean ret = false; + if (managedBean != null) { + final String source = getManagedBeanSource(managedBean); + if (source != null && source.equals(MANAGEDBEAN_SOURCE_CDI_ANNOTATION)) { + ret = true; + } + } + return ret; + } + class ImplicitNavigationResourceProxyVisitor implements IResourceProxyVisitor { diff --git a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/designtime/symbols/DefaultBeanSymbolSourceProvider.java b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/designtime/symbols/DefaultBeanSymbolSourceProvider.java index 5464d49ac..61ee51d22 100644 --- a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/designtime/symbols/DefaultBeanSymbolSourceProvider.java +++ b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/designtime/symbols/DefaultBeanSymbolSourceProvider.java @@ -224,7 +224,7 @@ public class DefaultBeanSymbolSourceProvider { additionalInfo.append("<p><b>"); //$NON-NLS-1$ additionalInfo.append(Messages.getString("DefaultBeanSymbolSourceProvider.AdditionalInformation.Description")); //$NON-NLS-1$ - additionalInfo.append("</b>"); //$NON-NLS-1$ + additionalInfo.append(" </b>"); //$NON-NLS-1$ additionalInfo.append(descBuffer); additionalInfo.append("</p>"); //$NON-NLS-1$ } |