Bug 315428 - [refactoring] Renaming base features does not update
inferred callouts
- preparatory refactoring: publish API for searching playedBy bindings
- String version of a utility method (actually unused)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/core/compiler/OTNameUtils.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/core/compiler/OTNameUtils.java
index 131b715..446b4c8 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/core/compiler/OTNameUtils.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/core/compiler/OTNameUtils.java
@@ -82,6 +82,21 @@
 		char[] prefix = isSetter ? OTNameUtils.SET : OTNameUtils.GET;
 		return CharOperation.concat(prefix, capitalized);
 	}
+	/** 
+	 * Given a fieldName (e.g. val) construct an accessor method name (getVal, or setVal) for inferred callout.
+	 * @param isSetter asking for a "set" accessor?
+	 * @param fieldName 
+	 */
+	public static String accessorName(boolean isSetter, String fieldName) {
+		if (fieldName == null)
+			return null;
+		int len = fieldName.length();
+		char[] accessor = new char[3+len];
+		System.arraycopy(isSetter ? OTNameUtils.SET : OTNameUtils.GET, 0, accessor, 0, 3);
+		accessor[3] = Character.toUpperCase(fieldName.charAt(0)); 
+		fieldName.getChars(1, len, accessor, 4);
+		return String.valueOf(accessor);
+	}
 
 	/** Does name denote a synthetic marker interface used for marking tsuper methods? */
 	public static boolean isTSuperMarkerInterface(char[] name) {
diff --git a/org.eclipse.jdt.core/search/org/eclipse/objectteams/otdt/core/search/Messages.java b/org.eclipse.jdt.core/search/org/eclipse/objectteams/otdt/core/search/Messages.java
new file mode 100644
index 0000000..c6cdfab
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/objectteams/otdt/core/search/Messages.java
@@ -0,0 +1,33 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 2013 GK Software AG, Germany,
+ * 
+ * All rights reserved. This program and the accompanying materials
+ * are 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
+ * 
+ * Please visit http://www.eclipse.org/objectteams for updates and contact.
+ * 
+ * Contributors:
+ * 	Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otdt.core.search;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+	
+	private static final String BUNDLE_NAME = "org.eclipse.objectteams.otdt.core.search.messages"; //$NON-NLS-1$
+	
+	public static String OTSearchHelper_progress_searchRoleTypes;
+	
+	static {
+		// initialize resource bundle
+		NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+	}
+
+	private Messages() {
+	}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/objectteams/otdt/core/search/OTSearchHelper.java b/org.eclipse.jdt.core/search/org/eclipse/objectteams/otdt/core/search/OTSearchHelper.java
new file mode 100644
index 0000000..6969474
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/objectteams/otdt/core/search/OTSearchHelper.java
@@ -0,0 +1,123 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 2013 GK Software AG, Germany,
+ * 
+ * All rights reserved. This program and the accompanying materials
+ * are 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
+ * 
+ * Please visit http://www.eclipse.org/objectteams for updates and contact.
+ * 
+ * Contributors:
+ * 	Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otdt.core.search;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IMember;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.search.IJavaSearchConstants;
+import org.eclipse.jdt.core.search.IJavaSearchScope;
+import org.eclipse.jdt.core.search.SearchMatch;
+import org.eclipse.jdt.core.search.SearchPattern;
+import org.eclipse.jdt.core.search.SearchRequestor;
+
+public class OTSearchHelper {
+
+	/**
+	 * Add the key->value pair to the given map of sets, creating a new value set if needed.
+	 * @param mapOfSets
+	 * @param key
+	 * @param value
+	 */
+	public static <M extends IMember> void addToMapOfSets(final Map<IMember, Set<M>> mapOfSets, IMember key, M value) 
+	{
+		Set<M> setForType = mapOfSets.get(key);
+		if (setForType == null)
+			mapOfSets.put(key, setForType = new HashSet<M>());
+		setForType.add(value);
+	}
+
+	/**
+	 * Find all playedBy bindings within a given set of projects refering to one of baseTypes as its baseclass.
+	 * 
+	 * @param baseTypes 
+	 * @param projects
+	 * @param monitor
+	 * @return a map indexed by base types containing sets of role types bound to the given base type.
+	 */
+	public static Map<IMember, Set<IType>> searchPlayedByBindings(Collection<IType> baseTypes, IJavaProject[] projects, IProgressMonitor monitor)
+	{
+	    if (baseTypes == null || baseTypes.size() == 0) {
+	        monitor.beginTask("", 1); //$NON-NLS-1$
+			monitor.done();
+	        return null;
+	    }
+	    
+	    OTSearchEngine engine = new OTSearchEngine();
+	    IJavaSearchScope searchScope = OTSearchEngine.createOTSearchScope(projects, false);
+	    final Map<IMember, Set<IType>> resultMap = new HashMap<IMember, Set<IType>>();
+	
+	    try {
+	        monitor.beginTask(Messages.OTSearchHelper_progress_searchRoleTypes, baseTypes.size());
+	        
+	        for (final IType baseType : baseTypes)
+	        {
+	        	if (monitor.isCanceled()) return null;
+	        	try
+	        	{
+		            IProgressMonitor searchMonitor = new SubProgressMonitor(monitor, 1);
+		            if (!baseType.exists()) // ensure it's 'open'
+		                continue;
+		            if (baseType.isEnum() || baseType.isAnnotation())
+		            	continue; // no callin-to-enum/annot 
+			        SearchPattern pattern = SearchPattern.createPattern(baseType, IJavaSearchConstants.PLAYEDBY_REFERENCES);
+			        if (pattern == null)
+			            JavaCore.getJavaCore().getLog().log(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, "Error creating pattern")); //$NON-NLS-1$
+			        else
+			        	engine.search(
+	                        pattern, 
+	                        searchScope, 
+	                        new SearchRequestor() {
+			                    public void acceptSearchMatch(SearchMatch match)
+			                            throws CoreException
+			                    {
+			                        Object element = match.getElement();
+			                        if (element instanceof IType)
+			                        {
+			                        	// FIXME(SH): check: if mapping is a role, baseType must be conform to its baseclass 
+			                            IType mapping = (IType) element;
+			                            addToMapOfSets(resultMap, baseType, mapping);
+			                        }
+			                    }
+	                        },
+	                        searchMonitor);
+	            }
+	            catch (CoreException ex)
+	            {
+	            	JavaCore.getJavaCore().getLog().log(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, "Error finding playedBy bindings", ex)); //$NON-NLS-1$
+	            }
+	        }
+	    }
+	    finally {
+	        monitor.done();
+	    }
+	    
+	    return resultMap;
+	}
+
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/objectteams/otdt/core/search/messages.properties b/org.eclipse.jdt.core/search/org/eclipse/objectteams/otdt/core/search/messages.properties
new file mode 100644
index 0000000..9ffdb87
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/objectteams/otdt/core/search/messages.properties
@@ -0,0 +1,14 @@
+# This file is part of "Object Teams Development Tooling"-Software
+# 
+# Copyright 2013 GK Software AG, Germany,
+# 
+# All rights reserved. This program and the accompanying materials
+# are 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
+# 
+# Please visit http://www.eclipse.org/objectteams for updates and contact.
+# 
+# Contributors:
+# 	Stephan Herrmann - Initial API and implementation
+OTSearchHelper_progress_searchRoleTypes=searching role types
diff --git a/plugins/org.eclipse.objectteams.otdt.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.objectteams.otdt.ui/META-INF/MANIFEST.MF
index e109f06..2f20ee5 100644
--- a/plugins/org.eclipse.objectteams.otdt.ui/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.objectteams.otdt.ui/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.objectteams.otdt.ui;singleton:=true
-Bundle-Version: 2.2.0.qualifier
+Bundle-Version: 2.3.0.qualifier
 Bundle-Activator: org.eclipse.objectteams.otdt.ui.OTDTUIPlugin
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
@@ -27,7 +27,7 @@
  org.eclipse.compare;bundle-version="[3.5.200,4.0.0)",
  org.eclipse.team.core;bundle-version="[3.6.0,4.0.0)",
  org.eclipse.team.ui;bundle-version="[3.6.100,4.0.0)",
