Java tutorial
/* * Copyright 2015 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. * * 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.jbpm.designer.web.preprocessing.impl; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.io.Writer; import java.net.URLEncoder; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Scanner; import java.util.Set; import java.util.TreeMap; import javax.servlet.ServletContext; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.codec.binary.Base64; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.drools.core.process.core.ParameterDefinition; import org.drools.core.process.core.datatype.DataType; import org.drools.core.process.core.impl.ParameterDefinitionImpl; import org.drools.core.util.MVELSafeHelper; import org.jbpm.designer.repository.Asset; import org.jbpm.designer.repository.AssetBuilderFactory; import org.jbpm.designer.repository.Repository; import org.jbpm.designer.repository.UriUtils; import org.jbpm.designer.repository.filters.FilterByExtension; import org.jbpm.designer.repository.filters.FilterByFileName; import org.jbpm.designer.repository.impl.AssetBuilder; import org.jbpm.designer.repository.vfs.RepositoryDescriptor; import org.jbpm.designer.util.ConfigurationProvider; import org.jbpm.designer.util.Utils; import org.jbpm.designer.web.preprocessing.IDiagramPreprocessingUnit; import org.jbpm.designer.web.profile.IDiagramProfile; import org.jbpm.process.workitem.WorkDefinitionImpl; import org.json.JSONArray; import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.stringtemplate.v4.ST; import org.uberfire.backend.vfs.Path; import org.uberfire.backend.vfs.VFSService; import org.uberfire.io.IOService; import org.uberfire.java.nio.file.FileSystem; import org.uberfire.java.nio.file.NoSuchFileException; /** * JbpmPreprocessingUnit - preprocessing unit for the jbpm profile * * @author Tihomir Surdilovic */ public class JbpmPreprocessingUnit implements IDiagramPreprocessingUnit { private static final Logger _logger = LoggerFactory.getLogger(JbpmPreprocessingUnit.class); public static final String STENCILSET_PATH = "stencilsets"; public static final String WORKITEM_DEFINITION_EXT = "wid"; public static final String THEME_NAME = "themes"; public static final String THEME_EXT = ".json"; public static final String PATTERNS_NAME = "patterns"; public static final String PATTERNS_EXT = ".json"; public static final String DEFAULT_THEME_NAME = "jBPM"; public static final String CUSTOMEDITORS_NAME = "customeditors"; public static final String PROCESSDICTIONARY_NAME = "processdictionary"; public static final String CUSTOMEDITORS_EXT = ".json"; public static final String THEME_COOKIE_NAME = "designercolortheme"; public static final String DEFAULT_CATEGORY_NAME = "Service Tasks"; public static final String INCLUDE_DATA_OBJECT = "designerdataobjects"; private String designer_path; private String stencilPath; private String origStencilFilePath; private String stencilFilePath; private String outData = ""; private String workitemSVGFilePath; private String origWorkitemSVGFile; private String default_emailicon; private String default_logicon; private String default_servicenodeicon; private String default_widconfigtemplate; private String defaultClasspathWid = "META-INF/WorkDefinitions.wid"; private String themeInfo; private String formWidgetsDir; private String customEditorsInfo; private String patternsData; private String sampleBpmn2; private String globalDir; private VFSService vfsService; private boolean includeDataObjects; public JbpmPreprocessingUnit(ServletContext servletContext, VFSService vfsService) { this(servletContext, ConfigurationProvider.getInstance().getDesignerContext(), vfsService); } public JbpmPreprocessingUnit(ServletContext servletContext, String designerPath, VFSService vfsService) { this.designer_path = designerPath.substring(0, designerPath.length() - 1); this.vfsService = vfsService; stencilPath = servletContext.getRealPath(designer_path + "/" + STENCILSET_PATH); origStencilFilePath = stencilPath + "/bpmn2.0jbpm/stencildata/" + "bpmn2.0jbpm.orig"; stencilFilePath = stencilPath + "/bpmn2.0jbpm/" + "bpmn2.0jbpm.json"; workitemSVGFilePath = stencilPath + "/bpmn2.0jbpm/view/activity/workitems/"; origWorkitemSVGFile = workitemSVGFilePath + "workitem.orig"; default_emailicon = servletContext.getRealPath(designer_path + "/defaults/defaultemailicon.gif"); default_logicon = servletContext.getRealPath(designer_path + "/defaults/defaultlogicon.gif"); default_servicenodeicon = servletContext .getRealPath(designer_path + "/defaults/defaultservicenodeicon.png"); default_widconfigtemplate = servletContext.getRealPath(designer_path + "/defaults/WorkDefinitions.wid.st"); themeInfo = servletContext.getRealPath(designer_path + "/defaults/themes.json"); formWidgetsDir = servletContext.getRealPath(designer_path + "/defaults/formwidgets"); customEditorsInfo = servletContext.getRealPath(designer_path + "/defaults/customeditors.json"); patternsData = servletContext.getRealPath(designer_path + "/defaults/patterns.json"); sampleBpmn2 = servletContext.getRealPath(designer_path + "/defaults/SampleProcess.bpmn2"); includeDataObjects = Boolean.parseBoolean( System.getProperty(INCLUDE_DATA_OBJECT) == null ? "true" : System.getProperty(INCLUDE_DATA_OBJECT)); } public String getOutData() { if (outData != null && outData.length() > 0) { if (outData.endsWith(",")) { outData = outData.substring(0, outData.length() - 1); } } return outData; } public void preprocess(HttpServletRequest req, HttpServletResponse res, IDiagramProfile profile, ServletContext serlvetContext, boolean readOnly, boolean viewLocked, IOService ioService, RepositoryDescriptor descriptor) { try { if (readOnly) { _logger.info("Performing preprocessing steps in readonly mode."); ST workItemTemplate = new ST(readFile(origStencilFilePath), '$', '$'); workItemTemplate.add("bopen", "{"); workItemTemplate.add("bclose", "}"); workItemTemplate.add("patternData", new HashMap<String, PatternInfo>()); workItemTemplate.add("packageName", "org.jbpm"); workItemTemplate.add("processn", ""); workItemTemplate.add("processid", ""); workItemTemplate.add("pversion", "1.0"); String readOnlyIconEncoded = "data:image/png;base64,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"; Map<String, WorkDefinitionImpl> workDefinitions = new HashMap<String, WorkDefinitionImpl>(); WorkDefinitionImpl readOnlyImpl = new WorkDefinitionImpl(); readOnlyImpl.setName("ReadOnlyService"); readOnlyImpl.setDisplayName("ReadOnlyService"); readOnlyImpl.setCategory("Service Tasks"); readOnlyImpl.setIcon("/global/defaultservicenodeicon.png"); readOnlyImpl.setIconEncoded(URLEncoder.encode(readOnlyIconEncoded, "UTF-8")); readOnlyImpl.setCustomEditor(""); workDefinitions.put("ReadOnlyService", readOnlyImpl); workItemTemplate.add("workitemDefs", workDefinitions); Map<String, ThemeInfo> themeData = setupThemesForReadOnly(req); workItemTemplate.add("colortheme", themeData); deletefile(stencilFilePath); createAndWriteToFile(stencilFilePath, workItemTemplate.render()); createAndParseViewSVGForReadOnly(workDefinitions, readOnlyIconEncoded); return; } if (ioService != null) { ioService.startBatch(new FileSystem[] { descriptor.getFileSystem() }); } Repository repository = profile.getRepository(); String uuid = Utils.getUUID(req); //createAssetIfNotExisting(repository, "/defaultPackage", "BPMN2-SampleProcess", "bpmn2", getBytesFromFile(new File(sampleBpmn2))); Asset<String> asset = repository.loadAsset(uuid); this.globalDir = profile.getRepositoryGlobalDir(uuid); outData = ""; Map<String, ThemeInfo> themeData = setupThemes(req, repository, profile); setupCustomEditors(repository, profile); setupFormWidgets(repository, profile); setupDefaultIcons(globalDir, repository); setupDefaultWorkflowPatterns(globalDir, repository); // figure out which package our uuid belongs in and get back the list of configs Collection<Asset> workitemConfigInfo = findWorkitemInfoForUUID(asset.getAssetLocation(), repository); // also get all from globals package Collection<Asset> globalWorkitemConfigInfo = findWorkitemInfoForUUID(globalDir, repository); if (workitemConfigInfo != null) { if (globalWorkitemConfigInfo != null) { workitemConfigInfo.addAll(globalWorkitemConfigInfo); } } else { workitemConfigInfo = globalWorkitemConfigInfo; } if (workitemConfigInfo == null || workitemConfigInfo.size() < 1) { setupDefaultWorkitemConfigs(asset.getAssetLocation(), repository); workitemConfigInfo = findWorkitemInfoForUUID(asset.getAssetLocation(), repository); } // get the contents of each of the configs Collection<Asset> workItemsContent = getWorkitemConfigContent(workitemConfigInfo, repository); // evaluate all configs Map<String, WorkDefinitionImpl> workDefinitions = new HashMap<String, WorkDefinitionImpl>(); for (Asset entry : workItemsContent) { try { evaluateWorkDefinitions(workDefinitions, entry, asset.getAssetLocation(), repository, profile); } catch (Exception e) { _logger.error("Unable to parse a workitem definition: " + e.getMessage()); } } // sort against display name WorkItemDisplayNameComparator wiComparator = new WorkItemDisplayNameComparator(workDefinitions); Map<String, WorkDefinitionImpl> workDefinitionsTree = new TreeMap<String, WorkDefinitionImpl>( wiComparator); workDefinitionsTree.putAll(workDefinitions); // set the out parameter for (Map.Entry<String, WorkDefinitionImpl> definition : workDefinitionsTree.entrySet()) { outData += definition.getValue().getName() + ","; } // parse the profile json to include config data // parse patterns data JSONArray patternsArray = new JSONArray(findWorkflowPatterns(repository).getAssetContent()); Map<String, PatternInfo> patternInfoMap = new HashMap<String, PatternInfo>(); for (int i = 0; i < patternsArray.length(); i++) { JSONObject patternObj = patternsArray.getJSONObject(i); PatternInfo pi = new PatternInfo(patternObj.getString("id"), patternObj.getString("name"), patternObj.getString("description")); patternInfoMap.put(patternObj.getString("id"), pi); } // parse the orig stencil data with workitem definitions ST workItemTemplate = new ST(readFile(origStencilFilePath), '$', '$'); workItemTemplate.add("bopen", "{"); workItemTemplate.add("bclose", "}"); workItemTemplate.add("workitemDefs", workDefinitionsTree); workItemTemplate.add("patternData", patternInfoMap); workItemTemplate.add("includedo", includeDataObjects); String processPackage = asset.getAssetLocation(); if (processPackage.startsWith("/")) { processPackage = processPackage.substring(1, processPackage.length()); } processPackage = processPackage.replaceAll("/", "."); // final check in odd cases if (processPackage.startsWith(".")) { processPackage = processPackage.substring(1, processPackage.length()); } // set package to org.jbpm workItemTemplate.add("packageName", "org.jbpm"); String processName = asset.getName(); workItemTemplate.add("processn", processName); String packageNameStr = (processPackage.length() > 0) ? processPackage + "." : ""; if (packageNameStr.length() > 0) { String[] packageNameParts = packageNameStr.split("\\."); packageNameStr = packageNameParts[0] + "."; } // default the process id to packagename.processName String processIdString = packageNameStr + processName; if (processIdString.startsWith(".")) { processIdString = processIdString.substring(1, processIdString.length()); } workItemTemplate.add("processid", processIdString); // default version to 1.0 workItemTemplate.add("pversion", "1.0"); // color theme attribute workItemTemplate.add("colortheme", themeData); // delete stencil data json if exists deletefile(stencilFilePath); // copy our results as the stencil json data createAndWriteToFile(stencilFilePath, workItemTemplate.render()); // create and parse the view svg to include config data createAndParseViewSVG(workDefinitionsTree, repository); } catch (Exception e) { _logger.error(e.getMessage()); } catch (Throwable e) { _logger.error(e.getMessage()); } finally { try { if (!readOnly && ioService != null) { ioService.endBatch(); } } catch (Exception ee) { _logger.debug("Error ending batch: " + ee.getMessage()); } } } @SuppressWarnings("unchecked") private void createAndParseViewSVGForReadOnly(Map<String, WorkDefinitionImpl> workDefinitions, String iconBase64) { try { for (Map.Entry<String, WorkDefinitionImpl> definition : workDefinitions.entrySet()) { ST workItemTemplate = new ST(readFile(origWorkitemSVGFile), '$', '$'); workItemTemplate.add("workitemDef", definition.getValue()); String widIcon = definition.getValue().getIcon(); String iconEncoded = iconBase64; workItemTemplate.add("nodeicon", iconEncoded); String fileToWrite = workitemSVGFilePath + definition.getValue().getName() + ".svg"; createAndWriteToFile(fileToWrite, workItemTemplate.render()); } } catch (Exception e) { _logger.error("Failed to setup workitem svg images: " + e.getMessage()); } } @SuppressWarnings("unchecked") private void createAndParseViewSVG(Map<String, WorkDefinitionImpl> workDefinitions, Repository repository) { // first delete all existing workitem svgs Collection<File> workitemsvgs = FileUtils.listFiles(new File(workitemSVGFilePath), new String[] { "svg" }, true); if (workitemsvgs != null) { for (File wisvg : workitemsvgs) { deletefile(wisvg); } } try { for (Map.Entry<String, WorkDefinitionImpl> definition : workDefinitions.entrySet()) { ST workItemTemplate = new ST(readFile(origWorkitemSVGFile), '$', '$'); workItemTemplate.add("workitemDef", definition.getValue()); String widIcon = definition.getValue().getIcon(); Asset<byte[]> iconAsset = repository.loadAssetFromPath(widIcon); String iconEncoded = "data:image/png;base64," + javax.xml.bind.DatatypeConverter.printBase64Binary(iconAsset.getAssetContent()); workItemTemplate.add("nodeicon", iconEncoded); String fileToWrite = workitemSVGFilePath + definition.getValue().getName() + ".svg"; createAndWriteToFile(fileToWrite, workItemTemplate.render()); } } catch (Exception e) { _logger.error("Failed to setup workitem svg images: " + e.getMessage()); } } @SuppressWarnings({ "unchecked", "rawtypes" }) private void evaluateWorkDefinitions(Map<String, WorkDefinitionImpl> workDefinitions, Asset<String> widAsset, String assetLocation, Repository repository, IDiagramProfile profile) throws Exception { List<Map<String, Object>> workDefinitionsMaps; try { workDefinitionsMaps = (List<Map<String, Object>>) MVELSafeHelper.getEvaluator() .eval(widAsset.getAssetContent(), new HashMap()); } catch (Exception e) { throw new Exception(e.getMessage()); } for (Map<String, Object> workDefinitionMap : workDefinitionsMaps) { if (workDefinitionMap != null) { WorkDefinitionImpl workDefinition = new WorkDefinitionImpl(); workDefinition.setName(((String) workDefinitionMap.get("name")).replaceAll("\\s", "")); workDefinition.setDisplayName((String) workDefinitionMap.get("displayName")); String category = (String) workDefinitionMap.get("category"); if (category == null || category.length() < 1) { category = DEFAULT_CATEGORY_NAME; } workDefinition.setCategory(category); String icon = (String) workDefinitionMap.get("icon"); if (icon == null) { icon = this.globalDir + "/defaultservicenodeicon.png"; } Asset<byte[]> iconAsset = null; boolean iconFound = false; // Look for icon located relative to the asset String absoluteIcon = createAbsoluteIconPath(assetLocation, icon); if (repository.assetExists(absoluteIcon)) { icon = absoluteIcon; iconFound = true; } // Icon not found relative to asset, look for it relative to globalDir if (!iconFound) { if (!icon.startsWith(this.globalDir)) { if (icon.startsWith("/")) { icon = this.globalDir + icon; } else { icon = this.globalDir + "/" + icon; } } } try { if (!repository.assetExists(icon)) { icon = this.globalDir + "/defaultservicenodeicon.png"; } } catch (Exception e) { _logger.error(e.getMessage()); icon = this.globalDir + "/defaultservicenodeicon.png"; } iconAsset = repository.loadAssetFromPath(icon); workDefinition.setIcon(icon); String iconEncoded = "data:image/png;base64," + javax.xml.bind.DatatypeConverter.printBase64Binary(iconAsset.getAssetContent()); workDefinition.setIconEncoded(URLEncoder.encode(iconEncoded, "UTF-8")); if (workDefinitionMap.get("customEditor") != null) { workDefinition.setCustomEditor((String) workDefinitionMap.get("customEditor")); } Set<ParameterDefinition> parameters = new HashSet<ParameterDefinition>(); if (workDefinitionMap.get("parameters") != null) { Map<String, DataType> parameterMap = (Map<String, DataType>) workDefinitionMap .get("parameters"); if (parameterMap != null) { for (Map.Entry<String, DataType> entry : parameterMap.entrySet()) { parameters.add(new ParameterDefinitionImpl(entry.getKey(), entry.getValue())); } } workDefinition.setParameters(parameters); } if (workDefinitionMap.get("results") != null) { Set<ParameterDefinition> results = new HashSet<ParameterDefinition>(); Map<String, DataType> resultMap = (Map<String, DataType>) workDefinitionMap.get("results"); if (resultMap != null) { for (Map.Entry<String, DataType> entry : resultMap.entrySet()) { results.add(new ParameterDefinitionImpl(entry.getKey(), entry.getValue())); } } workDefinition.setResults(results); } if (workDefinitionMap.get("defaultHandler") != null) { workDefinition.setDefaultHandler((String) workDefinitionMap.get("defaultHandler")); } if (workDefinitionMap.get("dependencies") != null) { workDefinition.setDependencies( ((List<String>) workDefinitionMap.get("dependencies")).toArray(new String[0])); } workDefinitions.put(workDefinition.getName(), workDefinition); } } } private Collection<Asset> getWorkitemConfigContent(Collection<Asset> widAssets, Repository repository) { List<Asset> loadedAssets = new ArrayList<Asset>(); for (Asset widAsset : widAssets) { try { Asset assetWithContent = repository.loadAsset(widAsset.getUniqueId()); loadedAssets.add(assetWithContent); } catch (NoSuchFileException e) { _logger.error("Asset " + widAsset.getName() + " not found"); } } return loadedAssets; } private void setupFormWidgets(Repository repository, IDiagramProfile profile) { File[] allFormWidgets = new File(formWidgetsDir).listFiles(); for (File formWidget : allFormWidgets) { try { int extPosition = formWidget.getName().lastIndexOf("."); String extension = formWidget.getName().substring(extPosition + 1); String name = formWidget.getName().substring(0, extPosition); createAssetIfNotExisting(repository, this.globalDir, name, extension, getBytesFromFile(formWidget)); } catch (Exception e) { _logger.error("Error setting up form widgets: " + e.getMessage()); } } } private void setupCustomEditors(Repository repository, IDiagramProfile profile) { try { createAssetIfNotExisting(repository, this.globalDir, CUSTOMEDITORS_NAME, "json", getBytesFromFile(new File(customEditorsInfo))); } catch (Exception e) { _logger.error(e.getMessage()); } } private Map<String, ThemeInfo> setupThemesForReadOnly(HttpServletRequest req) { Map<String, ThemeInfo> themeData = new HashMap<String, ThemeInfo>(); try { String themesStr = readFile(themeInfo); JSONObject themesObject = new JSONObject(themesStr); // extract theme info from json JSONObject themes = (JSONObject) themesObject.get("themes"); JSONObject selectedTheme = (JSONObject) themes.get("jBPM"); for (String key : JSONObject.getNames(selectedTheme)) { String val = (String) selectedTheme.get(key); String[] valParts = val.split("\\|\\s*"); ThemeInfo ti; if (valParts.length == 3) { ti = new ThemeInfo(valParts[0], valParts[1], valParts[2]); } else { ti = new ThemeInfo("#000000", "#000000", "#000000"); } themeData.put(key, ti); } return themeData; } catch (Exception e) { e.printStackTrace(); // we dont want to barf..just log that error happened _logger.error(e.getMessage()); return themeData; } } private Map<String, ThemeInfo> setupThemes(HttpServletRequest req, Repository repository, IDiagramProfile profile) { Map<String, ThemeInfo> themeData = new HashMap<String, ThemeInfo>(); Asset<String> themeAsset = null; try { boolean themeExists = repository.assetExists(this.globalDir + "/" + THEME_NAME + THEME_EXT); if (!themeExists) { // create theme asset AssetBuilder assetBuilder = AssetBuilderFactory.getAssetBuilder(Asset.AssetType.Text); assetBuilder.content(new String(getBytesFromFile(new File(themeInfo)), "UTF-8")) .location(this.globalDir).name(THEME_NAME).type("json").version("1.0"); themeAsset = assetBuilder.getAsset(); repository.createAsset(themeAsset); } else { themeAsset = repository.loadAssetFromPath(this.globalDir + "/" + THEME_NAME + THEME_EXT); } String themesStr = themeAsset.getAssetContent(); JSONObject themesObject = new JSONObject(themesStr); // get the theme name from cookie if exists or default String themeName = DEFAULT_THEME_NAME; Cookie[] cookies = req.getCookies(); if (cookies != null) { for (Cookie ck : cookies) { if (ck.getName().equals(THEME_COOKIE_NAME)) { themeName = ck.getValue(); } } } // extract theme info from json JSONObject themes = (JSONObject) themesObject.get("themes"); JSONObject selectedTheme = (JSONObject) themes.get(themeName); for (String key : JSONObject.getNames(selectedTheme)) { String val = (String) selectedTheme.get(key); String[] valParts = val.split("\\|\\s*"); ThemeInfo ti; if (valParts.length == 3) { ti = new ThemeInfo(valParts[0], valParts[1], valParts[2]); } else { ti = new ThemeInfo("#000000", "#000000", "#000000"); } themeData.put(key, ti); } return themeData; } catch (Exception e) { e.printStackTrace(); // we dont want to barf..just log that error happened _logger.error(e.getMessage()); return themeData; } } private void setupDefaultIcons(String location, Repository repository) { try { createAssetIfNotExisting(repository, location, "defaultemailicon", "gif", getBytesFromFile(new File(default_emailicon))); createAssetIfNotExisting(repository, location, "defaultlogicon", "gif", getBytesFromFile(new File(default_logicon))); createAssetIfNotExisting(repository, location, "defaultservicenodeicon", "png", getBytesFromFile(new File(default_servicenodeicon))); } catch (Exception e) { _logger.error(e.getMessage()); } } private void setupDefaultWorkflowPatterns(String location, Repository repository) { try { createAssetIfNotExisting(repository, location, "patterns", "json", getBytesFromFile(new File(patternsData))); } catch (Exception e) { _logger.error(e.getMessage()); } } private void setupDefaultWorkitemConfigs(String location, Repository repository) { try { location = UriUtils.encode(location); // push default configuration wid // check classpath first InputStream widIn = this.getClass().getClassLoader().getResourceAsStream(defaultClasspathWid); String createdUUID; if (widIn != null) { createdUUID = createAssetIfNotExisting(repository, location, "WorkDefinitions", "wid", IOUtils.toByteArray(widIn)); } else { ST widConfigTemplate = new ST(readFile(default_widconfigtemplate), '$', '$'); createdUUID = createAssetIfNotExisting(repository, location, "WorkDefinitions", "wid", widConfigTemplate.render().getBytes("UTF-8")); } if (Base64.isBase64(createdUUID)) { byte[] decoded = Base64.decodeBase64(createdUUID); try { createdUUID = new String(decoded, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } if (vfsService != null && createdUUID != null) { Path newWidAssetPath = vfsService.get(UriUtils.encode(createdUUID)); } } catch (Exception e) { e.printStackTrace(); } } private Collection<Asset> findWorkitemInfoForUUID(String location, Repository repository) { Collection<Asset> widAssets = repository.listAssets(location, new FilterByExtension(WORKITEM_DEFINITION_EXT) { @Override public boolean accept(org.uberfire.java.nio.file.Path path) { boolean accept = super.accept(path); return accept && !path.getFileName().toString().startsWith("."); // JBPM-4215 fix: filter out hidden files of the same suffix but different format } }); return widAssets; } private Asset<String> findWorkflowPatterns(Repository repository) { return repository.loadAssetFromPath(this.globalDir + "/" + PATTERNS_NAME + PATTERNS_EXT); } protected static String readFile(String pathname) throws IOException { if (pathname == null) { return null; } StringBuilder fileContents = new StringBuilder(); String lineSeparator = System.getProperty("line.separator"); Scanner scanner = null; try { scanner = new Scanner(new File(pathname), "UTF-8"); while (scanner.hasNextLine()) { fileContents.append(scanner.nextLine() + lineSeparator); } return fileContents.toString(); } finally { IOUtils.closeQuietly(scanner); } } private void deletefile(String file) { File f = new File(file); boolean success = f.delete(); if (!success) { _logger.info("Unable to delete file: " + file); } else { _logger.info("Successfully deleted file: " + file); } } private void deletefile(File f) { String fname = f.getAbsolutePath(); boolean success = f.delete(); if (!success) { _logger.info("Unable to delete file: " + fname); } else { _logger.info("Successfully deleted file: " + fname); } } private void createAndWriteToFile(String file, String content) throws Exception { Writer output = null; try { output = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8")); output.write(content); _logger.info("Created file: " + file); } finally { IOUtils.closeQuietly(output); } } protected static byte[] getBytesFromFile(File file) throws IOException { if (file == null || file.length() > Integer.MAX_VALUE) { return null; // File is null or too large } long length = file.length(); byte[] bytes; InputStream is = null; try { is = new FileInputStream(file); bytes = new byte[(int) length]; int offset = 0; int numRead = 0; while (offset < bytes.length && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) { offset += numRead; } if (offset < bytes.length) { throw new IOException("Could not completely read file " + file.getName()); } } finally { IOUtils.closeQuietly(is); } return bytes; } private String createAssetIfNotExisting(Repository repository, String location, String name, String type, byte[] content) { try { boolean assetExists = repository.assetExists(location + "/" + name + "." + type); if (!assetExists) { // create theme asset AssetBuilder assetBuilder = AssetBuilderFactory.getAssetBuilder(Asset.AssetType.Byte); assetBuilder.content(content).location(location).name(name).type(type).version("1.0"); Asset<byte[]> customEditorsAsset = assetBuilder.getAsset(); return repository.createAsset(customEditorsAsset); } } catch (Exception e) { _logger.error(e.getMessage()); } return null; } public static String createAbsoluteIconPath(String assetPath, String iconPath) { if (assetPath == null || assetPath.length() < 1) { return iconPath; } if (iconPath == null || iconPath.length() < 1) { return assetPath; } // Handle cases where iconPath doesn't start with ".." if (iconPath.startsWith("/")) { return iconPath; } else if (!iconPath.startsWith("..")) { return assetPath + "/" + iconPath; } // Handle ".." once or more at start of iconPath String separator = "/"; String[] assetFolders = assetPath.split(separator); String[] iconFolders = iconPath.split(separator); int toRemoveFromIconFolders = 0; int toIncludeInAssetFolders = assetFolders.length; for (int i = 0; i < iconFolders.length; i++) { if ("..".equals(iconFolders[i])) { toRemoveFromIconFolders++; toIncludeInAssetFolders--; } else { break; } } StringBuilder sb = new StringBuilder(assetPath.length() + iconPath.length() + 1); sb.append(separator); for (int i = 1; i < toIncludeInAssetFolders; i++) { sb.append(assetFolders[i]).append(separator); } for (int i = toRemoveFromIconFolders; i < iconFolders.length; i++) { sb.append(iconFolders[i]).append(separator); } sb.setLength(sb.length() - 1); return sb.toString(); } private class ThemeInfo { private String bgColor; private String borderColor; private String fontColor; public ThemeInfo(String bgColor, String borderColor, String fontColor) { this.bgColor = bgColor; this.borderColor = borderColor; this.fontColor = fontColor; } public String getBgColor() { return bgColor; } public void setBgColor(String bgColor) { this.bgColor = bgColor; } public String getBorderColor() { return borderColor; } public void setBorderColor(String borderColor) { this.borderColor = borderColor; } public String getFontColor() { return fontColor; } public void setFontColor(String fontColor) { this.fontColor = fontColor; } } private class PatternInfo { private String id; private String name; private String description; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getId() { return id; } public void setId(String id) { this.id = id; } public PatternInfo(String id, String name, String description) { this.id = id; this.name = name; this.description = description; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } } public class WorkItemDisplayNameComparator implements Comparator<String> { private Map<String, WorkDefinitionImpl> workMap; public WorkItemDisplayNameComparator(Map<String, WorkDefinitionImpl> workMap) { this.workMap = workMap; } public int compare(String a, String b) { try { return workMap.get(a).getDisplayName().compareTo(workMap.get(b).getDisplayName()); } catch (Exception e) { return a.compareTo(b); } } } }