Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[stp-dev] patch for bug 169265

hi,

I've written some codes to support annotations on field in our annotation
view.
If the selected JDT member in the Java editor is a field, we first list all
annotations annotated with Target=ElementType.FIELD. When attributes of this
kind of annotation are edited in the annotation view/java editor, the
modified values
are synchronized to the java editor/annotation view. Enabling and disabling
annotations for field is also supported and synchronized between editor &
view.

Please find attached the patch file.

regards,

Frank
### Eclipse Workspace Patch 1.0
#P org.eclipse.stp.sc.common
Index: src/org/eclipse/stp/sc/common/views/AnnotationView.java
===================================================================
RCS file: /cvsroot/stp/org.eclipse.stp.servicecreation/org.eclipse.stp.sc.common/src/org/eclipse/stp/sc/common/views/AnnotationView.java,v
retrieving revision 1.1
diff -u -r1.1 AnnotationView.java
--- src/org/eclipse/stp/sc/common/views/AnnotationView.java	25 Dec 2006 06:10:27 -0000	1.1
+++ src/org/eclipse/stp/sc/common/views/AnnotationView.java	15 Jan 2007 07:54:24 -0000
@@ -10,37 +10,34 @@
 *******************************************************************************/
 package org.eclipse.stp.sc.common.views;
 
-import java.lang.reflect.Method;
+import java.util.Map;
+import java.util.List;
 import java.util.HashMap;
 import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
+import java.lang.reflect.Method;
 
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.jdt.core.ICompilationUnit;
-import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.core.IMember;
 import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.dom.AST;
 import org.eclipse.jdt.core.dom.Annotation;
+import org.eclipse.jdt.core.dom.Type;
+import org.eclipse.jdt.core.dom.TypeLiteral;
 import org.eclipse.jdt.core.dom.CompilationUnit;
 import org.eclipse.jdt.core.dom.MemberValuePair;
 import org.eclipse.jdt.core.dom.NormalAnnotation;
+import org.eclipse.jdt.core.dom.ArrayInitializer;
 import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
-import org.eclipse.jface.text.BadLocationException;
 import org.eclipse.jface.text.ITextSelection;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.text.BadLocationException;
 import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.jface.viewers.ViewerSorter;
-import org.eclipse.stp.common.logging.LoggingProxy;
-import org.eclipse.stp.common.utils.JDTUtils;
-import org.eclipse.stp.sc.common.annotations.ScAnnotationSupportUtils;
-import org.eclipse.stp.sc.common.CommonResources;
-import org.eclipse.stp.sc.common.annotations.ScJDTAnnUtils;
-import org.eclipse.stp.sc.common.views.AnnotationViewerContentProvider;
-import org.eclipse.stp.sc.common.views.AnnotationViewerLabelProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.TreeEditor;
 import org.eclipse.swt.events.FocusAdapter;
@@ -69,9 +66,16 @@
 import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.part.FileEditorInput;
 import org.eclipse.ui.part.ViewPart;
+import org.eclipse.stp.common.utils.JDTUtils;
+import org.eclipse.stp.common.logging.LoggingProxy;
+import org.eclipse.stp.sc.common.CommonResources;
+import org.eclipse.stp.sc.common.annotations.ScJDTAnnUtils;
+import org.eclipse.stp.sc.common.annotations.ScAnnotationSupportUtils;
+import org.eclipse.stp.sc.common.views.AnnotationViewerContentProvider;
+import org.eclipse.stp.sc.common.views.AnnotationViewerLabelProvider;
 
 /**
- * this view is to display and edit the JAX-WS (JSR181 only) annotation setup for a selected java element
+ * this view is to display and edit the JAXWS 2.0 annotation setup for a selected java element
  */
 public class AnnotationView extends ViewPart {
 
@@ -90,11 +94,11 @@
 
     public TreeViewer annotationsviewer;
     // edit support -- end
+
     // the listener to register with the selection service 
     public ISelectionListener workbenchSelectionListener = new AnnotationSelectionListener();
     protected IPartListener2 workbenchPartListener = new JavaEditorListener();
     
-    
     private IMember selectedJdtMember;
     private SingleVariableDeclaration selectedJdtMethodParam;
     private boolean editSupportEnabled;
@@ -107,7 +111,8 @@
     static final String JAVA_EDITOR_ID = "org.eclipse.jdt.ui.CompilationUnitEditor";
 
     private int offset;
-
+    
+    private String originalValue;
 
     public void createPartControl(Composite parent) {
         annotationsviewer = new TreeViewer(parent, SWT.MULTI | SWT.FULL_SELECTION);
@@ -123,7 +128,7 @@
         column.setWidth(700);
 
         annotationsviewer.setLabelProvider(new AnnotationViewerLabelProvider(this));
-        annotationsviewer.setContentProvider(new AnnotationViewerContentProvider());
+        annotationsviewer.setContentProvider(new AnnotationViewerContentProvider(this));
         annotationsviewer.setSorter(new ViewerSorter());
 
         // edit support -- start
@@ -131,11 +136,10 @@
         treeEditor.grabHorizontal = true;
         treeEditor.grabVertical = true;
         annotationsviewer.getTree().addSelectionListener(new SelectionAdapter() {
-                public void widgetSelected(SelectionEvent event) {
-                    activateEditSupport(event);
-                }
-            });
-        
+        	public void widgetSelected(SelectionEvent event) {
+        		activateEditSupport(event);
+        	}
+        });
         // edit support -- end
 
         IWorkbenchWindow window = getSite().getWorkbenchWindow();
@@ -183,7 +187,11 @@
         }
 
         Object element = item.getData();
+        
+        activateEditSupport(element, item);
+    }
 
