All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.modeshape.schematic.internal.document.BsonUtils Maven / Gradle / Ivy

The newest version!
/*
 * ModeShape (http://www.modeshape.org)
 *
 * 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.modeshape.schematic.internal.document;

import java.util.regex.Pattern;
import org.modeshape.schematic.document.Null;
import org.modeshape.schematic.document.ObjectId;

public class BsonUtils {

   public static int regexFlagsFrom(String flags) {
      if (flags == null)
         return 0;
      flags = flags.toLowerCase();
      int value = 0;

      for (int i = 0; i < flags.length(); i++) {
         char c = flags.charAt(i);
         switch (c) {
            case 'i':
               value |= Pattern.CASE_INSENSITIVE;
               break;
            case 'm':
               value |= Pattern.MULTILINE;
               break;
            case 'd':
               value |= Pattern.UNIX_LINES;
               break;
            case 'c':
               value |= Pattern.CANON_EQ;
               break;
            case 's':
               value |= Pattern.DOTALL;
               break;
            case 't':
               value |= Pattern.LITERAL;
               break;
            case 'u':
               value |= Pattern.UNICODE_CASE;
               break;
            case 'x':
               value |= Pattern.COMMENTS;
               break;
            case 'g': // global flag
               // ignore
               break;
            default:
               throw new IllegalArgumentException("unrecognized regex flag '" + c + "'");
         }
      }
      return value;
   }

   public static String regexFlagsFor(Pattern pattern) {
      return regexFlagsFor(pattern.flags());
   }

   public static String regexFlagsFor(int flags) {
      if (flags == 0)
         return "";
      StringBuilder sb = new StringBuilder();
      // Order of characters is important here
      if ((flags & Pattern.CANON_EQ) == Pattern.CANON_EQ)
         sb.append('c');
      if ((flags & Pattern.UNIX_LINES) == Pattern.UNIX_LINES)
         sb.append('d');
      if ((flags & Pattern.CASE_INSENSITIVE) == Pattern.CASE_INSENSITIVE)
         sb.append('i');
      if ((flags & Pattern.MULTILINE) == Pattern.MULTILINE)
         sb.append('m');
      if ((flags & Pattern.DOTALL) == Pattern.DOTALL)
         sb.append('s');
      if ((flags & Pattern.LITERAL) == Pattern.LITERAL)
         sb.append('t');
      if ((flags & Pattern.UNICODE_CASE) == Pattern.UNICODE_CASE)
         sb.append('u');
      if ((flags & Pattern.COMMENTS) == Pattern.COMMENTS)
         sb.append('x');
      return sb.toString();
   }

   /**
    * The BSON specification (or rather the MongoDB
    * documentation) defines the structure of this data:
    * 

* "A BSON ObjectID is a 12-byte value consisting of a 4-byte timestamp (seconds since epoch), a 3-byte * machine id, a 2-byte process id, and a 3-byte counter. Note that the timestamp and counter fields must be stored * big endian unlike the rest of BSON. This is because they are compared byte-by-byte and we want to ensure a mostly * increasing order." *

* * @param bytes * @return the ObjectId */ public static ObjectId readObjectId(byte[] bytes) { // Compute the values in big-endian ... int time = ((bytes[0] & 0xff) << 24) + ((bytes[1] & 0xff) << 16) + ((bytes[2] & 0xff) << 8) + ((bytes[3] & 0xff) << 0); int machine = ((bytes[4] & 0xff) << 16) + ((bytes[5] & 0xff) << 8) + ((bytes[6] & 0xff) << 0); int process = ((bytes[7] & 0xff) << 8) + ((bytes[8] & 0xff) << 0); int inc = ((bytes[9] & 0xff) << 16) + ((bytes[10] & 0xff) << 8) + ((bytes[11] & 0xff) << 0); // Create the value object ... return new ObjectId(time, machine, process, inc); } /** * Read the {@link ObjectId} from the hexadecimal string representation of the ObjectId. * * @param bytesInHex * the hexadecimal identifier * @return the ObjectId */ public static ObjectId readObjectId(String bytesInHex) { byte[] bytes = new byte[12]; assert bytesInHex.length() == 24; for (int i = 0, index = 0; i != 12; ++i) { String hexChar = bytesInHex.substring(index, index += 2); bytes[i] = (byte) Integer.parseInt(hexChar, 16); } return readObjectId(bytes); } /** * Write the 12-byte representation of the ObjectId per the BSON specification (or rather the MongoDB documentation). * * @param id * the ObjectId; may not be null * @param b * the bytes into which the object ID should be written */ public static void writeObjectId(ObjectId id, byte[] b) { int time = id.getTime(); int machine = id.getMachine(); int process = id.getProcess(); int inc = id.getInc(); b[0] = (byte) ((time >>> 24) & 0xFF); b[1] = (byte) ((time >>> 16) & 0xFF); b[2] = (byte) ((time >>> 8) & 0xFF); b[3] = (byte) ((time >>> 0) & 0xFF); b[4] = (byte) ((machine >>> 16) & 0xFF); b[5] = (byte) ((machine >>> 8) & 0xFF); b[6] = (byte) ((machine >>> 0) & 0xFF); b[7] = (byte) ((process >>> 8) & 0xFF); b[8] = (byte) ((process >>> 0) & 0xFF); b[9] = (byte) ((inc >>> 16) & 0xFF); b[10] = (byte) ((inc >>> 8) & 0xFF); b[11] = (byte) ((inc >>> 0) & 0xFF); } public static boolean valuesAreEqual(Object thisValue, Object thatValue) { if (thisValue == thatValue) { return true; } if (thisValue == null || thisValue instanceof Null) { return Null.matches(thatValue); } if (thisValue instanceof Number && thatValue instanceof Number) { // Need to handle float vs. doubles Number thisNumber = (Number) thisValue; Number thatNumber = (Number) thatValue; return thisNumber.doubleValue() == thatNumber.doubleValue(); } if (thisValue instanceof Pattern && thatValue instanceof Pattern) { // java.util.regex.Pattern does not implement equals!! Pattern thisPattern = (Pattern) thisValue; Pattern thatPattern = (Pattern) thatValue; return thisPattern.pattern().equals(thatPattern.pattern()) && thisPattern.flags() == thatPattern.flags(); } return thisValue.equals(thatValue); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy