private List<LoadedManifestInfo> loadLibraries( SelectorResolver selectors, MergingReport.Builder mergingReportBuilder) throws MergeFailureException { ImmutableList.Builder<LoadedManifestInfo> loadedLibraryDocuments = ImmutableList.builder(); for (Pair<String, File> libraryFile : mLibraryFiles) { mLogger.info("Loading library manifest " + libraryFile.getSecond().getPath()); ManifestInfo manifestInfo = new ManifestInfo( libraryFile.getFirst(), libraryFile.getSecond(), XmlDocument.Type.LIBRARY, Optional.<String>absent()); XmlDocument libraryDocument; try { libraryDocument = XmlLoader.load( selectors, mSystemPropertyResolver, manifestInfo.mName, manifestInfo.mLocation, XmlDocument.Type.LIBRARY, Optional.<String>absent() /* mainManifestPackageName */); } catch (Exception e) { throw new MergeFailureException(e); } // extract the package name... String libraryPackage = libraryDocument.getRootNode().getXml().getAttribute("package"); // save it in the selector instance. if (!Strings.isNullOrEmpty(libraryPackage)) { selectors.addSelector(libraryPackage, libraryFile.getFirst()); } // perform placeholder substitution, this is useful when the library is using // a placeholder in a key element, we however do not need to record these // substitutions so feed it with a fake merging report. MergingReport.Builder builder = new MergingReport.Builder(mergingReportBuilder.getLogger()); builder.getActionRecorder().recordDefaultNodeAction(libraryDocument.getRootNode()); performPlaceHolderSubstitution(manifestInfo, libraryDocument, builder); if (builder.hasErrors()) { // we log the errors but continue, in case the error is of no consequence // to the application consuming the library. builder.build().log(mLogger); } loadedLibraryDocuments.add( new LoadedManifestInfo( manifestInfo, Optional.fromNullable(libraryDocument.getPackageName()), libraryDocument)); } return loadedLibraryDocuments.build(); }
/** * Add one library file manifest, will be added last in the list of library files which will * make the parameter the lowest priority library manifest file. * * @param file the library manifest file to add. * @return itself. */ public Invoker addLibraryManifest(File file) { if (mMergeType == MergeType.LIBRARY) { throw new IllegalStateException( "Cannot add library dependencies manifests when creating a library"); } mLibraryFilesBuilder.add(Pair.of(file.getName(), file)); return thisAsT(); }
private static void forkResourceFile( @NotNull Module module, @NotNull final ResourceFolderType folderType, @NotNull final VirtualFile file, @Nullable final XmlFile xmlFile, @Nullable String myNewFolder, @Nullable Configuration configuration, boolean open) { final Project project = module.getProject(); final FolderConfiguration folderConfig; if (myNewFolder == null) { // Open a file chooser to select the configuration to be created VirtualFile parentFolder = file.getParent(); assert parentFolder != null; VirtualFile res = parentFolder.getParent(); folderConfig = selectFolderConfig(project, res, folderType); } else { folderConfig = FolderConfiguration.getConfigForFolder(myNewFolder); } if (folderConfig == null) { return; } final Computable<Pair<String, VirtualFile>> computable = new Computable<Pair<String, VirtualFile>>() { @Override public Pair<String, VirtualFile> compute() { String folderName = folderConfig.getFolderName(folderType); try { VirtualFile parentFolder = file.getParent(); assert parentFolder != null; VirtualFile res = parentFolder.getParent(); VirtualFile newParentFolder = res.findChild(folderName); if (newParentFolder == null) { newParentFolder = res.createChildDirectory(this, folderName); if (newParentFolder == null) { String message = String.format( "Could not create folder %1$s in %2$s", folderName, res.getPath()); return Pair.of(message, null); } } final VirtualFile existing = newParentFolder.findChild(file.getName()); if (existing != null && existing.exists()) { String message = String.format( "File 'res/%1$s/%2$s' already exists!", folderName, file.getName()); return Pair.of(message, null); } // Attempt to get the document from the PSI file rather than the file on disk: get // edited contents too String text; if (xmlFile != null) { text = xmlFile.getText(); } else { text = StreamUtil.readText(file.getInputStream(), "UTF-8"); } VirtualFile newFile = newParentFolder.createChildData(this, file.getName()); VfsUtil.saveText(newFile, text); return Pair.of(null, newFile); } catch (IOException e2) { String message = String.format( "Failed to create File 'res/%1$s/%2$s' : %3$s", folderName, file.getName(), e2.getMessage()); return Pair.of(message, null); } } }; WriteCommandAction<Pair<String, VirtualFile>> action = new WriteCommandAction<Pair<String, VirtualFile>>(project, "Add Resource") { @Override protected void run(@NotNull Result<Pair<String, VirtualFile>> result) throws Throwable { result.setResult(computable.compute()); } }; Pair<String, VirtualFile> result = action.execute().getResultObject(); String error = result.getFirst(); VirtualFile newFile = result.getSecond(); if (error != null) { Messages.showErrorDialog(project, error, "Create Resource"); } else { // First create a compatible configuration based on the current configuration if (configuration != null) { ConfigurationManager configurationManager = configuration.getConfigurationManager(); configurationManager.createSimilar(newFile, file); } if (open) { OpenFileDescriptor descriptor = new OpenFileDescriptor(project, newFile, -1); FileEditorManager.getInstance(project).openEditor(descriptor, true); } } }
/** * Called by {@link NewXmlFileWizard} to initialize the page with the selection received by the * wizard -- typically the current user workbench selection. * * <p>Things we expect to find out from the selection: * * <ul> * <li>The project name, valid if it's an android nature. * <li>The current folder, valid if it's a folder under /res * <li>An existing filename, in which case the user will be asked whether to override it. * </ul> * * <p>The selection can also be set to a {@link Pair} of {@link IProject} and a workspace resource * path (where the resource path does not have to exist yet, such as res/anim/). * * @param selection The selection when the wizard was initiated. */ private boolean initializeFromSelection(IStructuredSelection selection) { if (selection == null) { return false; } // Find the best match in the element list. In case there are multiple selected elements // select the one that provides the most information and assign them a score, // e.g. project=1 + folder=2 + file=4. IProject targetProject = null; String targetWsFolderPath = null; String targetFileName = null; int targetScore = 0; for (Object element : selection.toList()) { if (element instanceof IAdaptable) { IResource res = (IResource) ((IAdaptable) element).getAdapter(IResource.class); IProject project = res != null ? res.getProject() : null; // Is this an Android project? try { if (project == null || !project.hasNature(AdtConstants.NATURE_DEFAULT)) { continue; } } catch (CoreException e) { // checking the nature failed, ignore this resource continue; } int score = 1; // we have a valid project at least IPath wsFolderPath = null; String fileName = null; assert res != null; // Eclipse incorrectly thinks res could be null, so tell it no if (res.getType() == IResource.FOLDER) { wsFolderPath = res.getProjectRelativePath(); } else if (res.getType() == IResource.FILE) { if (SdkUtils.endsWithIgnoreCase(res.getName(), DOT_XML)) { fileName = res.getName(); } wsFolderPath = res.getParent().getProjectRelativePath(); } // Disregard this folder selection if it doesn't point to /res/something if (wsFolderPath != null && wsFolderPath.segmentCount() > 1 && SdkConstants.FD_RESOURCES.equals(wsFolderPath.segment(0))) { score += 2; } else { wsFolderPath = null; fileName = null; } score += fileName != null ? 4 : 0; if (score > targetScore) { targetScore = score; targetProject = project; targetWsFolderPath = wsFolderPath != null ? wsFolderPath.toString() : null; targetFileName = fileName; } } else if (element instanceof Pair<?, ?>) { // Pair of Project/String @SuppressWarnings("unchecked") Pair<IProject, String> pair = (Pair<IProject, String>) element; targetScore = 1; targetProject = pair.getFirst(); targetWsFolderPath = pair.getSecond(); targetFileName = ""; } } if (targetProject == null) { // Try to figure out the project from the active editor IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); if (window != null) { IWorkbenchPage page = window.getActivePage(); if (page != null) { IEditorPart activeEditor = page.getActiveEditor(); if (activeEditor instanceof AndroidXmlEditor) { Object input = ((AndroidXmlEditor) activeEditor).getEditorInput(); if (input instanceof FileEditorInput) { FileEditorInput fileInput = (FileEditorInput) input; targetScore = 1; IFile file = fileInput.getFile(); targetProject = file.getProject(); IPath path = file.getParent().getProjectRelativePath(); targetWsFolderPath = path != null ? path.toString() : null; } } } } } if (targetProject == null) { // If we didn't find a default project based on the selection, check how many // open Android projects we can find in the current workspace. If there's only // one, we'll just select it by default. IJavaProject[] projects = AdtUtils.getOpenAndroidProjects(); if (projects != null && projects.length == 1) { targetScore = 1; targetProject = projects[0].getProject(); } } // Now set the UI accordingly if (targetScore > 0) { mValues.project = targetProject; mValues.folderPath = targetWsFolderPath; mProjectButton.setSelectedProject(targetProject); mFileNameTextField.setText(targetFileName != null ? targetFileName : ""); // $NON-NLS-1$ // If the current selection context corresponds to a specific file type, // select it. if (targetWsFolderPath != null) { int pos = targetWsFolderPath.lastIndexOf(WS_SEP_CHAR); if (pos >= 0) { targetWsFolderPath = targetWsFolderPath.substring(pos + 1); } String[] folderSegments = targetWsFolderPath.split(RES_QUALIFIER_SEP); if (folderSegments.length > 0) { mValues.configuration = FolderConfiguration.getConfig(folderSegments); String folderName = folderSegments[0]; selectTypeFromFolder(folderName); } } } return true; }