+    private void activateEditSupport(Object element, TreeItem item) {
         // case 1: adding/removing annotation to/from the java element
         if (element instanceof Class) {
             
@@ -201,6 +209,8 @@
             // case 2: support for enum based properties
             if (returnTypeClass.isEnum()) {
                 handleEditOnEnumAttribute(item, returnTypeClass);
+            } else if (returnTypeClass.isArray()) {
+            	handleEditOnArrayAttribute(item, returnTypeClass);
             } else if (returnTypeClass.equals(String.class)) {
                 handleEditOnStringAttribute(item);
             } else if (returnTypeClass.equals(Boolean.TYPE) || returnTypeClass.equals(Boolean.class)) {
@@ -213,9 +223,110 @@
             } else {
                 handleEditOnStringAttribute(item);
             }
+        } else if (element instanceof Object[]) {
+        	Object[] pair = (Object[])element;
+        	if (pair[0] instanceof String) {
+        		if (item.getParentItem().getParentItem().getText(1).equals("true")) {
+        			handleEditOnArrayElement(item);
+        		}
+        	} else if (pair[0] instanceof Method) {
+        		Method method = (Method)pair[0];
+        		activateEditSupport(method, item);
+        	}
         }
     }
 
+    @SuppressWarnings("unchecked")
+    private void handleEditOnArrayElement(TreeItem item) {
+        
+        if (!editSupportEnabled) {
+            LOG.debug("edit support disabld");
+            return;
+        }
+
+        //Set the editor for the second column in the row                 
+        combo = new Combo(annotationsviewer.getTree(), SWT.READ_ONLY);
+        combo.setItems(new String[] {"" + true, "" + false });
+        combo.setFocus();
+
+        treeEditor.minimumHeight = combo.getSize().y;
+        // TODO see if we can make the control's width adaptable to the size of the content
+        //treeEditor.minimumWidth = annotationsviewer.getTree().getColumn(1).getWidth();
+        treeEditor.setEditor(combo, item, 1);
+
+        combo.select(combo.indexOf(treeEditor.getItem().getText(1)));
+
+        combo.addSelectionListener(new SelectionAdapter() {
+                public void widgetSelected(SelectionEvent event) {
+                    try {
+                        
+                        String originalValue = treeEditor.getItem().getText(1);
+                        String updatedValueStr = ((Combo)event.getSource()).getText();
+                        disposeEditWidgets();
+
+                        if (!originalValue.equals(updatedValueStr)) {
+                            Boolean value = new Boolean(updatedValueStr);
+                            
+                            treeEditor.getItem().setText(1, updatedValueStr);
+                            treeEditor.getItem().setImage(value ? iconOn : iconOff);
+
+                            Class topAnnoClass = (Class)treeEditor.getItem().getParentItem().getParentItem().getData();
+                        	NormalAnnotation topAnnoNode = (NormalAnnotation)annotationNodesMap.get(topAnnoClass.getSimpleName());
+
+                        	MemberValuePair mvp = null;
+                        	Method declaringMethod = (Method)treeEditor.getItem().getParentItem().getData();
+                        	for (int i = 0; i < topAnnoNode.values().size(); i++) {
+                        		MemberValuePair pair = (MemberValuePair)topAnnoNode.values().get(i);
+                        		if (pair.getName().getIdentifier().equals(declaringMethod.getName())) {
+                        			mvp = pair;
+                        			break;
+                        		}
+                        	}
+                        	
+                            List expList = ((ArrayInitializer)mvp.getValue()).expressions();
+
+                            if (value) {
+                            	try {
+                            		Object[] data = (Object[])treeEditor.getItem().getData();
+                            		String className = (String)data[0];
+                            		className = className.substring(0, className.indexOf(":"));
+                            		Class itemClass = Class.forName(className);
+                            		NormalAnnotation anno = (NormalAnnotation)ScAnnotationSupportUtils.getDefaultedAnnotationNode(
+                            				itemClass, compilationUnitAstNode, selectedJdtMember, selectedJdtMethodParam);
+                            		expList.add(anno);
+                            		data[1] = anno;
+                            	}
+                            	catch (ClassNotFoundException ignored) {}
+                            }
+                            else {
+                            	Object[] data = (Object[])treeEditor.getItem().getData();
+                            	String extraInfo = (String)data[0];
+                            	int pos = extraInfo.indexOf(":Existing");
+                            	String posStr = extraInfo.substring(pos + ":Existing".length());
+                            	expList.remove(Integer.valueOf(posStr).intValue());
+                            	data[1] = null;
+                            }
+    
+                            ScJDTAnnUtils.addAnnotationToCu(compilationUnitMember,
+                                                            compilationUnitAstNode,
+                                                            topAnnoNode,
+                                                            selectedJdtMember,
+                                                            selectedJdtMethodParam);
+                            refreshViewContent();
+                        }
+                    } catch (JavaModelException e) {
+                        LOG.error("Java model update failed: ", e);
+                    } catch (MalformedTreeException e) {
+                        LOG.error("Java model update failed: ", e);
+                    } catch (BadLocationException e) {
+                        LOG.error("Java model update failed: ", e);
+                    } finally {
+                        disposeEditWidgets();
+                    }
+                }
+            });
+    }
+    
     /**
      * prepares and enables the widgets necessary to handle the addition or removal of the annotaion 
      * represented by the <code>TreeItem</code> param
@@ -381,6 +492,49 @@
     /**
      * prepares and enables the widgets necessary to handle the update of the annotaion attribute 
      * represented by the <code>TreeItem</code> param. the widget produced will be specifically to handle an 
+     * array based attribute
+     * @param item
+     */
+    private void handleEditOnArrayAttribute(TreeItem item, Class returnTypeClass) {
+
+    	if (!editSupportEnabled) {
+            return;
+        }
+    	
+        text = new Text(annotationsviewer.getTree(), SWT.BORDER);
+        //text.setBackground(text.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
+        text.setForeground(item.getForeground());
+        text.setEditable(false);
+        text.selectAll();
+        text.setFocus();
+
+        // Recalculate the minimum width for the editor
+        treeEditor.minimumWidth = text.getBounds().width;
+
+        // Set the control into the editor
+        treeEditor.setEditor(text, item, 1);
+        text.setText(treeEditor.getItem().getText(1));
+
+        text.addKeyListener(new KeyAdapter() {
+            public void keyReleased(KeyEvent e) {
+                if ((text != null) 
+                        && !text.isDisposed()
+                        && ((e.keyCode == SWT.CR) || (e.keyCode == SWT.KEYPAD_CR))) {
+                    processUpdateOnTextAttribute();
+                }
+            }
+        });
+
+        text.addFocusListener(new FocusAdapter() {
+            public void focusLost(FocusEvent event) {
+                processUpdateOnTextAttribute();
+            }
+        });
+    }
+
+    /**
+     * prepares and enables the widgets necessary to handle the update of the annotaion attribute 
+     * represented by the <code>TreeItem</code> param. the widget produced will be specifically to handle an 
      * enum based attribute
      * @param item
      */
