com.axelor.apps.base.service.administration.ExportDbObjectService.java Source code

Java tutorial

Introduction

Here is the source code for com.axelor.apps.base.service.administration.ExportDbObjectService.java

Source

/**
 * Axelor Business Solutions
 *
 * Copyright (C) 2015 Axelor (<http://axelor.com>).
 *
 * This program is free software: you can redistribute it and/or  modify
 * it under the terms of the GNU Affero General Public License, version 3,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.axelor.apps.base.service.administration;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

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

import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import com.axelor.app.AppSettings;
import com.axelor.apps.base.service.user.UserService;
import com.axelor.apps.tool.file.CsvTool;
import com.axelor.auth.db.Group;
import com.axelor.auth.db.repo.GroupRepository;
import com.axelor.meta.db.repo.MetaFileRepository;
import com.axelor.meta.MetaFiles;
import com.axelor.meta.db.MetaAction;
import com.axelor.meta.db.MetaFile;
import com.axelor.meta.db.MetaMenu;
import com.axelor.meta.db.repo.MetaMenuRepository;
import com.axelor.meta.db.MetaTranslation;
import com.axelor.meta.db.repo.MetaTranslationRepository;
import com.google.inject.Inject;
import com.google.inject.persist.Transactional;
import com.axelor.inject.Beans;

public class ExportDbObjectService {

    @Inject
    UserService uis;

    private static final Logger log = LoggerFactory.getLogger(ExportDbObjectService.class);

    public static String[] fieldAttrs = new String[] { "name", "type", "title" };

    public String[] csvHeaders = new String[] { "object", "module", "name", "type", "title_en", "title_fr",
            "help_en", "help_fr", "url" };

    private List<String[]> fieldDataList = new ArrayList<String[]>();

    private List<String> objectList = new ArrayList<String>();

    private Map<String, Object> objectMap = new HashMap<String, Object>();

    private Group group = null;

    @Transactional
    public MetaFile exportObject() {

        //      group = AuthUtils.getUser().getGroup();
        group = Beans.get(GroupRepository.class).all().filter("self.code = 'admins'").fetchOne();
        try {
            log.debug("Attachment dir: {}", AppSettings.get().get("file.upload.dir"));
            String uploadDir = AppSettings.get().get("file.upload.dir");
            if (uploadDir == null || !new File(uploadDir).exists()) {
                return null;
            }
            String appSrc = AppSettings.get().get("application.src");
            log.debug("Module dir: {}", appSrc);
            if (appSrc == null) {
                return null;
            }
            File moduleDir = new File(appSrc);
            if (!moduleDir.exists()) {
                return null;
            }

            MetaFile metaFile = new MetaFile();
            String fileName = "ExportObject-" + DateTime.now().toString("yyyMMddHHmmSS") + ".csv";
            metaFile.setFileName(fileName);
            metaFile.setFilePath(fileName);
            metaFile = Beans.get(MetaFileRepository.class).save(metaFile);

            SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
            updateObjectMap(Arrays.asList(moduleDir.listFiles()), saxParserFactory.newSAXParser(),
                    new XmlHandler());

            writeObjects(MetaFiles.getPath(metaFile).toFile());

            return metaFile;

        } catch (ParserConfigurationException | SAXException | IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private void writeObjects(File objectFile) {
        try {
            List<? extends MetaMenu> menuList = Beans.get(MetaMenuRepository.class).all()
                    .filter("self.parent = null AND self.left = true AND ?1 MEMBER OF self.groups", group)
                    .order("-priority").order("id").fetch();
            log.debug("Total root menus: {}", menuList.size());
            generateMenuGraph(menuList);
            CsvTool.csvWriter(objectFile.getParent(), objectFile.getName(), ';', csvHeaders, fieldDataList);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void generateMenuGraph(List<? extends MetaMenu> menuList) {
        //log.debug("Checking menu list: {}",menuList);
        for (MetaMenu menu : menuList) {
            String model = menu.getAction() != null ? menu.getAction().getModel() : null;
            //log.debug("Action model: ",model);
            if (model != null && !objectList.contains(model)) {
                updateFieldData(menu.getAction());
            }
            //List<? extends MetaMenu> childList = MetaMenu.all().filter("self.parent = ?1 AND self.left = true AND ?2 MEMBER OF self.groups", menu,group).order("-priority").order("id").fetch();
            List<? extends MetaMenu> childList = Beans.get(MetaMenuRepository.class).all()
                    .filter("self.parent = ?1 AND self.left = true", menu).order("-priority").order("id").fetch();
            generateMenuGraph(childList);
        }

    }

    @SuppressWarnings("unchecked")
    private void updateFieldData(MetaAction action) {
        String[] objectName = action.getModel().split("\\.");
        String objName = objectName[objectName.length - 1];
        Map<String, Object> moduleMap = (Map<String, Object>) objectMap.get(objName);
        if (moduleMap == null) {
            return;
        }
        boolean addObject = true;

        MetaTranslationRepository metaTranslationRepo = Beans.get(MetaTranslationRepository.class);

        //log.debug("Adding object: {}",objName);
        for (Entry<String, Object> module : moduleMap.entrySet()) {
            boolean addModule = true;
            for (Map<String, String> field : (List<Map<String, String>>) module.getValue()) {
                String[] fields = new String[csvHeaders.length];
                fields[0] = "";
                if (addObject) {
                    fields[0] = action.getModel();
                    fields[8] = getActionUrl(action);
                }
                fields[1] = "";
                if (addModule) {
                    fields[1] = module.getKey();
                }
                fields[2] = field.get("name");
                fields[3] = field.get("type");
                fields[4] = field.get("title");
                MetaTranslation mts = metaTranslationRepo.findByKey(field.get("title"), "fr");
                if (mts != null) {
                    fields[5] = mts.getMessage();
                }
                mts = metaTranslationRepo.findByKey("help:" + objName + "." + field.get("name"), "en");
                if (mts != null) {
                    fields[6] = mts.getMessage().replace(";", "\n");
                }
                mts = metaTranslationRepo.findByKey("help:" + objName + "." + field.get("name"), "fr");
                if (mts != null) {
                    fields[7] = mts.getMessage().replace(";", "\n");
                }
                fieldDataList.add(fields);
                addObject = false;
                addModule = false;
            }

        }
        objectList.add(action.getModel());

    }

    private String getActionUrl(MetaAction action) {

        String url = AppSettings.get().getBaseURL() + "#/ds";
        String viewType = getActionViewType(action.getXml());
        if (viewType.equals("grid")) {
            url = url + "/" + action.getName() + "/list/1";
        } else if (viewType.equals("form")) {
            url = url + "/" + action.getName() + "/edit";
        } else if (viewType.equals("calendar")) {
            url = url + "/" + action.getName() + "/calendar";
        }

        return url;
    }

    public static String getActionViewType(String xml) {

        DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
        domFactory.setNamespaceAware(true); // never forget this!
        DocumentBuilder builder;

        try {
            builder = domFactory.newDocumentBuilder();
            File tempXml = File.createTempFile("Temp", "xml");
            FileWriter fw = new FileWriter(tempXml);
            fw.write(xml);
            fw.close();
            Document doc = builder.parse(new FileInputStream(tempXml));
            Node child = doc.getFirstChild();
            NodeList chs = child.getChildNodes();
            for (Integer i = 0; i < chs.getLength(); i++) {
                if (chs.item(i).getNodeName().equals("view")) {
                    NamedNodeMap attributes = chs.item(i).getAttributes();
                    return attributes.getNamedItem("type").getNodeValue();
                }
            }
            return "";
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return null;
    }

    @SuppressWarnings("unchecked")
    private void updateObjectMap(List<File> modules, SAXParser parser, XmlHandler xmlHandler)
            throws SAXException, IOException {

        for (File module : modules) {
            String modulePath = module.getAbsolutePath();
            File modelDir = new File(modulePath + "/src/main/resources/domains/");
            if (!modelDir.exists()) {
                continue;
            }
            //log.debug("Module : {}",modelDir.getAbsolutePath());

            for (File objectFile : modelDir.listFiles()) {
                //log.debug("Parsing domain : {}",objectFile.getName());
                String objectName = objectFile.getName().split("\\.")[0];
                parser.parse(new InputSource(new FileInputStream(objectFile)), xmlHandler);
                Map<String, Object> moduleMap = (Map<String, Object>) objectMap.get(objectName);
                if (moduleMap == null) {
                    moduleMap = new HashMap<String, Object>();
                }
                moduleMap.put(module.getName(),
                        updateObjectModel(xmlHandler.fieldList, objectName, module.getName()));
                objectMap.put(objectName, moduleMap);

            }
        }

    }

    private Object updateObjectModel(List<Map<String, String>> fieldList, String objectName, String moduleName) {

        for (Map<String, String> field : fieldList) {
            field.put("module", moduleName);
            field.put("object", objectName);
        }
        return fieldList;
    }

}

class XmlHandler extends DefaultHandler {

    public List<Map<String, String>> fieldList;

    private boolean isObject = false;

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes)
            throws SAXException {
        switch (qName) {
        case "entity": {
            isObject = true;
            fieldList = new ArrayList<Map<String, String>>();
            break;
        }
        default: {
            if (isObject) {
                Map<String, String> fieldMap = new HashMap<String, String>();
                fieldMap.put("type", qName);
                for (String fieldAttr : Arrays.asList(ExportDbObjectService.fieldAttrs)) {
                    if (attributes.getValue(fieldAttr) != null) {
                        fieldMap.put(fieldAttr, attributes.getValue(fieldAttr));
                    }
                }
                fieldList.add(fieldMap);
            }
        }
        }
        super.startElement(uri, localName, qName, attributes);

    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {

        if (qName.equals("entity")) {
            isObject = false;
        }
        super.endElement(uri, localName, qName);

    }

}