/** * Pretty prints the given node * * @param node the node, usually a document, to be printed * @param prefs the formatting preferences * @param style the formatting style to use * @param lineSeparator the line separator to use, or null to use the default * @param endWithNewline if true, ensure that the printed output ends with a newline * @return a formatted string */ @NonNull public static String prettyPrint( @NonNull Node node, @NonNull XmlFormatPreferences prefs, @NonNull XmlFormatStyle style, @Nullable String lineSeparator, boolean endWithNewline) { XmlPrettyPrinter printer = new XmlPrettyPrinter(prefs, style, lineSeparator); printer.setEndWithNewline(endWithNewline); StringBuilder sb = new StringBuilder(1000); printer.prettyPrint(-1, node, null, null, sb, false /*openTagOnly*/); String xml = sb.toString(); if (node.getNodeType() == Node.DOCUMENT_NODE && !xml.startsWith("<?")) { // $NON-NLS-1$ xml = XML_PROLOG + xml; } return xml; }
/** * Pretty-prints the given XML document, which must be well-formed. If it is not, the original * unformatted XML document is returned * * @param xml the XML content to format * @param prefs the preferences to format with * @param style the style to format with * @param lineSeparator the line separator to use, such as "\n" (can be null, in which case the * system default is looked up via the line.separator property) * @return the formatted document (or if a parsing error occurred, returns the unformatted * document) */ @NonNull public static String prettyPrint( @NonNull String xml, @NonNull XmlFormatPreferences prefs, @NonNull XmlFormatStyle style, @Nullable String lineSeparator) { Document document = XmlUtils.parseDocumentSilently(xml, true); if (document != null) { XmlPrettyPrinter printer = new XmlPrettyPrinter(prefs, style, lineSeparator); printer.setEndWithNewline(xml.endsWith(printer.getLineSeparator())); StringBuilder sb = new StringBuilder(3 * xml.length() / 2); printer.prettyPrint(-1, document, null, null, sb, false /*openTagOnly*/); return sb.toString(); } else { // Parser error: just return the unformatted content return xml; } }
private static void formatFile(@NonNull XmlFormatPreferences prefs, File file, boolean stdout) { if (file.isDirectory()) { File[] files = file.listFiles(); if (files != null) { for (File child : files) { formatFile(prefs, child, stdout); } } } else if (file.isFile() && SdkUtils.endsWithIgnoreCase(file.getName(), DOT_XML)) { XmlFormatStyle style = null; if (file.getName().equals(SdkConstants.ANDROID_MANIFEST_XML)) { style = XmlFormatStyle.MANIFEST; } else { File parent = file.getParentFile(); if (parent != null) { String parentName = parent.getName(); ResourceFolderType folderType = ResourceFolderType.getFolderType(parentName); if (folderType == ResourceFolderType.LAYOUT) { style = XmlFormatStyle.LAYOUT; } else if (folderType == ResourceFolderType.VALUES) { style = XmlFormatStyle.RESOURCE; } } } try { String xml = Files.toString(file, Charsets.UTF_8); Document document = XmlUtils.parseDocumentSilently(xml, true); if (document == null) { System.err.println("Could not parse " + file); System.exit(1); return; } if (style == null) { style = XmlFormatStyle.get(document); } boolean endWithNewline = xml.endsWith("\n"); int firstNewLine = xml.indexOf('\n'); String lineSeparator = firstNewLine > 0 && xml.charAt(firstNewLine - 1) == '\r' ? "\r\n" : "\n"; String formatted = XmlPrettyPrinter.prettyPrint(document, prefs, style, lineSeparator, endWithNewline); if (stdout) { System.out.println(formatted); } else { Files.write(formatted, file, Charsets.UTF_8); } } catch (IOException e) { System.err.println("Could not read " + file); System.exit(1); } } }
public void testRenderDrawable() throws Exception { VirtualFile file = myFixture.copyFileToProject( "drawables/progress_horizontal.xml", "res/drawable/progress_horizontal.xml"); assertNotNull(file); RenderService service = getRenderService(file); assertNotNull(service); ILayoutPullParser parser = LayoutPullParserFactory.create(service); assertTrue(parser instanceof DomPullParser); Element root = ((DomPullParser) parser).getRoot(); String layout = XmlPrettyPrinter.prettyPrint(root, true); assertEquals( "<ImageView\n" + "xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" + "layout_width=\"fill_parent\"\n" + "layout_height=\"fill_parent\"\n" + "src=\"@drawable/progress_horizontal\" />\n", layout); checkRendering(service, "drawable/progress_horizontal.png"); }
@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); } }