private int getApiVersion(Element usesSdk, String attribute, int defaultApiLevel) { String valueString = null; if (usesSdk.hasAttributeNS(NS_RESOURCES, attribute)) { valueString = usesSdk.getAttributeNS(NS_RESOURCES, attribute); } if (valueString != null) { int apiLevel = -1; try { apiLevel = Integer.valueOf(valueString); } catch (NumberFormatException e) { // Handle codename if (Sdk.getCurrent() != null) { IAndroidTarget target = Sdk.getCurrent().getTargetFromHashString("android-" + valueString); // $NON-NLS-1$ if (target != null) { // codename future API level is current api + 1 apiLevel = target.getVersion().getApiLevel() + 1; } } if (usesSdk.getTagName().equals(ATTRIBUTE_MIN_SDK_VERSION)) { mMinSdkName = valueString; } } return apiLevel; } return defaultApiLevel; }
// The default attributes must be determined dynamically since whether // we use match_parent or fill_parent depends on the API level of the // project @Override String getDefaultAttrs(IProject project, String root) { Sdk currentSdk = Sdk.getCurrent(); String fill = VALUE_FILL_PARENT; if (currentSdk != null) { IAndroidTarget target = currentSdk.getTarget(project); // fill_parent was renamed match_parent in API level 8 if (target != null && target.getVersion().getApiLevel() >= 8) { fill = VALUE_MATCH_PARENT; } } // Only set "vertical" orientation of LinearLayouts by default; // for GridLayouts for example we want to rely on the real default // of the layout String size = String.format( "android:layout_width=\"%1$s\"\n" //$NON-NLS-1$ + "android:layout_height=\"%2$s\"", //$NON-NLS-1$ fill, fill); if (LINEAR_LAYOUT.equals(root)) { return "android:orientation=\"vertical\"\n" + size; // $NON-NLS-1$ } else { return size; } }
private ResourceResolver getResourceResolver(Configuration configuration) { ResourceResolver resourceResolver = mResourceResolver.get(); if (resourceResolver != null) { return resourceResolver; } GraphicalEditorPart graphicalEditor = mCanvas.getEditorDelegate().getGraphicalEditor(); String theme = configuration.getTheme(); if (theme == null) { return null; } Map<ResourceType, Map<String, ResourceValue>> configuredFrameworkRes = null; Map<ResourceType, Map<String, ResourceValue>> configuredProjectRes = null; FolderConfiguration config = configuration.getFullConfig(); IAndroidTarget target = graphicalEditor.getRenderingTarget(); ResourceRepository frameworkRes = null; if (target != null) { Sdk sdk = Sdk.getCurrent(); if (sdk == null) { return null; } AndroidTargetData data = sdk.getTargetData(target); if (data != null) { // TODO: SHARE if possible frameworkRes = data.getFrameworkResources(); configuredFrameworkRes = frameworkRes.getConfiguredResources(config); } else { return null; } } else { return null; } assert configuredFrameworkRes != null; // get the resources of the file's project. ProjectResources projectRes = ResourceManager.getInstance().getProjectResources(graphicalEditor.getProject()); configuredProjectRes = projectRes.getConfiguredResources(config); if (!theme.startsWith(PREFIX_RESOURCE_REF)) { if (frameworkRes.hasResourceItem(ANDROID_STYLE_RESOURCE_PREFIX + theme)) { theme = ANDROID_STYLE_RESOURCE_PREFIX + theme; } else { theme = STYLE_RESOURCE_PREFIX + theme; } } resourceResolver = ResourceResolver.create( configuredProjectRes, configuredFrameworkRes, ResourceHelper.styleToTheme(theme), ResourceHelper.isProjectStyle(theme)); mResourceResolver = new SoftReference<ResourceResolver>(resourceResolver); return resourceResolver; }
private void setExistingProject(IProject project) { mValues.testedProject = project; // Try to update the application, package, sdk target and minSdkVersion accordingly if (project != null && (!mValues.applicationNameModifiedByUser || !mValues.packageNameModifiedByUser || !mValues.targetModifiedByUser || !mValues.minSdkModifiedByUser)) { ManifestData manifestData = AndroidManifestHelper.parseForData(project); if (manifestData != null) { String appName = String.format("%1$sTest", project.getName()); String packageName = manifestData.getPackage(); String minSdkVersion = manifestData.getMinSdkVersionString(); IAndroidTarget sdkTarget = null; if (Sdk.getCurrent() != null) { sdkTarget = Sdk.getCurrent().getTarget(project); } if (packageName == null) { packageName = ""; // $NON-NLS-1$ } mLastExistingPackageName = packageName; if (!mValues.projectNameModifiedByUser) { mValues.projectName = appName; } if (!mValues.applicationNameModifiedByUser) { mValues.applicationName = appName; } if (!mValues.packageNameModifiedByUser) { packageName += ".test"; // $NON-NLS-1$ mValues.packageName = packageName; } if (!mValues.targetModifiedByUser && sdkTarget != null) { mValues.target = sdkTarget; } if (!mValues.minSdkModifiedByUser) { if (minSdkVersion != null || sdkTarget != null) { mValues.minSdk = minSdkVersion; } if (sdkTarget == null) { mValues.updateSdkTargetToMatchMinSdkVersion(); } } } } updateTestTargetPackageField(mLastExistingPackageName); }
/** * Returns the Android SDK. * * @return the SDK instance or null */ public static final Sdk getAndroidSdk() { Sdk sdk; String s = AdtPlugin.getOsSdkFolder(); if (s.isEmpty()) { return null; } if (Sdk.getCurrent() == null) { sdk = Sdk.loadSdk(s); } else { sdk = Sdk.getCurrent(); } return sdk; }
/** * Validates the fields, displays errors and warnings. Enables the finish button if there are no * errors. */ private void validatePage() { String error = null; String warning = null; // -- validate type TypeInfo type = mValues.type; if (error == null) { if (type == null) { error = "One of the types must be selected (e.g. layout, values, etc.)"; } } // -- validate project if (mValues.project == null) { error = "Please select an Android project."; } // -- validate type API level if (error == null) { IAndroidTarget target = Sdk.getCurrent().getTarget(mValues.project); int currentApiLevel = 1; if (target != null) { currentApiLevel = target.getVersion().getApiLevel(); } assert type != null; if (type.getTargetApiLevel() > currentApiLevel) { error = "The API level of the selected type (e.g. AppWidget, etc.) is not " + "compatible with the API level of the project."; } } // -- validate filename if (error == null) { String fileName = mValues.getFileName(); assert type != null; ResourceFolderType folderType = type.getResFolderType(); error = ResourceNameValidator.create(true, folderType).isValid(fileName); } // -- validate destination file doesn't exist if (error == null) { IFile file = mValues.getDestinationFile(); if (file != null && file.exists()) { warning = "The destination file already exists"; } } // -- update UI & enable finish if there's no error setPageComplete(error == null); if (error != null) { setMessage(error, IMessageProvider.ERROR); } else if (warning != null) { setMessage(warning, IMessageProvider.WARNING); } else { setErrorMessage(null); setMessage(null); } }
/* (non-Javadoc) * @see org.eclipse.debug.ui.ILaunchShortcut#launch( * org.eclipse.jface.viewers.ISelection, java.lang.String) */ @Override public void launch(ISelection selection, String mode) { if (selection instanceof IStructuredSelection) { // get the object and the project from it IStructuredSelection structSelect = (IStructuredSelection) selection; Object o = structSelect.getFirstElement(); // get the first (and normally only) element if (o instanceof IAdaptable) { IResource r = (IResource) ((IAdaptable) o).getAdapter(IResource.class); // get the project from the resource if (r != null) { IProject project = r.getProject(); if (project != null) { ProjectState state = Sdk.getProjectState(project); if (state != null && state.isLibrary()) { MessageDialog.openError( PlatformUI.getWorkbench().getDisplay().getActiveShell(), "Android Launch", "Android library projects cannot be launched."); } else { // and launch launch(project, mode); } } } } } }
@Override public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException { if (pm.isCanceled()) { return null; } if (!getArguments().getUpdateReferences()) { return null; } CompositeChange result = new CompositeChange(getName()); result.markAsSynthetic(); addManifestFileChanges(result); // Update layout files; we don't just need to react to custom view // changes, we need to update fragment references and even tool:context activity // references addLayoutFileChanges(mProject, result); // Also update in dependent projects ProjectState projectState = Sdk.getProjectState(mProject); if (projectState != null) { Collection<ProjectState> parentProjects = projectState.getFullParentProjects(); for (ProjectState parentProject : parentProjects) { IProject project = parentProject.getProject(); addLayoutFileChanges(project, result); } } return (result.getChildren().length == 0) ? null : result; }
/** * Returns the target provided by the Google (Google Map implementation included). * * @param sdk * @return */ private static final IAndroidTarget getGoogleTarget(Sdk sdk, int targetNumber) { for (IAndroidTarget target : sdk.getTargets()) { if (checkTargetNumber(target, targetNumber) && checkGoogleVendor(target)) { return target; } } return null; }
@Override public void run(IAction action) { final Sdk sdk = Sdk.getCurrent(); if (sdk != null) { // Although orthogonal to the avd manager action, this is a good time // to check whether the SDK has changed on disk. AdtPlugin.getDefault().refreshSdk(); // Runs the updater window, directing all logs to the ADT console. AvdManagerWindow window = new AvdManagerWindow( AdtPlugin.getDisplay().getActiveShell(), new AdtConsoleSdkLog(), sdk.getSdkLocation(), AvdInvocationContext.IDE); window.open(); } else { AdtPlugin.displayError( "Android SDK", "Location of the Android SDK has not been setup in the preferences."); } }
/** * Computes the minimum SDK and target SDK versions for the project * * @param project the project to look up the versions for * @return a pair of (minimum SDK, target SDK) versions, never null */ @NonNull public static Pair<Integer, Integer> computeSdkVersions(IProject project) { int mMinSdkVersion = 1; int mTargetSdkVersion = 1; IAbstractFile manifestFile = AndroidManifest.getManifest(new IFolderWrapper(project)); if (manifestFile != null) { try { Object value = AndroidManifest.getMinSdkVersion(manifestFile); mMinSdkVersion = 1; // Default case if missing if (value instanceof Integer) { mMinSdkVersion = ((Integer) value).intValue(); } else if (value instanceof String) { // handle codename, only if we can resolve it. if (Sdk.getCurrent() != null) { IAndroidTarget target = Sdk.getCurrent().getTargetFromHashString("android-" + value); // $NON-NLS-1$ if (target != null) { // codename future API level is current api + 1 mMinSdkVersion = target.getVersion().getApiLevel() + 1; } } } Integer i = AndroidManifest.getTargetSdkVersion(manifestFile); if (i == null) { mTargetSdkVersion = mMinSdkVersion; } else { mTargetSdkVersion = i.intValue(); } } catch (XPathExpressionException e) { // do nothing we'll use 1 below. } catch (StreamException e) { // do nothing we'll use 1 below. } } return Pair.of(mMinSdkVersion, mTargetSdkVersion); }
/** * Add the available types in the type combobox, based on whether they are available for the * current SDK. * * <p>A type is available either if: - if mProject is null, API level 1 is considered valid - if * mProject is !null, the project->target->API must be >= to the type's API level. */ private void updateAvailableTypes() { IProject project = mValues.project; IAndroidTarget target = project != null ? Sdk.getCurrent().getTarget(project) : null; int currentApiLevel = 1; if (target != null) { currentApiLevel = target.getVersion().getApiLevel(); } List<String> items = new ArrayList<String>(sTypes.length); List<TypeInfo> types = new ArrayList<TypeInfo>(sTypes.length); for (int i = 0, n = sTypes.length; i < n; i++) { TypeInfo type = sTypes[i]; if (type.getTargetApiLevel() <= currentApiLevel) { items.add(type.getUiName()); types.add(type); } } mTypeCombo.setItems(items.toArray(new String[items.size()])); mTypeCombo.setData(types.toArray(new TypeInfo[types.size()])); }
/** Render immediately */ private void renderSync() { GraphicalEditorPart editor = mCanvas.getEditorDelegate().getGraphicalEditor(); if (editor.getReadyLayoutLib(false /*displayError*/) == null) { // Don't attempt to render when there is no ready layout library: most likely // the targets are loading/reloading. return; } disposeThumbnail(); Configuration configuration = mAlternateInput != null && mAlternateConfiguration != null ? mAlternateConfiguration : mConfiguration; ResourceResolver resolver = getResourceResolver(configuration); RenderService renderService = RenderService.create(editor, configuration, resolver); if (mIncludedWithin != null) { renderService.setIncludedWithin(mIncludedWithin); } if (mAlternateInput != null) { IAndroidTarget target = editor.getRenderingTarget(); AndroidTargetData data = null; if (target != null) { Sdk sdk = Sdk.getCurrent(); if (sdk != null) { data = sdk.getTargetData(target); } } // Construct UI model from XML DocumentDescriptor documentDescriptor; if (data == null) { documentDescriptor = new DocumentDescriptor("temp", null); // $NON-NLS-1$ } else { documentDescriptor = data.getLayoutDescriptors().getDescriptor(); } UiDocumentNode model = (UiDocumentNode) documentDescriptor.createUiNode(); model.setEditor(mCanvas.getEditorDelegate().getEditor()); model.setUnknownDescriptorProvider(editor.getModel().getUnknownDescriptorProvider()); Document document = DomUtilities.getDocument(mAlternateInput); if (document == null) { mError = "No document"; createErrorThumbnail(); return; } model.loadFromXmlNode(document); renderService.setModel(model); } else { renderService.setModel(editor.getModel()); } RenderLogger log = new RenderLogger(getDisplayName()); renderService.setLog(log); RenderSession session = renderService.createRenderSession(); Result render = session.render(1000); if (DUMP_RENDER_DIAGNOSTICS) { if (log.hasProblems() || !render.isSuccess()) { AdtPlugin.log( IStatus.ERROR, "Found problems rendering preview " + getDisplayName() + ": " + render.getErrorMessage() + " : " + log.getProblems(false)); Throwable exception = render.getException(); if (exception != null) { AdtPlugin.log(exception, "Failure rendering preview " + getDisplayName()); } } } if (render.isSuccess()) { mError = null; } else { mError = render.getErrorMessage(); if (mError == null) { mError = ""; } } if (render.getStatus() == Status.ERROR_TIMEOUT) { // TODO: Special handling? schedule update again later return; } if (render.isSuccess()) { BufferedImage image = session.getImage(); if (image != null) { createThumbnail(image); } } if (mError != null) { createErrorThumbnail(); } }
public void run(IAction action) { final Sdk sdk = Sdk.getCurrent(); if (sdk != null) { // Runs the updater window, directing all logs to the ADT console. SdkUpdaterWindow window = new SdkUpdaterWindow( AdtPlugin.getDisplay().getActiveShell(), new AdtConsoleSdkLog(), sdk.getSdkLocation(), SdkInvocationContext.IDE); ISdkChangeListener listener = new ISdkChangeListener() { public void onSdkLoaded() { // Ignore initial load of the SDK. } /** * Unload all we can from the SDK before new packages are installed. Typically we need * to get rid of references to dx from platform-tools and to any platform resource data. * * <p>{@inheritDoc} */ public void preInstallHook() { // TODO we need to unload as much of as SDK as possible. Otherwise // on Windows we end up with Eclipse locking some files and we can't // replace them. // // At this point, we know what the user wants to install so it would be // possible to pass in flags to know what needs to be unloaded. Typically // we need to: // - unload dex if platform-tools is going to be updated. There's a vague // attempt below at removing any references to dex and GCing. Seems // to do the trick. // - unload any target that is going to be updated since it may have // resource data used by a current layout editor (e.g. data/*.ttf // and various data/res/*.xml). // // Most important we need to make sure there isn't a build going on // and if there is one, either abort it or wait for it to complete and // then we want to make sure we don't get any attempt to use the SDK // before the postInstallHook is called. if (sdk != null) { sdk.unloadTargetData(true /*preventReload*/); DexWrapper dx = sdk.getDexWrapper(); dx.unload(); } } /** * Nothing to do. We'll reparse the SDK later in onSdkReload. * * <p>{@inheritDoc} */ public void postInstallHook() {} /** * Reparse the SDK in case anything was add/removed. * * <p>{@inheritDoc} */ public void onSdkReload() { AdtPlugin.getDefault().reparseSdk(); } }; window.addListener(listener); window.open(); } else { AdtPlugin.displayError( "Android SDK", "Location of the Android SDK has not been setup in the preferences."); } }
private Pair<List<String>, List<String>> findViews(final boolean layoutsOnly) { final Set<String> customViews = new HashSet<String>(); final Set<String> thirdPartyViews = new HashSet<String>(); ProjectState state = Sdk.getProjectState(mProject); final List<IProject> libraries = state != null ? state.getFullLibraryProjects() : Collections.<IProject>emptyList(); SearchRequestor requestor = new SearchRequestor() { @Override public void acceptSearchMatch(SearchMatch match) throws CoreException { // Ignore matches in comments if (match.isInsideDocComment()) { return; } Object element = match.getElement(); if (element instanceof ResolvedBinaryType) { // Third party view ResolvedBinaryType type = (ResolvedBinaryType) element; IPackageFragment fragment = type.getPackageFragment(); IPath path = fragment.getPath(); String last = path.lastSegment(); // Filter out android.jar stuff if (last.equals(FN_FRAMEWORK_LIBRARY)) { return; } if (!isValidView(type, layoutsOnly)) { return; } IProject matchProject = match.getResource().getProject(); if (mProject == matchProject || libraries.contains(matchProject)) { String fqn = type.getFullyQualifiedName(); thirdPartyViews.add(fqn); } } else if (element instanceof ResolvedSourceType) { // User custom view IProject matchProject = match.getResource().getProject(); if (mProject == matchProject || libraries.contains(matchProject)) { ResolvedSourceType type = (ResolvedSourceType) element; if (!isValidView(type, layoutsOnly)) { return; } String fqn = type.getFullyQualifiedName(); fqn = fqn.replace('$', '.'); customViews.add(fqn); } } } }; try { IJavaProject javaProject = BaseProjectHelper.getJavaProject(mProject); if (javaProject != null) { String className = layoutsOnly ? CLASS_VIEWGROUP : CLASS_VIEW; IType viewType = javaProject.findType(className); if (viewType != null) { IJavaSearchScope scope = SearchEngine.createHierarchyScope(viewType); SearchParticipant[] participants = new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()}; int matchRule = SearchPattern.R_PATTERN_MATCH | SearchPattern.R_CASE_SENSITIVE; SearchPattern pattern = SearchPattern.createPattern( "*", IJavaSearchConstants.CLASS, IJavaSearchConstants.IMPLEMENTORS, matchRule); SearchEngine engine = new SearchEngine(); engine.search(pattern, participants, scope, requestor, new NullProgressMonitor()); } } } catch (CoreException e) { AdtPlugin.log(e, null); } List<String> custom = new ArrayList<String>(customViews); List<String> thirdParty = new ArrayList<String>(thirdPartyViews); if (!layoutsOnly) { // Update our cached answers (unless we were filtered on only layouts) mCustomViews = custom; mThirdPartyViews = thirdParty; } return Pair.of(custom, thirdParty); }
static void show(final ConfigurationChooser chooser, ToolItem combo) { Configuration configuration = chooser.getConfiguration(); Device current = configuration.getDevice(); Menu menu = new Menu(chooser.getShell(), SWT.POP_UP); List<Device> deviceList = chooser.getDeviceList(); Sdk sdk = Sdk.getCurrent(); if (sdk != null) { AvdManager avdManager = sdk.getAvdManager(); if (avdManager != null) { boolean separatorNeeded = false; AvdInfo[] avds = avdManager.getValidAvds(); for (AvdInfo avd : avds) { for (Device device : deviceList) { if (device.getManufacturer().equals(avd.getDeviceManufacturer()) && device.getName().equals(avd.getDeviceName())) { separatorNeeded = true; MenuItem item = new MenuItem(menu, SWT.CHECK); item.setText(avd.getName()); item.setSelection(current == device); item.addSelectionListener(new DeviceMenuListener(chooser, device)); } } } if (separatorNeeded) { @SuppressWarnings("unused") MenuItem separator = new MenuItem(menu, SWT.SEPARATOR); } } } // Group the devices by manufacturer, then put them in the menu. // If we don't have anything but Nexus devices, group them together rather than // make many manufacturer submenus. boolean haveNexus = false; boolean haveNonNexus = false; if (!deviceList.isEmpty()) { Map<String, List<Device>> manufacturers = new TreeMap<String, List<Device>>(); for (Device device : deviceList) { List<Device> devices; if (isNexus(device)) { haveNexus = true; } else if (!isGeneric(device)) { haveNonNexus = true; } if (manufacturers.containsKey(device.getManufacturer())) { devices = manufacturers.get(device.getManufacturer()); } else { devices = new ArrayList<Device>(); manufacturers.put(device.getManufacturer(), devices); } devices.add(device); } if (haveNonNexus) { for (List<Device> devices : manufacturers.values()) { Menu manufacturerMenu = menu; if (manufacturers.size() > 1) { MenuItem item = new MenuItem(menu, SWT.CASCADE); item.setText(devices.get(0).getManufacturer()); manufacturerMenu = new Menu(menu); item.setMenu(manufacturerMenu); } for (final Device device : devices) { MenuItem deviceItem = new MenuItem(manufacturerMenu, SWT.CHECK); deviceItem.setText(getGenericLabel(device)); deviceItem.setSelection(current == device); deviceItem.addSelectionListener(new DeviceMenuListener(chooser, device)); } } } else { List<Device> nexus = new ArrayList<Device>(); List<Device> generic = new ArrayList<Device>(); if (haveNexus) { // Nexus for (List<Device> devices : manufacturers.values()) { for (Device device : devices) { if (isNexus(device)) { if (device.getManufacturer().equals(GENERIC)) { generic.add(device); } else { nexus.add(device); } } else { generic.add(device); } } } } if (!nexus.isEmpty()) { sortNexusList(nexus); for (final Device device : nexus) { MenuItem item = new MenuItem(menu, SWT.CHECK); item.setText(getNexusLabel(device)); item.setSelection(current == device); item.addSelectionListener(new DeviceMenuListener(chooser, device)); } @SuppressWarnings("unused") MenuItem separator = new MenuItem(menu, SWT.SEPARATOR); } // Generate the generic menu. Collections.reverse(generic); for (final Device device : generic) { MenuItem item = new MenuItem(menu, SWT.CHECK); item.setText(getGenericLabel(device)); item.setSelection(current == device); item.addSelectionListener(new DeviceMenuListener(chooser, device)); } } } @SuppressWarnings("unused") MenuItem separator = new MenuItem(menu, SWT.SEPARATOR); ConfigurationMenuListener.addTogglePreviewModeAction( menu, "Preview All Screens", chooser, RenderPreviewMode.SCREENS); Rectangle bounds = combo.getBounds(); Point location = new Point(bounds.x, bounds.y + bounds.height); location = combo.getParent().toDisplay(location); menu.setLocation(location.x, location.y); menu.setVisible(true); }
/** Initialize the root values of the type infos based on the current framework values. */ private void initializeRootValues() { IProject project = mValues.project; for (TypeInfo type : sTypes) { // Clear all the roots for this type ArrayList<String> roots = type.getRoots(); if (roots.size() > 0) { roots.clear(); } // depending of the type of the seed, initialize the root in different ways Object rootSeed = type.getRootSeed(); if (rootSeed instanceof String) { // The seed is a single string, Add it as-is. roots.add((String) rootSeed); } else if (rootSeed instanceof String[]) { // The seed is an array of strings. Add them as-is. for (String value : (String[]) rootSeed) { roots.add(value); } } else if (rootSeed instanceof Integer && project != null) { // The seed is a descriptor reference defined in AndroidTargetData.DESCRIPTOR_* // In this case add all the children element descriptors defined, recursively, // and avoid infinite recursion by keeping track of what has already been added. // Note: if project is null, the root list will be empty since it has been // cleared above. // get the AndroidTargetData from the project IAndroidTarget target = null; AndroidTargetData data = null; target = Sdk.getCurrent().getTarget(project); if (target == null) { // A project should have a target. The target can be missing if the project // is an old project for which a target hasn't been affected or if the // target no longer exists in this SDK. Simply log the error and dismiss. AdtPlugin.log( IStatus.INFO, "NewXmlFile wizard: no platform target for project %s", //$NON-NLS-1$ project.getName()); continue; } else { data = Sdk.getCurrent().getTargetData(target); if (data == null) { // We should have both a target and its data. // However if the wizard is invoked whilst the platform is still being // loaded we can end up in a weird case where we have a target but it // doesn't have any data yet. // Lets log a warning and silently ignore this root. AdtPlugin.log( IStatus.INFO, "NewXmlFile wizard: no data for target %s, project %s", //$NON-NLS-1$ target.getName(), project.getName()); continue; } } IDescriptorProvider provider = data.getDescriptorProvider((Integer) rootSeed); ElementDescriptor descriptor = provider.getDescriptor(); if (descriptor != null) { HashSet<ElementDescriptor> visited = new HashSet<ElementDescriptor>(); initRootElementDescriptor(roots, descriptor, visited); } // Sort alphabetically. Collections.sort(roots); } } }