/* * Copyright 2015 - 2016 i-net software * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.inet.gradle.setup.util; import java.io.File; import java.net.URL; import java.util.Objects; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import com.inet.gradle.setup.SetupBuilder; import com.inet.gradle.setup.abstracts.AbstractSetupTask; /** * Build an XML. * @author gamma * * @param <T> The SetupBuilder Task. */ public class XmlFileBuilder<T extends AbstractSetupTask> { public final T task; public final SetupBuilder setup; public final File xmlFile; public final File buildDir; public final Document doc; public XmlFileBuilder( T task, SetupBuilder setup, File xmlFile, File buildDir, URL template ) throws Exception { this.task = task; this.setup = setup; this.xmlFile = xmlFile; this.buildDir = buildDir; xmlFile.getParentFile().mkdirs(); DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); docFactory.setIgnoringComments( true ); DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); doc = template != null ? docBuilder.parse( template.toString() ) : docBuilder.newDocument(); } /** * Save the XML file * @throws Exception if any error occur */ public void save() throws Exception { TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); DOMSource source = new DOMSource( doc ); StreamResult result = new StreamResult( xmlFile ); transformer.setOutputProperty( OutputKeys.INDENT, "yes" ); transformer.setOutputProperty( "{http://xml.apache.org/xslt}indent-amount", "2" ); transformer.transform( source, result ); } /** * Add a attribute if not exists. * * @param el the element/node in the XML * @param name the name of the attribute * @param value the value */ public void addAttributeIfNotExists( Element el, String name, String value ) { if( !el.hasAttribute( name ) ) { el.setAttribute( name, value ); } } /** * Adds Text content to a node * @param el Node * @param text content */ public void addNodeText( Element el, String text ) { Document doc = el.getOwnerDocument(); el.appendChild( doc.createTextNode( text ) ); } public Element getOrCreateChild( Node parent, String name ) { return getOrCreateChild( parent, name, true ); } public Element getOrCreateChild( Node parent, String name, boolean append ) { Node first = parent.getFirstChild(); for( Node child = first; child != null; child = child.getNextSibling() ) { if( name.equals( child.getNodeName() ) ) { return (Element)child; } } Document doc = parent instanceof Document ? (Document)parent : parent.getOwnerDocument(); Element child = doc.createElement( name ); if( append || first == null ) { parent.appendChild( child ); } else { parent.insertBefore( child, first ); } return child; } public Element getOrCreateChildById( Node parent, String name, String id ) { return getOrCreateChildByKeyValue( parent, name, "Id", id, true ); } public Element getOrCreateChildById( Node parent, String name, String id, boolean append ) { return getOrCreateChildByKeyValue( parent, name, "Id", id, append ); } public Element getOrCreateChildByKeyValue( Node parent, String name, String key, String value ) { return getOrCreateChildByKeyValue( parent, name, key, value, true ); } /** * Get or create a child element. * * @param parent the parent node in which we search and create * @param name The tag name of the element * @param key the name of an attribute, can't be null * @param value the value, can be null for not existing * @param append true, append at end of the children; false, add at top of the children * @return the create of find Element */ public Element getOrCreateChildByKeyValue( Node parent, String name, String key, String value, boolean append ) { Node first = parent.getFirstChild(); for( Node child = first; child != null; child = child.getNextSibling() ) { if( name.equals( child.getNodeName() ) ) { if( Objects.equals( value, ((Element)child).getAttribute( key ) ) || (value == null && !((Element)child).hasAttribute( key )) ) { return (Element)child; } } } Document doc = parent.getOwnerDocument(); Element child = doc.createElement( name ); if( value != null ) { child.setAttribute( key, value ); } if( append || first == null ) { parent.appendChild( child ); } else { parent.insertBefore( child, first ); } return child; } }