- org.eclipse.jdt.core;bundle-version="[3.7.0.v_OTDT_r200,4.0.0)",
+ org.eclipse.jdt.core;bundle-version="[3.10.0.v_OTDT_r230,4.0.0)",
  org.eclipse.objectteams.otdt.debug;bundle-version="[2.0.0,3.0.0)",
  org.eclipse.objectteams.otdt;bundle-version="[2.0.0,3.0.0)"
 Bundle-ActivationPolicy: lazy
diff --git a/plugins/org.eclipse.objectteams.otdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/callinmarkers/CallinMarkerCreator2.java b/plugins/org.eclipse.objectteams.otdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/callinmarkers/CallinMarkerCreator2.java
index 00b391b..e0b36ce 100644
--- a/plugins/org.eclipse.objectteams.otdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/callinmarkers/CallinMarkerCreator2.java
+++ b/plugins/org.eclipse.objectteams.otdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/callinmarkers/CallinMarkerCreator2.java
@@ -50,11 +50,8 @@
 import org.eclipse.jdt.core.IType;
 import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jdt.core.search.IJavaSearchConstants;
-import org.eclipse.jdt.core.search.IJavaSearchScope;
 import org.eclipse.jdt.core.search.SearchEngine;
-import org.eclipse.jdt.core.search.SearchMatch;
 import org.eclipse.jdt.core.search.SearchPattern;
