Package org.jboss.errai.otec.client

Source Code of org.jboss.errai.otec.client.StringState

/*
* Copyright 2013 JBoss, by Red Hat, Inc
*
* Licensed 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 org.jboss.errai.otec.client;

import java.util.LinkedList;
import java.util.List;

import org.jboss.errai.otec.client.util.Md5Digest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* @author Mike Brock
* @author Christian Sadilek <csadilek@redhat.com>
*/
public class StringState implements State<String> {
  private List<StateChangeListener> stateChangeListeners = new LinkedList<StateChangeListener>();
  public StringBuffer buffer;
  public String stateId = "<initial>";
 
  private static final Logger logger = LoggerFactory.getLogger(StringState.class);

  private StringState(final String buffer) {
    this.buffer = new StringBuffer(buffer);
  }

  private StringState(final StringBuffer buffer) {
    this.buffer = buffer;
  }

  public static StringState of(final String buffer) {
    return new StringState(buffer);
  }

  public void insert(final int pos, final char data) {
    if (pos == buffer.length()) {
      buffer.append(String.valueOf(data));
    }
    else {
      buffer.insert(pos, String.valueOf(data));
    }

    updateStateId();
    notifyStateChangeListeners(pos, 1);
  }

  public void insert(final int pos, final String data) {
    try {
      if (pos == buffer.length()) {
        buffer.append(data);
      }
      else {
        buffer.insert(pos, data);
      }

      updateStateId();
      notifyStateChangeListeners(pos, data.length());
    }
    catch (StringIndexOutOfBoundsException e) {
      System.out.println("********");
      System.out.println("FAILED TO INSERT: \"" + data + "\"");
      System.out.println("        POSITION: " + pos);
      System.out.println("      BUFFER LEN: " + buffer.length());

      e.printStackTrace(System.out);
      System.out.println("********");

      throw new OTException("could not update state", e);
    }
  }

  public void delete(final int pos) {
    buffer.delete(pos, pos + 1);
    updateStateId();
    notifyStateChangeListeners(pos, -1);
  }

  public void delete(final int pos, final int length) {
    try {
      buffer.delete(pos, pos + length);
      updateStateId();
      notifyStateChangeListeners(pos, -length);
    }
    catch (StringIndexOutOfBoundsException e) {
      System.out.println("********");
      System.out.println("FAILED TO DELETE: " + length);
      System.out.println("        POSITION: " + pos);
      System.out.println("      BUFFER LEN: " + buffer.length());
      throw new OTException("could not update state", e);
    }
  }

  private void updateStateId() {
    final String string = buffer.toString();
    stateId = createHashFor(string);
  }

  private void notifyStateChangeListeners(final int pos, final int offset) {
    for (final StateChangeListener listener : stateChangeListeners) {
      int cursorPos = listener.getCursorPos();
      if (cursorPos > pos) {
        cursorPos += offset;

        logger.debug("change pos: " + pos + "; offset: " + offset + "; newCursor: " + cursorPos);
      }

      if (cursorPos < 0) {
        cursorPos = 0;
      }

      if (cursorPos > length()) {
        cursorPos = length();
      }

      listener.onStateChange(cursorPos, buffer.toString());
    }
  }

  @Override
  public String get() {
    return buffer.toString();
  }

  @Override
  public State<String> snapshot() {
    return of(buffer.toString());
  }

  @SuppressWarnings("RedundantStringToString")
  @Override
  public void syncStateFrom(final State<String> fromState) {
    if (fromState instanceof StringState) {
      clear();
      buffer.append(fromState.get().toString());
      updateStateId();
    }
    else {
      throw new RuntimeException("cannot sync state with non-StringState");
    }
  }

  @Override
  public String getHash() {
    return stateId;
  }

  @Override
  public void clear() {
    buffer.delete(0, buffer.length());
  }

  @Override
  public State<String> getTransientState() {
    return new StringState(new StringBuffer(buffer));
  }

  @Override
  public void updateHash() {
    updateStateId();
  }

  @Override
  public int length() {
    return buffer.length();
  }

  @Override
  public ListenerRegistration addStateChangeListener(final StateChangeListener stateChangeListener) {
    stateChangeListeners.add(stateChangeListener);
    return new ListenerRegistration() {
      @Override
      public void remove() {
        stateChangeListeners.remove(stateChangeListener);
      }
    };
  }

  private static String createHashFor(final String string) {
    try {
      final Md5Digest digest = new Md5Digest();
      digest.update(string.getBytes("UTF-8"));
      return hashToHexString(digest.digest());
    }
    catch (Throwable e) {
      throw new RuntimeException(e);
    }
  }

  private static String hashToHexString(final byte[] hash) {
    final StringBuilder hexString = new StringBuilder(hash.length);
    for (final byte mdbyte : hash) {
      hexString.append(Integer.toHexString(0xFF & mdbyte));
    }
    return hexString.toString();
  }

  @Override
  public String toString() {
    return "\"" + buffer.toString() + "\"";
  }
}
TOP

Related Classes of org.jboss.errai.otec.client.StringState

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.