@@ -543,7 +697,9 @@
                 ? CommonResources.getString("annotation.view.java.element.method.lbl")
                 : ((javaElementTypeId == IJavaElement.METHOD && selectedJdtMethodParam != null)
                     ? CommonResources.getString("annotation.view.java.element.param.lbl") 
-                    : ""));
+                    : ((javaElementTypeId == IJavaElement.FIELD)
+                            ? CommonResources.getString("annotation.view.java.element.field.lbl") 
+                                    : "")));
 
         StringBuffer desc = new StringBuffer(javaElementTypeLabel)
                             .append(" : ")
@@ -602,31 +758,131 @@
         }
     }
 
+    @SuppressWarnings("unchecked")
     private void applyAnnotationAttributeUpdate(Object formatedValue) {
         try {
             String attributeName = treeEditor.getItem().getText();
             
-            Class annotationClass = (Class)treeEditor.getItem().getParentItem().getData();
-            Annotation annotationNode = annotationNodesMap.get(annotationClass.getSimpleName());
-            if (annotationNode == null) {
-                annotationNode = annotationNodesMap.get(annotationClass.getName());
-            }
-
-            if (annotationNode.isMarkerAnnotation()) {
-                // this annotation doesn't accept attibutes (no "()" in the source)
-                // TODO should convert to a normal annotation?
-                return; 
-            }
-            NormalAnnotation normalAnnotationNode = (NormalAnnotation)annotationNode;
-
-            addOrUpdateAttributeInAnnotation(attributeName, formatedValue, normalAnnotationNode);
+            if (treeEditor.getItem().getData() instanceof Method) {
+            	Class annotationClass = (Class)treeEditor.getItem().getParentItem().getData();
+            	Annotation annotationNode = annotationNodesMap.get(annotationClass.getSimpleName());
+            	if (annotationNode == null) {
+            		annotationNode = annotationNodesMap.get(annotationClass.getName());
+            	}
+
+            	if (annotationNode.isMarkerAnnotation()) {
+            		// this annotation doesn't accept attibutes (no "()" in the source)
+            		// TODO should convert to a normal annotation?
+            		return; 
+            	}
+            	NormalAnnotation normalAnnotationNode = (NormalAnnotation)annotationNode;
+
+            	Class attributeType = annotationClass.getMethod(attributeName, (Class[])null).getReturnType(); 
+            	if (attributeType.equals(java.lang.Class.class)) {
+            		String attributeValue = (String)formatedValue;
+            		if (attributeValue.endsWith(".class")) {
+            			attributeValue = attributeValue.substring(0, attributeValue.length() - ".class".length());
+            		}
+            		try {
+            			formatedValue = Class.forName(attributeValue);
+            			// JDTUtils.addImport(compilationUnitAstNode, attributeValue, ASTRewrite.create(compilationUnitAstNode.getAST()));
+            		} catch (ClassNotFoundException e) {
+            			try {
+            				LOG.error("error to find class: " + attributeValue);
+            				String originalClass = originalValue.substring(0, originalValue.length() - ".class".length());
+            				formatedValue = Class.forName(originalClass);
+            			} catch (ClassNotFoundException ignored) {}
+            		}
+            	} else if (attributeType.isArray()) {
+            		// Array attribute cannot be edited directly
+            	}
+            
+            	addOrUpdateAttributeInAnnotation(attributeName, formatedValue, normalAnnotationNode);
             
-            ScJDTAnnUtils.addAnnotationToCu(compilationUnitMember,
-                                       compilationUnitAstNode,
-                                       normalAnnotationNode,
-                                       selectedJdtMember,
-                                       selectedJdtMethodParam);
-            refreshViewContent();
+            	ScJDTAnnUtils.addAnnotationToCu(compilationUnitMember,
+                                                compilationUnitAstNode,
+                                                normalAnnotationNode,
+                                                selectedJdtMember,
+                                                selectedJdtMethodParam);
+            	refreshViewContent();
+
+            } else if (treeEditor.getItem().getData() instanceof Object[]) {
+            	Object[] pair = (Object[])treeEditor.getItem().getData();
+            	Class annotationClass = null;
+            	if (pair[0] instanceof Method) {
+            		MemberValuePair mvp = (MemberValuePair)pair[1];
+            		if (mvp != null) {
+            			// if (mvp.getValue() instanceof TypeLiteral) {
+            			if (((Method)pair[0]).getReturnType().equals(Class.class)) {
+            				/*
+            				try {
+            					String className = (String)formatedValue;
+            					if (className.endsWith(".class")) {
+            						className = className.substring(0, className.length() - ".class".length());
+            					}
+            					formatedValue = Class.forName(className);
+            				}
+            				catch (ClassNotFoundException ignored) {}
+            				*/
+        					String className = (String)formatedValue;
+        					if (className.endsWith(".class")) {
+        						className = className.substring(0, className.length() - ".class".length());
+        					}
+            	            AST ast = compilationUnitAstNode.getAST();
+            	            int previousIndex = -1;
+            	            int nextIndex = className.indexOf('.');
+            	            Type theType;
+            	            if (nextIndex == -1) {
+            	            	theType = ast.newSimpleType(ast.newSimpleName(className));
+            	            } else {
+            	            	theType = ast.newSimpleType(ast.newSimpleName(className.substring(1 + previousIndex, nextIndex)));
+            	            }
+            	            previousIndex = nextIndex;
+            	            nextIndex = className.indexOf('.', previousIndex + 1);
+            	            while (nextIndex != -1) {
+            	                String substring = className.substring(1 + previousIndex, nextIndex);
+            	                theType = ast.newQualifiedType(theType, ast.newSimpleName(substring));
+            	                previousIndex = nextIndex;
+            	                nextIndex = className.indexOf('.', previousIndex + 1);
+            	            }
+            	            if (previousIndex != -1) {
+            	            	String substring = className.substring(1 + previousIndex);
+            	            	theType = ast.newQualifiedType(theType, ast.newSimpleName(substring));
+            	            }
+            	            formatedValue = theType;
+            			}
+            		}
+    				MemberValuePair tmp = JDTUtils.newMemberValuePair(compilationUnitAstNode,
+                                                                      attributeName,
+                                                                      formatedValue);
+    				Object[] arrayItem = (Object[])treeEditor.getItem().getParentItem().getData();
+    				NormalAnnotation na = (NormalAnnotation)arrayItem[1];
+    				List<MemberValuePair> list = na.values();
+
+    				for (int i = 0; i < list.size(); i++) {
+    					MemberValuePair item = (MemberValuePair)list.get(i);
+    					if (item.getName().getIdentifier().equals(attributeName)) {
+    						list.remove(i);
+    						break;
+    					}
+    				}
+    				list.add(tmp);
+    				pair[1] = tmp;
+            		annotationClass = (Class)treeEditor.getItem().getParentItem().getParentItem().getParentItem().getData();
+            	} else if (pair[0] instanceof String) {
+            		// handled elsewhere
+            	}
+
+            	Annotation annotationNode = annotationNodesMap.get(annotationClass.getSimpleName());
+                NormalAnnotation normalAnnotationNode = (NormalAnnotation)annotationNode;
+
+                ScJDTAnnUtils.addAnnotationToCu(compilationUnitMember,
+                                                compilationUnitAstNode,
+                                                normalAnnotationNode,
+                                                selectedJdtMember,
+                                                selectedJdtMethodParam);
+            	refreshViewContent();
+            }
 
         } catch (JavaModelException e) {
             // TODO notify the user ??
@@ -637,6 +893,9 @@
         } catch (BadLocationException e) {
             // TODO notify the user ??
             LOG.error("Java model update failed: ", e);
+        } catch (NoSuchMethodException e) {
+            // TODO notify the user ??
+            LOG.error("Java model update failed: ", e);
         }
     }
 
