Package com.orientechnologies.orient.core.serialization.serializer

Source Code of com.orientechnologies.orient.core.serialization.serializer.OStringSerializerHelper

/*
* Copyright 1999-2010 Luca Garulli (l.garulli--at--orientechnologies.com)
*
* 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 com.orientechnologies.orient.core.serialization.serializer;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.orientechnologies.orient.core.db.record.ODatabaseRecord;
import com.orientechnologies.orient.core.exception.OSerializationException;
import com.orientechnologies.orient.core.id.ORID;
import com.orientechnologies.orient.core.id.ORecordId;
import com.orientechnologies.orient.core.metadata.schema.OClass;
import com.orientechnologies.orient.core.metadata.schema.OType;
import com.orientechnologies.orient.core.record.ORecord;
import com.orientechnologies.orient.core.record.impl.ODocument;
import com.orientechnologies.orient.core.serialization.OBase64Utils;
import com.orientechnologies.orient.core.serialization.serializer.record.string.ORecordSerializerSchemaAware2CSV;
import com.orientechnologies.orient.core.serialization.serializer.string.OStringSerializerAnyStreamable;

public abstract class OStringSerializerHelper {
  public static final char                RECORD_SEPARATOR        = ',';

  public static final String              CLASS_SEPARATOR          = "@";
  public static final char                DOCUMENT_ATTRIB          = '@';
  public static final char                LINK                    = ORID.PREFIX;
  public static final char                PARENTHESIS_BEGIN        = '(';
  public static final char                PARENTHESIS_END          = ')';
  public static final char                COLLECTION_BEGIN        = '[';
  public static final char                COLLECTION_END          = ']';
  public static final char                MAP_BEGIN                = '{';
  public static final char                MAP_END                  = '}';
  public static final char                ENTRY_SEPARATOR          = ':';
  public static final char                PARAMETER_NAMED          = ':';
  public static final char                PARAMETER_POSITIONAL    = '?';
  public static final char[]              PARAMETER_SEPARATOR      = new char[] { ',', ')' };
  public static final char[]              PARAMETER_EXT_SEPARATOR  = new char[] { ' ', '.' };
  public static final char                COLLECTION_SEPARATOR    = ',';
  public static final List<String>        EMPTY_LIST              = Collections.unmodifiableList(new ArrayList<String>());
  public static final Map<String, String>  EMPTY_MAP                = Collections.unmodifiableMap(new HashMap<String, String>());

  public static Object fieldTypeFromStream(final ODocument iDocument, OType iType, final Object iValue) {
    if (iValue == null)
      return null;

    if (iType == null)
      iType = OType.EMBEDDED;

    switch (iType) {
    case STRING:
      if (iValue instanceof String) {
        final String s = (String) iValue;
        return decode(s.substring(1, s.length() - 1));
      }
      return iValue.toString();

    case INTEGER:
      if (iValue instanceof Integer)
        return iValue;
      return new Integer(getStringContent(iValue));

    case BOOLEAN:
      if (iValue instanceof Boolean)
        return iValue;
      return new Boolean(getStringContent(iValue));

    case FLOAT:
      if (iValue instanceof Float)
        return iValue;
      return new Float(getStringContent(iValue));

    case LONG:
      if (iValue instanceof Long)
        return iValue;
      return new Long(getStringContent(iValue));

    case DOUBLE:
      if (iValue instanceof Double)
        return iValue;
      return new Double(getStringContent(iValue));

    case SHORT:
      if (iValue instanceof Short)
        return iValue;
      return new Short(getStringContent(iValue));

    case BYTE:
      if (iValue instanceof Byte)
        return iValue;
      return new Byte(getStringContent(iValue));

    case BINARY:
      if (iValue instanceof byte[])
        return iValue;
      if (iValue instanceof String) {
        final String s = (String) iValue;
        if (s.length() > 2)
          return OBase64Utils.decode(s.substring(1, s.length() - 1));
        return null;
      }

    case DATE:
    case DATETIME:
      if (iValue instanceof Date)
        return iValue;
      return new Date(Long.parseLong(getStringContent(iValue)));

    case LINK:
      if (iValue instanceof ORID)
        return iValue.toString();
      else if (iValue instanceof String)
        return new ORecordId((String) iValue);
      else
        return ((ORecord<?>) iValue).getIdentity().toString();

    case EMBEDDED:
      // RECORD
      return OStringSerializerAnyStreamable.INSTANCE.fromStream(iDocument.getDatabase(), (String) iValue);

    case EMBEDDEDMAP:
      // RECORD
      final String value = (String) iValue;
      return ORecordSerializerSchemaAware2CSV.INSTANCE.embeddedMapFromStream(iDocument, null, value);
    }

    throw new IllegalArgumentException("Type " + iType + " not supported to convert value: " + iValue);
  }

  public static List<String> smartSplit(final String iSource, final char iRecordSeparator, final char... iJumpChars) {
    return smartSplit(iSource, new char[] { iRecordSeparator }, 0, iSource.length(), false, iJumpChars);
  }

  public static List<String> smartSplit(final String iSource, final char[] iRecordSeparator, int beginIndex, final int endIndex,
      final boolean iStringSeparatorExtended, final char... iJumpChars) {
    final StringBuilder buffer = new StringBuilder();
    final ArrayList<String> parts = new ArrayList<String>();

    while ((beginIndex = parse(iSource, buffer, beginIndex, endIndex, iRecordSeparator, iStringSeparatorExtended, iJumpChars)) > -1) {
      parts.add(buffer.toString());
      buffer.setLength(0);
    }

    if (buffer.length() > 0)
      parts.add(buffer.toString());

    return parts;
  }

  public static int parse(final String iSource, final StringBuilder iBuffer, final int beginIndex, final int endIndex,
      final char[] iRecordSeparator, final boolean iStringSeparatorExtended, final char... iJumpChars) {
    char stringBeginChar = ' ';
    boolean encodeMode = false;
    int insideParenthesis = 0;
    int insideCollection = 0;
    int insideMap = 0;
    int insideLinkPart = 0;

    final int max = endIndex > -1 ? endIndex : iSource.length();

    for (int i = beginIndex; i < max; ++i) {
      char c = iSource.charAt(i);

      if (stringBeginChar == ' ') {
        // OUTSIDE A STRING

        if (c == COLLECTION_BEGIN)
          insideCollection++;
        else if (c == COLLECTION_END) {
          if (!isCharPresent(c, iRecordSeparator)) {
            if (insideCollection == 0)
              throw new OSerializationException("Found invalid " + COLLECTION_END
                  + " character. Assure to open and close correctly.");
            insideCollection--;
          }

        } else if (c == PARENTHESIS_BEGIN) {
          insideParenthesis++;
        } else if (c == PARENTHESIS_END) {
          if (!isCharPresent(c, iRecordSeparator)) {
            if (insideParenthesis == 0)
              throw new OSerializationException("Found invalid " + PARENTHESIS_END
                  + " character. Assure to open and close correctly.");
            insideParenthesis--;
          }

        } else if (c == MAP_BEGIN) {
          insideMap++;
        } else if (c == MAP_END) {
          if (!isCharPresent(c, iRecordSeparator)) {
            if (insideMap == 0)
              throw new OSerializationException("Found invalid " + MAP_END + " character. Assure to open and close correctly.");
            insideMap--;
          }
        }

        else if (c == LINK)
          // FIRST PART OF LINK
          insideLinkPart = 1;
        else if (insideLinkPart == 1 && c == ORID.SEPARATOR)
          // SECOND PART OF LINK
          insideLinkPart = 2;

        if (insideLinkPart > 0 && c != '-' && !Character.isDigit(c) && c != ORID.SEPARATOR && c != LINK)
          insideLinkPart = 0;

        if ((c == '"' || iStringSeparatorExtended && c == '\'') && !encodeMode) {
          // START STRING
          stringBeginChar = c;
        }

        if (insideParenthesis == 0 && insideCollection == 0 && insideMap == 0 && insideLinkPart == 0) {
          // OUTSIDE A PARAMS/COLLECTION/MAP
          if (isCharPresent(c, iRecordSeparator)) {
            // SEPARATOR (OUTSIDE A STRING): PUSH
            return i + 1;
          }
        }

      } else {
        // INSIDE A STRING
        if ((c == '"' || iStringSeparatorExtended && c == '\'') && !encodeMode) {
          // CLOSE THE STRING ?
          if (stringBeginChar == c) {
            // SAME CHAR AS THE BEGIN OF THE STRING: CLOSE IT AND PUSH
            stringBeginChar = ' ';
          }
        }
      }

      if (c == '\\' && !encodeMode)
        encodeMode = true;
      else
        encodeMode = false;

      if (iJumpChars.length > 0) {
        if (isCharPresent(c, iJumpChars))
          continue;
      }

      iBuffer.append(c);
    }
    return -1;
  }

  public static boolean isCharPresent(final char iCharacter, final char[] iCharacters) {
    final int len = iCharacters.length;
    for (int i = 0; i < len; ++i) {
      if (iCharacter == iCharacters[i]) {
        return true;
      }
    }

    return false;
  }

  public static List<String> split(final String iSource, final char iRecordSeparator, final char... iJumpCharacters) {
    return split(iSource, 0, iSource.length(), iRecordSeparator, iJumpCharacters);
  }

  public static Collection<String> split(final Collection<String> iParts, final String iSource, final char iRecordSeparator,
      final char... iJumpCharacters) {
    return split(iParts, iSource, 0, iSource.length(), iRecordSeparator, iJumpCharacters);
  }

  public static List<String> split(final String iSource, final int iStartPosition, final int iEndPosition,
      final char iRecordSeparator, final char... iJumpCharacters) {
    return (List<String>) split(new ArrayList<String>(), iSource, 0, iSource.length(), iRecordSeparator, iJumpCharacters);
  }

  public static Collection<String> split(final Collection<String> iParts, final String iSource, final int iStartPosition,
      final int iEndPosition, final char iRecordSeparator, final char... iJumpCharacters) {
    final StringBuilder buffer = new StringBuilder();

    for (int i = iStartPosition; i < iEndPosition; ++i) {
      char c = iSource.charAt(i);

      if (c == iRecordSeparator) {
        iParts.add(buffer.toString());
        buffer.setLength(0);
      } else {
        if (iJumpCharacters.length > 0 && buffer.length() == 0) {
          // CHECK IF IT'S A CHAR TO JUMP
          if (!isCharPresent(c, iJumpCharacters)) {
            buffer.append(c);
          }
        } else
          buffer.append(c);
      }
    }

    if (iJumpCharacters.length > 0 && buffer.length() > 0) {
      // CHECK THE END OF LAST ITEM IF NEED TO CUT THE CHARS TO JUMP
      char b;
      int newSize = 0;
      boolean found;
      for (int i = buffer.length() - 1; i >= 0; --i) {
        b = buffer.charAt(i);
        found = false;
        for (char j : iJumpCharacters) {
          if (j == b) {
            found = true;
            ++newSize;
            break;
          }
        }
        if (!found)
          break;
      }
      if (newSize > 0)
        buffer.setLength(buffer.length() - newSize);
    }

    iParts.add(buffer.toString());

    return iParts;
  }

  public static String joinIntArray(int[] iArray) {
    final StringBuilder ids = new StringBuilder();
    for (int id : iArray) {
      if (ids.length() > 0)
        ids.append(RECORD_SEPARATOR);
      ids.append(id);
    }
    return ids.toString();
  }

  public static int[] splitIntArray(final String iInput) {
    final List<String> items = split(iInput, RECORD_SEPARATOR);
    final int[] values = new int[items.size()];
    for (int i = 0; i < items.size(); ++i) {
      values[i] = Integer.parseInt(items.get(i));
    }
    return values;
  }

  public static boolean contains(final String iText, final char iSeparator) {
    if (iText == null)
      return false;

    final int max = iText.length();
    for (int i = 0; i < max; ++i) {
      if (iText.charAt(i) == iSeparator)
        return true;
    }

    return false;
  }

  public static int getCollection(final String iText, final int iStartPosition, final Collection<String> iCollection) {
    int openPos = iText.indexOf(COLLECTION_BEGIN, iStartPosition);
    if (openPos == -1)
      return -1;

    int closePos = iText.indexOf(COLLECTION_END, openPos + 1);
    if (closePos == -1)
      return -1;

    split(iCollection, iText.substring(openPos + 1, closePos), COLLECTION_SEPARATOR, ' ');

    return closePos;
  }

  public static int getParameters(final String iText, final int iBeginPosition, final List<String> iParameters) {
    iParameters.clear();

    final int openPos = iText.indexOf(PARENTHESIS_BEGIN, iBeginPosition);
    if (openPos == -1)
      return iBeginPosition;

    final StringBuilder buffer = new StringBuilder();
    parse(iText, buffer, openPos, -1, PARAMETER_EXT_SEPARATOR, true);
    if (buffer.length() == 0)
      return iBeginPosition;

    final int firstClose = buffer.indexOf(")", 1);
    if (firstClose > -1 && firstClose < buffer.length() - 1) {
      final int otherParenthesis = buffer.indexOf("(", firstClose);
      if (otherParenthesis > -1)
        buffer.delete(otherParenthesis, buffer.length());
    }

    final String t = buffer.substring(1, buffer.length() - 1);
    final List<String> pars = smartSplit(t, PARAMETER_SEPARATOR, 0, t.length(), true);

    for (int i = 0; i < pars.size(); ++i)
      iParameters.add(pars.get(i).trim());

    return iBeginPosition + buffer.length();
  }

  public static List<String> getParameters(final String iText) {
    final List<String> params = new ArrayList<String>();
    getParameters(iText, 0, params);
    return params;
  }

  public static Map<String, String> getMap(final ODatabaseRecord iDatabase, final String iText) {
    int openPos = iText.indexOf(MAP_BEGIN);
    if (openPos == -1)
      return EMPTY_MAP;

    int closePos = iText.indexOf(MAP_END, openPos + 1);
    if (closePos == -1)
      return EMPTY_MAP;

    final List<String> entries = smartSplit(iText.substring(openPos + 1, closePos), COLLECTION_SEPARATOR);
    if (entries.size() == 0)
      return EMPTY_MAP;

    Map<String, String> map = new HashMap<String, String>();

    List<String> entry;
    for (String item : entries) {
      if (item != null && item.length() > 0) {
        entry = OStringSerializerHelper.split(item, OStringSerializerHelper.ENTRY_SEPARATOR);

        map.put((String) fieldTypeFromStream(null, OType.STRING, entry.get(0)), entry.get(1));
      }
    }

    return map;
  }

  /**
   * Transforms, only if needed, the source string escaping the characters \ and ".
   *
   * @param iText
   *          Input String
   * @return Modified string if needed, otherwise the same input object
   * @see OStringSerializerHelper#decode(String)
   */
  public static String encode(final String iText) {
    int pos = -1;

    final int newSize = iText.length();
    for (int i = 0; i < newSize; ++i) {
      final char c = iText.charAt(i);

      if (c == '"' || c == '\\') {
        pos = i;
        break;
      }
    }

    if (pos > -1) {
      // CHANGE THE INPUT STRING
      final StringBuilder iOutput = new StringBuilder();

      char c;
      for (int i = 0; i < iText.length(); ++i) {
        c = iText.charAt(i);

        if (c == '"' || c == '\\')
          iOutput.append('\\');

        iOutput.append(c);
      }
      return iOutput.toString();
    }

    return iText;
  }

  /**
   * Transforms, only if needed, the source string un-escaping the characters \ and ".
   *
   * @param iText
   *          Input String
   * @return Modified string if needed, otherwise the same input object
   * @see OStringSerializerHelper#encode(String)
   */
  public static String decode(final String iText) {
    int pos = -1;

    for (int i = 0; i < iText.length(); ++i)
      if (iText.charAt(i) == '"' || iText.charAt(i) == '\\') {
        pos = i;
        break;
      }

    if (pos == -1)
      // NOT FOUND, RETURN THE SAME STRING (AVOID COPIES)
      return iText;

    // CHANGE THE INPUT STRING
    final StringBuilder buffer = new StringBuilder(iText);

    char c;
    for (int i = pos; i < buffer.length(); ++i) {
      c = buffer.charAt(i);

      if (c == '\\') {
        buffer.deleteCharAt(i);
      }
    }

    return buffer.toString();
  }

  public static OClass getRecordClassName(final ODatabaseRecord iDatabase, String iValue, OClass iLinkedClass) {
    // EXTRACT THE CLASS NAME
    int classSeparatorPos = iValue.indexOf(OStringSerializerHelper.CLASS_SEPARATOR);
    if (classSeparatorPos > -1) {
      final String className = iValue.substring(0, classSeparatorPos);
      if (className != null && iDatabase != null)
        iLinkedClass = iDatabase.getMetadata().getSchema().getClass(className);

      iValue = iValue.substring(classSeparatorPos + 1);
    }
    return iLinkedClass;
  }

  public static String java2unicode(final String iInput) {
    final StringBuffer result = new StringBuffer();

    char ch;
    String hex;
    for (int i = 0; i < iInput.length(); i++) {
      ch = iInput.charAt(i);

      if (ch >= 0x0020 && ch <= 0x007e) // Does the char need to be converted to unicode?
        result.append(ch); // No.
      else // Yes.
      {
        result.append("\\u"); // standard unicode format.
        hex = Integer.toHexString(iInput.charAt(i) & 0xFFFF); // Get hex value of the char.
        for (int j = 0; j < 4 - hex.length(); j++)
          // Prepend zeros because unicode requires 4 digits
          result.append('0');
        result.append(hex.toLowerCase()); // standard unicode format.
        // ostr.append(hex.toLowerCase(Locale.ENGLISH));
      }
    }

    return result.toString();
  }

  public static String getStringContent(final Object iValue) {
    if (iValue == null)
      return null;

    final String s = iValue.toString();

    if (s == null)
      return null;

    if (s.length() > 1
        && (s.charAt(0) == '\'' && s.charAt(s.length() - 1) == '\'' || s.charAt(0) == '"' && s.charAt(s.length() - 1) == '"'))
      return s.substring(1, s.length() - 1);

    return s;
  }

  /**
   * Checks if a string contains alphanumeric only characters.
   *
   * @param iContent
   *          String to check
   * @return true is all the content is alphanumeric, otherwise false
   */
  public static boolean isAlphanumeric(final String iContent) {
    final int tot = iContent.length();
    for (int i = 0; i < tot; ++i) {
      if (!Character.isLetterOrDigit(iContent.charAt(i)))
        return false;
    }
    return true;
  }

  public static String removeQuotationMarks(final String iValue) {
    if (iValue != null
        && iValue.length() > 1
        && (iValue.charAt(0) == '\'' && iValue.charAt(iValue.length() - 1) == '\'' || iValue.charAt(0) == '"'
            && iValue.charAt(iValue.length() - 1) == '"'))
      return iValue.substring(1, iValue.length() - 1);

    return iValue;
  }

  public static boolean startsWithIgnoreCase(final String iFirst, final String iSecond) {
    if (iFirst == null)
      throw new IllegalArgumentException("Origin string to compare is null");
    if (iSecond == null)
      throw new IllegalArgumentException("String to match is null");

    final int iSecondLength = iSecond.length();

    if (iSecondLength > iFirst.length())
      return false;

    for (int i = 0; i < iSecondLength; ++i) {
      if (Character.toUpperCase(iFirst.charAt(i)) != Character.toUpperCase(iSecond.charAt(i)))
        return false;
    }
    return true;
  }
}
TOP

Related Classes of com.orientechnologies.orient.core.serialization.serializer.OStringSerializerHelper

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.