Java tutorial
/* * The DecidR Development Team licenses this file to you 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 de.decidr.ui.view; import java.util.List; import java.util.Map; import java.util.Vector; import org.apache.log4j.Logger; import com.vaadin.terminal.PaintException; import com.vaadin.terminal.PaintTarget; import com.vaadin.ui.AbstractComponent; import com.vaadin.ui.ClientWidget; import de.decidr.model.annotations.Reviewed; import de.decidr.model.annotations.Reviewed.State; import de.decidr.model.exceptions.MonitoringException; import de.decidr.model.exceptions.TransactionException; import de.decidr.model.facades.WorkflowInstanceFacade; import de.decidr.model.logging.DefaultLogger; import de.decidr.model.schema.webservice.odemanagement.TScopeStatus; import de.decidr.ui.beans.WorkflowInstanceBean; import de.decidr.ui.main.DecidrUI; import de.decidr.ui.main.ModelFacades; import de.decidr.ui.view.client.ui.VWorkflowInstanceViewer; import de.decidr.ui.view.windows.InformationDialogComponent; import de.decidr.ui.view.windows.TransactionErrorDialogComponent; /** * This class represents the server side component of the instance viewer widget * which is integrated into the Vaadin web portal. It is used to communicate * with the client side of the instance viewer widget. * * @author Wolfgang Fellger */ @Reviewed(reviewers = { "unknown" }, lastRevision = "0", currentReviewState = State.NeedsReview) @ClientWidget(VWorkflowInstanceViewer.class) public class WorkflowInstanceViewerComponent extends AbstractComponent { private static final long serialVersionUID = -2284244108529453835L; private Logger logger = DefaultLogger.getLogger(WorkflowModelEditorComponent.class); private final WorkflowInstanceBean instanceBean; private final WorkflowInstanceFacade instanceFacade; private List<String> variableIDs; /** * Initializes the server side components which are needed to gain access to * the database. * * @throws TransactionException * Iff the transaction is aborted for any reason. */ public WorkflowInstanceViewerComponent(WorkflowInstanceBean instance) throws TransactionException { super(); this.instanceBean = instance; this.instanceFacade = ModelFacades.getWorkflowInstanceFacade(); this.setSizeFull(); this.setImmediate(true); } @SuppressWarnings("unchecked") @Override public void changeVariables(Object source, Map variables) { super.changeVariables(source, variables); logger.debug("[Instance Viewer] Received update from client..."); /** * When the clients requests an update, it sets one of these variables. * To "send" data to the client, we must trigger a repaint, which will * then update variables, which will then make Vaadin actually send * stuff. */ if (variables.containsKey(VWorkflowInstanceViewer.ACTIVITY_INFO_VAR)) { logger.debug("[Instance Viewer] Event: Update activity info"); this.requestRepaint(); } else if (variables.containsKey(VWorkflowInstanceViewer.INSTANCE_VARIABLES_VAR)) { logger.debug("[Instance Viewer] Event: Update instance variables"); Object o = variables.get(VWorkflowInstanceViewer.INSTANCE_VARIABLES_VAR); if (o instanceof Object[]) { try { variableIDs = new Vector<String>(); for (Object item : (Object[]) o) { if (o != null) { variableIDs.add(item.toString()); } } this.requestRepaint(); } catch (Exception e) { ; } } } } @Override public void paintContent(PaintTarget target) throws PaintException { super.paintContent(target); try { target.addVariable(this, VWorkflowInstanceViewer.DWDL_VAR, getDWDL()); if (variableIDs != null) { target.addVariable(this, VWorkflowInstanceViewer.INSTANCE_VARIABLES_VAR, getInstanceVariables(variableIDs)); variableIDs = null; } target.addVariable(this, VWorkflowInstanceViewer.ACTIVITY_INFO_VAR, getActivityInfo()); } catch (MonitoringException e) { DecidrUI.getCurrent().getMainWindow().addWindow(new InformationDialogComponent( "Monitoring encountered an error.\n\nMessage: " + e.getLocalizedMessage(), "Monitoring error")); } catch (TransactionException e) { DecidrUI.getCurrent().getMainWindow().addWindow(new TransactionErrorDialogComponent(e)); } } /** * Retrieve current activity information from ODE and return as JSON. * * @return JSON string containing activity info * @throws TransactionException */ private String getActivityInfo() throws TransactionException { Map<String, TScopeStatus> activities = instanceFacade.getActivityInfo(this.instanceBean.getId()); return mapToJSON(activities); } /** * Retrieve current values of instance variables from ODE. * * @return JSON string containing instance variables * @throws TransactionException * Iff the transaction is aborted for any reason. */ private String getInstanceVariables(List<String> variableIds) throws TransactionException { Map<String, String> variables = instanceFacade.getInstanceVariables(this.instanceBean.getId(), variableIds); return mapToJSON(variables); } /** * Retrieve DWDL of the workflow instance's model. * * @return XML string containing DWDL. */ private String getDWDL() { return new String(this.instanceBean.getModel().getDwdl()); } /** * Escape string for use as JSON string literal. */ private String escapeJSON(String value) { StringBuilder sb = new StringBuilder(value.length()); for (char c : value.toCharArray()) { if (c == '"') { sb.append("\\\""); } else if (c == '\\') { sb.append("\\\\"); } else if (Character.isISOControl(c)) { sb.append(String.format("\\x%02x", Integer.valueOf(c))); } else { sb.append(c); } } return sb.toString(); } /** * Convert any Map to a JSON object, by calling toString on both keys and * values. * * @param map * Map to convert to JSON. May be null. * @return JSON string encoding a JSON object which maps strings to strings. */ private String mapToJSON(Map<?, ?> map) { if (map == null) { return "{}"; } StringBuilder result = new StringBuilder(); boolean first = true; result.append("{"); for (Object key : map.keySet()) { if (first) { first = false; } else { result.append(",\n"); } result.append('"'); result.append(key.toString()); result.append("\": \""); result.append(escapeJSON(map.get(key).toString())); result.append('"'); } result.append("}"); return result.toString(); } }