/* * 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.vfsImport; import java.io.File; import java.io.IOException; import java.util.Iterator; import java.util.Map; import java.util.Set; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import javax.inject.Named; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.drools.workbench.jcr2vfsmigration.common.FileManager; import org.drools.workbench.jcr2vfsmigration.util.MigrationPathManager; import org.drools.workbench.jcr2vfsmigration.util.PackageImportHelper; import org.drools.workbench.jcr2vfsmigration.vfsImport.asset.AttachmentAssetImporter; import org.drools.workbench.jcr2vfsmigration.vfsImport.asset.FactModelImporter; import org.drools.workbench.jcr2vfsmigration.vfsImport.asset.GuidedDecisionTableImporter; import org.drools.workbench.jcr2vfsmigration.vfsImport.asset.GuidedEditorImporter; import org.drools.workbench.jcr2vfsmigration.vfsImport.asset.GuidedScoreCardImporter; import org.drools.workbench.jcr2vfsmigration.vfsImport.asset.PlainTextAssetImporter; import org.drools.workbench.jcr2vfsmigration.vfsImport.asset.PlainTextAssetWithPackagePropertyImporter; import org.drools.workbench.jcr2vfsmigration.vfsImport.asset.TestScenarioImporter; import org.drools.workbench.jcr2vfsmigration.xml.format.ModulesXmlFormat; import org.drools.workbench.jcr2vfsmigration.xml.format.XmlAssetsFormat; import org.drools.workbench.jcr2vfsmigration.xml.model.Module; import org.drools.workbench.jcr2vfsmigration.xml.model.Modules; import org.drools.workbench.jcr2vfsmigration.xml.model.asset.AttachmentAsset; import org.drools.workbench.jcr2vfsmigration.xml.model.asset.BusinessRuleAsset; import org.drools.workbench.jcr2vfsmigration.xml.model.asset.DataModelAsset; import org.drools.workbench.jcr2vfsmigration.xml.model.asset.GuidedDecisionTableAsset; import org.drools.workbench.jcr2vfsmigration.xml.model.asset.PlainTextAsset; import org.drools.workbench.jcr2vfsmigration.xml.model.asset.XmlAsset; import org.drools.workbench.jcr2vfsmigration.xml.model.asset.XmlAssets; import org.guvnor.common.services.project.model.GAV; import org.guvnor.common.services.project.model.MavenRepositoryMetadata; import org.guvnor.common.services.project.model.POM; import org.guvnor.common.services.project.service.GAVAlreadyExistsException; import org.kie.workbench.common.services.shared.project.KieProjectService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.backend.server.util.Paths; import org.uberfire.backend.vfs.Path; import org.uberfire.io.IOService; import org.uberfire.java.nio.base.options.CommentedOption; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; @ApplicationScoped public class ModuleAssetImporter { private static final Logger logger = LoggerFactory.getLogger(ModuleAssetImporter.class); @Inject private Paths paths; @Inject private FileManager fileManager; @Inject private MigrationPathManager migrationPathManager; @Inject private PackageImportHelper packageImportHelper; @Inject @Named("ioStrategy") private IOService ioService; @Inject private FactModelImporter factModelImporter; @Inject private KieProjectService projectService; @Inject private PlainTextAssetImporter plainTextAssetImporter; @Inject private PlainTextAssetWithPackagePropertyImporter plainTextAssetWithPackagePropertyImporter; @Inject private GuidedScoreCardImporter guidedScoreCardImporter; @Inject private GuidedEditorImporter guidedEditorImporter; @Inject private GuidedDecisionTableImporter guidedDecisionTableImporter; @Inject private TestScenarioImporter testScenarioImporter; @Inject private AttachmentAssetImporter attachmentAssetImporter; private ModulesXmlFormat modulesXmlFormat = new ModulesXmlFormat(); private XmlAssetsFormat xmlAssetsFormat = new XmlAssetsFormat(); public void importAll() { logger.info( " Module import started" ); Document xml; try { File modulesXmlFile = fileManager.getModulesExportFile(); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); xml = db.parse( modulesXmlFile ); NodeList children = xml.getChildNodes(); if ( children.getLength() > 1 ) { throw new Exception( "Wrong modules.xml format" ); } Modules modules = modulesXmlFormat.parse( children.item( 0 ) ); // import 'normal' modules for ( Iterator<Module> moduleIterator = modules.getModules().iterator(); moduleIterator.hasNext(); ) { importModule( moduleIterator.next() ); } // import 'global' module importModule( modules.getGlobalModule() ); } catch ( Exception e ) { e.printStackTrace(); } logger.info( " Module import ended" ); } private void importModule( Module module ) { logger.info(" Importing module [{}] (UUID={})", module.getName(), module.getUuid()); //Set up project structure: String normalizedModuleName = module.getNormalizedPackageName(); String[] nameSplit = normalizedModuleName.split( "\\." ); StringBuilder groupIdBuilder = new StringBuilder(); groupIdBuilder.append( nameSplit[ 0 ] ); for ( int i = 1; i < nameSplit.length - 1; i++ ) { groupIdBuilder.append( "." ); groupIdBuilder.append( nameSplit[ i ] ); } String groupId = groupIdBuilder.toString(); String artifactId = nameSplit[ nameSplit.length - 1 ]; GAV gav = new GAV( groupId, artifactId, "0.0.1" ); POM pom = new POM( gav ); pom.setName( normalizedModuleName ); Path modulePath = migrationPathManager.generateRootPath(); try { projectService.newProject( modulePath, pom, "http://localhost" ); } catch ( GAVAlreadyExistsException gae ) { logger.warn( "Project's GAV [{}] already exists at [{}]!", pom.getGav(), toString( gae.getRepositories() ), gae ); } try { importAssets( module ); } catch ( Exception e ) { // just log the error and continue importing the rest // it is better to try to import as many things as possible, instead of failing fast directly logger.error("Exception while importing assets for module '{}'.", module.getName(), e); } // Import globals String globals = module.getGlobalsString(); if ( globals == null || "".equals( globals ) ) { return; } Path path = migrationPathManager.generatePathForGlobal( module ); final org.uberfire.java.nio.file.Path nioPath = paths.convert( path ); String contentWithImport = packageImportHelper.assertPackageImportDRL( globals, module.getPackageHeaderInfo(), path ); String contentWithPackage = packageImportHelper.assertPackageName( contentWithImport, null ); ioService.write( nioPath, contentWithPackage, (Map<String, ?>) null, // cast is for disambiguation new CommentedOption( module.getLastContributor(), null, module.getCheckinComment(), module.getLastModified() ) ); } private String toString( final Set<MavenRepositoryMetadata> repositories ) { final StringBuilder sb = new StringBuilder(); for ( MavenRepositoryMetadata md : repositories ) { sb.append( md.getId() ).append( " : " ).append( md.getUrl() ).append( " : " ).append( md.getSource() ).append( ", " ); } sb.delete( sb.length() - 2, sb.length() - 1 ); return sb.toString(); } private void importAssets( Module module ) throws IOException, SAXException, ParserConfigurationException { Document xml; File assetsXmlFile = fileManager.getAssetExportFile(module.getAssetExportFileName()); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); xml = db.parse(assetsXmlFile); NodeList rootNodeList = xml.getChildNodes(); if (rootNodeList.getLength() > 1) { throw new RuntimeException("Wrong asset file XML format!"); } Node assetsNode = rootNodeList.item(0); XmlAssets xmlAssets = xmlAssetsFormat.parse(assetsNode); for (XmlAsset xmlAsset : xmlAssets.getAssets()) { if (xmlAsset == null) { logger.warn(" Skipping null asset during import."); continue; } logger.info(" Importing asset [{}.{}].", xmlAsset.getName(), xmlAsset.getAssetType()); try { importAssetHistory(module, xmlAsset); importAsset(module, xmlAsset, null); } catch (Exception e) { // just log error and continue importing the rest of the assets // it is better to at least try to import the rest as there is a high chance that the other assets // will be imported successfully logger.error("Exception while importing asset [{}.{}].", xmlAsset.getName(), xmlAsset.getAssetType(), e); } } } private Path importAsset( Module module, XmlAsset xmlAsset, Path previousVersionPath ) { switch ( xmlAsset.getAssetType() ) { case DRL_MODEL: return factModelImporter.importAsset( module, (DataModelAsset) xmlAsset, previousVersionPath ); case ENUMERATION: case DSL: case DSL_TEMPLATE_RULE: case RULE_TEMPLATE: case FORM_DEFINITION: case SPRING_CONTEXT: case SERVICE_CONFIG: case WORKITEM_DEFINITION: case CHANGE_SET: case RULE_FLOW_RF: case BPMN_PROCESS: case BPMN2_PROCESS: case FTL: case JSON: case FW: return plainTextAssetImporter.importAsset( module, (PlainTextAsset) xmlAsset, previousVersionPath ); case DRL: case FUNCTION: return plainTextAssetWithPackagePropertyImporter.importAsset( module, (PlainTextAsset) xmlAsset, previousVersionPath ); case DECISION_SPREADSHEET_XLS: case SCORECARD_SPREADSHEET_XLS: case PNG: case GIF: case JPG: case PDF: case DOC: case ODT: return attachmentAssetImporter.importAsset( module, (AttachmentAsset) xmlAsset, previousVersionPath ); case SCORECARD_GUIDED: return guidedScoreCardImporter.importAsset( module, (PlainTextAsset) xmlAsset, previousVersionPath ); case BUSINESS_RULE: return guidedEditorImporter.importAsset( module, (BusinessRuleAsset) xmlAsset, previousVersionPath ); case DECISION_TABLE_GUIDED: return guidedDecisionTableImporter.importAsset( module, (GuidedDecisionTableAsset) xmlAsset, previousVersionPath ); case TEST_SCENARIO: return testScenarioImporter.importAsset( module, (PlainTextAsset) xmlAsset, previousVersionPath ); case UNSUPPORTED: default: return attachmentAssetImporter.importAsset( module, (AttachmentAsset) xmlAsset, previousVersionPath ); } } private void importAssetHistory( Module module, XmlAsset xmlAsset ) { Path previousVersionPath = null; XmlAssets history = xmlAsset.getAssetHistory(); if ( history == null || history.getAssets().size() == 0 ) { return; } for ( XmlAsset hAsset : history.getAssets() ) { previousVersionPath = importAsset( module, hAsset, previousVersionPath ); } } }