package org.aperteworkflow.editor.stepeditor.auto; import com.vaadin.terminal.Sizeable; import com.vaadin.ui.ComponentContainer; import com.vaadin.ui.Label; import com.vaadin.ui.TabSheet; import com.vaadin.ui.VerticalLayout; import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang.StringUtils; import org.aperteworkflow.editor.stepeditor.AbstractStepEditorWindow; import org.aperteworkflow.editor.stepeditor.StepEditorApplication; import org.aperteworkflow.editor.stepeditor.TaskConfig; import org.aperteworkflow.editor.ui.property.PropertiesPanel; import org.aperteworkflow.editor.vaadin.GenericEditorApplication; import org.aperteworkflow.util.vaadin.VaadinUtility; import org.codehaus.jackson.JsonGenerationException; import org.codehaus.jackson.map.JsonMappingException; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.type.TypeReference; import pl.net.bluesoft.rnd.processtool.plugins.ProcessToolRegistry; import pl.net.bluesoft.rnd.processtool.steps.ProcessToolProcessStep; import pl.net.bluesoft.rnd.processtool.ui.widgets.annotations.AliasName; import pl.net.bluesoft.rnd.util.i18n.I18NSource; import pl.net.bluesoft.util.lang.Classes; import java.io.IOException; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import static org.aperteworkflow.util.vaadin.VaadinUtility.styled; public class AutoStepEditorWindow extends AbstractStepEditorWindow { private static final long serialVersionUID = 2136349026207825108L; private static final Logger logger = Logger.getLogger(AutoStepEditorWindow.class.getName()); private static final ObjectMapper mapper = new ObjectMapper(); private PropertiesPanel propertiesPanel; private TabSheet tabSheet; private Label stepTypeLabel; public AutoStepEditorWindow(StepEditorApplication application, String jsonConfig, String url, String stepName, String stepType) { super(application, jsonConfig, url, stepName, stepType); } public ComponentContainer init() { I18NSource messages = I18NSource.ThreadUtil.getThreadI18nSource(); VerticalLayout vll = new VerticalLayout(); vll.setWidth(100, Sizeable.UNITS_PERCENTAGE); vll.addComponent(new Label(messages.getMessage("jse.instructions"), Label.CONTENT_XHTML)); vll.setSpacing(true); if (stepType != null) { propertiesPanel = new PropertiesPanel(); Class<?> stepClass = getStepClass(stepType); propertiesPanel.init(stepClass); propertiesPanel.refreshForm(false, getLoadedJsonData(jsonConfig)); stepTypeLabel = styled(new Label(propertiesPanel.getClassInfo().getDocName()), "h2"); tabSheet = new TabSheet(); tabSheet.addTab(propertiesPanel, messages.getMessage("form.properties")); vll.addComponent(stepTypeLabel); vll.addComponent(tabSheet); } return vll; } private Map<String,Object> getLoadedJsonData(String jsonConfig) { I18NSource messages = I18NSource.ThreadUtil.getThreadI18nSource(); if (StringUtils.isEmpty(jsonConfig)) return new HashMap<String,Object>(); try { Map<String,Object> propertiesMap = mapper.readValue( jsonConfig, new TypeReference<HashMap<String, Object>>() {} ); // decode base64 and drop empty properties if (propertiesMap != null && !propertiesMap.isEmpty()) { Iterator<Map.Entry<String, Object>> it = propertiesMap.entrySet().iterator(); while (it.hasNext()) { Map.Entry<String, Object> e = it.next(); String propertyName = e.getKey(); Object encodedValue = e.getValue(); if (encodedValue == null) { it.remove(); continue; } if (encodedValue instanceof String) { if (encodedValue.toString().trim().isEmpty()) { it.remove(); continue; } byte[] decoded = Base64.decodeBase64(encodedValue.toString().getBytes()); propertiesMap.put(propertyName, new String(decoded)); } } } return propertiesMap; } catch (JsonMappingException e) { logger.log(Level.SEVERE, "Error parsing JSON data", e); } catch (JsonGenerationException e) { logger.log(Level.SEVERE, "Error parsing JSON data", e); } catch (IOException e) { logger.log(Level.SEVERE, "Error parsing JSON data", e); } application.getMainWindow().showNotification(messages.getMessage("jse.error.read")); return null; } // private boolean isPropertyEmpty(Object value) { // return (value == null || value.toString().trim().isEmpty()); // } private String getJsonToSave() { // encode the properties with base64 and drop the empty values Map<String, Object> propertiesMap = propertiesPanel.getPropertiesMap(); if (propertiesMap != null && !propertiesMap.isEmpty()) { Iterator<Map.Entry<String, Object>> it = propertiesMap.entrySet().iterator(); while (it.hasNext()) { Map.Entry<String, Object> e = it.next(); String propertyName = e.getKey(); Object propertyValue = e.getValue(); if (propertyValue == null) { it.remove(); continue; } if (propertyValue instanceof String) { if (propertyValue.toString().trim().isEmpty()) { it.remove(); continue; } String encodedValue = Base64.encodeBase64URLSafeString(propertyValue.toString().getBytes()); propertiesMap.put(propertyName, encodedValue); } } } I18NSource messages = I18NSource.ThreadUtil.getThreadI18nSource(); TaskConfig tc = new TaskConfig(); tc.setTaskName(propertiesPanel.getClassInfo().getAliasName()); tc.setParams(propertiesMap); try { return mapper.writeValueAsString(tc); } catch (JsonMappingException e) { logger.log(Level.SEVERE, "Error creating JSON", e); } catch (JsonGenerationException e) { logger.log(Level.SEVERE, "Error creating JSON", e); } catch (IOException e) { logger.log(Level.SEVERE, "Error creating JSON", e); } application.getMainWindow().showNotification(messages.getMessage("jse.error.write")); return ""; } @Override public void save() { if (!propertiesPanel.getPropertiesForm().isValid()) { GenericEditorApplication.getCurrent() .getMainWindow().showNotification(VaadinUtility.validationNotification("Validation error", "Correct data")); return; } String json = getJsonToSave(); application.getJsHelper().postAndRedirectStep(url, json); } private Class<?> getStepClass(String stepType) { ProcessToolRegistry reg = GenericEditorApplication.getRegistry(); Map<String,ProcessToolProcessStep> availableSteps = reg.getAvailableSteps(); for (ProcessToolProcessStep stepInstance : availableSteps.values()) { Class stepClass = stepInstance.getClass(); AliasName a = Classes.getClassAnnotation(stepClass, AliasName.class); if (stepType.equals(a.name())) { return stepClass; } } return null; } }