Java tutorial
/* * Copyright (c) 2013. Alexander Herwix * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * 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/>. * You can also obtain a commercial license. Contact: alex@herwix.com for further details. */ package com.iterranux.droolsjbpmCore.runtime.build.impl; import com.iterranux.droolsjbpmCore.internal.DroolsjbpmCoreUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.kie.api.KieServices; import org.kie.api.builder.KieBuilder; import org.kie.api.builder.KieFileSystem; import org.kie.api.builder.Message; import org.kie.api.builder.ReleaseId; import org.kie.api.io.KieResources; import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.core.io.support.ResourcePatternResolver; import javax.annotation.PostConstruct; import java.io.IOException; import java.net.URL; public class KieModuleBuilder { private static final Log log = LogFactory.getLog(KieModuleBuilder.class); public static final String KMODULE_ROOT_PATH = "src/main/resources/"; public static final String KMODULE_GROUP_ID = "org.grails.kieModules"; private KieServices kieServices; private KieResources kieResources; private DroolsjbpmCoreUtils droolsjbpmCoreUtils; private Boolean reloadActive; public KieModuleBuilder(KieServices ks) { kieServices = ks; kieResources = kieServices.getResources(); } /** * Builds all kmodules from grails plugins or the kmodule from the parent application that it can find on the classpath. * Kmodules are registered under the release id: * * org.grails.plugins : Plugin Name : Plugin Version * */ @PostConstruct public void buildKmodulesForGrailsModules() throws IOException { log.debug("Starting build of KieModules for grails modules"); //Find all kmodule.xml ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); String pattern = "/droolsjbpm/*/kmodule.xml"; org.springframework.core.io.Resource[] resources = resolver.getResources("classpath*:" + pattern); for (org.springframework.core.io.Resource kmoduleXml : resources) { if (!isTestResource(kmoduleXml.getURL())) { String moduleName = extractModuleNameFromKmoduleXmlUrl(kmoduleXml.getURL().toString()); buildKmoduleForGrailsModule(moduleName, kmoduleXml); } } log.debug("Finished build of KieModules for grails modules"); } public void buildKmoduleForGrailsModule(String moduleName, Resource kmoduleXml) throws IOException { //ReleaseId for this kmodule ReleaseId releaseId = droolsjbpmCoreUtils.getReleaseIdForGrailsModule(moduleName); //Only build kmodule for modules that exist if (releaseId != null) { log.debug("Found KieModule for: " + moduleName); org.springframework.core.io.Resource[] moduleResources = getGrailsModuleResources(moduleName); KieFileSystem kfs = kieServices.newKieFileSystem(); for (org.springframework.core.io.Resource moduleResource : moduleResources) { URL moduleResourceURL = moduleResource.getURL(); if (!isTestResource(moduleResourceURL) && !isFolder(moduleResourceURL)) { if (log.isDebugEnabled()) log.debug("Resources found for '" + moduleName + "': " + moduleResourceURL); org.kie.api.io.Resource kieResource = kieResources.newUrlResource(moduleResourceURL); kfs.write(getKmodulePathForResourceUrlAndModuleName(moduleResourceURL.toString(), moduleName), kieResource); } } //Generate Basic POM kfs.generateAndWritePomXML(releaseId); //Add Kmodule.xml kfs.writeKModuleXML(IOUtils.toByteArray(kmoduleXml.getInputStream())); //Builder for the KieModule from the kfs, also possible from folder KieBuilder kbuilder = kieServices.newKieBuilder(kfs); //Build KieModule and automatically deploy to kieRepo if successful kbuilder.buildAll(); //Throw RuntimeException if build failed if (kbuilder.getResults().hasMessages(Message.Level.ERROR)) { throw new RuntimeException("Error: \n" + kbuilder.getResults().toString()); } } else { log.error("Error: There was an attempt to build a KieModule for a plugin or application named '" + moduleName + "' which doesn't exist.\n" + " Please check that your KieModule directory structure is setup as intended:\n\n" + " 1) Save any resources you might have in the 'grails-app/conf/droolsjbpm' to a secure location\n" + " 2) Delete anything in the 'grails-app/conf/droolsjbpm' folder except the 'data' directory\n" + " 3) Use the grails command 'droolsjbpm --init-kmodule' to set up a correct folder structure\n\n" + " If the error still persists please file a bug report."); } } public void buildKmoduleForGrailsModule(String moduleName) { Resource kmoduleXml = new FileSystemResource("grails-app/conf/droolsjbpm/" + moduleName + "/kmodule.xml"); if (kmoduleXml.exists()) { try { buildKmoduleForGrailsModule(moduleName, kmoduleXml); } catch (IOException e) { log.error("Error: KieModule build for '" + moduleName + "' failed", e); } } else { log.error("Error: KieModule build for '" + moduleName + "' was tried, but no kmodule.xml could be found."); } } protected Resource[] getGrailsModuleResources(String moduleName) throws IOException { ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); org.springframework.core.io.Resource[] moduleResources; if (moduleName.equals(droolsjbpmCoreUtils.getApplicationNameAsPropertyName()) && reloadActive) { moduleResources = resolver .getResources("file:grails-app/conf/droolsjbpm/" + moduleName + "/resources/**"); } else { moduleResources = resolver.getResources("classpath*:/droolsjbpm/" + moduleName + "/resources/**"); } return moduleResources; } /** * Simple Method to check if resource is duplicated in target/test-classes on classpath which happens during testing. * WARNING: This also excludes non test files if there path somehow contains '/target/test-classes/' which is unlikely. * * @param resourceURL * @return Boolean */ protected Boolean isTestResource(URL resourceURL) { return resourceURL.toString().contains("/target/test-classes/"); } /** * Simple Method to check if resource is folder. (Checks if last char of URL is /) * * @param resourceURL * @return Boolean */ protected Boolean isFolder(URL resourceURL) { return resourceURL.toString().endsWith("/"); } /** * Trims the URL to the moduleName. * Expected URL format: abc/xyz/droolsjbpm/moduleName/kmodule.xml * * @param url of the kmodule.xml file on the classpath * @return moduleName */ protected String extractModuleNameFromKmoduleXmlUrl(String url) { url = url.substring(0, url.length() - 12); return url.substring(url.lastIndexOf("/") + 1); } /** * Creates the correct path for the referenced resource inside the kmodule. * * @param url of the resource * @param moduleName the resource resides in * @return path inside the kmodule */ protected String getKmodulePathForResourceUrlAndModuleName(String url, String moduleName) { String pattern = "/droolsjbpm/" + moduleName + "/resources/"; int index = url.indexOf(pattern); if (index == -1) { throw new IllegalArgumentException("The provided url had an unexpected format: '/droolsjbpm/" + moduleName + "/resources/' couldn't be identified"); } url = url.substring(index + pattern.length()); return KMODULE_ROOT_PATH + url; } public void setKieServices(KieServices kieServices) { this.kieServices = kieServices; } public void setKieResources(KieResources kieResources) { this.kieResources = kieResources; } public void setDroolsjbpmCoreUtils(DroolsjbpmCoreUtils droolsjbpmCoreUtils) { this.droolsjbpmCoreUtils = droolsjbpmCoreUtils; } public void setReloadActive(Boolean reloadActive) { this.reloadActive = reloadActive; } }