fr.rjoakim.android.jonetouch.util.XMLReaderUtils.java Source code

Java tutorial

Introduction

Here is the source code for fr.rjoakim.android.jonetouch.util.XMLReaderUtils.java

Source

package fr.rjoakim.android.jonetouch.util;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs;

import fr.rjoakim.android.jonetouch.bean.Action;
import fr.rjoakim.android.jonetouch.bean.ActionScript;
import fr.rjoakim.android.jonetouch.bean.Authentication;
import fr.rjoakim.android.jonetouch.bean.AuthenticationTypeEnum;
import fr.rjoakim.android.jonetouch.bean.MyAuthentication;
import fr.rjoakim.android.jonetouch.bean.NoAuthentication;
import fr.rjoakim.android.jonetouch.bean.SSHAuthenticationPassword;
import fr.rjoakim.android.jonetouch.bean.Server;
import fr.rjoakim.android.jonetouch.dialog.bean.BackupXmlParse;

/**
 * 
 * Copyright 2013 Joakim Ribier
 * 
 * 
 * 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.
 * 
 */
public class XMLReaderUtils extends XMLParserUtils {

    public static BackupXmlParse parse(String xml, MyAuthentication myAuthentication, String key,
            boolean isParseServers, boolean isParseActions) throws XMLParserUtilsException {

        try {
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document document = dBuilder.parse(new ByteArrayInputStream(xml.getBytes()));
            document.getDocumentElement().normalize();

            checkBackupFormat(document);
            boolean isEncrypt = isEncryptBackupPassword(document.getDocumentElement());

            List<Server> servers = Lists.newArrayList();
            List<Action> actions = Lists.newArrayList();

            if (isParseServers) {
                parseServersElements(document, myAuthentication, key, servers, isEncrypt);
            }

            if (isParseActions) {
                parseActionsElements(document, actions);
            }

            return new BackupXmlParse(servers, actions);
        } catch (ParserConfigurationException e) {
            throw new XMLParserUtilsException(e.getMessage(), e);
        } catch (SAXException e) {
            throw new XMLParserUtilsException(e.getMessage(), e);
        } catch (IOException e) {
            throw new XMLParserUtilsException(e.getMessage(), e);
        }
    }

    private static boolean isEncryptBackupPassword(Element parent) {
        String value = getRequiredAttribute(parent, AUTHENTICATION);
        return value.equals(ENCRYPT);
    }

    private static void parseServersElements(Document document, MyAuthentication myAuthentication, String key,
            List<Server> servers, boolean isEncrypt) throws XMLParserUtilsException {

        NodeList serversNodeList = document.getElementsByTagName(SERVER);
        for (int cpt = 0; cpt < serversNodeList.getLength(); cpt++) {

            Node serverNode = serversNodeList.item(cpt);
            if (serverNode.getNodeType() == Node.ELEMENT_NODE) {

                Element serverElement = (Element) serverNode;

                long id = getRequiredLongAttribute(serverElement, DATABASE_ID);
                int port = getRequiredIntAttribute(serverElement, PORT);

                String title = getRequiredElementValue(serverElement, TITLE);
                String hostname = getRequiredElementValue(serverElement, HOSTNAME);
                String description = getRequiredElementValue(serverElement, DESCRIPTION);
                Authentication authentication = parseAuthenticationElement(serverElement, myAuthentication, key,
                        isEncrypt);

                servers.add(new Server(id, title, hostname, port, description, authentication));
            }
        }
    }

    private static Authentication parseAuthenticationElement(Element serverElement,
            MyAuthentication myAuthentication, String key, boolean isEncrypt) throws XMLParserUtilsException {

        Element serverAuthentication = getRequiredElement(serverElement, AUTHENTICATION);
        long type = getRequiredLongAttribute(serverAuthentication, TYPE);
        AuthenticationTypeEnum authenticationTypeEnum = AuthenticationTypeEnum.fromId(type);
        Authentication authentication = null;
        switch (authenticationTypeEnum) {
        case NO_AUTHENTICATION:
            authentication = new NoAuthentication(getRequiredElementValue(serverElement, LOGIN), null);
            break;
        case SSH_AUTHENTICATION_PASSWORD:
            authentication = parseSSHAuthenticationPasword(serverElement, myAuthentication, key, isEncrypt);

            break;
        default:
            throw new XMLParserUtilsException("authentication field is required.");
        }
        return authentication;
    }

    private static Authentication parseSSHAuthenticationPasword(Element serverElement,
            MyAuthentication myAuthentication, String key, boolean isEncrypt) throws XMLParserUtilsException {

        String passwordValue = getRequiredElementValue(serverElement, PASSWORD);
        String newPwd = getPassword(key, isEncrypt, passwordValue);
        String pwdEncoded = encryptPassword(myAuthentication, newPwd);
        String login = getRequiredElementValue(serverElement, LOGIN);
        return new SSHAuthenticationPassword(login, pwdEncoded, null);
    }