@@ -653,7 +912,7 @@
     }
 
     private void processUpdateOnTextAttribute() {
-        String originalValue = treeEditor.getItem().getText(1);
+        originalValue = treeEditor.getItem().getText(1);
         String updatedValue = text.getText().trim().length() > 0 ? text.getText() : null;
         disposeEditWidgets();
         
Index: src/org/eclipse/stp/sc/common/views/AnnotationViewerLabelProvider.java
===================================================================
RCS file: /cvsroot/stp/org.eclipse.stp.servicecreation/org.eclipse.stp.sc.common/src/org/eclipse/stp/sc/common/views/AnnotationViewerLabelProvider.java,v
retrieving revision 1.1
diff -u -r1.1 AnnotationViewerLabelProvider.java
--- src/org/eclipse/stp/sc/common/views/AnnotationViewerLabelProvider.java	25 Dec 2006 06:10:27 -0000	1.1
+++ src/org/eclipse/stp/sc/common/views/AnnotationViewerLabelProvider.java	15 Jan 2007 07:54:27 -0000
@@ -21,7 +21,8 @@
 import org.eclipse.jface.viewers.ITableLabelProvider;
 import org.eclipse.stp.common.logging.LoggingProxy;
 import org.eclipse.swt.graphics.Image;
-
+import org.eclipse.jdt.core.dom.Expression;
+import org.eclipse.jdt.core.dom.StringLiteral;
 
 /**
  * label provider for the <code>TreeViewer</code> of the <code>AnnotationView</code>.
@@ -37,9 +38,16 @@
     }
 
     public Image getColumnImage(Object element, int columnIndex) {
-        if (element instanceof Class && (columnIndex == 0)) {
+    	if (columnIndex != 0) return null;
+        if (element instanceof Class) {
             return isAnnotationDeclaredForElement((Class)element) ? parent.iconOn : parent.iconOff;
         }
+        if (element instanceof Object[]) {
+        	Object[] pair = (Object[])element;
+        	if (pair[0] instanceof String) {
+        		return (((String)pair[0]).indexOf(":Existing") >= 0) ? parent.iconOn : parent.iconOff;
+        	}
+        }
         return null;
     }
 
@@ -93,6 +101,47 @@
             default:
                 return "";
             }
+        } else if (element instanceof Object[]) {
+        	Object[] pair = (Object[])element;
+        	if (pair[0] instanceof String) {
+        		String className = (String)pair[0];
+        		int index = className.indexOf(":");
+        		className = className.substring(0, index);
+        		switch (columnIndex) {
+        		case 0:
+        			return className;
+
+        		case 1:
+        			return "" + (((String)pair[0]).indexOf(":Existing") >= 0);
+
+        		default:
+        			return "";
+        		}
+        	} else if (pair[0] instanceof Method) {
+        		Method method = (Method)pair[0];
+        		switch (columnIndex) {
+        		case 0:
+        			return method.getName();
+
+        		case 1:
+        			String value = "";
+        			if (pair[1] != null) {
+        				MemberValuePair mvp = (MemberValuePair)pair[1];
+        				Expression expression = mvp.getValue();
+        				if (expression instanceof StringLiteral) {
+        					StringLiteral sl = (StringLiteral)expression;
+        					value = sl.getEscapedValue();
+        					value = value.substring(1, value.length() - 1);
+        				} else {
+        					value = expression.toString();
+        				}
+        			}
+        			return value;
+
+        		default:
+        			return "";
+        		}
+        	}
         }
         return null;
     }
Index: src/org/eclipse/stp/sc/common/views/AnnotationViewerContentProvider.java
===================================================================
RCS file: /cvsroot/stp/org.eclipse.stp.servicecreation/org.eclipse.stp.sc.common/src/org/eclipse/stp/sc/common/views/AnnotationViewerContentProvider.java,v
retrieving revision 1.2
diff -u -r1.2 AnnotationViewerContentProvider.java
--- src/org/eclipse/stp/sc/common/views/AnnotationViewerContentProvider.java	26 Dec 2006 10:21:59 -0000	1.2
+++ src/org/eclipse/stp/sc/common/views/AnnotationViewerContentProvider.java	15 Jan 2007 07:54:26 -0000
@@ -11,10 +11,18 @@
 package org.eclipse.stp.sc.common.views;
 
 import java.util.List;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.lang.reflect.Method;
 
 import org.eclipse.core.resources.IProject;
 import org.eclipse.jdt.core.IMethod;
 import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.IField;
+import org.eclipse.jdt.core.dom.Annotation;
+import org.eclipse.jdt.core.dom.ArrayInitializer;
+import org.eclipse.jdt.core.dom.NormalAnnotation;
+import org.eclipse.jdt.core.dom.MemberValuePair;
 import org.eclipse.jdt.core.dom.CompilationUnit;
 import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
 import org.eclipse.jface.viewers.ITreeContentProvider;
@@ -30,10 +38,114 @@
     
     private static final LoggingProxy LOG = LoggingProxy.getlogger(AnnotationViewerContentProvider.class);
     
+    private AnnotationView parent;
+    
+    public AnnotationViewerContentProvider(AnnotationView aParent) {
+    	parent = aParent;
+    }
+
     public Object[] getChildren(Object node) {
         if (node instanceof Class) {
             return ((Class)node).getDeclaredMethods();
         }
+        else if (node instanceof Method) {
+        	Method method = (Method)node;
+        	Class returnType = method.getReturnType();
+        	if (returnType.isArray()) {
+        		Class annoClass = method.getDeclaringClass();
+        		Annotation annoNode = parent.annotationNodesMap.get(annoClass.getSimpleName());
+        		if (annoNode == null) {
+        			annoNode = parent.annotationNodesMap.get(annoClass.getName());
+        		}
+        		if (annoNode != null) {
+        			if (annoNode instanceof NormalAnnotation) {
+        				MemberValuePair mvpOne = null;
+           				for (Object obj : ((NormalAnnotation)annoNode).values()) {
+           					MemberValuePair mvp = (MemberValuePair)obj;
+           					if (mvp.getName().getIdentifier().equals(method.getName())) {
+           						mvpOne = mvp;
+           						break;
+           					}
+           				}
+           				if (mvpOne != null) {
+           					ArrayInitializer arrayInit = (ArrayInitializer)mvpOne.getValue();
+           					int number = arrayInit.expressions().size();
+           					Object[] children = new Object[number + 1];
+           					for (int i = 0; i < children.length; i++) {
+           						children[i] = new Object[2];
+           					}
+           					Arrays.sort(children, new Comparator<Object>() {
+           						public int compare(Object o1, Object o2) {
+           							return o1.toString().compareTo(o2.toString());
+           						}
+           					});
+           					for (int i = 0; i < number; i++) {
+           						Object[] pair = (Object[])children[i];
+           						pair[0] = returnType.getComponentType().getCanonicalName() + ":Existing" + i;
+           						pair[1] = arrayInit.expressions().get(i);
+           						
+           					}
+           					Object[] pair = (Object[])children[number];
+           					pair[0] = returnType.getComponentType().getCanonicalName() + ":ClickToAdd";
+           					pair[1] = null;
+           					return children;
+           				}
+        			}
+        		} else {
+   					Object[] pair = new Object[2];
+   					pair[0] = returnType.getComponentType().getCanonicalName() + ":ClickToAdd";
+   					pair[1] = null;
+   					Object[] children = new Object[1];
+   					children[0] = pair;
+   					return children;
+        		}
+        	}
+        }
+        else if (node instanceof Object[]) {
+        	Object[] pair = (Object[])node;
+        	if (pair[0] instanceof String) {
+        		String str = (String)pair[0];
+        		NormalAnnotation anno = (NormalAnnotation)pair[1];
+        		String className = str.substring(0, str.indexOf(":"));
+        		try {
+        			Method[] methods = Class.forName(className).getDeclaredMethods();
+   					Arrays.sort(methods, new Comparator<Method>() {
+   						public int compare(Method m1, Method m2) {
+   							return m1.toString().compareTo(m2.toString());
+   						}
+   					});
+        			Object[] children = new Object[methods.length];
+        			for (int i = 0; i < methods.length; i++) {
+        				children[i] = new Object[2];
+        			}
+   					Arrays.sort(children, new Comparator<Object>() {
+   						public int compare(Object o1, Object o2) {
+   							return o1.toString().compareTo(o2.toString());
+   						}
+   					});
+        			for (int i = 0; i < methods.length; i++) {
+        				Method method = methods[i];
+        				Object[] sub = (Object[])children[i];
+        				sub[0] = method;
+        				sub[1] = null;
+        				if (anno != null) {
+        					for (Object obj : anno.values()) {
+        						MemberValuePair mvp2 = (MemberValuePair)obj;
+        						if (mvp2.getName().getIdentifier().equals(method.getName())) {
+        							sub[1] = mvp2;
+        							break;
+        						}
+        					}
+        				}
+        			}
+        			return children;
+        		} catch (ClassNotFoundException e) {
+        			return null;
+        		}
+        	} else if (pair[0] instanceof Method) {
+        		return null;
+        	}
+        }
 
         return null;
     }
@@ -43,34 +155,57 @@
     }
 
     public boolean hasChildren(Object arg0) {
-        return arg0 instanceof Class;
+    	if (arg0 instanceof Class) {
+    		return true;
+    	} else if (arg0 instanceof Method) {
+    		if (((Method)arg0).getReturnType().isArray()) {
+    			return true;
+    		}
+    	} else if (arg0 instanceof Object[]) {
+    		Object[] pair = (Object[])arg0;
+    		if (pair[0] instanceof String) {
+    			return true;
+    		}
+    	}
+        return false;
     }
 
     /**
      * identify the base nodes of the tree based on the type of java element selected
      */
     public Object[] getElements(Object input) {
+    	
     	try {
-        if (input instanceof IMethod) {
-        	IMethod method = (IMethod)input;
-        	IProject project = method.getUnderlyingResource().getProject();
-        	List<Class> list = ScAnnotationSupportUtils.getAvailableAnnotationsForMethod(project);
-            LOG.debug("retrieved methods annotations: " + list);
-            return list.toArray();
-        }
-
-        if (input instanceof IType) {
-        	IType method = (IType)input;
-        	IProject project = method.getUnderlyingResource().getProject();
-        	return ScAnnotationSupportUtils.getAvailableAnnotationsForType(project).toArray();
-        }
+    		if (input instanceof IMethod) {
+    			IMethod method = (IMethod)input;
+    			IProject project = method.getUnderlyingResource().getProject();
+    			List<Class> list = ScAnnotationSupportUtils.getAvailableAnnotationsForMethod(project);
+    			LOG.debug("retrieved methods annotations: " + list);
+    			return list.toArray();
+    		}
+
+    		if (input instanceof IType) {
+    			IType type = (IType)input;
+    			IProject project = type.getUnderlyingResource().getProject();
+    			if (type.isAnnotation()) {
+    				return ScAnnotationSupportUtils.getAvailableAnnotationsForAnno(project).toArray();
+    			} else {
+    				return ScAnnotationSupportUtils.getAvailableAnnotationsForType(project).toArray();
+    			}
+    		}
         
-        if (input instanceof SingleVariableDeclaration) {
-        	SingleVariableDeclaration var = (SingleVariableDeclaration)input;
-        	CompilationUnit root = (CompilationUnit)var.getRoot();
-        	IProject project = root.getJavaElement().getCorrespondingResource().getProject();
-            return ScAnnotationSupportUtils.getAvailableAnnotationsForParam(project).toArray();
-        }
+    		if (input instanceof SingleVariableDeclaration) {
+    			SingleVariableDeclaration var = (SingleVariableDeclaration)input;
+    			CompilationUnit root = (CompilationUnit)var.getRoot();
+    			IProject project = root.getJavaElement().getCorrespondingResource().getProject();
+    			return ScAnnotationSupportUtils.getAvailableAnnotationsForParam(project).toArray();
+    		}
+        
+    		if (input instanceof IField) {
+    			IField field = (IField)input;
+    			IProject project = field.getUnderlyingResource().getProject();
+    			return ScAnnotationSupportUtils.getAvailableAnnotationsForField(project).toArray();
+    		}
     	} catch (Exception e) {
     		e.printStackTrace();
     	}
Index: schema/AnnotationSupport.exsd
===================================================================
RCS file: /cvsroot/stp/org.eclipse.stp.servicecreation/org.eclipse.stp.sc.common/schema/AnnotationSupport.exsd,v
retrieving revision 1.3
diff -u -r1.3 AnnotationSupport.exsd
--- schema/AnnotationSupport.exsd	30 Dec 2006 07:00:54 -0000	1.3
+++ schema/AnnotationSupport.exsd	15 Jan 2007 07:53:30 -0000
@@ -140,4 +140,4 @@
       </documentation>
    </annotation>
 
-</schema>
+</schema>
\ No newline at end of file
Index: src/org/eclipse/stp/sc/common/annotations/ScJDTAnnUtils.java
===================================================================
RCS file: /cvsroot/stp/org.eclipse.stp.servicecreation/org.eclipse.stp.sc.common/src/org/eclipse/stp/sc/common/annotations/ScJDTAnnUtils.java,v
retrieving revision 1.1
diff -u -r1.1 ScJDTAnnUtils.java
--- src/org/eclipse/stp/sc/common/annotations/ScJDTAnnUtils.java	25 Dec 2006 06:10:28 -0000	1.1
+++ src/org/eclipse/stp/sc/common/annotations/ScJDTAnnUtils.java	15 Jan 2007 07:53:39 -0000
@@ -36,6 +36,7 @@
 import org.eclipse.stp.common.utils.JDTUtils;
 import org.eclipse.text.edits.MalformedTreeException;
 import org.eclipse.text.edits.TextEdit;
+import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
 
 public class ScJDTAnnUtils {
 private static final LoggingProxy LOG = LoggingProxy.getlogger(ScJDTAnnUtils.class);
@@ -68,10 +69,34 @@
                                             IField field,
                                             ASTRewrite rewrite) {
         //todo: check the annotation exists first?
-        //JDTUtils.addAnnotationImport(astRoot, annotation, rewrite);
-        FieldDeclaration fieldDesc = JDTUtils.getFieldDeclaration(compilationUnitAstNode, field);
-        ListRewrite lrw2 = rewrite.getListRewrite((ASTNode)fieldDesc, FieldDeclaration.MODIFIERS2_PROPERTY);
-        lrw2.insertFirst(annotationNode, null);
+        addAnnotationImport(compilationUnitAstNode, annotationNode, rewrite);
+        
+        Annotation oldAnnotationNode = JDTUtils.findAnnotation(compilationUnitAstNode, field, annotationNode);
+        if (oldAnnotationNode != null) {
+        	rewrite.remove(oldAnnotationNode, null);
+        }
+        
+        IType type = field.getDeclaringType();
+        
+        for (Iterator it = compilationUnitAstNode.types().iterator(); it.hasNext();) {
+            TypeDeclaration t = (TypeDeclaration)it.next();
+
+            if (t.getName().getIdentifier().equals(type.getElementName())) {
+                String fieldName = field.getElementName();
+                FieldDeclaration[] fields = t.getFields();
+
+                for (int inx = 0; inx < fields.length; inx++) {
+                	for (Object obj : fields[inx].fragments()) {
+                		VariableDeclarationFragment var = (VariableDeclarationFragment)obj;
+                		if (var.getName().getFullyQualifiedName().equals(fieldName)) {
+                            ListRewrite lrw2 = rewrite.getListRewrite((ASTNode)fields[inx],
+                                                                      FieldDeclaration.MODIFIERS2_PROPERTY);
+                            lrw2.insertFirst(annotationNode, null);
+                		}
+                	}
+                }
+            }
+        }
     }
     
     
Index: src/org/eclipse/stp/sc/common/annotations/ScAnnotationSupportUtils.java
===================================================================
RCS file: /cvsroot/stp/org.eclipse.stp.servicecreation/org.eclipse.stp.sc.common/src/org/eclipse/stp/sc/common/annotations/ScAnnotationSupportUtils.java,v
retrieving revision 1.2
diff -u -r1.2 ScAnnotationSupportUtils.java
--- src/org/eclipse/stp/sc/common/annotations/ScAnnotationSupportUtils.java	26 Dec 2006 10:21:59 -0000	1.2
+++ src/org/eclipse/stp/sc/common/annotations/ScAnnotationSupportUtils.java	15 Jan 2007 07:53:38 -0000
@@ -21,6 +21,8 @@
 import org.eclipse.jdt.core.IMember;
 import org.eclipse.jdt.core.IMethod;
 import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.IField;
+import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jdt.core.dom.Annotation;
 import org.eclipse.jdt.core.dom.CompilationUnit;
 import org.eclipse.jdt.core.dom.MemberValuePair;
@@ -29,7 +31,6 @@
 import org.eclipse.stp.common.utils.JDTUtils;
 import org.eclipse.stp.sc.common.annotations.ext.AnnotationSupportProxy;
 
-
 /**
  * simple utility to handle JAX-WS annotations artefacts:
  * <br> - identify valid annotation candidates for specific Java artefacts
@@ -38,36 +39,82 @@
  */
 public class ScAnnotationSupportUtils {
     
+	public enum JavaTypes {
+		ENUM,
+		CLASS,
+		INTERFACE,
+		ANNOTATION,
+	}
     public static final LoggingProxy LOG = LoggingProxy.getlogger(ScAnnotationSupportUtils.class);
 
-    private static List<Class> methodAnnotations;
-    private static List<Class> typeAnnotations;
-    private static List<Class> paramAnnotations;
+    //Johnson comment out below lists. since we get annotations according to project nature.
+    //hence we can't cache those annotations anymore
+//    private static List<Class> methodAnnotations;
+//    private static List<Class> typeAnnotations;
+//    private static List<Class> paramAnnotations;
 
     protected ScAnnotationSupportUtils() {
     }
 
-    public static List<Class> getAvailableAnnotationsForMethod(IProject project) {
-        if (methodAnnotations == null || methodAnnotations.size() == 0) {
-            methodAnnotations = getAnnotationClassesForJavaElement(ElementType.METHOD, project);
+    public static List<Class> getAvailableAnnotationsForClass(IProject project) {
+    	List<Class> typeAnnotations = getAnnotationClassesForJavaElement(ElementType.TYPE, project);
+    	for (int i = 0; i < typeAnnotations.size(); i++) {
+        	if (!isTypeAllowed(typeAnnotations.get(i), JavaTypes.CLASS)) {
+        		typeAnnotations.remove(i);
+        	}
         }
+        return typeAnnotations;
+    }
 
-        return methodAnnotations;
+    public static List<Class> getAvailableAnnotationsForInterface(IProject project) {
+    	List<Class> typeAnnotations = getAnnotationClassesForJavaElement(ElementType.TYPE, project);
+    	for (int i = 0; i < typeAnnotations.size(); i++) {
+        	if (!isTypeAllowed(typeAnnotations.get(i), JavaTypes.INTERFACE)) {
+        		typeAnnotations.remove(i);
+        	}
+        }
+        return typeAnnotations;
+    }
+
+    public static List<Class> getAvailableAnnotationsForAnno(IProject project) {
+        return getAnnotationClassesForJavaElement(ElementType.ANNOTATION_TYPE, project);
     }
 
     public static List<Class> getAvailableAnnotationsForType(IProject project) {
-        if (typeAnnotations == null || typeAnnotations.size() == 0) {
-            typeAnnotations = getAnnotationClassesForJavaElement(ElementType.TYPE, project);
-        }
+        return getAnnotationClassesForJavaElement(ElementType.TYPE, project);
+    }
 
-        return typeAnnotations;
+    public static List<Class> getAvailableAnnotationsForType(IProject project, IType type) {
+    	try {
+        	if (type.isClass()) {
+        		return getAvailableAnnotationsForClass(project);
+        	}
+        	if (type.isInterface()) {
+        		return getAvailableAnnotationsForInterface(project);
+        	}
+        }
+        catch (JavaModelException e) {
+        	LOG.error("error to check sub-types of java element type");
+        }
+		return getAvailableAnnotationsForType(project);
+    }
+
+    public static List<Class> getAvailableAnnotationsForField(IProject project) {
+    	/*
+    	if (fieldAnnotations == null || fieldAnnotations.size() == 0) {
+    		fieldAnnotations = getAnnotationClassesForJavaElement(ElementType.FIELD, project);
+    	}
+    	return fieldAnnotations;
+    	*/
+    	return getAnnotationClassesForJavaElement(ElementType.FIELD, project);
+    }
+
+    public static List<Class> getAvailableAnnotationsForMethod(IProject project) {
+        return getAnnotationClassesForJavaElement(ElementType.METHOD, project);
     }
 
     public static List<Class> getAvailableAnnotationsForParam(IProject project) {
-        if (paramAnnotations == null || paramAnnotations.size() == 0) {
-            paramAnnotations = getAnnotationClassesForJavaElement(ElementType.PARAMETER, project);
-        }
-        return paramAnnotations;
+        return getAnnotationClassesForJavaElement(ElementType.PARAMETER, project);
     }
 
     public static String getAnnotationImport(Annotation annotation) {
@@ -117,18 +164,21 @@
         return (jdtMember instanceof IMethod 
                 && getAvailableAnnotationsForMethod(project).contains(annotationClass))
                     || (jdtMember instanceof IType 
-                        && getAvailableAnnotationsForType(project).contains(annotationClass))
-                            || (getAvailableAnnotationsForParam(project).contains(annotationClass)
-                                && jdtMemberParam != null);
+                        && getAvailableAnnotationsForType(project, (IType)jdtMember).contains(annotationClass))
+                            || (jdtMember instanceof IField
+                            		&& getAvailableAnnotationsForField(project).contains(annotationClass))
+                            			|| (getAvailableAnnotationsForParam(project).contains(annotationClass)
+                            					&& jdtMemberParam != null);
     }
 
 
     private static List<Class> getAnnotationClassesForJavaElement(ElementType aType, IProject project) {
-        
-        List<Class> theList = new ArrayList<Class>();
+
+    	List<Class> theList = new ArrayList<Class>();
         
         Iterator<Class <? extends java.lang.annotation.Annotation> > iter = 
-            AnnotationSupportProxy.getAllAvailableAnnotations().values().iterator();
+        	AnnotationSupportProxy.getAllAvailableAnnotations().values().iterator();
+
         while (iter.hasNext()) {
             
             Class<? extends java.lang.annotation.Annotation> nextAnnotationClass = iter.next();
@@ -144,7 +194,7 @@
                 		LOG.error("error during get project nature", e);
                 	}
                 	if (AnnotationSupportProxy.verifyNature(nextAnnotationClass.getName(), natureIDs)) {
-                    theList.add(nextAnnotationClass);
+                		theList.add(nextAnnotationClass);
                 	}
                 }
             }
@@ -157,4 +207,15 @@
         
         return theList;
     }
+
+    private static boolean isTypeAllowed(Class anno, JavaTypes type) {
+
+    	boolean classOnly = AnnotationSupportProxy.isClassOnly(anno.getCanonicalName());
+   		boolean interfaceOnly = AnnotationSupportProxy.isInterfaceOnly(anno.getCanonicalName());
+
+   		if (classOnly && type != JavaTypes.CLASS) return false;
+    	if (interfaceOnly && type != JavaTypes.INTERFACE) return false;
+
+    	return true;
+    }
 }
Index: src/org/eclipse/stp/sc/common/CommonResources.properties
===================================================================
RCS file: /cvsroot/stp/org.eclipse.stp.servicecreation/org.eclipse.stp.sc.common/src/org/eclipse/stp/sc/common/CommonResources.properties,v
retrieving revision 1.1
diff -u -r1.1 CommonResources.properties
--- src/org/eclipse/stp/sc/common/CommonResources.properties	25 Dec 2006 06:10:27 -0000	1.1
+++ src/org/eclipse/stp/sc/common/CommonResources.properties	15 Jan 2007 07:53:30 -0000
@@ -1,4 +1,5 @@
 annotation.view.java.element.type.lbl=Type
+annotation.view.java.element.field.lbl=Field
 annotation.view.java.element.param.lbl=Parameter
 annotation.view.java.element.method.lbl=Method
 annotation.view.view.mode.lbl=View Only mode (open the file in a Java editor to enable the edit support)
Index: src/org/eclipse/stp/sc/common/annotations/ext/AnnotationSupportProxy.java
===================================================================
RCS file: /cvsroot/stp/org.eclipse.stp.servicecreation/org.eclipse.stp.sc.common/src/org/eclipse/stp/sc/common/annotations/ext/AnnotationSupportProxy.java,v
retrieving revision 1.2
diff -u -r1.2 AnnotationSupportProxy.java
--- src/org/eclipse/stp/sc/common/annotations/ext/AnnotationSupportProxy.java	26 Dec 2006 10:21:59 -0000	1.2
+++ src/org/eclipse/stp/sc/common/annotations/ext/AnnotationSupportProxy.java	15 Jan 2007 07:53:49 -0000
@@ -28,6 +28,8 @@
 
 public class AnnotationSupportProxy {
 
+	private static final String EXT_ATT_SC_ANN_CLASS_ONLY = "classOnly";
+	private static final String EXT_ATT_SC_ANN_INTERFACE_ONLY = "interfaceOnly";
 	private static final String EXT_ATT_SC_ANN_NATURE = "nature";
     private static final String EXT_ATT_SC_ANN_INIT_CLASS = "initializerClass";
     private static final String EXT_ATT_SC_ANN_CLASS = "annotationClass";
@@ -36,6 +38,8 @@
     private static Map<String, Class<? extends Annotation> > JAXWS_ANN_DECL;
     private static Map<Class <? extends Annotation>, IAnnotationInitializer > JAXWS_ANN_INIT;
     private static Map<String, String> ANN_NATURES;
+    private static Map<String, Boolean> ANN_CLASS_ONLY;
+    private static Map<String, Boolean> ANN_INTERFACE_ONLY;
 
     private static final LoggingProxy LOG = LoggingProxy.getlogger(AnnotationSupportProxy.class);
     public static final String EXT_POINT_SC_ANNOTATION_SUPPORT = "org.eclipse.stp.sc.common.AnnotationSupport";
@@ -51,6 +55,8 @@
         JAXWS_ANN_DECL = new HashMap<String, Class <? extends Annotation>>(extElts.length);
         JAXWS_ANN_INIT = new HashMap<Class <? extends Annotation>, IAnnotationInitializer>(extElts.length);
         ANN_NATURES = new HashMap<String, String>();
+        ANN_CLASS_ONLY = new HashMap<String, Boolean>();
+        ANN_INTERFACE_ONLY = new HashMap<String, Boolean>();
         
         for (int extIndex = 0; extIndex < extElts.length; extIndex++) {
             if (extElts[extIndex].getName().equals(EXT_ELT_SC_ANN)) {
@@ -126,6 +132,14 @@
                 if (natureID != null) {
                     ANN_NATURES.put(annotationClassName, natureID);
                 }
+                
+                //process class only
+                Boolean classOnly = new Boolean(extElts[extIndex].getAttribute(EXT_ATT_SC_ANN_CLASS_ONLY));
+                ANN_CLASS_ONLY.put(annotationClassName, classOnly);
+                
+                //process interface only
+                Boolean interfaceOnly = new Boolean(extElts[extIndex].getAttribute(EXT_ATT_SC_ANN_INTERFACE_ONLY));
+                ANN_INTERFACE_ONLY.put(annotationClassName, interfaceOnly);
             }
         }
     }
@@ -143,6 +157,20 @@
     	return false;
     }
 
+    public static boolean isClassOnly(String annotationName) {
+        if (JAXWS_ANN_DECL == null || JAXWS_ANN_DECL.size() == 0) {
+            loadAnnotationSupportExtensions();
+        }
+        return ANN_CLASS_ONLY.get(annotationName).booleanValue();
+    }
+
+    public static boolean isInterfaceOnly(String annotationName) {
+        if (JAXWS_ANN_DECL == null || JAXWS_ANN_DECL.size() == 0) {
+            loadAnnotationSupportExtensions();
+        }
+        return ANN_INTERFACE_ONLY.get(annotationName).booleanValue();
+    }
+
     public static Map<String, Class <? extends Annotation>> getAllAvailableAnnotations() {
         if (JAXWS_ANN_DECL == null || JAXWS_ANN_DECL.size() == 0) {
             loadAnnotationSupportExtensions();

Back to the top