org.drools.workbench.jcr2vfsmigration.jcrExport.ModuleAssetExporter.java Source code

Java tutorial

Introduction

Here is the source code for org.drools.workbench.jcr2vfsmigration.jcrExport.ModuleAssetExporter.java

Source

/*
 * Copyright 2014 Red Hat, Inc. and/or its affiliates.
 *
 * 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 org.drools.workbench.jcr2vfsmigration.jcrExport;

import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import javax.inject.Inject;

import com.google.gwt.user.client.rpc.SerializationException;
import org.apache.commons.lang3.StringUtils;
import org.drools.guvnor.client.common.AssetFormats;
import org.drools.guvnor.client.rpc.AssetPageRequest;
import org.drools.guvnor.client.rpc.AssetPageRow;
import org.drools.guvnor.client.rpc.Module;
import org.drools.guvnor.client.rpc.PageResponse;
import org.drools.guvnor.client.rpc.TableDataResult;
import org.drools.guvnor.client.rpc.TableDataRow;
import org.drools.guvnor.server.RepositoryAssetService;
import org.drools.guvnor.server.RepositoryModuleService;
import org.drools.guvnor.server.repository.Preferred;
import org.drools.repository.AssetItem;
import org.drools.repository.ModuleItem;
import org.drools.repository.ModuleIterator;
import org.drools.repository.RulesRepository;
import org.drools.workbench.jcr2vfsmigration.common.FileManager;
import org.drools.workbench.jcr2vfsmigration.jcrExport.asset.AttachmentAssetExporter;
import org.drools.workbench.jcr2vfsmigration.jcrExport.asset.ExportContext;
import org.drools.workbench.jcr2vfsmigration.jcrExport.asset.FactModelExporter;
import org.drools.workbench.jcr2vfsmigration.jcrExport.asset.GuidedDecisionTableExporter;
import org.drools.workbench.jcr2vfsmigration.jcrExport.asset.GuidedEditorExporter;
import org.drools.workbench.jcr2vfsmigration.jcrExport.asset.PlainTextAssetExporter;
import org.drools.workbench.jcr2vfsmigration.jcrExport.asset.PlainTextAssetWithPackagePropertyExporter;
import org.drools.workbench.jcr2vfsmigration.util.ExportUtils;
import org.drools.workbench.jcr2vfsmigration.xml.format.ModulesXmlFormat;
import org.drools.workbench.jcr2vfsmigration.xml.format.XmlAssetsFormat;
import org.drools.workbench.jcr2vfsmigration.xml.model.ModuleType;
import org.drools.workbench.jcr2vfsmigration.xml.model.Modules;
import org.drools.workbench.jcr2vfsmigration.xml.model.asset.IgnoredAsset;
import org.drools.workbench.jcr2vfsmigration.xml.model.asset.XmlAsset;
import org.drools.workbench.jcr2vfsmigration.xml.model.asset.XmlAssets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ModuleAssetExporter {

    private static final Logger logger = LoggerFactory.getLogger(ModuleAssetExporter.class);

    private static int assetFileName = 1;
    private static final String GLOBAL_KEYWORD = "global ";

    @Inject
    private FileManager fileManager;

    @Inject
    private ExportUtils exportUtils;

    @Inject
    private RepositoryModuleService jcrRepositoryModuleService;

    @Inject
    private RepositoryAssetService jcrRepositoryAssetService;

    @Inject
    @Preferred
    private RulesRepository rulesRepository;

    @Inject
    private PlainTextAssetExporter plainTextAssetExporter;

    @Inject
    private PlainTextAssetWithPackagePropertyExporter plainTextAssetWithPackagePropertyExporter;

    @Inject
    private GuidedEditorExporter guidedEditorExporter;

    @Inject
    private GuidedDecisionTableExporter guidedDecisionTableExporter;

    @Inject
    private FactModelExporter factModelExporter;

    @Inject
    private AttachmentAssetExporter attachmentAssetExporter;

    private ModulesXmlFormat modulesXmlFormat = new ModulesXmlFormat();
    private XmlAssetsFormat xmlAssetsFormat = new XmlAssetsFormat();

    public void exportAll() {

        logger.info("  Module export started");
        Module jcrGlobalModule = jcrRepositoryModuleService.loadGlobalModule();
        Module[] jcrModules = jcrRepositoryModuleService.listModules();

        if (jcrGlobalModule == null && jcrModules.length == 0) {
            logger.info("  No modules to be exported");
            return;
        }

        Collection<org.drools.workbench.jcr2vfsmigration.xml.model.Module> normalModules = new ArrayList<org.drools.workbench.jcr2vfsmigration.xml.model.Module>(
                5);
        for (Module jcrModule : jcrModules) {
            normalModules.add(export(ModuleType.NORMAL, jcrModule));
        }

        org.drools.workbench.jcr2vfsmigration.xml.model.Module globalModule = export(ModuleType.GLOBAL,
                jcrGlobalModule);

        Modules modules = new Modules(globalModule, normalModules);

        StringBuilder xml = new StringBuilder();
        modulesXmlFormat.format(xml, modules);

        PrintWriter pw = fileManager.createModuleExportFileWriter();
        pw.print(xml.toString());
        pw.close();

        logger.info("  Module export ended");
    }

    private org.drools.workbench.jcr2vfsmigration.xml.model.Module export(ModuleType moduleType, Module jcrModule) {
        logger.info("    Exporting module [{}] (UUID={}).", jcrModule.getName(), jcrModule.getUuid());

        //setting CategoryRules to jcr module (needed in asset migration)
        for (ModuleIterator packageItems = rulesRepository.listModules(); packageItems.hasNext();) {
            ModuleItem packageItem = packageItems.next();
            if (packageItem.getUUID().equals(jcrModule.getUuid())) {
                jcrModule.setCatRules(packageItem.getCategoryRules());
                break;
            }
        }

        // Save module name for later
        String moduleName = jcrModule.getName();
        String normalizedPackageName = exportUtils.normalizePackageName(jcrModule.getName());
        jcrModule.setName(normalizedPackageName);

        // Export package header info
        String packageHeaderInfo = null;
        try {
            List<String> formats = new ArrayList<String>();
            formats.add("package");
            AssetPageRequest request = new AssetPageRequest(jcrModule.getUuid(), formats, null, 0, 10);
            PageResponse<AssetPageRow> response = jcrRepositoryAssetService.findAssetPage(request);
            if (response.getTotalRowSize() > 0) {
                AssetPageRow row = response.getPageRowList().get(0);
                AssetItem assetItemJCR = rulesRepository.loadAssetByUUID(row.getUuid());

                packageHeaderInfo = assetItemJCR.getContent();
            }
        } catch (SerializationException e) {
            throw new IllegalStateException(e);
        }

        // Export globalsString
        StringBuffer sbGlobal = new StringBuffer();
        List<String> lGlobals = ExportUtils.parseGlobals(packageHeaderInfo);
        if (lGlobals.size() > 0) {
            for (String global : lGlobals) {
                sbGlobal.append(GLOBAL_KEYWORD);
                sbGlobal.append(global);
                sbGlobal.append("\n");
            }
        }

        String assetExportFileName = setupAssetExportFile(jcrModule.getUuid());

        boolean assetExportSuccess = exportModuleAssets(jcrModule, assetExportFileName);
        if (!assetExportSuccess)
            logger.error("An error occurred during asset export for module {} (UUID={})!", jcrModule.getName(),
                    jcrModule.getUuid());

        return new org.drools.workbench.jcr2vfsmigration.xml.model.Module(moduleType, jcrModule.getUuid(),
                moduleName, jcrModule.getLastContributor(), jcrModule.getCheckinComment(),
                jcrModule.getLastModified(), normalizedPackageName, packageHeaderInfo, sbGlobal.toString(),
                jcrModule.getCatRules(), assetExportFileName);
    }

    private boolean exportModuleAssets(Module jcrModule, String assetFileName) {
        Collection<XmlAsset> assets = new ArrayList<XmlAsset>(10);

        StringBuilder xml = new StringBuilder();
        PrintWriter pw;
        try {
            pw = fileManager.createAssetExportFileWriter(assetFileName);
        } catch (FileNotFoundException e) {
            logger.error("Can't find file for {}!", assetFileName, e);
            return false;
        }

        boolean hasMorePages = true;
        int startRowIndex = 0;
        final int pageSize = 100;
        PageResponse<AssetPageRow> response;
        while (hasMorePages) {
            AssetPageRequest request = new AssetPageRequest(jcrModule.getUuid(), null, // get all formats
                    null, startRowIndex, pageSize);
            String assetName = "";
            try {
                response = jcrRepositoryAssetService.findAssetPage(request);
                for (AssetPageRow row : response.getPageRowList()) {
                    AssetItem assetItemJCR = rulesRepository.loadAssetByUUID(row.getUuid());
                    assetName = assetItemJCR.getName();
                    boolean isDisabled = assetItemJCR.getDisabled();
                    if (isDisabled) {
                        logger.info("      Ignoring disabled asset [{}.{}].", assetItemJCR.getName(),
                                assetItemJCR.getFormat());
                    } else {
                        logger.info("      Exporting asset [{}.{}].", assetItemJCR.getName(),
                                assetItemJCR.getFormat());
                        //TODO: Git won't check in a version if the file is not changed in this version. Eg, the version 3 of "testFunction.function"
                        //We need to find a way to force a git check in. Otherwise migrated version history is not consistent with the version history in old Guvnor.

                        //Still need to migrate the "current version" even though in most cases the "current version" (actually it is not a version in version
                        //control, its just the current content on jcr node) is equal to the latest version that had been checked in.
                        //Eg, when we import mortgage example, we just dump the mortgage package to a jcr node, no version check in.
                        XmlAsset xmlAsset = export(ExportContext.create(jcrModule, assetItemJCR, assetFileName));
                        xmlAsset.setAssetHistory(
                                exportAssetHistory(ExportContext.create(jcrModule, row.getUuid(), assetFileName)));
                        assets.add(xmlAsset);
                    }
                }
            } catch (SerializationException e) {
                logger.error("SerializationException exporting asset {} from module {}!", assetName,
                        jcrModule.getName(), e);
                return false;
            } catch (Exception e) {
                logger.error("Exception exporting asset {} from module {}!", assetName, jcrModule.getName(), e);
                return false;
            }

            if (response.isLastPage()) {
                hasMorePages = false;
            } else {
                startRowIndex += pageSize;
            }
        }
        xmlAssetsFormat.format(xml, new XmlAssets(assets));
        pw.print(xml.toString());
        pw.close();
        return true;
    }

    private XmlAsset export(ExportContext exportContext) {
        String name = exportContext.getJcrAssetItem().getName();
        String format = exportContext.getJcrAssetItem().getFormat();

        if (AssetFormats.DRL_MODEL.equals(format)) {
            return factModelExporter.export(exportContext);

        } else if (AssetFormats.BUSINESS_RULE.equals(format)) {
            return guidedEditorExporter.export(exportContext);

        } else if (AssetFormats.DECISION_TABLE_GUIDED.equals(format)) {
            return guidedDecisionTableExporter.export(exportContext);

        } else if (AssetFormats.ENUMERATION.equals(format) || AssetFormats.DSL.equals(format)
                || AssetFormats.DSL_TEMPLATE_RULE.equals(format) || AssetFormats.RULE_TEMPLATE.equals(format)
                || AssetFormats.FORM_DEFINITION.equals(format) || AssetFormats.SPRING_CONTEXT.equals(format)
                || AssetFormats.SERVICE_CONFIG.equals(format) || AssetFormats.WORKITEM_DEFINITION.equals(format)
                || AssetFormats.CHANGE_SET.equals(format) || AssetFormats.RULE_FLOW_RF.equals(format)
                || AssetFormats.BPMN_PROCESS.equals(format) || AssetFormats.BPMN2_PROCESS.equals(format)
                || "ftl".equals(format) || "json".equals(format) || "fw".equals(format)) {
            return plainTextAssetExporter.export(exportContext);

        } else if (AssetFormats.DRL.equals(format) || AssetFormats.FUNCTION.equals(format)) {
            return plainTextAssetWithPackagePropertyExporter.export(exportContext);

        } else if (AssetFormats.DECISION_SPREADSHEET_XLS.equals(format)
                || AssetFormats.SCORECARD_SPREADSHEET_XLS.equals(format) || "png".equals(format)
                || "gif".equals(format) || "jpg".equals(format) || "pdf".equals(format) || "doc".equals(format)
                || "odt".equals(format)) {
            return attachmentAssetExporter.export(exportContext);

        } else if (AssetFormats.MODEL.equals(format)) {
            logger.warn(
                    "        POJO Model jar [{}] is not supported by export tool. Please add your POJO model jar to Guvnor manually.",
                    name);
            return new IgnoredAsset();
        } else if (AssetFormats.SCORECARD_GUIDED.equals(format)) {
            // No special treatment or attributes needed; use PlainTextAsset
            return plainTextAssetExporter.export(exportContext);

        } else if (AssetFormats.TEST_SCENARIO.equals(format)) {
            // No special treatment or attributes needed; use PlainTextAsset
            return plainTextAssetExporter.export(exportContext);

        } else if ("package".equals(format)) {
            return new IgnoredAsset();
        } else { //another format is migrated as a attachmentAsset
            logger.warn(
                    "        Asset [{}.{}] is not a known format by export tool. It will be exported as attachmentAsset",
                    name, format);
            return attachmentAssetExporter.export(exportContext);
        }
    }

    private XmlAssets exportAssetHistory(ExportContext historyContext) throws SerializationException {
        XmlAssets xmlAssets = new XmlAssets();

        //loadItemHistory wont return the current version
        String currentVersionAssetName = "";
        try {
            TableDataResult history = jcrRepositoryAssetService.loadItemHistory(historyContext.getAssetUUID());
            TableDataRow[] rows = history.data;
            Arrays.sort(rows, new Comparator<TableDataRow>() {
                public int compare(TableDataRow r1, TableDataRow r2) {
                    Integer v2 = Integer.valueOf(r2.values[0]);
                    Integer v1 = Integer.valueOf(r1.values[0]);

                    return v1.compareTo(v2);
                }
            });

            String historicalAssetExportFileName = "h_" + historyContext.getAssetExportFileName();
            for (TableDataRow row : rows) {
                AssetItem historicalAssetJCR = rulesRepository.loadAssetByUUID(row.id);
                currentVersionAssetName = historicalAssetJCR.getName();

                ExportContext historicalAssetExportContext = ExportContext.create(historyContext.getJcrModule(),
                        historicalAssetJCR, historicalAssetExportFileName);
                xmlAssets.addAsset(export(historicalAssetExportContext));

                logger.info("    Asset [{}.{}] migrated: version [{}], comment [{}], lastModified [{}]",
                        historicalAssetJCR.getName(), historicalAssetJCR.getFormat(),
                        historicalAssetJCR.getVersionNumber(), historicalAssetJCR.getCheckinComment(),
                        historicalAssetJCR.getLastModified().getTime());
            }
        } catch (RuntimeException e) {
            logger.error("Exception migrating assetHistory at version {} from module {}!", currentVersionAssetName,
                    historyContext.getJcrModule().getName());
        }
        return xmlAssets;
    }

    // Attempt creation of the asset export file firstly with the module's uuid. If this were null or the file could not
    // be successfully created, then try again with a shorter (i.e. simple number) name.
    private String setupAssetExportFile(String moduleUuid) {
        StringBuilder fileNameBuilder = new StringBuilder();
        boolean success = false;
        if (StringUtils.isNotBlank(moduleUuid)) {
            fileNameBuilder.insert(0, moduleUuid);
            success = fileManager.createAssetExportFile(fileNameBuilder.toString());
        }
        if (!success) {
            fileNameBuilder.replace(0, fileNameBuilder.lastIndexOf("."), Integer.toString(assetFileName++));
            success = fileManager.createAssetExportFile(fileNameBuilder.toString());
            if (!success) {
                logger.error("Module asset file could not be created");
                return null;
            }
        }
        return fileNameBuilder.toString();
    }
}