@Override public void addItem(@NonNull final ResourceItem item) throws ConsumerException { ResourceFile.FileType type = item.getSource().getType(); if (type == ResourceFile.FileType.MULTI) { // this is a resource for the values files // just add the node to write to the map based on the qualifier. // We'll figure out later if the files needs to be written or (not) mValuesResMap.put(item.getSource().getQualifiers(), item); } else { // This is a single value file. // Only write it if the state is TOUCHED. if (item.isTouched()) { getExecutor() .execute( new Callable<Void>() { @Override public Void call() throws Exception { ResourceFile resourceFile = item.getSource(); File file = resourceFile.getFile(); String filename = file.getName(); String folderName = item.getType().getName(); String qualifiers = resourceFile.getQualifiers(); if (!qualifiers.isEmpty()) { folderName = folderName + RES_QUALIFIER_SEP + qualifiers; } File typeFolder = new File(getRootFolder(), folderName); createDir(typeFolder); File outFile = new File(typeFolder, filename); if (mAaptRunner != null && filename.endsWith(DOT_PNG)) { // run aapt in single crunch mode on the original file to write the // destination file. mAaptRunner.crunchPng(file, outFile); } else if (filename.endsWith(DOT_XML)) { copyXmlWithComment(file, outFile, createPathComment(file)); } else { Files.copy(file, outFile); } return null; } }); } } }
@Override protected void postWriteAction() throws ConsumerException { // now write the values files. for (String key : mValuesResMap.keySet()) { // the key is the qualifier. // check if we have to write the file due to deleted values. // also remove it from that list anyway (to detect empty qualifiers later). boolean mustWriteFile = mQualifierWithDeletedValues.remove(key); // get the list of items to write List<ResourceItem> items = mValuesResMap.get(key); // now check if we really have to write it if (!mustWriteFile) { for (ResourceItem item : items) { if (item.isTouched()) { mustWriteFile = true; break; } } } if (mustWriteFile) { String folderName = key.isEmpty() ? ResourceFolderType.VALUES.getName() : ResourceFolderType.VALUES.getName() + RES_QUALIFIER_SEP + key; try { File valuesFolder = new File(getRootFolder(), folderName); createDir(valuesFolder); File outFile = new File(valuesFolder, FN_VALUES_XML); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); factory.setValidating(false); factory.setIgnoringComments(true); DocumentBuilder builder; builder = factory.newDocumentBuilder(); Document document = builder.newDocument(); Node rootNode = document.createElement(TAG_RESOURCES); document.appendChild(rootNode); Collections.sort(items); ResourceFile currentFile = null; for (ResourceItem item : items) { ResourceFile source = item.getSource(); if (source != currentFile) { currentFile = source; rootNode.appendChild(document.createTextNode("\n")); File file = source.getFile(); rootNode.appendChild(document.createComment(createPathComment(file))); rootNode.appendChild(document.createTextNode("\n")); } Node adoptedNode = NodeUtils.adoptNode(document, item.getValue()); rootNode.appendChild(adoptedNode); } String content; try { content = XmlPrettyPrinter.prettyPrint(document, true); } catch (Throwable t) { content = XmlUtils.toXml(document, false); } Files.write(content, outFile, Charsets.UTF_8); } catch (Throwable t) { throw new ConsumerException(t); } } } // now remove empty values files. for (String key : mQualifierWithDeletedValues) { String folderName = key != null && !key.isEmpty() ? ResourceFolderType.VALUES.getName() + RES_QUALIFIER_SEP + key : ResourceFolderType.VALUES.getName(); removeOutFile(folderName, FN_VALUES_XML); } }