-import org.eclipse.jdt.core.search.SearchRequestor;
 import org.eclipse.jdt.core.search.TypeNameRequestor;
 import org.eclipse.jdt.internal.ui.javaeditor.IClassFileEditorInput;
 import org.eclipse.jface.action.IStatusLineManager;
@@ -74,7 +71,7 @@
 import org.eclipse.objectteams.otdt.core.OTModelManager;
 import org.eclipse.objectteams.otdt.core.ext.IMarkableJavaElement;
 import org.eclipse.objectteams.otdt.core.ext.MarkableFactory;
-import org.eclipse.objectteams.otdt.core.search.OTSearchEngine;
+import org.eclipse.objectteams.otdt.core.search.OTSearchHelper;
 import org.eclipse.objectteams.otdt.internal.ui.preferences.GeneralPreferences;
 import org.eclipse.objectteams.otdt.ui.OTDTUIPlugin;
 import org.eclipse.osgi.util.NLS;
@@ -306,7 +303,7 @@
 		    // ==== role bindings: ====
 		    IJavaProject[] projects = target.getProjects();
 		    Set<IType> allTypes = target.getAllTypes(projects, monitor); // 10 ticks
-		    Map<IMember, Set<IType>> playedByMap = searchPlayedByBindings(allTypes, projects, new MySubProgressMonitor(monitor, 20));
+		    Map<IMember, Set<IType>> playedByMap = OTSearchHelper.searchPlayedByBindings(allTypes, projects, new MySubProgressMonitor(monitor, 20));
 			if (playedByMap == null || playedByMap.size() == 0)
 				return; // no base types or cancelled
 
@@ -368,7 +365,7 @@
 			    // find direct roles:
 			    ArrayList<IType> allTypes = new ArrayList<IType>(1);
 			    allTypes.add((IType)member.getAncestor(IJavaElement.TYPE)); // TODO(SH): could be IOTType?
