@Override
 @SuppressWarnings({"rawtypes", "unchecked"})
 public void redo() {
   for (final Entry<DiscreteMapping<?, ?>, Map<Object, Object>> entry :
       newMappingValues.entrySet()) {
     final DiscreteMapping dm = entry.getKey();
     dm.putAll(entry.getValue());
   }
 }
  @SuppressWarnings({"rawtypes", "unchecked"})
  private final DiscreteMapping parseDiscrete(
      String columnName,
      Class<?> type,
      VisualProperty<?> vp,
      VisualMappingFunctionFactory factory,
      JsonNode discreteMapping) {
    DiscreteMapping mapping =
        (DiscreteMapping) factory.createVisualMappingFunction(columnName, type, vp);

    final Map map = new HashMap();
    for (JsonNode pair : discreteMapping) {
      final Object key = parseKeyValue(type, pair.get(MAPPING_DISCRETE_KEY).textValue());
      if (key != null) {
        map.put(key, vp.parseSerializableString(pair.get(MAPPING_DISCRETE_VALUE).textValue()));
      }
    }
    mapping.putAll(map);
    return mapping;
  }
  /** Edit all selected cells at once. This is for Discrete Mapping only. */
  @Override
  @SuppressWarnings({"rawtypes", "unchecked"})
  public void actionPerformed(final ActionEvent e) {
    final VizMapperMainPanel vizMapperMainPanel = getVizMapperMainPanel();

    if (vizMapperMainPanel == null) return;

    final VisualPropertySheet vpSheet = vizMapperMainPanel.getSelectedVisualPropertySheet();

    if (vpSheet == null) return;

    for (final VisualPropertySheetItem<?> vpSheetItem : vpSheet.getSelectedItems()) {
      final VisualPropertySheetItemModel<?> model = vpSheetItem.getModel();
      final PropertySheetTable table = vpSheetItem.getPropSheetPnl().getTable();
      final int[] selected = table.getSelectedRows();

      if (selected == null
          || selected.length == 0
          || !(model.getVisualMappingFunction() instanceof DiscreteMapping)) continue;

      // Test with the first selected item
      final DiscreteMapping dm = (DiscreteMapping) model.getVisualMappingFunction();
      final VisualProperty vp = dm.getVisualProperty();

      Object newValue = null;

      try {
        // Get new value
        newValue =
            editorManager.showVisualPropertyValueEditor(vizMapperMainPanel, vp, vp.getDefault());
      } catch (Exception ex) {
        logger.error("Could not edit value.", ex);
      }

      if (newValue == null) continue;

      final Map<Object, Object> newValues = new HashMap<Object, Object>();
      final Map<Object, Object> previousValues = new HashMap<Object, Object>();

      for (int i = 0; i < selected.length; i++) {
        final Item item = ((Item) table.getValueAt(selected[i], 0));

        if (item != null && item.getProperty() instanceof VizMapperProperty) {
          final VizMapperProperty<?, ?, ?> prop = (VizMapperProperty<?, ?, ?>) item.getProperty();

          if (prop.getCellType() == CellType.DISCRETE) {
            // Save the current value for undo
            previousValues.put(prop.getKey(), prop.getValue());

            // New value
            newValues.put(prop.getKey(), newValue);
          }
        }
      }

      // Save the mapping->old_values for undo
      if (!previousValues.isEmpty()) previousMappingValues.put(dm, previousValues);

      // Save the mapping->new_values for redo
      if (!newValues.isEmpty()) newMappingValues.put(dm, newValues);

      // Update the visual mapping
      dm.putAll(newValues);
    }

    // Undo support
    if (!previousMappingValues.isEmpty()) {
      final UndoSupport undo = servicesUtil.get(UndoSupport.class);
      undo.postEdit(new EditSelectedDiscreteValuesEdit());
    }
  }
  @SuppressWarnings("unchecked")
  private void checkCurrentVisualStyle(final VisualStyle style) {
    assertNotNull(style);
    assertEquals("Sample3", style.getTitle());

    Collection<VisualMappingFunction<?, ?>> mappings = style.getAllVisualMappingFunctions();
    assertEquals(6, mappings.size());

    // Test defaults
    NodeShape defaultShape = style.getDefaultValue(NODE_SHAPE);
    Paint nodeColor = style.getDefaultValue(NODE_FILL_COLOR);
    Integer fontSize = style.getDefaultValue(NODE_LABEL_FONT_SIZE);
    Integer transparency = style.getDefaultValue(NODE_TRANSPARENCY);
    Double w = style.getDefaultValue(NODE_WIDTH);
    Double h = style.getDefaultValue(NODE_HEIGHT);

    Paint edgeLabelColor = style.getDefaultValue(EDGE_LABEL_COLOR);
    assertEquals(new Color(255, 255, 204), edgeLabelColor);

    assertEquals(NodeShapeVisualProperty.ROUND_RECTANGLE, defaultShape);
    assertEquals(Color.WHITE, nodeColor);
    assertEquals(Integer.valueOf(16), fontSize);
    assertEquals(Integer.valueOf(180), transparency);
    assertEquals(Double.valueOf(80), w);
    assertEquals(Double.valueOf(30), h);

    // Check each mapping
    VisualMappingFunction<?, String> nodeLabelMapping = style.getVisualMappingFunction(NODE_LABEL);
    VisualMappingFunction<?, String> edgeLabelMapping = style.getVisualMappingFunction(EDGE_LABEL);

    assertTrue(nodeLabelMapping instanceof PassthroughMapping);
    assertTrue(edgeLabelMapping instanceof PassthroughMapping);

    assertEquals(CyNetwork.NAME, nodeLabelMapping.getMappingColumnName());
    assertEquals(CyEdge.INTERACTION, edgeLabelMapping.getMappingColumnName());
    assertEquals(String.class, nodeLabelMapping.getMappingColumnType());
    assertEquals(String.class, edgeLabelMapping.getMappingColumnType());

    // Node Color mapping
    VisualMappingFunction<?, Paint> nodeColorMapping =
        style.getVisualMappingFunction(NODE_FILL_COLOR);
    assertTrue(nodeColorMapping instanceof ContinuousMapping);
    assertEquals("gal4RGexp", nodeColorMapping.getMappingColumnName());
    assertEquals(Number.class, nodeColorMapping.getMappingColumnType());

    // Edge Color mapping
    VisualMappingFunction<?, Paint> edgeColorMapping =
        style.getVisualMappingFunction(EDGE_STROKE_UNSELECTED_PAINT);
    assertTrue(edgeColorMapping instanceof DiscreteMapping);
    assertEquals(CyEdge.INTERACTION, edgeColorMapping.getMappingColumnName());
    assertEquals(String.class, edgeColorMapping.getMappingColumnType());
    DiscreteMapping<String, Paint> disc1 = (DiscreteMapping<String, Paint>) edgeColorMapping;
    assertEquals(Color.WHITE, disc1.getMapValue("pp"));
    assertEquals(new Color(102, 255, 255), disc1.getMapValue("pd"));
    assertEquals(null, disc1.getMapValue("this is an invalid value"));

    // Numbers as Tooltip
    VisualMappingFunction<?, String> nodeTooltipMapping =
        style.getVisualMappingFunction(NODE_TOOLTIP);
    assertTrue(nodeTooltipMapping instanceof PassthroughMapping);
    assertEquals("gal4RGexp", nodeTooltipMapping.getMappingColumnName());
    // Cy2 doesn't write the "controllerType" property for PassThroughMappings,
    // so it's always created as String (it shouldn't cause any issues)
    assertEquals(String.class, nodeTooltipMapping.getMappingColumnType());

    VisualMappingFunction<?, LineType> edgeLineStyleMapping =
        style.getVisualMappingFunction(EDGE_LINE_TYPE);
    assertTrue(edgeLineStyleMapping instanceof DiscreteMapping);
    assertEquals(CyEdge.INTERACTION, edgeLineStyleMapping.getMappingColumnName());
    assertEquals(String.class, edgeLineStyleMapping.getMappingColumnType());
    DiscreteMapping<String, LineType> disc2 =
        (DiscreteMapping<String, LineType>) edgeLineStyleMapping;
    assertEquals(LineTypeVisualProperty.SOLID, disc2.getMapValue("pp"));
    assertEquals(LineTypeVisualProperty.LONG_DASH, disc2.getMapValue("pd"));
    assertEquals(null, disc2.getMapValue("this is an invalid value"));
  }