You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@usergrid.apache.org by sn...@apache.org on 2014/03/15 01:26:51 UTC
[03/50] [abbrv] Package re-org.
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/75da9b8d/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/utils/UUIDUtils.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/utils/UUIDUtils.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/utils/UUIDUtils.java
deleted file mode 100644
index 0363cd6..0000000
--- a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/utils/UUIDUtils.java
+++ /dev/null
@@ -1,412 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.apache.usergrid.persistence.utils;
-
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Random;
-import java.util.UUID;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.locks.ReentrantLock;
-
-import com.fasterxml.uuid.EthernetAddress;
-import com.fasterxml.uuid.UUIDComparator;
-
-import static com.fasterxml.uuid.impl.UUIDUtil.BYTE_OFFSET_CLOCK_HI;
-import static com.fasterxml.uuid.impl.UUIDUtil.BYTE_OFFSET_CLOCK_LO;
-import static com.fasterxml.uuid.impl.UUIDUtil.BYTE_OFFSET_CLOCK_MID;
-import static com.fasterxml.uuid.impl.UUIDUtil.BYTE_OFFSET_CLOCK_SEQUENCE;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import static org.apache.commons.codec.binary.Base64.decodeBase64;
-import static org.apache.commons.codec.binary.Base64.encodeBase64URLSafeString;
-
-import static org.apache.usergrid.persistence.utils.ConversionUtils.bytes;
-import static org.apache.usergrid.persistence.utils.ConversionUtils.uuid;
-
-
-public class UUIDUtils {
- private static final Logger LOG = LoggerFactory.getLogger( UUIDUtils.class );
- private static final int[] MICROS = new int[1000];
-
-
- static {
- for ( int x = 0; x < 1000; x++ ) {
- MICROS[x] = x * 10;
- }
- }
-
-
- private static ReentrantLock tsLock = new ReentrantLock( true );
-
- public static final UUID MIN_TIME_UUID = UUID.fromString( "00000000-0000-1000-8000-000000000000" );
-
- public static final UUID MAX_TIME_UUID = UUID.fromString( "ffffffff-ffff-1fff-bfff-ffffffffffff" );
-
- public static final UUID ZERO_UUID = new UUID( 0, 0 );
-
- private static long timestampMillisNow = System.currentTimeMillis();
-
- private static AtomicInteger currentMicrosPoint = new AtomicInteger( 0 );
- private static AtomicInteger customMicrosPointer = new AtomicInteger( 0 );
-
-
- /**
- * Return the "next" UUID in micro second resolution. <b>WARNING</b>: this is designed to return the next unique
- * timestamped UUID for this JVM. Depending on velocity of the call, this method may block internally to insure that
- * "now" is kept in sync with the UUIDs being generated by this call.
- * <p/>
- * In other words, we will intentionally burn CPU insuring that this method is not executed more than 10k -1 times
- * per millisecond and guarantee that those microseconds held within are sequential.
- * <p/>
- * If we did not do this, you would get <b>timestamp collision</b> even though the UUIDs will technically be
- * 'unique.'
- */
- public static java.util.UUID newTimeUUID() {
- // get & inc counter, but roll on 1k (because we divide by 10 on retrieval)
- // if count + currentMicro > 1k, block and roll
- tsLock.lock();
- long ts = System.currentTimeMillis();
- if ( ts > timestampMillisNow ) {
- timestampMillisNow = ts;
- currentMicrosPoint.set( 0 );
- }
- int pointer = currentMicrosPoint.getAndIncrement();
- try {
- if ( pointer > 990 ) {
- TimeUnit.MILLISECONDS.sleep( 1L );
- }
- }
- catch ( Exception ex ) {
- ex.printStackTrace();
- }
- finally {
- tsLock.unlock();
- }
- return newTimeUUID( ts, MICROS[pointer] );
- }
-
-
- private static final long KCLOCK_OFFSET = 0x01b21dd213814000L;
- private static final long KCLOCK_MULTIPLIER_L = 10000L;
-
- private static final Random CLOCK_SEQ_RANDOM = new Random();
-
-
- // 14 bits of randomness
- private static int getRandomClockSequence() {
- return CLOCK_SEQ_RANDOM.nextInt() & 0x3FFF;
- }
-
-
- private static void setTimestamp( long timestamp, byte[] uuidBytes, int clockSeq, int timeOffset ) {
-
- timestamp *= KCLOCK_MULTIPLIER_L;
- timestamp += KCLOCK_OFFSET;
- timestamp += timeOffset;
-
- // Set random clock sequence
- uuidBytes[BYTE_OFFSET_CLOCK_SEQUENCE] = ( byte ) ( clockSeq >> 8 );
- uuidBytes[BYTE_OFFSET_CLOCK_SEQUENCE + 1] = ( byte ) clockSeq;
-
- // Set variant
- uuidBytes[BYTE_OFFSET_CLOCK_SEQUENCE] &= 0x3F;
- uuidBytes[BYTE_OFFSET_CLOCK_SEQUENCE] |= 0x80;
- setTime( uuidBytes, timestamp );
- }
-
-
- @SuppressWarnings("all")
- private static void setTime( byte[] uuidBytes, long timestamp ) {
-
- // Time fields aren't nicely split across the UUID, so can't just
- // linearly dump the stamp:
- int clockHi = ( int ) ( timestamp >>> 32 );
- int clockLo = ( int ) timestamp;
-
- uuidBytes[BYTE_OFFSET_CLOCK_HI] = ( byte ) ( clockHi >>> 24 );
- uuidBytes[BYTE_OFFSET_CLOCK_HI + 1] = ( byte ) ( clockHi >>> 16 );
- uuidBytes[BYTE_OFFSET_CLOCK_MID] = ( byte ) ( clockHi >>> 8 );
- uuidBytes[BYTE_OFFSET_CLOCK_MID + 1] = ( byte ) clockHi;
-
- uuidBytes[BYTE_OFFSET_CLOCK_LO] = ( byte ) ( clockLo >>> 24 );
- uuidBytes[BYTE_OFFSET_CLOCK_LO + 1] = ( byte ) ( clockLo >>> 16 );
- uuidBytes[BYTE_OFFSET_CLOCK_LO + 2] = ( byte ) ( clockLo >>> 8 );
- uuidBytes[BYTE_OFFSET_CLOCK_LO + 3] = ( byte ) clockLo;
-
- // Set version
- uuidBytes[BYTE_OFFSET_CLOCK_HI] &= 0x0F;
- uuidBytes[BYTE_OFFSET_CLOCK_HI] |= 0x10;
- }
-
-
- /**
- * Generate a timeuuid with the given timestamp in milliseconds and the time offset. Useful when you need to
- * generate sequential UUIDs for the same period in time. I.E
- * <p/>
- * newTimeUUID(1000, 0) <br/> newTimeUUID(1000, 1) <br /> newTimeUUID(1000, 2) <br />
- * <p/>
- * etc.
- * <p/>
- * Only use this method if you are absolutely sure you need it. When it doubt use the method without the timestamp
- * offset
- *
- * @param ts The timestamp in milliseconds
- * @param timeoffset The offset, which should always be <= 10000. If you go beyond this range, the millisecond will
- * be incremented since this is beyond the possible values when coverrting from millis to 1/10 microseconds stored
- * in the time uuid.
- */
- public static UUID newTimeUUID( long ts, int timeoffset ) {
- if ( ts == 0 ) {
- return newTimeUUID();
- }
-
- byte[] uuidBytes = new byte[16];
- // 47 bits of randomness
- EthernetAddress eth = EthernetAddress.constructMulticastAddress();
- eth.toByteArray( uuidBytes, 10 );
- setTimestamp( ts, uuidBytes, getRandomClockSequence(), timeoffset );
-
- return uuid( uuidBytes );
- }
-
-
- /**
- * Generate a new UUID with the given time stamp in milliseconds. This method guarantees that subsequent calls will
- * be of increasing value chronologically. If a large number of subsequent calls are made to this method (>1000)
- * with the same timestamp, you will have non-unique temporal values stored in your UUID.
- */
- public static UUID newTimeUUID( long ts ) {
- tsLock.lock();
- int pointer = customMicrosPointer.getAndIncrement();
- try {
- if ( pointer > 990 ) {
- customMicrosPointer.set( 0 );
- }
- }
- finally {
- tsLock.unlock();
- }
- return newTimeUUID( ts, MICROS[pointer] );
- }
-
-
- public static UUID minTimeUUID( long ts ) {
- byte[] uuidBytes = new byte[16];
- setTimestamp( ts, uuidBytes, 0, 0 );
-
- return uuid( uuidBytes );
- }
-
-
- public static UUID maxTimeUUID( long ts ) {
- byte[] uuidBytes = new byte[16];
- uuidBytes[10] = ( byte ) 0xFF;
- uuidBytes[11] = ( byte ) 0xFF;
- uuidBytes[12] = ( byte ) 0xFF;
- uuidBytes[13] = ( byte ) 0xFF;
- uuidBytes[14] = ( byte ) 0xFF;
- uuidBytes[15] = ( byte ) 0xFF;
- setTimestamp( ts, uuidBytes, 0x3FFF, 0x1FFF );
-
- return uuid( uuidBytes );
- }
-
-
- /** Returns the minimum UUID */
- public static UUID min( UUID first, UUID second ) {
- if ( first == null ) {
- if ( second == null ) {
- return null;
- }
- return second;
- }
-
- if ( second == null ) {
- return first;
- }
-
- if ( compare( first, second ) < 0 ) {
- return first;
- }
- return second;
- }
-
-
- /** Returns the minimum UUID */
- public static UUID max( UUID first, UUID second ) {
- if ( first == null ) {
- if ( second == null ) {
- return null;
- }
- return second;
- }
-
- if ( second == null ) {
- return first;
- }
-
- if ( compare( first, second ) < 0 ) {
- return second;
- }
- return first;
- }
-
-
- /** Returns a UUID that is -1 of the passed uuid, sorted by time uuid only */
- public static UUID decrement( UUID uuid ) {
- if ( !isTimeBased( uuid ) ) {
- throw new IllegalArgumentException( "The uuid must be a time type" );
- }
-
-
- //timestamp is in the 60 bit timestamp
- long timestamp = uuid.timestamp();
- timestamp--;
-
- if ( timestamp < 0 ) {
- throw new IllegalArgumentException( "You must specify a time uuid with a timestamp > 0" );
- }
-
- //get our bytes, then set the smaller timestamp into it
- byte[] uuidBytes = bytes( uuid );
-
- setTime( uuidBytes, timestamp );
-
- return uuid( uuidBytes );
- }
-
-
- public static boolean isTimeBased( UUID uuid ) {
- if ( uuid == null ) {
- return false;
- }
- return uuid.version() == 1;
- }
-
-
- public static long getTimestampInMillis( UUID uuid ) {
- if ( uuid == null ) {
- return 0;
- }
- long t = uuid.timestamp();
- return ( t - KCLOCK_OFFSET ) / KCLOCK_MULTIPLIER_L;
- }
-
-
- public static long getTimestampInMicros( UUID uuid ) {
- if ( uuid == null ) {
- return 0;
- }
- long t = uuid.timestamp();
- return ( t - KCLOCK_OFFSET ) / 10;
- }
-
-
- public static UUID tryGetUUID( String s ) {
- if ( s == null ) {
- return null;
- }
- if ( s.length() != 36 ) {
- return null;
- }
- // 8-4-4-4-12
- // 0-7,8,9-12,13,14-17,18,19-22,23,24-35
- if ( s.charAt( 8 ) != '-' ) {
- return null;
- }
- if ( s.charAt( 13 ) != '-' ) {
- return null;
- }
- if ( s.charAt( 18 ) != '-' ) {
- return null;
- }
- if ( s.charAt( 23 ) != '-' ) {
- return null;
- }
- UUID uuid = null;
- try {
- uuid = UUID.fromString( s );
- }
- catch ( Exception e ) {
- LOG.info( "Could not convert String {} into a UUID", s, e );
- }
- return uuid;
- }
-
-
- public static boolean isUUID( String s ) {
- return tryGetUUID( s ) != null;
- }
-
-
- public static UUID tryExtractUUID( String s ) {
- if ( s == null ) {
- return null;
- }
- if ( s.length() < 36 ) {
- return null;
- }
- return tryGetUUID( s.substring( 0, 36 ) );
- }
-
-
- public static UUID tryExtractUUID( String s, int offset ) {
- if ( s == null ) {
- return null;
- }
- if ( ( s.length() - offset ) < 36 ) {
- return null;
- }
- return tryGetUUID( s.substring( offset, offset + 36 ) );
- }
-
-
- public static String toBase64( UUID id ) {
- if ( id == null ) {
- return null;
- }
- return encodeBase64URLSafeString( bytes( id ) );
- }
-
-
- public static UUID fromBase64( String str ) {
- if ( str == null ) {
- return null;
- }
- byte[] bytes = decodeBase64( str );
- if ( bytes.length != 16 ) {
- return null;
- }
- return uuid( bytes );
- }
-
-
- public static int compare( UUID u1, UUID u2 ) {
- return UUIDComparator.staticCompare( u1, u2 );
- }
-
-
- public static List<UUID> sort( List<UUID> uuids ) {
- Collections.sort( uuids, new UUIDComparator() );
- return uuids;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/75da9b8d/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/ClassUtils.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/ClassUtils.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/ClassUtils.java
new file mode 100644
index 0000000..6ce847e
--- /dev/null
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/ClassUtils.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.usergrid.utils;
+
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+
+public class ClassUtils extends org.apache.commons.lang.ClassUtils {
+
+ @SuppressWarnings("unchecked")
+ public static <A, B> B cast( A a ) {
+ return ( B ) a;
+ }
+
+
+ @SuppressWarnings("unchecked")
+ private static final Set<Class<?>> WRAPPER_TYPES = new HashSet<Class<?>>(
+ Arrays.asList( Boolean.class, Byte.class, Character.class, Double.class, Float.class, Integer.class,
+ Long.class, Short.class, Void.class ) );
+
+
+ public static boolean isWrapperType( Class<?> clazz ) {
+ return WRAPPER_TYPES.contains( clazz );
+ }
+
+
+ public static boolean isPrimitiveType( Class<?> clazz ) {
+ if ( clazz == null ) {
+ return false;
+ }
+ return clazz.isPrimitive() || isWrapperType( clazz );
+ }
+
+
+ public static boolean isBasicType( Class<?> clazz ) {
+ if ( clazz == null ) {
+ return false;
+ }
+ return ( String.class.isAssignableFrom( clazz ) ) || isPrimitiveType( clazz );
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/75da9b8d/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/ConversionUtils.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/ConversionUtils.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/ConversionUtils.java
new file mode 100644
index 0000000..567a713
--- /dev/null
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/ConversionUtils.java
@@ -0,0 +1,765 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.usergrid.utils;
+
+
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.commons.lang.math.NumberUtils;
+
+
+/** Convenience methods for converting to and from formats, primarily between byte arrays and UUIDs, Strings,
+ * and Longs. */
+public class ConversionUtils {
+
+ private static final Logger logger = LoggerFactory.getLogger( ConversionUtils.class );
+
+ /**
+ *
+ */
+ public static final String UTF8_ENCODING = "UTF-8";
+
+ /**
+ *
+ */
+ public static final String ASCII_ENCODING = "US-ASCII";
+
+ public static final ByteBuffer HOLDER = ByteBuffer.wrap( new byte[] { 0 } );
+
+
+ /**
+ * @param uuid
+ * @return
+ */
+ public static UUID uuid( byte[] uuid ) {
+ return uuid( uuid, 0 );
+ }
+
+
+ /**
+ * @param uuid
+ * @param offset
+ * @return
+ */
+ public static UUID uuid( byte[] uuid, int offset ) {
+ ByteBuffer bb = ByteBuffer.wrap( uuid, offset, 16 );
+ return new UUID( bb.getLong(), bb.getLong() );
+ }
+
+
+ public static UUID uuid( ByteBuffer bb ) {
+ if ( bb == null ) {
+ return null;
+ }
+ if ( bb.remaining() < 16 ) {
+ return null;
+ }
+ bb = bb.slice();
+ return new UUID( bb.getLong(), bb.getLong() );
+ }
+
+
+ /**
+ * @param uuid
+ * @return
+ */
+ public static UUID uuid( String uuid ) {
+ try {
+ return UUID.fromString( uuid );
+ }
+ catch ( Exception e ) {
+ logger.error( "Bad UUID", e );
+ }
+ return UUIDUtils.ZERO_UUID;
+ }
+
+
+ /**
+ * @param obj
+ * @return
+ */
+ public static UUID uuid( Object obj ) {
+ return uuid( obj, UUIDUtils.ZERO_UUID );
+ }
+
+
+ public static UUID uuid( Object obj, UUID defaultValue ) {
+ if ( obj instanceof UUID ) {
+ return ( UUID ) obj;
+ }
+ else if ( obj instanceof byte[] ) {
+ return uuid( ( byte[] ) obj );
+ }
+ else if ( obj instanceof ByteBuffer ) {
+ return uuid( ( ByteBuffer ) obj );
+ }
+ else if ( obj instanceof String ) {
+ return uuid( ( String ) obj );
+ }
+ return defaultValue;
+ }
+
+
+ /**
+ * @param uuid
+ * @return
+ */
+ public static byte[] bytes( UUID uuid ) {
+ if ( uuid == null ) {
+ return null;
+ }
+ long msb = uuid.getMostSignificantBits();
+ long lsb = uuid.getLeastSignificantBits();
+ byte[] buffer = new byte[16];
+
+ for ( int i = 0; i < 8; i++ ) {
+ buffer[i] = ( byte ) ( msb >>> ( 8 * ( 7 - i ) ) );
+ }
+ for ( int i = 8; i < 16; i++ ) {
+ buffer[i] = ( byte ) ( lsb >>> ( 8 * ( 7 - i ) ) );
+ }
+
+ return buffer;
+ }
+
+
+ public static ByteBuffer bytebuffer( UUID uuid ) {
+ if ( uuid == null ) {
+ return null;
+ }
+ return ByteBuffer.wrap( bytes( uuid ) );
+ }
+
+
+ /**
+ * @param uuid
+ * @return
+ */
+ public static byte[] uuidToBytesNullOk( UUID uuid ) {
+ if ( uuid != null ) {
+ return bytes( uuid );
+ }
+ return new byte[16];
+ }
+
+
+ /**
+ * @param s
+ * @return
+ */
+ public static byte[] bytes( String s ) {
+ return bytes( s, UTF8_ENCODING );
+ }
+
+
+ public static ByteBuffer bytebuffer( String s ) {
+ return ByteBuffer.wrap( bytes( s ) );
+ }
+
+
+ /**
+ * @param s
+ * @return
+ */
+ public static byte[] ascii( String s ) {
+ if ( s == null ) {
+ return new byte[0];
+ }
+ return bytes( s, ASCII_ENCODING );
+ }
+
+
+ public ByteBuffer asciibuffer( String s ) {
+ return ByteBuffer.wrap( ascii( s ) );
+ }
+
+
+ /**
+ * @param s
+ * @param encoding
+ * @return
+ */
+ public static byte[] bytes( String s, String encoding ) {
+ try {
+ return s.getBytes( encoding );
+ }
+ catch ( UnsupportedEncodingException e ) {
+ // logger.log(Level.SEVERE, "UnsupportedEncodingException ", e);
+ throw new RuntimeException( e );
+ }
+ }
+
+
+ public static byte[] bytes( ByteBuffer bb ) {
+ byte[] b = new byte[bb.remaining()];
+ bb.duplicate().get( b );
+ return b;
+ }
+
+
+ public static ByteBuffer bytebuffer( String s, String encoding ) {
+ return ByteBuffer.wrap( bytes( s, encoding ) );
+ }
+
+
+ /**
+ * @param b
+ * @return
+ */
+ public static byte[] bytes( Boolean b ) {
+ byte[] bytes = new byte[1];
+ bytes[0] = b ? ( byte ) 1 : 0;
+ return bytes;
+ }
+
+
+ public static ByteBuffer bytebuffer( Boolean b ) {
+ return ByteBuffer.wrap( bytes( b ) );
+ }
+
+
+ /**
+ * @param val
+ * @return
+ */
+ public static byte[] bytes( Long val ) {
+ ByteBuffer buf = ByteBuffer.allocate( 8 );
+ buf.order( ByteOrder.BIG_ENDIAN );
+ buf.putLong( val );
+ return buf.array();
+ }
+
+
+ public static ByteBuffer bytebuffer( Long val ) {
+ ByteBuffer buf = ByteBuffer.allocate( 8 );
+ buf.order( ByteOrder.BIG_ENDIAN );
+ buf.putLong( val );
+ return ( ByteBuffer ) buf.rewind();
+ }
+
+
+ /**
+ * @param obj
+ * @return
+ */
+ public static byte[] bytes( Object obj ) {
+ if ( obj == null ) {
+ return new byte[0];
+ }
+ else if ( obj instanceof byte[] ) {
+ return ( byte[] ) obj;
+ }
+ else if ( obj instanceof Long ) {
+ return bytes( ( Long ) obj );
+ }
+ else if ( obj instanceof String ) {
+ return bytes( ( String ) obj );
+ }
+ else if ( obj instanceof UUID ) {
+ return bytes( ( UUID ) obj );
+ }
+ else if ( obj instanceof Boolean ) {
+ return bytes( ( Boolean ) obj );
+ }
+ else if ( obj instanceof Date ) {
+ return bytes( ( ( Date ) obj ).getTime() );
+ }
+ else {
+ return bytes( obj.toString() );
+ }
+ }
+
+
+ public static ByteBuffer bytebuffer( byte[] bytes ) {
+ return ByteBuffer.wrap( bytes );
+ }
+
+
+ public static ByteBuffer bytebuffer( ByteBuffer bytes ) {
+ return bytes.duplicate();
+ }
+
+
+ public static ByteBuffer bytebuffer( Object obj ) {
+ if ( obj instanceof ByteBuffer ) {
+ return ( ( ByteBuffer ) obj ).duplicate();
+ }
+ return ByteBuffer.wrap( bytes( obj ) );
+ }
+
+
+ public static List<ByteBuffer> bytebuffers( List<?> l ) {
+ List<ByteBuffer> results = new ArrayList<ByteBuffer>( l.size() );
+ for ( Object o : l ) {
+ results.add( bytebuffer( o ) );
+ }
+ return results;
+ }
+
+
+ /**
+ * @param bytes
+ * @return
+ */
+ public static boolean getBoolean( byte[] bytes ) {
+ return bytes[0] != 0;
+ }
+
+
+ public static boolean getBoolean( ByteBuffer bytes ) {
+ return bytes.slice().get() != 0;
+ }
+
+
+ /**
+ * @param bytes
+ * @param offset
+ * @return
+ */
+ public static boolean getBoolean( byte[] bytes, int offset ) {
+ return bytes[offset] != 0;
+ }
+
+
+ public static boolean getBoolean( Object obj ) {
+ if ( obj instanceof Boolean ) {
+ return ( Boolean ) obj;
+ }
+ else if ( obj instanceof String ) {
+ return Boolean.parseBoolean( ( String ) obj );
+ }
+ else if ( obj instanceof Number ) {
+ return ( ( Number ) obj ).longValue() > 0;
+ }
+
+ return false;
+ }
+
+
+ /**
+ * @param obj
+ * @return
+ */
+ public static String string( Object obj ) {
+ if ( obj instanceof String ) {
+ return ( String ) obj;
+ }
+ else if ( obj instanceof byte[] ) {
+ return string( ( byte[] ) obj );
+ }
+ else if ( obj instanceof ByteBuffer ) {
+ return string( ( ByteBuffer ) obj );
+ }
+ else if ( obj != null ) {
+ return obj.toString();
+ }
+ return null;
+ }
+
+
+ /**
+ * @param bytes
+ * @return
+ */
+ public static String string( byte[] bytes ) {
+ if ( bytes == null ) {
+ return null;
+ }
+ return string( bytes, 0, bytes.length, UTF8_ENCODING );
+ }
+
+
+ public static String string( ByteBuffer bytes ) {
+ if ( bytes == null ) {
+ return null;
+ }
+ return string( bytes.array(), bytes.arrayOffset() + bytes.position(), bytes.remaining(), UTF8_ENCODING );
+ }
+
+
+ /**
+ * @param bytes
+ * @param offset
+ * @param length
+ * @return
+ */
+ public static String string( byte[] bytes, int offset, int length ) {
+ return string( bytes, offset, length, UTF8_ENCODING );
+ }
+
+
+ /**
+ * @param bytes
+ * @param offset
+ * @param length
+ * @param encoding
+ * @return
+ */
+ public static String string( byte[] bytes, int offset, int length, String encoding ) {
+
+ if ( length <= 0 ) {
+ return "";
+ }
+
+ if ( bytes == null ) {
+ return "";
+ }
+
+ try {
+ return new String( bytes, offset, length, encoding );
+ }
+ catch ( UnsupportedEncodingException e ) {
+ // logger.log(Level.SEVERE, "UnsupportedEncodingException ", e);
+ throw new RuntimeException( e );
+ }
+ }
+
+
+ public static <T> List<String> strings( Collection<T> items ) {
+ List<String> strings = new ArrayList<String>();
+ for ( T item : items ) {
+ strings.add( string( item ) );
+ }
+ return strings;
+ }
+
+
+ /**
+ * @param bytes
+ * @param offset
+ * @return
+ */
+ public static String stringFromLong( byte[] bytes, int offset ) {
+ if ( bytes.length == 0 ) {
+ return "";
+ }
+ if ( ( bytes.length - offset ) < 8 ) {
+ throw new IllegalArgumentException( "A long is at least 8 bytes" );
+ }
+ return String.valueOf( ByteBuffer.wrap( bytes, offset, 8 ).getLong() );
+ }
+
+
+ /**
+ * @param bytes
+ * @return
+ */
+ public static long getLong( byte[] bytes ) {
+ return ByteBuffer.wrap( bytes, 0, 8 ).getLong();
+ }
+
+
+ public static long getLong( ByteBuffer bytes ) {
+ return bytes.slice().getLong();
+ }
+
+
+ public static long getLong( Object obj ) {
+ if ( obj instanceof Long ) {
+ return ( Long ) obj;
+ }
+ if ( obj instanceof Number ) {
+ return ( ( Number ) obj ).longValue();
+ }
+ if ( obj instanceof String ) {
+ return NumberUtils.toLong( ( String ) obj );
+ }
+ if ( obj instanceof Date ) {
+ return ( ( Date ) obj ).getTime();
+ }
+ if ( obj instanceof byte[] ) {
+ return getLong( ( byte[] ) obj );
+ }
+ if ( obj instanceof ByteBuffer ) {
+ return getLong( ( ByteBuffer ) obj );
+ }
+ return 0;
+ }
+
+
+ /**
+ * @param bytes
+ * @return
+ */
+ public static int getInt( byte[] bytes ) {
+ return ByteBuffer.wrap( bytes, 0, 4 ).getInt();
+ }
+
+
+ public static int getInt( ByteBuffer bytes ) {
+ return bytes.slice().getInt();
+ }
+
+
+ public static int getInt( Object obj ) {
+ if ( obj instanceof Integer ) {
+ return ( Integer ) obj;
+ }
+ if ( obj instanceof Number ) {
+ return ( ( Number ) obj ).intValue();
+ }
+ if ( obj instanceof String ) {
+ return NumberUtils.toInt( ( String ) obj );
+ }
+ if ( obj instanceof Date ) {
+ return ( int ) ( ( Date ) obj ).getTime();
+ }
+ if ( obj instanceof byte[] ) {
+ return getInt( ( byte[] ) obj );
+ }
+ if ( obj instanceof ByteBuffer ) {
+ return getInt( ( ByteBuffer ) obj );
+ }
+ return 0;
+ }
+
+
+ /**
+ * @param bytes
+ * @return
+ */
+ public static float getFloat( byte[] bytes ) {
+ return ByteBuffer.wrap( bytes, 0, 4 ).getFloat();
+ }
+
+
+ public static float getFloat( ByteBuffer bytes ) {
+ return bytes.slice().getFloat();
+ }
+
+
+ public static float getFloat( Object obj ) {
+ if ( obj instanceof Float ) {
+ return ( Float ) obj;
+ }
+ if ( obj instanceof Number ) {
+ return ( ( Number ) obj ).floatValue();
+ }
+ if ( obj instanceof String ) {
+ return NumberUtils.toFloat( ( String ) obj );
+ }
+ if ( obj instanceof Date ) {
+ return ( ( Date ) obj ).getTime();
+ }
+ if ( obj instanceof byte[] ) {
+ return getFloat( ( byte[] ) obj );
+ }
+ if ( obj instanceof ByteBuffer ) {
+ return getFloat( ( ByteBuffer ) obj );
+ }
+ return 0;
+ }
+
+
+ public static double getDouble( byte[] bytes ) {
+ return ByteBuffer.wrap( bytes, 0, 8 ).getDouble();
+ }
+
+
+ public static double getDouble( ByteBuffer bytes ) {
+ return bytes.slice().getDouble();
+ }
+
+
+ public static double getDouble( Object obj ) {
+ if ( obj instanceof Double ) {
+ return ( Double ) obj;
+ }
+ if ( obj instanceof Number ) {
+ return ( ( Number ) obj ).doubleValue();
+ }
+ if ( obj instanceof String ) {
+ return NumberUtils.toDouble( ( String ) obj );
+ }
+ if ( obj instanceof Date ) {
+ return ( ( Date ) obj ).getTime();
+ }
+ if ( obj instanceof byte[] ) {
+ return getDouble( ( byte[] ) obj );
+ }
+ if ( obj instanceof ByteBuffer ) {
+ return getDouble( ( ByteBuffer ) obj );
+ }
+ return 0;
+ }
+
+
+ /**
+ * @param type
+ * @param bytes
+ * @return
+ */
+ public static Object object( Class<?> type, byte[] bytes ) {
+
+ try {
+ if ( Long.class.isAssignableFrom( type ) ) {
+ return getLong( bytes );
+ }
+ else if ( UUID.class.isAssignableFrom( type ) ) {
+ return uuid( bytes );
+ }
+ else if ( String.class.isAssignableFrom( type ) ) {
+ return string( bytes );
+ }
+ else if ( Boolean.class.isAssignableFrom( type ) ) {
+ return getBoolean( bytes );
+ }
+ else if ( Integer.class.isAssignableFrom( type ) ) {
+ return getInt( bytes );
+ }
+ else if ( Double.class.isAssignableFrom( type ) ) {
+ return getDouble( bytes );
+ }
+ else if ( Float.class.isAssignableFrom( type ) ) {
+ return getFloat( bytes );
+ }
+ else if ( byte[].class.isAssignableFrom( type ) ) {
+ return bytes;
+ }
+ }
+ catch ( Exception e ) {
+ logger.error( "Unable to get object from bytes for type " + type.getName(), e );
+ }
+ return null;
+ }
+
+
+ public static Object object( Class<?> type, ByteBuffer bytes ) {
+
+ try {
+ if ( Long.class.isAssignableFrom( type ) ) {
+ return bytes.slice().getLong();
+ }
+ else if ( UUID.class.isAssignableFrom( type ) ) {
+ return uuid( bytes );
+ }
+ else if ( String.class.isAssignableFrom( type ) ) {
+ return string( bytes );
+ }
+ else if ( Boolean.class.isAssignableFrom( type ) ) {
+ return bytes.slice().get() != 0;
+ }
+ else if ( Integer.class.isAssignableFrom( type ) ) {
+ return bytes.slice().getInt();
+ }
+ else if ( Double.class.isAssignableFrom( type ) ) {
+ return bytes.slice().getDouble();
+ }
+ else if ( Float.class.isAssignableFrom( type ) ) {
+ return bytes.slice().getFloat();
+ }
+ else if ( ByteBuffer.class.isAssignableFrom( type ) ) {
+ return bytes.duplicate();
+ }
+ else if ( byte[].class.isAssignableFrom( type ) ) {
+ byte[] b = new byte[bytes.remaining()];
+ bytes.slice().get( b );
+ return b;
+ }
+ }
+ catch ( Exception e ) {
+ logger.error( "Unable to get object from bytes for type " + type.getName(), e );
+ }
+ return null;
+ }
+
+
+ /**
+ * @param bb
+ * @param bytes
+ * @param len
+ * @return
+ */
+ public static ByteBuffer appendToByteBuffer( ByteBuffer bb, byte[] bytes, int len ) {
+ if ( len > bytes.length ) {
+ int pos = bb.position();
+ bb.put( bytes );
+ bb.position( pos + len );
+ }
+ else {
+ bb.put( bytes, 0, len );
+ }
+ return bb;
+ }
+
+
+ public static Object coerce( Class<?> type, Object obj ) {
+
+ if ( obj == null ) {
+ return null;
+ }
+
+ if ( type == null ) {
+ return obj;
+ }
+
+ try {
+ if ( Long.class.isAssignableFrom( type ) ) {
+ return getLong( obj );
+ }
+ else if ( UUID.class.isAssignableFrom( type ) ) {
+ return uuid( obj );
+ }
+ else if ( String.class.isAssignableFrom( type ) ) {
+ return string( obj );
+ }
+ else if ( Boolean.class.isAssignableFrom( type ) ) {
+ return getBoolean( obj );
+ }
+ else if ( Integer.class.isAssignableFrom( type ) ) {
+ return getInt( obj );
+ }
+ else if ( Double.class.isAssignableFrom( type ) ) {
+ return getDouble( obj );
+ }
+ else if ( Float.class.isAssignableFrom( type ) ) {
+ return getFloat( obj );
+ }
+ else if ( byte[].class.isAssignableFrom( type ) ) {
+ return bytes( obj );
+ }
+ else if ( ByteBuffer.class.isAssignableFrom( type ) ) {
+ return bytebuffer( obj );
+ }
+ }
+ catch ( Exception e ) {
+ logger.error( "Unable to get object from bytes for type " + type.getName(), e );
+ }
+ return null;
+ }
+
+
+ public static Map<String, Object> coerceMap( Map<String, Class<?>> types, Map<String, Object> values ) {
+ for ( Map.Entry<String, Object> entry : values.entrySet() ) {
+ if ( types.containsKey( entry.getKey() ) ) {
+ values.put( entry.getKey(), coerce( types.get( entry.getKey() ), entry.getValue() ) );
+ }
+ }
+ return values;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/75da9b8d/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/JsonUtils.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/JsonUtils.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/JsonUtils.java
new file mode 100644
index 0000000..4b3e40d
--- /dev/null
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/JsonUtils.java
@@ -0,0 +1,329 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.usergrid.utils;
+
+
+import java.io.File;
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.usergrid.persistence.exceptions.JsonReadException;
+import org.apache.usergrid.persistence.exceptions.JsonWriteException;
+//import org.apache.usergrid.persistence.Entity;
+
+import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.io.JsonStringEncoder;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.map.SerializationConfig.Feature;
+import org.codehaus.jackson.smile.SmileFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.apache.commons.lang.StringUtils.substringAfter;
+
+import static org.apache.usergrid.utils.StringUtils.stringOrSubstringBeforeFirst;
+
+
+public class JsonUtils {
+
+ private static final Logger LOG = LoggerFactory.getLogger( JsonUtils.class );
+
+ static ObjectMapper mapper = new ObjectMapper();
+
+ static SmileFactory smile = new SmileFactory();
+
+ static ObjectMapper smileMapper = new ObjectMapper( smile );
+
+ private static ObjectMapper indentObjectMapper = new ObjectMapper();
+
+
+ static {
+ indentObjectMapper.getSerializationConfig().set( Feature.INDENT_OUTPUT, true );
+ }
+
+
+ /** Converts object to JSON string, throws runtime exception JsonWriteException on failure. */
+ public static String mapToJsonString( Object obj ) {
+ try {
+ return mapper.writeValueAsString( obj );
+ }
+ catch ( Throwable t ) {
+ LOG.debug( "Error generating JSON", t );
+ throw new JsonWriteException( "Error generating JSON", t );
+ }
+ }
+
+
+ /** Converts object to JSON string, throws runtime exception JsonWriteException on failure. */
+ public static String mapToFormattedJsonString( Object obj ) {
+ try {
+ return indentObjectMapper.writeValueAsString( obj );
+ }
+ catch ( Throwable t ) {
+ LOG.debug( "Error generating JSON", t );
+ throw new JsonWriteException( "Error generating JSON", t );
+ }
+ }
+
+
+ /** Parses JSON string and returns object, throws runtime exception JsonReadException on failure. */
+ public static Object parse( String json ) {
+ try {
+ return mapper.readValue( json, Object.class );
+ }
+ catch ( Throwable t ) {
+ LOG.debug( "Error parsing JSON", t );
+ throw new JsonReadException( "Error parsing JSON", t );
+ }
+ }
+
+
+ public static String quoteString( String s ) {
+ JsonStringEncoder encoder = new JsonStringEncoder();
+ return new String( encoder.quoteAsUTF8( s ) );
+ }
+
+
+ public static ByteBuffer toByteBuffer( Object obj ) {
+ if ( obj == null ) {
+ return null;
+ }
+
+ byte[] bytes = null;
+ try {
+ bytes = smileMapper.writeValueAsBytes( obj );
+ }
+ catch ( Exception e ) {
+ LOG.error( "Error getting SMILE bytes", e );
+ }
+ if ( bytes != null ) {
+ return ByteBuffer.wrap( bytes );
+ }
+ return null;
+ }
+
+
+ public static Object fromByteBuffer( ByteBuffer byteBuffer ) {
+ return fromByteBuffer( byteBuffer, Object.class );
+ }
+
+
+ public static Object fromByteBuffer( ByteBuffer byteBuffer, Class<?> clazz ) {
+ if ( ( byteBuffer == null ) || !byteBuffer.hasRemaining() ) {
+ return null;
+ }
+ if ( clazz == null ) {
+ clazz = Object.class;
+ }
+
+ Object obj = null;
+ try {
+ obj = smileMapper.readValue( byteBuffer.array(), byteBuffer.arrayOffset() + byteBuffer.position(),
+ byteBuffer.remaining(), clazz );
+ }
+ catch ( Exception e ) {
+ LOG.error( "Error parsing SMILE bytes", e );
+ }
+ return obj;
+ }
+
+
+ public static JsonNode toJsonNode( Object obj ) {
+ if ( obj == null ) {
+ return null;
+ }
+ return mapper.convertValue( obj, JsonNode.class );
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public static Map<String, Object> toJsonMap( Object obj ) {
+ if ( obj == null ) {
+ return null;
+ }
+
+ return ( Map<String, Object> ) mapper.convertValue( obj, Map.class );
+ }
+
+
+ private static UUID tryConvertToUUID( Object o ) {
+ if ( o instanceof String ) {
+ String s = ( String ) o;
+ if ( s.length() == 36 ) {
+ try {
+ return UUID.fromString( s );
+ }
+ catch ( IllegalArgumentException e ) {
+ LOG.warn( "Argument to UUID.fromString({}) was invalid.", s, e );
+ }
+ }
+ }
+ return null;
+ }
+
+
+ public static Object normalizeJsonTree( Object obj ) {
+ if ( obj instanceof Map ) {
+ @SuppressWarnings("unchecked") Map<Object, Object> m = ( Map<Object, Object> ) obj;
+ Object o;
+ UUID uuid;
+ for ( Object k : m.keySet() ) {
+ if ( k instanceof String && ( ( String ) k ).equalsIgnoreCase( "name" ) ) {
+ continue;
+ }
+
+ o = m.get( k );
+ uuid = tryConvertToUUID( o );
+ if ( uuid != null ) {
+ m.put( k, uuid );
+ }
+ else if ( o instanceof Integer ) {
+ m.put( k, ( ( Integer ) o ).longValue() );
+ }
+ else if ( o instanceof BigInteger ) {
+ m.put( k, ( ( BigInteger ) o ).longValue() );
+ }
+ }
+ }
+ else if ( obj instanceof List ) {
+ @SuppressWarnings("unchecked") List<Object> l = ( List<Object> ) obj;
+ Object o;
+ UUID uuid;
+ for ( int i = 0; i < l.size(); i++ ) {
+ o = l.get( i );
+ uuid = tryConvertToUUID( o );
+ if ( uuid != null ) {
+ l.set( i, uuid );
+ }
+ else if ( ( o instanceof Map ) || ( o instanceof List ) ) {
+ normalizeJsonTree( o );
+ }
+ else if ( o instanceof Integer ) {
+ l.set( i, ( ( Integer ) o ).longValue() );
+ }
+ else if ( o instanceof BigInteger ) {
+ l.set( i, ( ( BigInteger ) o ).longValue() );
+ }
+ }
+ }
+ else if ( obj instanceof String ) {
+ UUID uuid = tryConvertToUUID( obj );
+ if ( uuid != null ) {
+ return uuid;
+ }
+ }
+ else if ( obj instanceof Integer ) {
+ return ( ( Integer ) obj ).longValue();
+ }
+ else if ( obj instanceof BigInteger ) {
+ return ( ( BigInteger ) obj ).longValue();
+ }
+ else if ( obj instanceof JsonNode ) {
+ return mapper.convertValue( obj, Object.class );
+ }
+ return obj;
+ }
+
+
+// public static Object select( Object obj, String path ) {
+// return select( obj, path, false );
+// }
+//
+//
+// public static Object select( Object obj, String path, boolean buildResultTree ) {
+//
+// if ( obj == null ) {
+// return null;
+// }
+//
+// if ( org.apache.commons.lang.StringUtils.isBlank( path ) ) {
+// return obj;
+// }
+//
+// String segment = stringOrSubstringBeforeFirst( path, '.' );
+// String remaining = substringAfter( path, "." );
+//
+// if ( obj instanceof Map ) {
+// Map<?, ?> map = ( Map<?, ?> ) obj;
+// Object child = map.get( segment );
+// Object result = select( child, remaining, buildResultTree );
+// if ( result != null ) {
+// if ( buildResultTree ) {
+// Map<Object, Object> results = new LinkedHashMap<Object, Object>();
+// results.put( segment, result );
+// return results;
+// }
+// else {
+// return result;
+// }
+// }
+// return null;
+// }
+// if ( obj instanceof List ) {
+// List<Object> results = new ArrayList<Object>();
+// List<?> list = ( List<?> ) obj;
+// for ( Object i : list ) {
+// Object result = select( i, path, buildResultTree );
+// if ( result != null ) {
+// results.add( result );
+// }
+// }
+// if ( !results.isEmpty() ) {
+// return results;
+// }
+// return null;
+// }
+//
+// if ( obj instanceof Entity ) {
+// Object child = ( ( Entity ) obj ).getProperty( segment );
+// Object result = select( child, remaining, buildResultTree );
+// if ( result != null ) {
+// if ( buildResultTree ) {
+// Map<Object, Object> results = new LinkedHashMap<Object, Object>();
+// results.put( segment, result );
+// return results;
+// }
+// else {
+// return result;
+// }
+// }
+// else {
+// return result;
+// }
+// }
+//
+// return obj;
+// }
+
+
+ public static Object loadFromFilesystem( String filename ) {
+ Object json = null;
+ try {
+ File file = new File( filename );
+ json = mapper.readValue( file, Object.class );
+ }
+ catch ( Exception e ) {
+ LOG.error( "Error loading JSON", e );
+ }
+ return json;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/75da9b8d/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/ListUtils.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/ListUtils.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/ListUtils.java
new file mode 100644
index 0000000..db56cdd
--- /dev/null
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/ListUtils.java
@@ -0,0 +1,232 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.usergrid.utils;
+
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.UUID;
+
+import org.apache.commons.lang.math.NumberUtils;
+import org.apache.usergrid.persistence.collection.util.EntityUtils;
+import org.apache.usergrid.persistence.model.entity.Id;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class ListUtils extends org.apache.commons.collections.ListUtils {
+ private static final Logger LOG = LoggerFactory.getLogger( ListUtils.class );
+
+
+ public static <A> A first( List<A> list ) {
+ if ( list == null ) {
+ return null;
+ }
+ if ( list.size() == 0 ) {
+ return null;
+ }
+ return list.get( 0 );
+ }
+
+
+ public static <A> A last( List<A> list ) {
+ if ( list == null ) {
+ return null;
+ }
+ if ( list.size() == 0 ) {
+ return null;
+ }
+ return list.get( list.size() - 1 );
+ }
+
+
+ public static <A> Integer firstInteger( List<A> list ) {
+ A a = first( list );
+ if ( a == null ) {
+ return null;
+ }
+
+ if ( a instanceof Integer ) {
+ return ( Integer ) a;
+ }
+
+ try {
+ return NumberUtils.toInt( ( String ) a );
+ }
+ catch ( Exception e ) {
+ LOG.warn( "Could not convert list item {} to int", a, e );
+ }
+ return null;
+ }
+
+
+ public static <A> Long firstLong( List<A> list ) {
+ A a = first( list );
+ if ( a == null ) {
+ return null;
+ }
+
+ if ( a instanceof Long ) {
+ return ( Long ) a;
+ }
+
+ try {
+ return NumberUtils.toLong( ( String ) a );
+ }
+ catch ( Exception e ) {
+ LOG.warn( "Could not convert list item {} to long", a, e );
+ }
+ return null;
+ }
+
+
+ public static <A> Boolean firstBoolean( List<A> list ) {
+ A a = first( list );
+ if ( a == null ) {
+ return null;
+ }
+
+ if ( a instanceof Boolean ) {
+ return ( Boolean ) a;
+ }
+
+ try {
+ return Boolean.parseBoolean( ( String ) a );
+ }
+ catch ( Exception e ) {
+ LOG.warn( "Could not convert list item {} to boolean", a, e );
+ }
+ return null;
+ }
+
+
+ public static <A> UUID firstUuid( List<A> list ) {
+ A i = first( list );
+ if ( i == null ) {
+ return null;
+ }
+
+ if ( i instanceof UUID ) {
+ return ( UUID ) i;
+ }
+
+ try {
+ return UUIDUtils.tryGetUUID( ( String ) i );
+ }
+ catch ( Exception e ) {
+ LOG.warn( "Could not convert list item {} to UUID", i, e );
+ }
+ return null;
+ }
+
+
+ public static boolean isEmpty( List<?> list ) {
+ return ( list == null ) || ( list.size() == 0 );
+ }
+
+
+ public static <T> List<T> dequeueCopy( List<T> list ) {
+ if ( !isEmpty( list ) ) {
+ list = list.subList( 1, list.size() );
+ }
+ return list;
+ }
+
+
+ public static <T> List<T> initCopy( List<T> list ) {
+ if ( !isEmpty( list ) ) {
+ list = new ArrayList<T>( list );
+ }
+ else {
+ list = new ArrayList<T>();
+ }
+ return list;
+ }
+
+
+ public static <T> T dequeue( List<T> list ) {
+ if ( !isEmpty( list ) ) {
+ return list.remove( 0 );
+ }
+ return null;
+ }
+
+
+ public static <T> List<T> queue( List<T> list, T item ) {
+ if ( list == null ) {
+ list = new ArrayList<T>();
+ }
+ list.add( item );
+ return list;
+ }
+
+
+ public static <T> List<T> requeue( List<T> list, T item ) {
+ if ( list == null ) {
+ list = new ArrayList<T>();
+ }
+ list.add( 0, item );
+ return list;
+ }
+
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public static List<?> flatten( Collection<?> l ) {
+ boolean hasCollection = false;
+ for ( Object o : l ) {
+ if ( o instanceof Collection ) {
+ hasCollection = true;
+ break;
+ }
+ }
+ if ( !hasCollection && ( l instanceof List ) ) {
+ return ( List<?> ) l;
+ }
+ List newList = new ArrayList();
+ for ( Object o : l ) {
+ if ( o instanceof List ) {
+ newList.addAll( flatten( ( List ) o ) );
+ }
+ else {
+ newList.add( o );
+ }
+ }
+ return newList;
+ }
+
+
+ public static boolean anyNull( List<?> l ) {
+ for ( Object o : l ) {
+ if ( o == null ) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+ public static boolean anyNull( Object... objects ) {
+ for ( Object o : objects ) {
+ if ( o == null ) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/75da9b8d/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/MapUtils.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/MapUtils.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/MapUtils.java
new file mode 100644
index 0000000..12da2e0
--- /dev/null
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/MapUtils.java
@@ -0,0 +1,377 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.usergrid.utils;
+
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import static org.apache.commons.lang.StringUtils.isNotBlank;
+
+import static org.apache.usergrid.utils.ClassUtils.cast;
+
+
+public class MapUtils extends org.apache.commons.collections.MapUtils {
+
+ public static <A, B> void addMapSet( Map<A, Set<B>> map, A a, B b ) {
+ addMapSet( map, false, a, b );
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public static <A, B> void addMapSet( Map<A, Set<B>> map, boolean ignoreCase, A a, B b ) {
+
+ Set<B> setB = map.get( a );
+ if ( setB == null ) {
+ if ( ignoreCase && ( b instanceof String ) ) {
+ setB = ( Set<B> ) new TreeSet<String>( String.CASE_INSENSITIVE_ORDER );
+ }
+ else {
+ setB = new LinkedHashSet<B>();
+ }
+ map.put( a, setB );
+ }
+ setB.add( b );
+ }
+
+
+ public static <A, B, C> void addMapMapSet( Map<A, Map<B, Set<C>>> map, A a, B b, C c ) {
+ addMapMapSet( map, false, a, b, c );
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public static <A, B, C> void addMapMapSet( Map<A, Map<B, Set<C>>> map, boolean ignoreCase, A a, B b, C c ) {
+
+ Map<B, Set<C>> mapB = map.get( a );
+ if ( mapB == null ) {
+ if ( ignoreCase && ( b instanceof String ) ) {
+ mapB = ( Map<B, Set<C>> ) new TreeMap<String, Set<C>>( String.CASE_INSENSITIVE_ORDER );
+ }
+ else {
+ mapB = new LinkedHashMap<B, Set<C>>();
+ }
+ map.put( a, mapB );
+ }
+ addMapSet( mapB, ignoreCase, b, c );
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public static <A, B, C, D> void addMapMapMapSet( Map<A, Map<B, Map<C, Set<D>>>> map, boolean ignoreCase, A a, B b,
+ C c, D d ) {
+ Map<B, Map<C, Set<D>>> mapB = map.get( a );
+ if ( mapB == null ) {
+ if ( ignoreCase && ( b instanceof String ) ) {
+ mapB = ( Map<B, Map<C, Set<D>>> ) new TreeMap<String, Map<C, Set<D>>>( String.CASE_INSENSITIVE_ORDER );
+ }
+ else {
+ mapB = new LinkedHashMap<B, Map<C, Set<D>>>();
+ }
+ map.put( a, mapB );
+ }
+ addMapMapSet( mapB, ignoreCase, b, c, d );
+ }
+
+
+ public static <A, B, C> C getMapMap( Map<A, Map<B, C>> map, A a, B b ) {
+
+ Map<B, C> mapB = map.get( a );
+ if ( mapB == null ) {
+ return null;
+ }
+ return mapB.get( b );
+ }
+
+
+ public static <A, B> void addMapList( Map<A, List<B>> map, A a, B b ) {
+
+ List<B> listB = map.get( a );
+ if ( listB == null ) {
+ listB = new ArrayList<B>();
+ map.put( a, listB );
+ }
+ listB.add( b );
+ }
+
+
+ public static <A, B> void addListToMapList( Map<A, List<B>> map, A a, List<B> b ) {
+
+ List<B> listB = map.get( a );
+ if ( listB == null ) {
+ listB = new ArrayList<B>();
+ map.put( a, listB );
+ }
+ listB.addAll( b );
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public static <K, V> V getValue( Map<K, ?> map, K k ) {
+ V v = null;
+ try {
+ v = ( V ) map.get( k );
+ }
+ catch ( ClassCastException e ) {
+ //LOG.war( "Map value {} was not the expected class", map.get( k ), e );
+ }
+
+ return v;
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public static <K, V> Map<?, ?> map( Object... objects ) {
+ Map<K, V> map = new LinkedHashMap<K, V>();
+ int i = 0;
+ while ( i < objects.length ) {
+ if ( objects[i] instanceof Map.Entry ) {
+ Map.Entry<K, V> entry = ( Entry<K, V> ) objects[i];
+ map.put( entry.getKey(), entry.getValue() );
+ i++;
+ }
+ else if ( objects[i] instanceof Map ) {
+ map.putAll( ( Map<? extends K, ? extends V> ) objects[i] );
+ i++;
+ }
+ else if ( i < ( objects.length - 1 ) ) {
+ K k = ( K ) objects[i];
+ V v = ( V ) objects[i + 1];
+ map.put( k, v );
+ i += 2;
+ }
+ else {
+ break;
+ }
+ }
+ return map;
+ }
+
+
+ private static class SimpleMapEntry<K, V> implements Map.Entry<K, V> {
+
+ private final K k;
+ private V v;
+
+
+ public SimpleMapEntry( K k, V v ) {
+ this.k = k;
+ this.v = v;
+ }
+
+
+ @Override
+ public K getKey() {
+ return k;
+ }
+
+
+ @Override
+ public V getValue() {
+ return v;
+ }
+
+
+ @Override
+ public V setValue( V v ) {
+ V oldV = this.v;
+ this.v = v;
+ return oldV;
+ }
+ }
+
+
+ public static <K, V> Map.Entry<K, V> entry( K k, V v ) {
+ return new SimpleMapEntry<K, V>( k, v );
+ }
+
+
+ public static <K, V> K getFirstKey( Map<K, V> map ) {
+ if ( map == null ) {
+ return null;
+ }
+ Entry<K, V> e = map.entrySet().iterator().next();
+ if ( e != null ) {
+ return e.getKey();
+ }
+ return null;
+ }
+
+
+ public static <V> Map<String, V> filter( Map<String, V> map, String prefix, boolean removePrefix ) {
+ Map<String, V> filteredMap = new LinkedHashMap<String, V>();
+ for ( Entry<String, V> entry : map.entrySet() ) {
+ if ( entry.getKey().startsWith( prefix ) ) {
+ if ( removePrefix ) {
+ filteredMap.put( entry.getKey().substring( prefix.length() ), entry.getValue() );
+ }
+ else {
+ filteredMap.put( entry.getKey(), entry.getValue() );
+ }
+ }
+ }
+ return filteredMap;
+ }
+
+
+ public static <V> Map<String, V> filter( Map<String, V> map, String prefix ) {
+ return filter( map, prefix, false );
+ }
+
+
+ public static Properties filter( Properties properties, String prefix, boolean removePrefix ) {
+ Properties filteredProperties = new Properties();
+ for ( Entry<String, String> entry : asMap( properties ).entrySet() ) {
+ if ( entry.getKey().startsWith( prefix ) ) {
+ if ( removePrefix ) {
+ filteredProperties.put( entry.getKey().substring( prefix.length() ), entry.getValue() );
+ }
+ else {
+ filteredProperties.put( entry.getKey(), entry.getValue() );
+ }
+ }
+ }
+ return filteredProperties;
+ }
+
+
+ public static Properties filter( Properties properties, String prefix ) {
+ return filter( properties, prefix, false );
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public static Map<String, String> asMap( Properties properties ) {
+ return cast( properties );
+ }
+
+
+ public static <S, T> HashMapBuilder<S, T> hashMap( S key, T value ) {
+ return new HashMapBuilder<S, T>().map( key, value );
+ }
+
+
+ public static class HashMapBuilder<S, T> extends HashMap<S, T> {
+ private static final long serialVersionUID = 1L;
+
+
+ public HashMapBuilder() {
+ }
+
+
+ public HashMapBuilder<S, T> map( S key, T value ) {
+ put( key, value );
+ return this;
+ }
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public static Map<String, List<?>> toMapList( Map<String, ?> m ) {
+ Map<String, List<Object>> mapList = new LinkedHashMap<String, List<Object>>();
+
+ for ( Entry<String, ?> e : m.entrySet() ) {
+ if ( e.getValue() instanceof List ) {
+ addListToMapList( mapList, e.getKey(), ( List<Object> ) e.getValue() );
+ }
+ else {
+ addMapList( mapList, e.getKey(), e.getValue() );
+ }
+ }
+
+ return cast( mapList );
+ }
+
+
+ public static Map<String, ?> putPath( String path, Object value ) {
+ return putPath( null, path, value );
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public static Map<String, ?> putPath( Map<String, ?> map, String path, Object value ) {
+
+ if ( map == null ) {
+ map = new HashMap<String, Object>();
+ }
+
+ int i = path.indexOf( '.' );
+ if ( i < 0 ) {
+ ( ( Map<String, Object> ) map ).put( path, value );
+ return map;
+ }
+ String segment = path.substring( 0, i ).trim();
+ if ( isNotBlank( segment ) ) {
+ Object o = map.get( segment );
+ if ( ( o != null ) && ( !( o instanceof Map ) ) ) {
+ return map;
+ }
+ Map<String, Object> subMap = ( Map<String, Object> ) o;
+ if ( subMap == null ) {
+ subMap = new HashMap<String, Object>();
+ ( ( Map<String, Object> ) map ).put( segment, subMap );
+ }
+ String subPath = path.substring( i + 1 );
+ if ( isNotBlank( subPath ) ) {
+ putPath( subMap, subPath, value );
+ }
+ }
+
+ return map;
+ }
+
+
+ public static <K, V> Map<K, V> emptyMapWithKeys( Map<K, V> map ) {
+ Map<K, V> newMap = new HashMap<K, V>();
+
+ for ( K k : map.keySet() ) {
+ newMap.put( k, null );
+ }
+
+ return newMap;
+ }
+
+
+ public static boolean hasKeys( Map<?, ?> map, String... keys ) {
+ if ( map == null ) {
+ return false;
+ }
+ for ( String key : keys ) {
+ if ( !map.containsKey( key ) ) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+
+ public static boolean hasKeys( Map<?, ?> map, Set<String> keys ) {
+ if ( map == null ) {
+ return false;
+ }
+ return map.keySet().containsAll( keys );
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/75da9b8d/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/StringUtils.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/StringUtils.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/StringUtils.java
new file mode 100644
index 0000000..5f64ef3
--- /dev/null
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/StringUtils.java
@@ -0,0 +1,172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.usergrid.utils;
+
+
+import java.util.Arrays;
+
+import org.apache.commons.io.IOUtils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.apache.usergrid.utils.ConversionUtils.string;
+
+
+public class StringUtils extends org.apache.commons.lang.StringUtils {
+
+ private static final Logger LOG = LoggerFactory.getLogger( StringUtils.class );
+
+
+ public static Object lower( Object obj ) {
+ if ( !( obj instanceof String ) ) {
+ return obj;
+ }
+ return ( ( String ) obj ).toLowerCase();
+ }
+
+
+ public static String stringOrSubstringAfterLast( String str, char c ) {
+ if ( str == null ) {
+ return null;
+ }
+ int i = str.lastIndexOf( c );
+ if ( i != -1 ) {
+ return str.substring( i + 1 );
+ }
+ return str;
+ }
+
+
+ public static String stringOrSubstringBeforeLast( String str, char c ) {
+ if ( str == null ) {
+ return null;
+ }
+ int i = str.lastIndexOf( c );
+ if ( i != -1 ) {
+ return str.substring( 0, i );
+ }
+ return str;
+ }
+
+
+ public static String stringOrSubstringBeforeFirst( String str, char c ) {
+ if ( str == null ) {
+ return null;
+ }
+ int i = str.indexOf( c );
+ if ( i != -1 ) {
+ return str.substring( 0, i );
+ }
+ return str;
+ }
+
+
+ public static String stringOrSubstringAfterFirst( String str, char c ) {
+ if ( str == null ) {
+ return null;
+ }
+ int i = str.indexOf( c );
+ if ( i != -1 ) {
+ return str.substring( i + 1 );
+ }
+ return str;
+ }
+
+
+ public static String compactWhitespace( String str ) {
+ if ( str == null ) {
+ return null;
+ }
+ boolean prevWS = false;
+ StringBuilder builder = new StringBuilder();
+ for ( int i = 0; i < str.length(); i++ ) {
+ char c = str.charAt( i );
+ if ( Character.isWhitespace( c ) ) {
+ if ( !prevWS ) {
+ builder.append( ' ' );
+ }
+ prevWS = true;
+ }
+ else {
+ prevWS = false;
+ builder.append( c );
+ }
+ }
+ return builder.toString().trim();
+ }
+
+
+ /** @return new string with replace applied */
+ public static String replaceAll( String source, String find, String replace ) {
+ if ( source == null ) {
+ return null;
+ }
+ while ( true ) {
+ String old = source;
+ source = source.replaceAll( find, replace );
+ if ( source.equals( old ) ) {
+ return source;
+ }
+ }
+ }
+
+
+ public static String toString( Object obj ) {
+ return string( obj );
+ }
+
+
+ public static String toStringFormat( Object obj, String format ) {
+ if ( obj != null ) {
+ if ( format != null ) {
+ if ( obj.getClass().isArray() ) {
+ return String.format( format, Arrays.toString( ( Object[] ) obj ) );
+ }
+ return String.format( format, string( obj ) );
+ }
+ else {
+ return string( obj );
+ }
+ }
+ return "";
+ }
+
+
+ public static boolean isString( Object obj ) {
+ return obj instanceof String;
+ }
+
+
+ public static boolean isStringOrNull( Object obj ) {
+ if ( obj == null ) {
+ return true;
+ }
+ return obj instanceof String;
+ }
+
+
+ public static String readClasspathFileAsString( String filePath ) {
+ try {
+ return IOUtils.toString( StringUtils.class.getResourceAsStream( filePath ) );
+ }
+ catch ( Exception e ) {
+ LOG.error( "Error getting file from classpath: " + filePath, e );
+ }
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/75da9b8d/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/UUIDUtils.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/UUIDUtils.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/UUIDUtils.java
new file mode 100644
index 0000000..6d8175c
--- /dev/null
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/UUIDUtils.java
@@ -0,0 +1,412 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.usergrid.utils;
+
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.ReentrantLock;
+
+import com.fasterxml.uuid.EthernetAddress;
+import com.fasterxml.uuid.UUIDComparator;
+
+import static com.fasterxml.uuid.impl.UUIDUtil.BYTE_OFFSET_CLOCK_HI;
+import static com.fasterxml.uuid.impl.UUIDUtil.BYTE_OFFSET_CLOCK_LO;
+import static com.fasterxml.uuid.impl.UUIDUtil.BYTE_OFFSET_CLOCK_MID;
+import static com.fasterxml.uuid.impl.UUIDUtil.BYTE_OFFSET_CLOCK_SEQUENCE;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.apache.commons.codec.binary.Base64.decodeBase64;
+import static org.apache.commons.codec.binary.Base64.encodeBase64URLSafeString;
+
+import static org.apache.usergrid.utils.ConversionUtils.bytes;
+import static org.apache.usergrid.utils.ConversionUtils.uuid;
+
+
+public class UUIDUtils {
+ private static final Logger LOG = LoggerFactory.getLogger( UUIDUtils.class );
+ private static final int[] MICROS = new int[1000];
+
+
+ static {
+ for ( int x = 0; x < 1000; x++ ) {
+ MICROS[x] = x * 10;
+ }
+ }
+
+
+ private static ReentrantLock tsLock = new ReentrantLock( true );
+
+ public static final UUID MIN_TIME_UUID = UUID.fromString( "00000000-0000-1000-8000-000000000000" );
+
+ public static final UUID MAX_TIME_UUID = UUID.fromString( "ffffffff-ffff-1fff-bfff-ffffffffffff" );
+
+ public static final UUID ZERO_UUID = new UUID( 0, 0 );
+
+ private static long timestampMillisNow = System.currentTimeMillis();
+
+ private static AtomicInteger currentMicrosPoint = new AtomicInteger( 0 );
+ private static AtomicInteger customMicrosPointer = new AtomicInteger( 0 );
+
+
+ /**
+ * Return the "next" UUID in micro second resolution. <b>WARNING</b>: this is designed to return the next unique
+ * timestamped UUID for this JVM. Depending on velocity of the call, this method may block internally to insure that
+ * "now" is kept in sync with the UUIDs being generated by this call.
+ * <p/>
+ * In other words, we will intentionally burn CPU insuring that this method is not executed more than 10k -1 times
+ * per millisecond and guarantee that those microseconds held within are sequential.
+ * <p/>
+ * If we did not do this, you would get <b>timestamp collision</b> even though the UUIDs will technically be
+ * 'unique.'
+ */
+ public static java.util.UUID newTimeUUID() {
+ // get & inc counter, but roll on 1k (because we divide by 10 on retrieval)
+ // if count + currentMicro > 1k, block and roll
+ tsLock.lock();
+ long ts = System.currentTimeMillis();
+ if ( ts > timestampMillisNow ) {
+ timestampMillisNow = ts;
+ currentMicrosPoint.set( 0 );
+ }
+ int pointer = currentMicrosPoint.getAndIncrement();
+ try {
+ if ( pointer > 990 ) {
+ TimeUnit.MILLISECONDS.sleep( 1L );
+ }
+ }
+ catch ( Exception ex ) {
+ ex.printStackTrace();
+ }
+ finally {
+ tsLock.unlock();
+ }
+ return newTimeUUID( ts, MICROS[pointer] );
+ }
+
+
+ private static final long KCLOCK_OFFSET = 0x01b21dd213814000L;
+ private static final long KCLOCK_MULTIPLIER_L = 10000L;
+
+ private static final Random CLOCK_SEQ_RANDOM = new Random();
+
+
+ // 14 bits of randomness
+ private static int getRandomClockSequence() {
+ return CLOCK_SEQ_RANDOM.nextInt() & 0x3FFF;
+ }
+
+
+ private static void setTimestamp( long timestamp, byte[] uuidBytes, int clockSeq, int timeOffset ) {
+
+ timestamp *= KCLOCK_MULTIPLIER_L;
+ timestamp += KCLOCK_OFFSET;
+ timestamp += timeOffset;
+
+ // Set random clock sequence
+ uuidBytes[BYTE_OFFSET_CLOCK_SEQUENCE] = ( byte ) ( clockSeq >> 8 );
+ uuidBytes[BYTE_OFFSET_CLOCK_SEQUENCE + 1] = ( byte ) clockSeq;
+
+ // Set variant
+ uuidBytes[BYTE_OFFSET_CLOCK_SEQUENCE] &= 0x3F;
+ uuidBytes[BYTE_OFFSET_CLOCK_SEQUENCE] |= 0x80;
+ setTime( uuidBytes, timestamp );
+ }
+
+
+ @SuppressWarnings("all")
+ private static void setTime( byte[] uuidBytes, long timestamp ) {
+
+ // Time fields aren't nicely split across the UUID, so can't just
+ // linearly dump the stamp:
+ int clockHi = ( int ) ( timestamp >>> 32 );
+ int clockLo = ( int ) timestamp;
+
+ uuidBytes[BYTE_OFFSET_CLOCK_HI] = ( byte ) ( clockHi >>> 24 );
+ uuidBytes[BYTE_OFFSET_CLOCK_HI + 1] = ( byte ) ( clockHi >>> 16 );
+ uuidBytes[BYTE_OFFSET_CLOCK_MID] = ( byte ) ( clockHi >>> 8 );
+ uuidBytes[BYTE_OFFSET_CLOCK_MID + 1] = ( byte ) clockHi;
+
+ uuidBytes[BYTE_OFFSET_CLOCK_LO] = ( byte ) ( clockLo >>> 24 );
+ uuidBytes[BYTE_OFFSET_CLOCK_LO + 1] = ( byte ) ( clockLo >>> 16 );
+ uuidBytes[BYTE_OFFSET_CLOCK_LO + 2] = ( byte ) ( clockLo >>> 8 );
+ uuidBytes[BYTE_OFFSET_CLOCK_LO + 3] = ( byte ) clockLo;
+
+ // Set version
+ uuidBytes[BYTE_OFFSET_CLOCK_HI] &= 0x0F;
+ uuidBytes[BYTE_OFFSET_CLOCK_HI] |= 0x10;
+ }
+
+
+ /**
+ * Generate a timeuuid with the given timestamp in milliseconds and the time offset. Useful when you need to
+ * generate sequential UUIDs for the same period in time. I.E
+ * <p/>
+ * newTimeUUID(1000, 0) <br/> newTimeUUID(1000, 1) <br /> newTimeUUID(1000, 2) <br />
+ * <p/>
+ * etc.
+ * <p/>
+ * Only use this method if you are absolutely sure you need it. When it doubt use the method without the timestamp
+ * offset
+ *
+ * @param ts The timestamp in milliseconds
+ * @param timeoffset The offset, which should always be <= 10000. If you go beyond this range, the millisecond will
+ * be incremented since this is beyond the possible values when coverrting from millis to 1/10 microseconds stored
+ * in the time uuid.
+ */
+ public static UUID newTimeUUID( long ts, int timeoffset ) {
+ if ( ts == 0 ) {
+ return newTimeUUID();
+ }
+
+ byte[] uuidBytes = new byte[16];
+ // 47 bits of randomness
+ EthernetAddress eth = EthernetAddress.constructMulticastAddress();
+ eth.toByteArray( uuidBytes, 10 );
+ setTimestamp( ts, uuidBytes, getRandomClockSequence(), timeoffset );
+
+ return uuid( uuidBytes );
+ }
+
+
+ /**
+ * Generate a new UUID with the given time stamp in milliseconds. This method guarantees that subsequent calls will
+ * be of increasing value chronologically. If a large number of subsequent calls are made to this method (>1000)
+ * with the same timestamp, you will have non-unique temporal values stored in your UUID.
+ */
+ public static UUID newTimeUUID( long ts ) {
+ tsLock.lock();
+ int pointer = customMicrosPointer.getAndIncrement();
+ try {
+ if ( pointer > 990 ) {
+ customMicrosPointer.set( 0 );
+ }
+ }
+ finally {
+ tsLock.unlock();
+ }
+ return newTimeUUID( ts, MICROS[pointer] );
+ }
+
+
+ public static UUID minTimeUUID( long ts ) {
+ byte[] uuidBytes = new byte[16];
+ setTimestamp( ts, uuidBytes, 0, 0 );
+
+ return uuid( uuidBytes );
+ }
+
+
+ public static UUID maxTimeUUID( long ts ) {
+ byte[] uuidBytes = new byte[16];
+ uuidBytes[10] = ( byte ) 0xFF;
+ uuidBytes[11] = ( byte ) 0xFF;
+ uuidBytes[12] = ( byte ) 0xFF;
+ uuidBytes[13] = ( byte ) 0xFF;
+ uuidBytes[14] = ( byte ) 0xFF;
+ uuidBytes[15] = ( byte ) 0xFF;
+ setTimestamp( ts, uuidBytes, 0x3FFF, 0x1FFF );
+
+ return uuid( uuidBytes );
+ }
+
+
+ /** Returns the minimum UUID */
+ public static UUID min( UUID first, UUID second ) {
+ if ( first == null ) {
+ if ( second == null ) {
+ return null;
+ }
+ return second;
+ }
+
+ if ( second == null ) {
+ return first;
+ }
+
+ if ( compare( first, second ) < 0 ) {
+ return first;
+ }
+ return second;
+ }
+
+
+ /** Returns the minimum UUID */
+ public static UUID max( UUID first, UUID second ) {
+ if ( first == null ) {
+ if ( second == null ) {
+ return null;
+ }
+ return second;
+ }
+
+ if ( second == null ) {
+ return first;
+ }
+
+ if ( compare( first, second ) < 0 ) {
+ return second;
+ }
+ return first;
+ }
+
+
+ /** Returns a UUID that is -1 of the passed uuid, sorted by time uuid only */
+ public static UUID decrement( UUID uuid ) {
+ if ( !isTimeBased( uuid ) ) {
+ throw new IllegalArgumentException( "The uuid must be a time type" );
+ }
+
+
+ //timestamp is in the 60 bit timestamp
+ long timestamp = uuid.timestamp();
+ timestamp--;
+
+ if ( timestamp < 0 ) {
+ throw new IllegalArgumentException( "You must specify a time uuid with a timestamp > 0" );
+ }
+
+ //get our bytes, then set the smaller timestamp into it
+ byte[] uuidBytes = bytes( uuid );
+
+ setTime( uuidBytes, timestamp );
+
+ return uuid( uuidBytes );
+ }
+
+
+ public static boolean isTimeBased( UUID uuid ) {
+ if ( uuid == null ) {
+ return false;
+ }
+ return uuid.version() == 1;
+ }
+
+
+ public static long getTimestampInMillis( UUID uuid ) {
+ if ( uuid == null ) {
+ return 0;
+ }
+ long t = uuid.timestamp();
+ return ( t - KCLOCK_OFFSET ) / KCLOCK_MULTIPLIER_L;
+ }
+
+
+ public static long getTimestampInMicros( UUID uuid ) {
+ if ( uuid == null ) {
+ return 0;
+ }
+ long t = uuid.timestamp();
+ return ( t - KCLOCK_OFFSET ) / 10;
+ }
+
+
+ public static UUID tryGetUUID( String s ) {
+ if ( s == null ) {
+ return null;
+ }
+ if ( s.length() != 36 ) {
+ return null;
+ }
+ // 8-4-4-4-12
+ // 0-7,8,9-12,13,14-17,18,19-22,23,24-35
+ if ( s.charAt( 8 ) != '-' ) {
+ return null;
+ }
+ if ( s.charAt( 13 ) != '-' ) {
+ return null;
+ }
+ if ( s.charAt( 18 ) != '-' ) {
+ return null;
+ }
+ if ( s.charAt( 23 ) != '-' ) {
+ return null;
+ }
+ UUID uuid = null;
+ try {
+ uuid = UUID.fromString( s );
+ }
+ catch ( Exception e ) {
+ LOG.info( "Could not convert String {} into a UUID", s, e );
+ }
+ return uuid;
+ }
+
+
+ public static boolean isUUID( String s ) {
+ return tryGetUUID( s ) != null;
+ }
+
+
+ public static UUID tryExtractUUID( String s ) {
+ if ( s == null ) {
+ return null;
+ }
+ if ( s.length() < 36 ) {
+ return null;
+ }
+ return tryGetUUID( s.substring( 0, 36 ) );
+ }
+
+
+ public static UUID tryExtractUUID( String s, int offset ) {
+ if ( s == null ) {
+ return null;
+ }
+ if ( ( s.length() - offset ) < 36 ) {
+ return null;
+ }
+ return tryGetUUID( s.substring( offset, offset + 36 ) );
+ }
+
+
+ public static String toBase64( UUID id ) {
+ if ( id == null ) {
+ return null;
+ }
+ return encodeBase64URLSafeString( bytes( id ) );
+ }
+
+
+ public static UUID fromBase64( String str ) {
+ if ( str == null ) {
+ return null;
+ }
+ byte[] bytes = decodeBase64( str );
+ if ( bytes.length != 16 ) {
+ return null;
+ }
+ return uuid( bytes );
+ }
+
+
+ public static int compare( UUID u1, UUID u2 ) {
+ return UUIDComparator.staticCompare( u1, u2 );
+ }
+
+
+ public static List<UUID> sort( List<UUID> uuids ) {
+ Collections.sort( uuids, new UUIDComparator() );
+ return uuids;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/75da9b8d/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/CollectionIT.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/CollectionIT.java b/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/CollectionIT.java
index 0444daf..f8736de 100644
--- a/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/CollectionIT.java
+++ b/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/CollectionIT.java
@@ -43,9 +43,9 @@ import org.apache.usergrid.persistence.model.entity.SimpleId;
import org.apache.usergrid.persistence.model.field.StringField;
import org.apache.usergrid.persistence.query.Query;
import org.apache.usergrid.persistence.query.Results;
-import org.apache.usergrid.persistence.utils.JsonUtils;
-import static org.apache.usergrid.persistence.utils.MapUtils.hashMap;
-import org.apache.usergrid.persistence.utils.UUIDUtils;
+import org.apache.usergrid.utils.JsonUtils;
+import static org.apache.usergrid.utils.MapUtils.hashMap;
+import org.apache.usergrid.utils.UUIDUtils;
import org.jukito.JukitoRunner;
import org.jukito.UseModules;
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/75da9b8d/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/GeoIT.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/GeoIT.java b/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/GeoIT.java
index 056e027..3a08638 100644
--- a/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/GeoIT.java
+++ b/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/GeoIT.java
@@ -39,7 +39,7 @@ import org.apache.usergrid.persistence.query.EntityRef;
import org.apache.usergrid.persistence.query.Query;
import org.apache.usergrid.persistence.query.Results;
import org.apache.usergrid.persistence.query.SimpleEntityRef;
-import org.apache.usergrid.persistence.utils.MapUtils;
+import org.apache.usergrid.utils.MapUtils;
import org.jukito.JukitoRunner;
import org.jukito.UseModules;
import static org.junit.Assert.assertEquals;