    private static String encryptPassword(MyAuthentication myAuthentication, String newPwd) {
        String pwdEncoded = "";
        try {
            pwdEncoded = CryptographyUtils.encrypt(newPwd, myAuthentication.getKey());
        } catch (CryptographyException e) {
            pwdEncoded = "error decrypt password";
        }
        return pwdEncoded;
    }

    private static String getPassword(String key, boolean isEncrypt, String password) {

        String newPwd = password;
        if (isEncrypt) {
            try {
                if (!Strings.isNullOrEmpty(key)) {
                    newPwd = CryptographyUtils.decrypt(password, key);
                }
            } catch (CryptographyException e) {
                newPwd = "error decrypt password";
            }
        }
        return newPwd;
    }

    private static long getRequiredLongAttribute(Element parent, String name) throws XMLParserUtilsException {
        Long value = getOptionalLongAttribute(parent, name);
        if (value != null) {
            return value.longValue();
        }
        throw new XMLParserUtilsException(name + " field is required.");
    }

    private static Long getOptionalLongAttribute(Element parent, String name) {
        return Longs.tryParse(parent.getAttribute(name));
    }

    private static int getRequiredIntAttribute(Element parent, String name) throws XMLParserUtilsException {
        Integer value = Ints.tryParse(parent.getAttribute(name));
        if (value != null) {
            return value.intValue();
        }
        throw new XMLParserUtilsException(name + " field is required.");
    }

    private static String getRequiredAttribute(Element parent, String name) {
        String value = parent.getAttribute(name);
        Preconditions.checkNotNull(value, name + " field is required");
        return value;
    }

    private static String getRequiredElementValue(Element parent, String name) throws XMLParserUtilsException {
        NodeList nodeList = parent.getElementsByTagName(name);
        Node node = nodeList.item(0);
        if (node.getNodeType() == Node.ELEMENT_NODE) {
            Element element = (Element) node;
            return element.getTextContent();
        }
        throw new XMLParserUtilsException(name + " field is required.");
    }

    private static Element getRequiredElement(Element parent, String name) throws XMLParserUtilsException {
        NodeList nodeList = parent.getElementsByTagName(name);
        Node node = nodeList.item(0);
        if (node.getNodeType() == Node.ELEMENT_NODE) {
            return (Element) node;
        }
        throw new XMLParserUtilsException(name + " field is required.");
    }

    private static void parseActionsElements(Document document, List<Action> actions)
            throws XMLParserUtilsException {
        NodeList actionsNodeList = document.getElementsByTagName(ACTION);
        for (int cpt = 0; cpt < actionsNodeList.getLength(); cpt++) {

            Node actionNode = actionsNodeList.item(cpt);
            if (actionNode.getNodeType() == Node.ELEMENT_NODE) {

                Element actionElement = (Element) actionNode;

                String backgroundHexColor = getRequiredAttribute(actionElement, BACKGROUND_COLOR);
                Long serverId = getOptionalLongAttribute(actionElement, SERVER_ID);
                String title = getRequiredElementValue(actionElement, TITLE);
                String description = getRequiredElementValue(actionElement, DESCRIPTION);

                List<ActionScript> actionScripts = Lists.newArrayList();
                parseActionScriptsElements(actionElement, actionScripts);
                actions.add(new Action(-1, title, description, backgroundHexColor, serverId, actionScripts));
            }
        }
    }

    private static void parseActionScriptsElements(Element actionElement, List<ActionScript> actionScripts) {

        NodeList actionScriptsNodeList = actionElement.getElementsByTagName(SCRIPT);
        for (int cpt = 0; cpt < actionScriptsNodeList.getLength(); cpt++) {

            Node scriptNode = actionScriptsNodeList.item(cpt);
            if (scriptNode.getNodeType() == Node.ELEMENT_NODE) {

                Element scriptElement = (Element) scriptNode;
                String script = scriptElement.getTextContent();
                actionScripts.add(new ActionScript(-1, script));
            }
        }
    }

    private static void checkBackupFormat(Document document) throws XMLParserUtilsException {
        String name = document.getDocumentElement().getAttribute(NAME);
        String authentication = document.getDocumentElement().getAttribute(AUTHENTICATION);

        try {
            Preconditions.checkArgument(!Strings.isNullOrEmpty(name), "name field is required");
            Preconditions.checkArgument(!Strings.isNullOrEmpty(authentication), "authentication field is required");
            Preconditions.checkArgument(name.equals(BACKUP), "name is not equals to " + BACKUP);
        } catch (IllegalArgumentException ex) {
            throw new XMLParserUtilsException(ex.getMessage(), ex);
        }

        if (!authentication.equals(ENCRYPT) && !authentication.equals(DECRYPT)) {
            throw new XMLParserUtilsException("authentication field wrong format.");
        }
    }
}