@Before public void setUp() throws Exception { startMonitoringJob(); System.out.println("AdtProject: setup"); System.out.println("Starting Test: " + testName.getMethodName()); // Prevent preview icon computation during plugin test to make test // faster if (AndmoreAndroidPlugin.getDefault() == null) { fail("This test must be run as an Eclipse plugin test, not a plain JUnit test!"); } AdtPrefs.getPrefs().setPaletteModes("ICON_TEXT"); // $NON-NLS-1$ getProject(); Sdk current = Sdk.getCurrent(); assertNotNull(current); LoadStatus sdkStatus = AndmoreAndroidPlugin.getDefault().getSdkLoadStatus(); assertSame(LoadStatus.LOADED, sdkStatus); IAndroidTarget target = current.getTarget(getProject()); IJavaProject javaProject = BaseProjectHelper.getJavaProject(getProject()); assertNotNull(javaProject); int iterations = 0; while (true) { if (iterations == 100) { fail("Couldn't load target; ran out of time"); } LoadStatus status = current.checkAndLoadTargetData(target, javaProject); if (status == LoadStatus.FAILED) { fail("Couldn't load target " + target); } if (status != LoadStatus.LOADING) { break; } Thread.sleep(250); iterations++; } // AndroidTargetData targetData = current.getTargetData(target); // assertNotNull(targetData); // LayoutDescriptors layoutDescriptors = targetData.getLayoutDescriptors(); // assertNotNull(layoutDescriptors); // List<ViewElementDescriptor> viewDescriptors = layoutDescriptors.getViewDescriptors(); // assertNotNull(viewDescriptors); // assertTrue(viewDescriptors.size() > 0); // List<ViewElementDescriptor> layoutParamDescriptors = // layoutDescriptors.getLayoutDescriptors(); // assertNotNull(layoutParamDescriptors); // assertTrue(layoutParamDescriptors.size() > 0); }
/** * Returns an optional ImageDescriptor for the element. * * <p>By default this tries to return an image based on the XML name of the element. If this * fails, it tries to return the default Android logo as defined in the plugin. If all fails, it * returns null. * * @return An ImageDescriptor for this element or null. */ public ImageDescriptor getImageDescriptor() { IconFactory factory = IconFactory.getInstance(); int color = hasChildren() ? IconFactory.COLOR_BLUE : IconFactory.COLOR_GREEN; int shape = hasChildren() ? IconFactory.SHAPE_RECT : IconFactory.SHAPE_CIRCLE; ImageDescriptor id = factory.getImageDescriptor(mXmlName, color, shape); return id != null ? id : AndmoreAndroidPlugin.getAndroidLogoDesc(); }
private static boolean showConvertMessageBox(String fileName) { return MessageDialog.openQuestion( AndmoreAndroidPlugin.getDisplay().getActiveShell(), "Warning", String.format( "The file \"%s\" doesn't seem to be a 9-patch file. \n" + "Do you want to convert?", fileName)); }
private static IClasspathContainer allocateContainer( IJavaProject javaProject, List<IClasspathEntry> entries, IPath id, String description) { if (AndmoreAndroidPlugin.getDefault() == null) { // This is totally weird, but I've seen it happen! return null; } // First check that the project has a library-type container. try { IClasspathEntry[] rawClasspath = javaProject.getRawClasspath(); final IClasspathEntry[] oldRawClasspath = rawClasspath; boolean foundContainer = false; for (IClasspathEntry entry : rawClasspath) { // get the entry and kind final int kind = entry.getEntryKind(); if (kind == IClasspathEntry.CPE_CONTAINER) { String path = entry.getPath().toString(); String idString = id.toString(); if (idString.equals(path)) { foundContainer = true; break; } } } // if there isn't any, add it. if (foundContainer == false) { // add the android container to the array rawClasspath = ProjectHelper.addEntryToClasspath( rawClasspath, JavaCore.newContainerEntry(id, true /*isExported*/)); } // set the new list of entries to the project if (rawClasspath != oldRawClasspath) { javaProject.setRawClasspath(rawClasspath, new NullProgressMonitor()); } } catch (JavaModelException e) { // This really shouldn't happen, but if it does, simply return null (the calling // method will fails as well) return null; } return new AndroidClasspathContainer( entries.toArray(new IClasspathEntry[entries.size()]), id, description, IClasspathContainer.K_APPLICATION); }
/** * Processes a {@link IClasspathEntry} and add it to one of the list if applicable. * * @param entry the entry to process * @param javaProject the {@link IJavaProject} from which this entry came. * @param wsRoot the {@link IWorkspaceRoot} * @param projects the project list to add to * @param jarFiles the jar list to add to * @param includeJarFiles whether to include jar files or just projects. This is useful when * calling on an Android project (value should be <code>false</code>) */ private static void processCPE( IClasspathEntry entry, IJavaProject javaProject, IWorkspaceRoot wsRoot, Set<IProject> projects, Set<File> jarFiles, boolean includeJarFiles) { // if this is a classpath variable reference, we resolve it. if (entry.getEntryKind() == IClasspathEntry.CPE_VARIABLE) { entry = JavaCore.getResolvedClasspathEntry(entry); } if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) { IProject refProject = wsRoot.getProject(entry.getPath().lastSegment()); try { // ignore if it's an Android project, or if it's not a Java Project if (refProject.hasNature(JavaCore.NATURE_ID) && refProject.hasNature(AndmoreAndroidConstants.NATURE_DEFAULT) == false) { // add this project to the list projects.add(refProject); // also get the dependency from this project. getDependencyListFromClasspath(refProject, projects, jarFiles, true /*includeJarFiles*/); } } catch (CoreException exception) { // can't query the project nature? ignore } } else if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) { if (includeJarFiles) { handleClasspathLibrary(entry, wsRoot, jarFiles); } } else if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) { // get the container and its content try { IClasspathContainer container = JavaCore.getClasspathContainer(entry.getPath(), javaProject); // ignore the system and default_system types as they represent // libraries that are part of the runtime. if (container != null && container.getKind() == IClasspathContainer.K_APPLICATION) { IClasspathEntry[] entries = container.getClasspathEntries(); for (IClasspathEntry cpe : entries) { processCPE(cpe, javaProject, wsRoot, projects, jarFiles, includeJarFiles); } } } catch (JavaModelException jme) { // can't resolve the container? ignore it. AndmoreAndroidPlugin.log(jme, "Failed to resolve ClasspathContainer: %s", entry.getPath()); } } }
private IPath showSaveAsDialog() { SaveAsDialog dialog = new SaveAsDialog(AndmoreAndroidPlugin.getDisplay().getActiveShell()); IFile dest = mProject.getFile( NinePatchedImage.getNinePatchedFileName( mFileEditorInput.getFile().getProjectRelativePath().toOSString())); dialog.setOriginalFile(dest); dialog.create(); if (dialog.open() == Window.CANCEL) { return null; } return dialog.getResult(); }
protected IFile getTestDataFile( IProject project, String sourceName, String destPath, boolean overwrite) throws Exception { String[] split = destPath.split("/"); // $NON-NLS-1$ IContainer parent; String name; if (split.length == 1) { parent = project; name = destPath; } else { IFolder folder = project.getFolder(split[0]); NullProgressMonitor monitor = new NullProgressMonitor(); if (!folder.exists()) { folder.create(true /* force */, true /* local */, monitor); } for (int i = 1, n = split.length; i < n - 1; i++) { IFolder subFolder = folder.getFolder(split[i]); if (!subFolder.exists()) { subFolder.create(true /* force */, true /* local */, monitor); } folder = subFolder; } name = split[split.length - 1]; parent = folder; } IFile file = parent.getFile(new Path(name)); if (overwrite && file.exists()) { String currentContents = AndmoreAndroidPlugin.readFile(file); String newContents = readTestFile(sourceName, true); if (currentContents == null || !currentContents.equals(newContents)) { file.delete(true, new NullProgressMonitor()); } else { return file; } } if (!file.exists()) { String xml = readTestFile(sourceName, true); InputStream bstream = new ByteArrayInputStream(xml.getBytes("UTF-8")); // $NON-NLS-1$ NullProgressMonitor monitor = new NullProgressMonitor(); file.create(bstream, false /* force */, monitor); } return file; }
/** * Returns the {@link RenderPreviewList} for the given project * * @param project the project the list is associated with * @return a {@link RenderPreviewList} for the given project, never null */ @NonNull public static RenderPreviewList get(@NonNull IProject project) { RenderPreviewList list = null; try { list = (RenderPreviewList) project.getSessionProperty(PREVIEW_LIST); } catch (CoreException e) { // Not a problem; we will just create a new one } if (list == null) { list = new RenderPreviewList(project); try { project.setSessionProperty(PREVIEW_LIST, list); } catch (CoreException e) { AndmoreAndroidPlugin.log(e, null); } } return list; }
@Override public void launch(ISelection selection, String mode) { if (!(selection instanceof IStructuredSelection)) { return; } Object s = ((IStructuredSelection) selection).getFirstElement(); if (!(s instanceof IAdaptable)) { return; } IResource r = (IResource) ((IAdaptable) s).getAdapter(IResource.class); if (r == null) { return; } IProject project = r.getProject(); if (project == null) { return; } // verify that this is a non library Android project ProjectState state = Sdk.getProjectState(project); if (state == null || state.isLibrary()) { return; } // verify that this project has C/C++ nature if (!CoreModel.hasCCNature(project) && !CoreModel.hasCNature(project)) { AndmoreAndroidPlugin.printErrorToConsole( project, String.format( "Selected project (%s) does not have C/C++ nature. " + "To add native support, right click on the project, " + "Android Tools -> Add Native Support", project.getName())); return; } debugProject(project, mode); }
/** * Returns an optional icon for the element, typically to be used in XML form trees. * * <p>This icon is customized to the given descriptor, that is different elements will have * different icons. * * <p>By default this tries to return an icon based on the XML name of the element. If this fails, * it tries to return the default Android logo as defined in the plugin. If all fails, it returns * null. * * @return An icon for this element. This is never null. */ public Image getCustomizedIcon() { IconFactory factory = IconFactory.getInstance(); int color = hasChildren() ? IconFactory.COLOR_BLUE : IconFactory.COLOR_GREEN; int shape = hasChildren() ? IconFactory.SHAPE_RECT : IconFactory.SHAPE_CIRCLE; String name = mXmlName; int pos = name.lastIndexOf('.'); if (pos != -1) { // If the user uses a fully qualified name, such as // "android.gesture.GestureOverlayView" in their XML, we need to // look up only by basename name = name.substring(pos + 1); } Image icon = factory.getIcon(name, color, shape); if (icon == null) { icon = getGenericIcon(); } if (icon == null) { icon = AndmoreAndroidPlugin.getAndroidLogo(); } return icon; }
private void debugProject(IProject project, String mode) { // obtain existing native debug config for project ILaunchConfiguration config = AndroidLaunchController.getLaunchConfig(project, NdkGdbLaunchDelegate.LAUNCH_TYPE_ID); if (config == null) { return; } // Set the ndk gdb specific launch attributes in the config (if // necessary) if (!hasNdkAttributes(config)) { try { config = setNdkDefaults(config, project); } catch (CoreException e) { AndmoreAndroidPlugin.printErrorToConsole( project, "Unable to create launch configuration for project."); return; } } // launch DebugUITools.launch(config, mode); }
protected int getCaretOffset(IFile file, String caretLocation) { assertTrue(caretLocation, caretLocation.contains("^")); String fileContent = AndmoreAndroidPlugin.readFile(file); return getCaretOffset(fileContent, caretLocation); }
private void checkResourceFix(String name, String caretLocation, String expectedNewPath) throws Exception { IProject project = getProject(); IFile file = getTestDataFile(project, name, FD_RES + "/" + FD_RES_LAYOUT + "/" + name); // Determine the offset final int offset = getCaretOffset(file, caretLocation); String osRoot = project.getLocation().toOSString(); List<String> errors = new ArrayList<String>(); String fileRelativePath = file.getProjectRelativePath().toPortableString(); String filePath = osRoot + File.separator + fileRelativePath; // Run AaptParser such that markers are added... // When debugging these tests, the project gets a chance to build itself // so // the real aapt errors are there. But when the test is run directly, // aapt has // not yet run. I tried waiting for the build (using the code in // SampleProjectTest) // but this had various adverse effects (exception popups from the // Eclipse debugger // etc) so instead this test just hardcodes the aapt errors that should // be // observed on quickfix1.xml. assertEquals("Unit test is hardcoded to errors for quickfix1.xml", "quickfix1.xml", name); errors.add( filePath + ":7: error: Error: No resource found that matches the given name" + " (at 'text' with value '@string/firststring')."); errors.add( filePath + ":7: error: Error: No resource found that matches the given name" + " (at 'layout_width' with value '@dimen/testdimen')."); errors.add( filePath + ":13: error: Error: No resource found that matches the given name" + " (at 'layout' with value '@layout/testlayout')."); AaptParser.parseOutput(errors, project); AaptQuickFix aaptQuickFix = new AaptQuickFix(); // Open file IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); assertNotNull(page); IEditorPart editor = IDE.openEditor(page, file); assertTrue(editor instanceof AndroidXmlEditor); AndroidXmlEditor layoutEditor = (AndroidXmlEditor) editor; final ISourceViewer viewer = layoutEditor.getStructuredSourceViewer(); // Test marker resolution. IMarker[] markers = file.findMarkers(AndmoreAndroidConstants.MARKER_AAPT_COMPILE, true, IResource.DEPTH_ZERO); for (IMarker marker : markers) { int start = marker.getAttribute(IMarker.CHAR_START, 0); int end = marker.getAttribute(IMarker.CHAR_END, 0); if (offset >= start && offset <= end) { // Found the target marker. Now check the marker resolution of // it. assertTrue(aaptQuickFix.hasResolutions(marker)); IMarkerResolution[] resolutions = aaptQuickFix.getResolutions(marker); assertNotNull(resolutions); assertEquals(1, resolutions.length); IMarkerResolution resolution = resolutions[0]; assertNotNull(resolution); assertTrue(resolution.getLabel().contains("Create resource")); // Not running marker yet -- if we create the files here they // already // exist when the quick assist code runs. (The quick fix and the // quick assist // mostly share code for the implementation anyway.) // resolution.run(marker); break; } } // Next test quick assist. IQuickAssistInvocationContext invocationContext = new IQuickAssistInvocationContext() { @Override public int getLength() { return 0; } @Override public int getOffset() { return offset; } @Override public ISourceViewer getSourceViewer() { return viewer; } }; ICompletionProposal[] proposals = aaptQuickFix.computeQuickAssistProposals(invocationContext); assertNotNull(proposals); assertTrue(proposals.length == 1); ICompletionProposal proposal = proposals[0]; assertNotNull(proposal.getAdditionalProposalInfo()); assertNotNull(proposal.getImage()); assertTrue(proposal.getDisplayString().contains("Create resource")); IDocument document = new Document(); String fileContent = AndmoreAndroidPlugin.readFile(file); document.set(fileContent); // Apply quick fix proposal.apply(document); IPath path = new Path(expectedNewPath); IFile newFile = project.getFile(path); assertNotNull(path.toPortableString(), newFile); // Ensure that the newly created file was opened IEditorPart currentFile = AdtUtils.getActiveEditor(); assertEquals( newFile.getProjectRelativePath(), ((FileEditorInput) currentFile.getEditorInput()).getFile().getProjectRelativePath()); // Look up caret offset assertTrue( currentFile != null ? currentFile.getClass().getName() : "null", currentFile instanceof AndroidXmlEditor); AndroidXmlEditor newEditor = (AndroidXmlEditor) currentFile; ISourceViewer newViewer = newEditor.getStructuredSourceViewer(); Point selectedRange = newViewer.getSelectedRange(); String newFileContents = AndmoreAndroidPlugin.readFile(newFile); // Insert selection markers -- [ ] for the selection range, ^ for the // caret String newFileWithCaret = addSelection(newFileContents, selectedRange); newFileWithCaret = removeSessionData(newFileWithCaret); assertEqualsGolden(name, newFileWithCaret); }
private void checkNamespaceFix(String name, String caretLocation) throws Exception { IProject project = getProject(); IFile file = getTestDataFile(project, name, FD_RES + "/" + FD_RES_COLOR + "/" + name); // Determine the offset final int offset = getCaretOffset(file, caretLocation); String osRoot = project.getLocation().toOSString(); List<String> errors = new ArrayList<String>(); String fileRelativePath = file.getProjectRelativePath().toPortableString(); String filePath = osRoot + File.separator + fileRelativePath; assertEquals("Unit test is hardcoded to errors for quickfix2.xml", "quickfix2.xml", name); errors.add(filePath + ":5: error: Error parsing XML: unbound prefix"); AaptParser.parseOutput(errors, project); AaptQuickFix aaptQuickFix = new AaptQuickFix(); // Open file IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); assertNotNull(page); IEditorPart editor = IDE.openEditor(page, file); assertTrue(editor instanceof AndroidXmlEditor); AndroidXmlEditor layoutEditor = (AndroidXmlEditor) editor; final ISourceViewer viewer = layoutEditor.getStructuredSourceViewer(); // Test marker resolution. IMarker[] markers = file.findMarkers(AndmoreAndroidConstants.MARKER_AAPT_COMPILE, true, IResource.DEPTH_ZERO); assertEquals(1, markers.length); IMarker marker = markers[0]; // Found the target marker. Now check the marker resolution of it. assertTrue(aaptQuickFix.hasResolutions(marker)); IMarkerResolution[] resolutions = aaptQuickFix.getResolutions(marker); assertNotNull(resolutions); assertEquals(1, resolutions.length); IMarkerResolution resolution = resolutions[0]; assertNotNull(resolution); assertTrue(resolution.getLabel().contains("Insert namespace")); // Next test quick assist. IQuickAssistInvocationContext invocationContext = new IQuickAssistInvocationContext() { @Override public int getLength() { return 0; } @Override public int getOffset() { return offset; } @Override public ISourceViewer getSourceViewer() { return viewer; } }; ICompletionProposal[] proposals = aaptQuickFix.computeQuickAssistProposals(invocationContext); assertNotNull(proposals); assertTrue(proposals.length == 1); ICompletionProposal proposal = proposals[0]; assertNotNull(proposal.getAdditionalProposalInfo()); assertNotNull(proposal.getImage()); assertTrue(proposal.getDisplayString().contains("Insert namespace")); // Open the file to ensure we can get an XML model with // getExistingModelForEdit: AndmoreAndroidPlugin.openFile(file, null); IEditorPart newEditor = AdtUtils.getActiveEditor(); assertTrue(newEditor instanceof AndroidXmlEditor); AndroidXmlEditor xmlEditor = (AndroidXmlEditor) newEditor; IDocument document = xmlEditor.getStructuredSourceViewer().getDocument(); // Apply quick fix String before = document.get(); proposal.apply(document); String after = document.get(); String diff = getDiff(before, after); assertEqualsGolden(name, diff); }
@Override public void doSave(final IProgressMonitor monitor) { boolean hasNinePatchExtension = mFileName.endsWith(DOT_9PNG); boolean doConvert = false; if (!hasNinePatchExtension) { String patchedName = NinePatchedImage.getNinePatchedFileName(mFileName); doConvert = MessageDialog.openQuestion( AndmoreAndroidPlugin.getDisplay().getActiveShell(), "Warning", String.format( "The file \"%s\" doesn't seem to be a 9-patch file. \n" + "Do you want to convert and save as \"%s\" ?", mFileName, patchedName)); if (doConvert) { IFile destFile = mProject.getFile( NinePatchedImage.getNinePatchedFileName( mFileEditorInput.getFile().getProjectRelativePath().toOSString())); if (!destFile.exists()) { mFileEditorInput = new FileEditorInput(destFile); mFileName = mFileEditorInput.getName(); } else { IPath relativePath = null; if ((relativePath = showSaveAsDialog()) != null) { mFileEditorInput = new FileEditorInput(ResourcesPlugin.getWorkspace().getRoot().getFile(relativePath)); mFileName = mFileEditorInput.getName(); } else { doConvert = false; } } } } if (hasNinePatchExtension || doConvert) { ImageLoader loader = new ImageLoader(); loader.data = new ImageData[] {mNinePatchedImage.getRawImageData()}; IFile file = mFileEditorInput.getFile(); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); loader.save(outputStream, SWT.IMAGE_PNG); byte[] byteArray = outputStream.toByteArray(); try { if (file.exists()) { file.setContents(new ByteArrayInputStream(byteArray), true, false, monitor); } else { file.create(new ByteArrayInputStream(byteArray), true, monitor); } mNinePatchedImage.clearDirtyFlag(); AndmoreAndroidPlugin.getDisplay() .asyncExec( new Runnable() { @Override public void run() { setPartName(mFileName); firePropertyChange(PROP_DIRTY); } }); } catch (CoreException e) { AndmoreAndroidPlugin.log(e, null); } } }
private static IClasspathContainer allocateDependencyContainer(IJavaProject javaProject) { final IProject iProject = javaProject.getProject(); final List<IClasspathEntry> entries = new ArrayList<IClasspathEntry>(); final Set<File> jarFiles = new HashSet<File>(); final IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); AndmoreAndroidPlugin plugin = AndmoreAndroidPlugin.getDefault(); if (plugin == null) { // This is totally weird, but I've seen it happen! return null; } synchronized (Sdk.getLock()) { boolean sdkIsLoaded = plugin.getSdkLoadStatus() == LoadStatus.LOADED; // check if the project has a valid target. final ProjectState state = Sdk.getProjectState(iProject); if (state == null) { // getProjectState should already have logged an error. Just bail out. return null; } // annotations support for older version of android if (state.getTarget() != null && state.getTarget().getVersion().getApiLevel() <= 15) { File annotationsJar = new File( Sdk.getCurrent().getSdkOsLocation(), SdkConstants.FD_TOOLS + File.separator + SdkConstants.FD_SUPPORT + File.separator + SdkConstants.FN_ANNOTATIONS_JAR); jarFiles.add(annotationsJar); } if (state.getRenderScriptSupportMode()) { if (!sdkIsLoaded) { return null; } BuildToolInfo buildToolInfo = state.getBuildToolInfo(); if (buildToolInfo == null) { buildToolInfo = Sdk.getCurrent().getLatestBuildTool(); if (buildToolInfo == null) { return null; } } File renderScriptSupportJar = RenderScriptProcessor.getSupportJar(buildToolInfo.getLocation().getAbsolutePath()); jarFiles.add(renderScriptSupportJar); } // process all the libraries List<IProject> libProjects = state.getFullLibraryProjects(); for (IProject libProject : libProjects) { // get the project output IFolder outputFolder = BaseProjectHelper.getAndroidOutputFolder(libProject); if (outputFolder != null) { // can happen when closing/deleting a library) IFile jarIFile = outputFolder.getFile(libProject.getName().toLowerCase() + SdkConstants.DOT_JAR); // get the source folder for the library project List<IPath> srcs = BaseProjectHelper.getSourceClasspaths(libProject); // find the first non-derived source folder. IPath sourceFolder = null; for (IPath src : srcs) { IFolder srcFolder = workspaceRoot.getFolder(src); if (srcFolder.isDerived() == false) { sourceFolder = src; break; } } // we can directly add a CPE for this jar as there's no risk of a duplicate. IClasspathEntry entry = JavaCore.newLibraryEntry( jarIFile.getLocation(), sourceFolder, // source attachment path null, // default source attachment root path. true /*isExported*/); entries.add(entry); } } entries.addAll(convertJarsToClasspathEntries(iProject, jarFiles)); return allocateContainer( javaProject, entries, new Path(CONTAINER_DEPENDENCIES), "Android Dependencies"); } }
private static List<IClasspathEntry> convertJarsToClasspathEntries( final IProject iProject, Set<File> jarFiles) { List<IClasspathEntry> entries = new ArrayList<IClasspathEntry>(jarFiles.size()); // and process the jar files list, but first sanitize it to remove dups. JarListSanitizer sanitizer = new JarListSanitizer( iProject.getFolder(SdkConstants.FD_OUTPUT).getLocation().toFile(), new AndroidPrintStream(iProject, null /*prefix*/, AndmoreAndroidPlugin.getOutStream())); String errorMessage = null; try { List<File> sanitizedList = sanitizer.sanitize(jarFiles); for (File jarFile : sanitizedList) { if (jarFile instanceof CPEFile) { CPEFile cpeFile = (CPEFile) jarFile; IClasspathEntry e = cpeFile.getClasspathEntry(); entries.add( JavaCore.newLibraryEntry( e.getPath(), e.getSourceAttachmentPath(), e.getSourceAttachmentRootPath(), e.getAccessRules(), e.getExtraAttributes(), true /*isExported*/)); } else { String jarPath = jarFile.getAbsolutePath(); IPath sourceAttachmentPath = null; IClasspathAttribute javaDocAttribute = null; File jarProperties = new File(jarPath + DOT_PROPERTIES); if (jarProperties.isFile()) { Properties p = new Properties(); InputStream is = null; try { p.load(is = new FileInputStream(jarProperties)); String value = p.getProperty(ATTR_SRC); if (value != null) { File srcPath = getFile(jarFile, value); if (srcPath.exists()) { sourceAttachmentPath = new Path(srcPath.getAbsolutePath()); } } value = p.getProperty(ATTR_DOC); if (value != null) { File docPath = getFile(jarFile, value); if (docPath.exists()) { try { javaDocAttribute = JavaCore.newClasspathAttribute( IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME, docPath.toURI().toURL().toString()); } catch (MalformedURLException e) { AndmoreAndroidPlugin.log( e, "Failed to process 'doc' attribute for %s", jarProperties.getAbsolutePath()); } } } } catch (FileNotFoundException e) { // shouldn't happen since we check upfront } catch (IOException e) { AndmoreAndroidPlugin.log(e, "Failed to read %s", jarProperties.getAbsolutePath()); } finally { if (is != null) { try { is.close(); } catch (IOException e) { // ignore } } } } if (javaDocAttribute != null) { entries.add( JavaCore.newLibraryEntry( new Path(jarPath), sourceAttachmentPath, null /*sourceAttachmentRootPath*/, new IAccessRule[0], new IClasspathAttribute[] {javaDocAttribute}, true /*isExported*/)); } else { entries.add( JavaCore.newLibraryEntry( new Path(jarPath), sourceAttachmentPath, null /*sourceAttachmentRootPath*/, true /*isExported*/)); } } } } catch (DifferentLibException e) { errorMessage = e.getMessage(); AndmoreAndroidPlugin.printErrorToConsole(iProject, (Object[]) e.getDetails()); } catch (Sha1Exception e) { errorMessage = e.getMessage(); } processError( iProject, errorMessage, AndmoreAndroidConstants.MARKER_DEPENDENCY, true /*outputToConsole*/); return entries; }