MessageManager.java :  » IDE-Eclipse » ui » org » eclipse » ui » internal » forms » Java Open Source

Java Open Source » IDE Eclipse » ui 
ui » org » eclipse » ui » internal » forms » MessageManager.java
/*******************************************************************************
 * Copyright (c) 2007 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 ******************************************************************************/

package org.eclipse.ui.internal.forms;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;

import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.fieldassist.ControlDecoration;
import org.eclipse.jface.fieldassist.FieldDecoration;
import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.forms.IMessage;
import org.eclipse.ui.forms.IMessageManager;
import org.eclipse.ui.forms.IMessagePrefixProvider;
import org.eclipse.ui.forms.widgets.Hyperlink;
import org.eclipse.ui.forms.widgets.ScrolledForm;

/**
 * @see IMessageManager
 */

public class MessageManager implements IMessageManager {
  private static final DefaultPrefixProvider DEFAULT_PREFIX_PROVIDER = new DefaultPrefixProvider();
  private ArrayList messages = new ArrayList();
  private Hashtable decorators = new Hashtable();
  private boolean autoUpdate = true;
  private ScrolledForm scrolledForm;
  private IMessagePrefixProvider prefixProvider = DEFAULT_PREFIX_PROVIDER;
  private int decorationPosition = SWT.LEFT | SWT.BOTTOM;
  private static FieldDecoration standardError = FieldDecorationRegistry
      .getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_ERROR);
  private static FieldDecoration standardWarning = FieldDecorationRegistry
      .getDefault().getFieldDecoration(
          FieldDecorationRegistry.DEC_WARNING);

  private static final String[] SINGLE_MESSAGE_SUMMARY_KEYS = {
      Messages.MessageManager_sMessageSummary,
      Messages.MessageManager_sMessageSummary,
      Messages.MessageManager_sWarningSummary,
      Messages.MessageManager_sErrorSummary };

  private static final String[] MULTIPLE_MESSAGE_SUMMARY_KEYS = {
      Messages.MessageManager_pMessageSummary,
      Messages.MessageManager_pMessageSummary,
      Messages.MessageManager_pWarningSummary,
      Messages.MessageManager_pErrorSummary };

  static class Message implements IMessage {
    Control control;
    Object data;
    Object key;
    String message;
    int type;
    String prefix;

    Message(Object key, String message, int type, Object data) {
      this.key = key;
      this.message = message;
      this.type = type;
      this.data = data;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.dialogs.IMessage#getKey()
     */
    public Object getKey() {
      return key;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.dialogs.IMessageProvider#getMessage()
     */
    public String getMessage() {
      return message;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.dialogs.IMessageProvider#getMessageType()
     */
    public int getMessageType() {
      return type;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.forms.messages.IMessage#getControl()
     */
    public Control getControl() {
      return control;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.forms.messages.IMessage#getData()
     */
    public Object getData() {
      return data;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.forms.messages.IMessage#getPrefix()
     */
    public String getPrefix() {
      return prefix;
    }
  }

  static class DefaultPrefixProvider implements IMessagePrefixProvider {

    public String getPrefix(Control c) {
      Composite parent = c.getParent();
      Control[] siblings = parent.getChildren();
      for (int i = 0; i < siblings.length; i++) {
        if (siblings[i] == c) {
          // this is us - go backward until you hit
          // a label-like widget
          for (int j = i - 1; j >= 0; j--) {
            Control label = siblings[j];
            String ltext = null;
            if (label instanceof Label) {
              ltext = ((Label) label).getText();
            } else if (label instanceof Hyperlink) {
              ltext = ((Hyperlink) label).getText();
            } else if (label instanceof CLabel) {
              ltext = ((CLabel) label).getText();
            }
            if (ltext != null) {
              if (!ltext.endsWith(":")) //$NON-NLS-1$
                return ltext + ": "; //$NON-NLS-1$
              return ltext + " "; //$NON-NLS-1$
            }
          }
          break;
        }
      }
      return null;
    }
  }

  class ControlDecorator {
    private ControlDecoration decoration;
    private ArrayList controlMessages = new ArrayList();
    private String prefix;

    ControlDecorator(Control control) {
      this.decoration = new ControlDecoration(control, decorationPosition, scrolledForm.getBody());
    }

    public boolean isDisposed() {
      return decoration.getControl() == null;
    }

    void updatePrefix() {
      prefix = null;
    }

    void updatePosition() {
      Control control = decoration.getControl();
      decoration.dispose();
      this.decoration = new ControlDecoration(control, decorationPosition, scrolledForm.getBody());
      update();
    }

    String getPrefix() {
      if (prefix == null)
        createPrefix();
      return prefix;
    }

    private void createPrefix() {
      if (prefixProvider == null) {
        prefix = ""; //$NON-NLS-1$
        return;
      }
      prefix = prefixProvider.getPrefix(decoration.getControl());
      if (prefix == null)
        // make a prefix anyway
        prefix = ""; //$NON-NLS-1$
    }

    void addAll(ArrayList target) {
      target.addAll(controlMessages);
    }

    void addMessage(Object key, String text, Object data, int type) {
      Message message = MessageManager.this.addMessage(getPrefix(), key,
          text, data, type, controlMessages);
      message.control = decoration.getControl();
      if (isAutoUpdate())
        update();
    }

    boolean removeMessage(Object key) {
      Message message = findMessage(key, controlMessages);
      if (message != null) {
        controlMessages.remove(message);
        if (isAutoUpdate())
          update();
      }
      return message != null;
    }

    boolean removeMessages() {
      if (controlMessages.isEmpty())
        return false;
      controlMessages.clear();
      if (isAutoUpdate())
        update();
      return true;
    }

    public void update() {
      if (controlMessages.isEmpty()) {
        decoration.setDescriptionText(null);
        decoration.hide();
      } else {
        ArrayList peers = createPeers(controlMessages);
        int type = ((IMessage) peers.get(0)).getMessageType();
        String description = createDetails(createPeers(peers), true);
        if (type == IMessageProvider.ERROR)
          decoration.setImage(standardError.getImage());
        else if (type == IMessageProvider.WARNING)
          decoration.setImage(standardWarning.getImage());
        decoration.setDescriptionText(description);
        decoration.show();
      }
    }
  }

  /**
   * Creates a new instance of the message manager that will work with the
   * provided form.
   * 
   * @param scrolledForm
   *            the form to control
   */
  public MessageManager(ScrolledForm scrolledForm) {
    this.scrolledForm = scrolledForm;
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.eclipse.ui.forms.IMessageManager#addMessage(java.lang.Object,
   *      java.lang.String, int)
   */
  public void addMessage(Object key, String messageText, Object data, int type) {
    addMessage(null, key, messageText, data, type, messages);
    if (isAutoUpdate())
      updateForm();
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.eclipse.ui.forms.IMessageManager#addMessage(java.lang.Object,
   *      java.lang.String, int, org.eclipse.swt.widgets.Control)
   */
  public void addMessage(Object key, String messageText, Object data,
      int type, Control control) {
    ControlDecorator dec = (ControlDecorator) decorators.get(control);

    if (dec == null) {
      dec = new ControlDecorator(control);
      decorators.put(control, dec);
    }
    dec.addMessage(key, messageText, data, type);
    if (isAutoUpdate())
      updateForm();
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.eclipse.ui.forms.IMessageManager#removeMessage(java.lang.Object)
   */
  public void removeMessage(Object key) {
    Message message = findMessage(key, messages);
    if (message != null) {
      messages.remove(message);
      if (isAutoUpdate())
        updateForm();
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.eclipse.ui.forms.IMessageManager#removeMessages()
   */
  public void removeMessages() {
    if (!messages.isEmpty()) {
      messages.clear();
      if (isAutoUpdate())
        updateForm();
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.eclipse.ui.forms.IMessageManager#removeMessage(java.lang.Object,
   *      org.eclipse.swt.widgets.Control)
   */
  public void removeMessage(Object key, Control control) {
    ControlDecorator dec = (ControlDecorator) decorators.get(control);
    if (dec == null)
      return;
    if (dec.removeMessage(key))
      if (isAutoUpdate())
        updateForm();
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.eclipse.ui.forms.IMessageManager#removeMessages(org.eclipse.swt.widgets.Control)
   */
  public void removeMessages(Control control) {
    ControlDecorator dec = (ControlDecorator) decorators.get(control);
    if (dec != null) {
      if (dec.removeMessages()) {
        if (isAutoUpdate())
          updateForm();
      }
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.eclipse.ui.forms.IMessageManager#removeAllMessages()
   */
  public void removeAllMessages() {
    boolean needsUpdate = false;
    for (Enumeration enm = decorators.elements(); enm.hasMoreElements();) {
      ControlDecorator control = (ControlDecorator) enm.nextElement();
      if (control.removeMessages())
        needsUpdate = true;
    }
    if (!messages.isEmpty()) {
      messages.clear();
      needsUpdate = true;
    }
    if (needsUpdate && isAutoUpdate())
      updateForm();
  }

  /*
   * Adds the message if it does not already exist in the provided list.
   */

  private Message addMessage(String prefix, Object key, String messageText,
      Object data, int type, ArrayList list) {
    Message message = findMessage(key, list);
    if (message == null) {
      message = new Message(key, messageText, type, data);
      message.prefix = prefix;
      list.add(message);
    } else {
      message.message = messageText;
      message.type = type;
      message.data = data;
    }
    return message;
  }

  /*
   * Finds the message with the provided key in the provided list.
   */

  private Message findMessage(Object key, ArrayList list) {
    for (int i = 0; i < list.size(); i++) {
      Message message = (Message) list.get(i);
      if (message.getKey().equals(key))
        return message;
    }
    return null;
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.eclipse.ui.forms.IMessageManager#update()
   */
  public void update() {
    // Update decorations
    for (Iterator iter = decorators.values().iterator(); iter.hasNext();) {
      ControlDecorator dec = (ControlDecorator) iter.next();
      dec.update();
    }
    // Update the form
    updateForm();
  }

  /*
   * Updates the container by rolling the messages up from the controls.
   */

  private void updateForm() {
    ArrayList mergedList = new ArrayList();
    mergedList.addAll(messages);
    for (Enumeration enm = decorators.elements(); enm.hasMoreElements();) {
      ControlDecorator dec = (ControlDecorator) enm.nextElement();
      dec.addAll(mergedList);
    }
    update(mergedList);
  }

  private void update(ArrayList mergedList) {
    pruneControlDecorators();
    if (mergedList.isEmpty() || mergedList == null) {
      scrolledForm.setMessage(null, IMessageProvider.NONE);
      return;
    }
    ArrayList peers = createPeers(mergedList);
    int maxType = ((IMessage) peers.get(0)).getMessageType();
    String messageText;
    IMessage[] array = (IMessage[]) peers
        .toArray(new IMessage[peers.size()]);
    if (peers.size() == 1 && ((Message) peers.get(0)).prefix == null) {
      // a single message
      IMessage message = (IMessage) peers.get(0);
      messageText = message.getMessage();
      scrolledForm.setMessage(messageText, maxType, array);
    } else {
      // show a summary message for the message
      // and list of errors for the details
      if (peers.size() > 1)
        messageText = Messages.bind(
            MULTIPLE_MESSAGE_SUMMARY_KEYS[maxType],
            new String[] { peers.size() + "" }); //$NON-NLS-1$
      else
        messageText = SINGLE_MESSAGE_SUMMARY_KEYS[maxType];
      scrolledForm.setMessage(messageText, maxType, array);
    }
  }

  private static String getFullMessage(IMessage message) {
    if (message.getPrefix() == null)
      return message.getMessage();
    return message.getPrefix() + message.getMessage();
  }

  private ArrayList createPeers(ArrayList messages) {
    ArrayList peers = new ArrayList();
    int maxType = 0;
    for (int i = 0; i < messages.size(); i++) {
      Message message = (Message) messages.get(i);
      if (message.type > maxType) {
        peers.clear();
        maxType = message.type;
      }
      if (message.type == maxType)
        peers.add(message);
    }
    return peers;
  }

  private String createDetails(ArrayList messages, boolean excludePrefix) {
    StringWriter sw = new StringWriter();
    PrintWriter out = new PrintWriter(sw);

    for (int i = 0; i < messages.size(); i++) {
      if (i > 0)
        out.println();
      IMessage m = (IMessage) messages.get(i);
      out.print(excludePrefix ? m.getMessage() : getFullMessage(m));
    }
    out.flush();
    return sw.toString();
  }

  public static String createDetails(IMessage[] messages) {
    if (messages == null || messages.length == 0)
      return null;
    StringWriter sw = new StringWriter();
    PrintWriter out = new PrintWriter(sw);

    for (int i = 0; i < messages.length; i++) {
      if (i > 0)
        out.println();
      out.print(getFullMessage(messages[i]));
    }
    out.flush();
    return sw.toString();
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.eclipse.ui.forms.IMessageManager#createSummary(org.eclipse.ui.forms.IMessage[])
   */
  public String createSummary(IMessage[] messages) {
    return createDetails(messages);
  }

  private void pruneControlDecorators() {
    for (Iterator iter = decorators.values().iterator(); iter.hasNext();) {
      ControlDecorator dec = (ControlDecorator) iter.next();
      if (dec.isDisposed())
        iter.remove();
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.eclipse.ui.forms.IMessageManager#getMessagePrefixProvider()
   */
  public IMessagePrefixProvider getMessagePrefixProvider() {
    return prefixProvider;
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.eclipse.ui.forms.IMessageManager#setMessagePrefixProvider(org.eclipse.ui.forms.IMessagePrefixProvider)
   */
  public void setMessagePrefixProvider(IMessagePrefixProvider provider) {
    this.prefixProvider = provider;
    for (Iterator iter = decorators.values().iterator(); iter.hasNext();) {
      ControlDecorator dec = (ControlDecorator) iter.next();
      dec.updatePrefix();
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.eclipse.ui.forms.IMessageManager#getDecorationPosition()
   */
  public int getDecorationPosition() {
    return decorationPosition;
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.eclipse.ui.forms.IMessageManager#setDecorationPosition(int)
   */
  public void setDecorationPosition(int position) {
    this.decorationPosition = position;
    for (Iterator iter = decorators.values().iterator(); iter.hasNext();) {
      ControlDecorator dec = (ControlDecorator) iter.next();
      dec.updatePosition();
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.eclipse.ui.forms.IMessageManager#isAutoUpdate()
   */
  public boolean isAutoUpdate() {
    return autoUpdate;
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.eclipse.ui.forms.IMessageManager#setAutoUpdate(boolean)
   */
  public void setAutoUpdate(boolean autoUpdate) {
    boolean needsUpdate = !this.autoUpdate && autoUpdate;
    this.autoUpdate = autoUpdate;
    if (needsUpdate)
      update();
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.