-			    Map<IMember, Set<IType>> playedByMap = searchPlayedByBindings(allTypes,
+			    Map<IMember, Set<IType>> playedByMap = OTSearchHelper.searchPlayedByBindings(allTypes,
 			    															  new IJavaProject[]{member.getJavaProject()}, 
 			    															  new MySubProgressMonitor(monitor, 20));
 			    if (playedByMap == null || playedByMap.isEmpty())
@@ -540,74 +537,6 @@
     }
     
     /**
-     * Find all playedBy bindings within a given set of projects refering to one of baseTypes as its baseclass.
-     * 
-     * @param baseTypes 
-     * @param projects
-     * @param monitor
-     * @return a map indexed by base types containing sets of role types bound to the given base type.
-     * @throws CoreException
-     */
-    private Map<IMember, Set<IType>> searchPlayedByBindings(Collection<IType> baseTypes, IJavaProject[] projects, MySubProgressMonitor monitor)
-    {
-        if (baseTypes == null || baseTypes.size() == 0) {
-            monitor.doneNothing();
-            return null;
-        }
-        
-        OTSearchEngine engine = new OTSearchEngine();
-        IJavaSearchScope searchScope = OTSearchEngine.createOTSearchScope(projects, false);
-        final Map<IMember, Set<IType>> resultMap = new HashMap<IMember, Set<IType>>();
-
-        try {
-	        monitor.beginTask(OTDTUIPlugin.getResourceString("searching role types"), baseTypes.size()); //$NON-NLS-1$
-	        
-	        for (final IType baseType : baseTypes)
-	        {
-	        	if (monitor.isCanceled()) return null;
-	        	try
-	        	{
-		            IProgressMonitor searchMonitor = new SubProgressMonitor(monitor, 1);
-		            if (!baseType.exists()) // ensure it's 'open'
-		                continue;
-		            if (baseType.isEnum() || baseType.isAnnotation())
-		            	continue; // no callin-to-enum/annot 
-			        SearchPattern pattern = SearchPattern.createPattern(baseType, IJavaSearchConstants.PLAYEDBY_REFERENCES);
-			        if (pattern == null)
-			            OTDTUIPlugin.getDefault().getLog().log(new Status(Status.ERROR, OTDTUIPlugin.UIPLUGIN_ID, "Error creating pattern")); //$NON-NLS-1$
-			        else
-			        	engine.search(
-	                        pattern, 
-	                        searchScope, 
-	                        new SearchRequestor() {
-			                    public void acceptSearchMatch(SearchMatch match)
-			                            throws CoreException
-			                    {
-			                        Object element = match.getElement();
-			                        if (element instanceof IType)
-			                        {
-			                        	// FIXME(SH): check: if mapping is a role, baseType must be conform to its baseclass 
-			                            IType mapping = (IType) element;
-			                            addToMapOfSets(resultMap, baseType, mapping);
-			                        }
-			                    }
-	                        },
-	                        searchMonitor);
-	            }
-	            catch (CoreException ex)
-	            {
-	            	OTDTUIPlugin.getDefault().getLog().log(new Status(Status.ERROR, OTDTUIPlugin.UIPLUGIN_ID, "Error finding playedBy bindings", ex)); //$NON-NLS-1$
-	            }
-	        }
-        }
-        finally {
-            monitor.done();
-        }
-        
-        return resultMap;
-    }
-
-    /**
      * Search all callin bindings within allRoleTypes mentioning one of baseMethods as a base method.
      * 
      * @param baseMembers   base methods and fields of interest
@@ -644,19 +573,19 @@
 						ICallinMapping callinMapping = (ICallinMapping) mapping;
 							for (IMethod baseMethod : callinMapping.getBoundBaseMethods())
 								if (baseMembers.contains(baseMethod)) // TODO(SH): would comparison of resources suffice??
-							    	addToMapOfSets(callinMap, baseMethod, mapping);
+							    	OTSearchHelper.addToMapOfSets(callinMap, baseMethod, mapping);
 					}
 					else if (mapping.getElementType() == IOTJavaElement.CALLOUT_MAPPING) {
 						ICalloutMapping calloutMapping = (ICalloutMapping) mapping;
 						IMethod baseMethod = calloutMapping.getBoundBaseMethod();
 						if (baseMembers.contains(baseMethod) && !isVisibleFor(baseMethod, roleType))
-					    	addToMapOfSets(calloutMap, baseMethod, mapping);
+					    	OTSearchHelper.addToMapOfSets(calloutMap, baseMethod, mapping);
 					}
 					else if (mapping.getElementType() == IOTJavaElement.CALLOUT_TO_FIELD_MAPPING) {
 						ICalloutToFieldMapping calloutMapping = (ICalloutToFieldMapping) mapping;
 						IField baseField = calloutMapping.getBoundBaseField();
 						if (baseMembers.contains(baseField) && !isVisibleFor(baseField, roleType))
-					    	addToMapOfSets(calloutMap, baseField, mapping);
+					    	OTSearchHelper.addToMapOfSets(calloutMap, baseField, mapping);
 					}
 				} catch (JavaModelException ex) {
 					OTDTUIPlugin.getDefault().getLog().log(new Status(Status.ERROR, OTDTUIPlugin.UIPLUGIN_ID, "Error checking callin/callout binding", ex)); //$NON-NLS-1$
@@ -676,20 +605,6 @@
     }
     
     /**
-     * add the key->value pair to the given map of sets, creating a new value set if needed.
-     * @param mapOfSets
-     * @param key
-     * @param value
-     */
-	private <M extends IMember> void addToMapOfSets(final Map<IMember, Set<M>> mapOfSets, IMember key, M value) 
-	{
-		Set<M> setForType = mapOfSets.get(key);
-		if (setForType == null)
-			mapOfSets.put(key, setForType = new HashSet<M>());
-		setForType.add(value);
-	}
-    
-	/**
 	 * Create actual markers wrapped by CallinMarkers from the data given as bindingMap.
 	 * 
 	 * @param target      where to attach the markers
diff --git a/releng/map/otdt.map.in b/releng/map/otdt.map.in
index 79c2675..7dd1c34 100644
--- a/releng/map/otdt.map.in
+++ b/releng/map/otdt.map.in
@@ -14,7 +14,7 @@
 

 plugin@org.eclipse.objectteams.otdt.debug,2.2.0=GIT,repo=git://git.eclipse.org/gitroot/objectteams/org.eclipse.objectteams.git,path=plugins/org.eclipse.objectteams.otdt.debug,tag=builds/201305210612

 plugin@org.eclipse.objectteams.otdt.debug.ui,2.2.0=GIT,repo=git://git.eclipse.org/gitroot/objectteams/org.eclipse.objectteams.git,path=plugins/org.eclipse.objectteams.otdt.debug.ui,tag=builds/201305210612

-plugin@org.eclipse.objectteams.otdt.ui,2.2.0=GIT,repo=git://git.eclipse.org/gitroot/objectteams/org.eclipse.objectteams.git,path=plugins/org.eclipse.objectteams.otdt.ui,tag=builds/201305210612

+plugin@org.eclipse.objectteams.otdt.ui,2.3.0=GIT,repo=git://git.eclipse.org/gitroot/objectteams/org.eclipse.objectteams.git,path=plugins/org.eclipse.objectteams.otdt.ui

 plugin@org.eclipse.objectteams.otdt.doc,2.2.0=GIT,repo=git://git.eclipse.org/gitroot/objectteams/org.eclipse.objectteams.git,path=plugins/org.eclipse.objectteams.otdt.doc,tag=builds/201306040500

 plugin@org.eclipse.objectteams.otdt.metrics,0.7.0=GIT,repo=git://git.eclipse.org/gitroot/objectteams/org.eclipse.objectteams.git,path=plugins/org.eclipse.objectteams.otdt.metrics,tag=builds/201101290806