Class Utils


  • public class Utils
    extends java.lang.Object
    Utility methods.
    • Field Summary

      Fields 
      Modifier and Type Field Description
      static org.apache.jackrabbit.guava.common.base.Predicate<java.lang.String> COMMITROOT_OR_REVISIONS
      A predicate for _commitRoot and _revisions names.
      static int NODE_NAME_LIMIT
      The maximum size a node name, in bytes.
      static int PATH_LONG
      The maximum length of the parent path, in bytes.
      static int PATH_SHORT
      The length of path (in characters), whose UTF-8 representation can not possibly be too large to be used for the primary key for the document store.
      static org.apache.jackrabbit.guava.common.base.Predicate<java.lang.String> PROPERTY_OR_DELETED
      A predicate for property and _deleted names.
      static org.apache.jackrabbit.guava.common.base.Predicate<java.lang.String> PROPERTY_OR_DELETED_OR_COMMITROOT_OR_REVISIONS
      A predicate for property, _deleted, _commitRoot or _revisions names.
    • Constructor Summary

      Constructors 
      Constructor Description
      Utils()  
    • Method Summary

      All Methods Static Methods Concrete Methods 
      Modifier and Type Method Description
      static <T> CloseableIterable<T> abortingIterable​(java.lang.Iterable<T> iterable, org.apache.jackrabbit.guava.common.base.Predicate<T> p)
      Wraps the given iterable and aborts iteration over elements when the predicate on an element evaluates to false.
      static void alignWithExternalRevisions​(@NotNull NodeDocument rootDoc, @NotNull Clock clock, int clusterId, long warnThresholdMillis)
      Makes sure the current time is after the most recent external revision timestamp in the _lastRev map of the given root document.
      static java.lang.String asISO8601​(long ms)
      Formats the epoch time in milliseconds as ISO-8601 in UTC.
      static java.lang.Long asLong​(@Nullable java.lang.Number n)
      Returns the given number instance as a Long.
      static java.lang.Iterable<StringValue> asStringValueIterable​(@NotNull java.lang.Iterable<java.lang.String> values)
      Transforms the given Iterable from String to StringValue elements.
      static void checkRevisionAge​(DocumentStore store, ClusterNodeInfo info, Clock clock)
      Check the revision age on the root document for the given cluster node info.
      static void closeIfCloseable​(java.lang.Object obj)
      Closes the obj its of type Closeable.
      static <K> void deepCopyMap​(java.util.Map<K,​java.lang.Object> source, java.util.Map<K,​java.lang.Object> target)
      Deep copy of a map that may contain map values.
      static java.lang.StringBuilder encodeHexString​(byte[] data, java.lang.StringBuilder sb)
      Encodes the given data as hexadecimal string representation and appends it to the StringBuilder.
      static java.lang.String escapePropertyName​(java.lang.String propertyName)  
      static int estimateMemoryUsage​(java.util.Map<?,​java.lang.Object> map)  
      static java.lang.Iterable<NodeDocument> getAllDocuments​(DocumentStore store)
      Returns an Iterable over all NodeDocuments in the given store.
      static int getDepthFromId​(java.lang.String id)  
      static int getIdDepth​(Path path)
      Calculates the depth prefix of the id for the given path.
      static java.lang.String getIdFromPath​(@NotNull java.lang.String path)  
      static java.lang.String getIdFromPath​(@NotNull Path path)  
      static java.lang.String getKeyLowerLimit​(Path path)
      Returns the lower key limit to retrieve the children of the given path.
      static java.lang.String getKeyUpperLimit​(Path path)
      Returns the upper key limit to retrieve the children of the given path.
      static long getMaxExternalTimestamp​(java.lang.Iterable<Revision> revisions, int localClusterId)
      Returns the highest timestamp of all the passed external revisions.
      static long getMinTimestampForDiff​(@NotNull RevisionVector fromRev, @NotNull RevisionVector toRev, @NotNull RevisionVector minRevisions)
      Returns the minimum timestamp to use for a query for child documents that have been modified between fromRev and toRev.
      static java.lang.String getModuleVersion()
      Returns the version of the module that contains the DocumentNodeStore.
      static @Nullable java.lang.String getParentId​(java.lang.String id)
      Returns the parent id for given id if possible
      static @Nullable java.lang.String getParentIdFromLowerLimit​(java.lang.String fromKey)
      Returns parentId extracted from the fromKey.
      static java.lang.String getPathFromId​(java.lang.String id)  
      static java.lang.String getPreviousIdFor​(Path path, Revision r, int height)  
      static Path getPreviousPathFor​(Path path, Revision r, int height)  
      static @NotNull NodeDocument getRootDocument​(@NotNull DocumentStore store)
      Returns the root node document of the given document store.
      static java.lang.Iterable<NodeDocument> getSelectedDocuments​(DocumentStore store, java.lang.String indexedProperty, long startValue)
      static java.lang.Iterable<NodeDocument> getSelectedDocuments​(DocumentStore store, java.lang.String indexedProperty, long startValue, int batchSize)
      Returns an Iterable over all NodeDocuments in the given store matching a condition on an indexed property.
      static @NotNull RevisionVector getStartRevisions​(@NotNull java.lang.Iterable<ClusterNodeInfoDocument> clusterNodes)
      Returns a revision vector that contains a revision for each of the passed cluster nodes with a revision timestamp that corresponds to the last known time when the cluster node was started.
      static boolean isCommitted​(@Nullable java.lang.String tag)
      Returns true if a revision tagged with the given revision should be considered committed, false otherwise.
      static boolean isGreaterOrEquals​(@NotNull RevisionVector a, @NotNull RevisionVector b)
      Returns true if all the revisions in the a greater or equals to their counterparts in b.
      static boolean isHiddenPath​(@NotNull java.lang.String path)  
      static boolean isIdFromLongPath​(java.lang.String id)  
      static boolean isLeafPreviousDocId​(java.lang.String id)
      Determines if the passed id belongs to a leaf level previous doc
      static boolean isLocalChange​(@NotNull RevisionVector from, @NotNull RevisionVector to, int clusterId)
      Returns true if changes identified by the from and to RevisionVector are considered local changes.
      static boolean isLongPath​(Path path)  
      static boolean isNodeNameLong​(Path path, int sizeLimit)
      Checks whether Node name is too long or not based on underlining document store
      static boolean isPreviousDocId​(java.lang.String id)
      Determines if the passed id belongs to a previous doc
      static boolean isPropertyName​(java.lang.String key)  
      static boolean isThrottlingEnabled​(DocumentNodeStoreBuilder<?> builder)
      Check whether throttling is enabled or not for document store.
      static void joinQuietly​(java.lang.Thread... threads)
      Calls Thread.join() on each of the passed threads and catches any potentially thrown InterruptedException.
      static java.lang.String mapEntryDiagnostics​(@NotNull java.util.Set<java.util.Map.Entry<java.lang.String,​java.lang.Object>> entries)
      Generates diagnostics about the structure of the entries of the document by counting properties and their lengths.
      static @Nullable Revision max​(@Nullable Revision a, @Nullable Revision b)
      Returns the revision with the newer timestamp or null if both revisions are null.
      static @Nullable Revision max​(@Nullable Revision a, @Nullable Revision b, @NotNull java.util.Comparator<Revision> c)
      Returns the revision which is considered more recent or null if both revisions are null.
      static @Nullable Revision min​(@Nullable Revision a, @Nullable Revision b)
      Returns the revision with the older timestamp or null if both revisions are null.
      static @Nullable Revision min​(@Nullable Revision a, @Nullable Revision b, @NotNull java.util.Comparator<Revision> c)
      Returns the revision which is considered older or null if both revisions are null.
      static int pathDepth​(java.lang.String path)  
      static java.lang.Iterable<java.lang.String> pathToId​(@NotNull java.lang.Iterable<java.lang.String> paths)
      Transforms the given paths into ids using getIdFromPath(String).
      static @NotNull Revision resolveCommitRevision​(@NotNull Revision rev, @NotNull java.lang.String tag)
      Resolve the commit revision for the given revision rev and the associated commit tag.
      static long sum​(long... addends)
      Calculates the sum of the given long values.
      static java.lang.String timestampToString​(long timestamp)
      Provides a readable string for given timestamp
      static java.lang.String unescapePropertyName​(java.lang.String key)  
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • PATH_SHORT

        public static final int PATH_SHORT
        The length of path (in characters), whose UTF-8 representation can not possibly be too large to be used for the primary key for the document store.
      • PATH_LONG

        public static final int PATH_LONG
        The maximum length of the parent path, in bytes. If the parent path is longer, then the id of a document is no longer the path, but the hash of the parent, and then the node name.
      • NODE_NAME_LIMIT

        public static final int NODE_NAME_LIMIT
        The maximum size a node name, in bytes. This is only a problem for long path.
      • PROPERTY_OR_DELETED

        public static final org.apache.jackrabbit.guava.common.base.Predicate<java.lang.String> PROPERTY_OR_DELETED
        A predicate for property and _deleted names.
      • PROPERTY_OR_DELETED_OR_COMMITROOT_OR_REVISIONS

        public static final org.apache.jackrabbit.guava.common.base.Predicate<java.lang.String> PROPERTY_OR_DELETED_OR_COMMITROOT_OR_REVISIONS
        A predicate for property, _deleted, _commitRoot or _revisions names.
      • COMMITROOT_OR_REVISIONS

        public static final org.apache.jackrabbit.guava.common.base.Predicate<java.lang.String> COMMITROOT_OR_REVISIONS
        A predicate for _commitRoot and _revisions names.
    • Constructor Detail

      • Utils

        public Utils()
    • Method Detail

      • pathDepth

        public static int pathDepth​(java.lang.String path)
      • getIdDepth

        public static int getIdDepth​(Path path)
        Calculates the depth prefix of the id for the given path. The is the same as pathDepth(String), but takes a Path argument.
        Parameters:
        path - a path.
        Returns:
        the id depth prefix for the given path.
      • estimateMemoryUsage

        public static int estimateMemoryUsage​(java.util.Map<?,​java.lang.Object> map)
      • mapEntryDiagnostics

        public static java.lang.String mapEntryDiagnostics​(@NotNull
                                                           @NotNull java.util.Set<java.util.Map.Entry<java.lang.String,​java.lang.Object>> entries)
        Generates diagnostics about the structure of the entries of the document by counting properties and their lengths.
      • escapePropertyName

        public static java.lang.String escapePropertyName​(java.lang.String propertyName)
      • unescapePropertyName

        public static java.lang.String unescapePropertyName​(java.lang.String key)
      • isPropertyName

        public static boolean isPropertyName​(java.lang.String key)
      • getIdFromPath

        public static java.lang.String getIdFromPath​(@NotNull
                                                     @NotNull java.lang.String path)
      • getIdFromPath

        public static java.lang.String getIdFromPath​(@NotNull
                                                     @NotNull Path path)
      • encodeHexString

        public static java.lang.StringBuilder encodeHexString​(byte[] data,
                                                              java.lang.StringBuilder sb)
        Encodes the given data as hexadecimal string representation and appends it to the StringBuilder. The hex digits are in lower case.
        Parameters:
        data - the bytes to encode.
        sb - the hexadecimal string representation is appended to this StringBuilder.
        Returns:
        the StringBuilder passed to this method.
      • getParentId

        @Nullable
        public static @Nullable java.lang.String getParentId​(java.lang.String id)
        Returns the parent id for given id if possible

        It would return null in following cases

        • If id is from long path
        • If id is for root path
        • If id is for an invalid path
        Parameters:
        id - id for which parent id needs to be determined
        Returns:
        parent id. null if parent id cannot be determined
      • isNodeNameLong

        public static boolean isNodeNameLong​(Path path,
                                             int sizeLimit)
        Checks whether Node name is too long or not based on underlining document store
        Parameters:
        path - node path
        sizeLimit - sizeLimit for node name
        Returns:
        true if node name is long else false
      • isLongPath

        public static boolean isLongPath​(Path path)
      • isIdFromLongPath

        public static boolean isIdFromLongPath​(java.lang.String id)
      • getPathFromId

        public static java.lang.String getPathFromId​(java.lang.String id)
      • getDepthFromId

        public static int getDepthFromId​(java.lang.String id)
                                  throws java.lang.IllegalArgumentException
        Throws:
        java.lang.IllegalArgumentException
      • getPreviousPathFor

        public static Path getPreviousPathFor​(Path path,
                                              Revision r,
                                              int height)
      • getPreviousIdFor

        public static java.lang.String getPreviousIdFor​(Path path,
                                                        Revision r,
                                                        int height)
      • isPreviousDocId

        public static boolean isPreviousDocId​(java.lang.String id)
        Determines if the passed id belongs to a previous doc
        Parameters:
        id - id to check
        Returns:
        true if the id belongs to a previous doc
      • isLeafPreviousDocId

        public static boolean isLeafPreviousDocId​(java.lang.String id)
        Determines if the passed id belongs to a leaf level previous doc
        Parameters:
        id - id to check
        Returns:
        true if the id belongs to a leaf level previous doc
      • deepCopyMap

        public static <K> void deepCopyMap​(java.util.Map<K,​java.lang.Object> source,
                                           java.util.Map<K,​java.lang.Object> target)
        Deep copy of a map that may contain map values.
        Type Parameters:
        K - the type of the map key
        Parameters:
        source - the source map
        target - the target map
      • getKeyLowerLimit

        public static java.lang.String getKeyLowerLimit​(Path path)
        Returns the lower key limit to retrieve the children of the given path.
        Parameters:
        path - a path.
        Returns:
        the lower key limit.
      • getKeyUpperLimit

        public static java.lang.String getKeyUpperLimit​(Path path)
        Returns the upper key limit to retrieve the children of the given path.
        Parameters:
        path - a path.
        Returns:
        the upper key limit.
      • getParentIdFromLowerLimit

        @Nullable
        public static @Nullable java.lang.String getParentIdFromLowerLimit​(java.lang.String fromKey)
        Returns parentId extracted from the fromKey. fromKey is usually constructed using Utils#getKeyLowerLimit
        Parameters:
        fromKey - key used as start key in queries
        Returns:
        parentId if possible.
      • isCommitted

        public static boolean isCommitted​(@Nullable
                                          @Nullable java.lang.String tag)
        Returns true if a revision tagged with the given revision should be considered committed, false otherwise. Committed revisions have a tag, which equals 'c' or starts with 'c-'.
        Parameters:
        tag - the tag (may be null).
        Returns:
        true if committed; false otherwise.
      • resolveCommitRevision

        @NotNull
        public static @NotNull Revision resolveCommitRevision​(@NotNull
                                                              @NotNull Revision rev,
                                                              @NotNull
                                                              @NotNull java.lang.String tag)
        Resolve the commit revision for the given revision rev and the associated commit tag.
        Parameters:
        rev - a revision.
        tag - the associated commit tag.
        Returns:
        the actual commit revision for rev.
      • closeIfCloseable

        public static void closeIfCloseable​(java.lang.Object obj)
        Closes the obj its of type Closeable. It is mostly used to close Iterator/Iterables which are backed by say DBCursor
        Parameters:
        obj - object to close
      • timestampToString

        public static java.lang.String timestampToString​(long timestamp)
        Provides a readable string for given timestamp
      • max

        @Nullable
        public static @Nullable Revision max​(@Nullable
                                             @Nullable Revision a,
                                             @Nullable
                                             @Nullable Revision b)
        Returns the revision with the newer timestamp or null if both revisions are null. The implementation will return the first revision if both have the same timestamp.
        Parameters:
        a - the first revision (or null).
        b - the second revision (or null).
        Returns:
        the revision with the newer timestamp.
      • max

        @Nullable
        public static @Nullable Revision max​(@Nullable
                                             @Nullable Revision a,
                                             @Nullable
                                             @Nullable Revision b,
                                             @NotNull
                                             @NotNull java.util.Comparator<Revision> c)
        Returns the revision which is considered more recent or null if both revisions are null. The implementation will return the first revision if both are considered equal. The comparison is done using the provided comparator.
        Parameters:
        a - the first revision (or null).
        b - the second revision (or null).
        c - the comparator.
        Returns:
        the revision considered more recent.
      • min

        @Nullable
        public static @Nullable Revision min​(@Nullable
                                             @Nullable Revision a,
                                             @Nullable
                                             @Nullable Revision b)
        Returns the revision with the older timestamp or null if both revisions are null. The implementation will return the first revision if both have the same timestamp.
        Parameters:
        a - the first revision (or null).
        b - the second revision (or null).
        Returns:
        the revision with the older timestamp.
      • min

        @Nullable
        public static @Nullable Revision min​(@Nullable
                                             @Nullable Revision a,
                                             @Nullable
                                             @Nullable Revision b,
                                             @NotNull
                                             @NotNull java.util.Comparator<Revision> c)
        Returns the revision which is considered older or null if both revisions are null. The implementation will return the first revision if both are considered equal. The comparison is done using the provided comparator.
        Parameters:
        a - the first revision (or null).
        b - the second revision (or null).
        c - the comparator.
        Returns:
        the revision considered more recent.
      • getAllDocuments

        public static java.lang.Iterable<NodeDocument> getAllDocuments​(DocumentStore store)
        Returns an Iterable over all NodeDocuments in the given store. The returned Iterable does not guarantee a consistent view on the store. it may return documents that have been added to the store after this method had been called.
        Parameters:
        store - a DocumentStore.
        Returns:
        an Iterable over all documents in the store.
      • getRootDocument

        @NotNull
        public static @NotNull NodeDocument getRootDocument​(@NotNull
                                                            @NotNull DocumentStore store)
        Returns the root node document of the given document store. The returned document is retrieved from the document store via DocumentStore.find(Collection, String), which means the implementation is allowed to return a cached version of the document. The document is therefore not guaranteed to be up-to-date.
        Parameters:
        store - a document store.
        Returns:
        the root document.
        Throws:
        java.lang.IllegalStateException - if there is no root document.
      • getSelectedDocuments

        public static java.lang.Iterable<NodeDocument> getSelectedDocuments​(DocumentStore store,
                                                                            java.lang.String indexedProperty,
                                                                            long startValue,
                                                                            int batchSize)
        Returns an Iterable over all NodeDocuments in the given store matching a condition on an indexed property. The returned Iterable does not guarantee a consistent view on the store. it may return documents that have been added to the store after this method had been called.
        Parameters:
        store - a DocumentStore.
        indexedProperty - the name of the indexed property.
        startValue - the lower bound value for the indexed property (inclusive).
        batchSize - number of documents to fetch at once
        Returns:
        an Iterable over all documents in the store matching the condition
      • isHiddenPath

        public static boolean isHiddenPath​(@NotNull
                                           @NotNull java.lang.String path)
        Returns:
        if path represent oak's internal path. That is, a path element start with a colon.
      • asStringValueIterable

        public static java.lang.Iterable<StringValue> asStringValueIterable​(@NotNull
                                                                            @NotNull java.lang.Iterable<java.lang.String> values)
        Transforms the given Iterable from String to StringValue elements. The Iterable must no have null values.
      • pathToId

        public static java.lang.Iterable<java.lang.String> pathToId​(@NotNull
                                                                    @NotNull java.lang.Iterable<java.lang.String> paths)
        Transforms the given paths into ids using getIdFromPath(String).
      • getMaxExternalTimestamp

        public static long getMaxExternalTimestamp​(java.lang.Iterable<Revision> revisions,
                                                   int localClusterId)
        Returns the highest timestamp of all the passed external revisions. A revision is considered external if the clusterId is different from the passed localClusterId.
        Parameters:
        revisions - the revisions to consider.
        localClusterId - the id of the local cluster node.
        Returns:
        the highest timestamp or Long.MIN_VALUE if none of the revisions is external.
      • asLong

        public static java.lang.Long asLong​(@Nullable
                                            @Nullable java.lang.Number n)
        Returns the given number instance as a Long.
        Parameters:
        n - a number or null.
        Returns:
        the number converted to a Long or null if n is null.
      • getStartRevisions

        @NotNull
        public static @NotNull RevisionVector getStartRevisions​(@NotNull
                                                                @NotNull java.lang.Iterable<ClusterNodeInfoDocument> clusterNodes)
        Returns a revision vector that contains a revision for each of the passed cluster nodes with a revision timestamp that corresponds to the last known time when the cluster node was started.
        Parameters:
        clusterNodes - the cluster node information.
        Returns:
        revision vector representing the last known time when the cluster nodes were started.
      • getMinTimestampForDiff

        public static long getMinTimestampForDiff​(@NotNull
                                                  @NotNull RevisionVector fromRev,
                                                  @NotNull
                                                  @NotNull RevisionVector toRev,
                                                  @NotNull
                                                  @NotNull RevisionVector minRevisions)
        Returns the minimum timestamp to use for a query for child documents that have been modified between fromRev and toRev.
        Parameters:
        fromRev - the from revision.
        toRev - the to revision.
        minRevisions - the minimum revisions of foreign cluster nodes. These are derived from the startTime of a cluster node.
        Returns:
        the minimum timestamp.
      • isThrottlingEnabled

        public static boolean isThrottlingEnabled​(DocumentNodeStoreBuilder<?> builder)
        Check whether throttling is enabled or not for document store.
        Parameters:
        builder - instance for DocumentNodeStoreBuilder
        Returns:
        true if throttling is enabled else false
      • isGreaterOrEquals

        public static boolean isGreaterOrEquals​(@NotNull
                                                @NotNull RevisionVector a,
                                                @NotNull
                                                @NotNull RevisionVector b)
        Returns true if all the revisions in the a greater or equals to their counterparts in b. If b contains revisions for cluster nodes that are not present in a, return false.
        Parameters:
        a -
        b -
        Returns:
        true if all the revisions in the a are at least as recent as their counterparts in the b
      • isLocalChange

        public static boolean isLocalChange​(@NotNull
                                            @NotNull RevisionVector from,
                                            @NotNull
                                            @NotNull RevisionVector to,
                                            int clusterId)
        Returns true if changes identified by the from and to RevisionVector are considered local changes. That is the only difference between the two revision vectors are for the given (local) clusterId.
        Parameters:
        from - the from revision vector.
        to - the to revision vector.
        clusterId - the local clusterId.
        Returns:
        whether the changes are considered local.
      • abortingIterable

        public static <T> CloseableIterable<T> abortingIterable​(java.lang.Iterable<T> iterable,
                                                                org.apache.jackrabbit.guava.common.base.Predicate<T> p)
        Wraps the given iterable and aborts iteration over elements when the predicate on an element evaluates to false. Calling close() on the returned iterable will close the passed iterable if it is Closeable.
        Parameters:
        iterable - the iterable to wrap.
        p - the predicate.
        Returns:
        the aborting iterable.
      • alignWithExternalRevisions

        public static void alignWithExternalRevisions​(@NotNull
                                                      @NotNull NodeDocument rootDoc,
                                                      @NotNull
                                                      @NotNull Clock clock,
                                                      int clusterId,
                                                      long warnThresholdMillis)
                                               throws java.lang.InterruptedException
        Makes sure the current time is after the most recent external revision timestamp in the _lastRev map of the given root document. If necessary the current thread waits until clock is after the external revision timestamp.
        Parameters:
        rootDoc - the root document.
        clock - the clock.
        clusterId - the local clusterId.
        warnThresholdMillis - log a warning when an external change in the future is detected with more than this time difference.
        Throws:
        java.lang.InterruptedException - if the current thread is interrupted while waiting. The interrupted status on the current thread is cleared when this exception is thrown.
      • joinQuietly

        public static void joinQuietly​(java.lang.Thread... threads)
        Calls Thread.join() on each of the passed threads and catches any potentially thrown InterruptedException.
        Parameters:
        threads - the threads to join.
      • getModuleVersion

        public static java.lang.String getModuleVersion()
        Returns the version of the module that contains the DocumentNodeStore.
        Returns:
        the module version or "SNAPSHOT" if unknown.
      • checkRevisionAge

        public static void checkRevisionAge​(DocumentStore store,
                                            ClusterNodeInfo info,
                                            Clock clock)
                                     throws DocumentStoreException
        Check the revision age on the root document for the given cluster node info. The check will fail with a DocumentStoreException if the _lastRev timestamp for the cluster node is newer then the current clock time. The check will not fail if the root document does not exist or does not have a _lastRev entry for the cluster node.
        Parameters:
        store - the document store from where to read the root document.
        info - the cluster node info with the clusterId.
        clock - the clock to get the current time.
        Throws:
        DocumentStoreException - if the check fails.
      • sum

        public static long sum​(long... addends)
        Calculates the sum of the given long values. The implementation protects against overflow by returning Long#MAX_VALUE when the result would actually be bigger than that. Similarly, Long#MIN_VALUE is returned when the result would actually be smaller than that.
        Parameters:
        addends - the values.
        Returns:
        the sum of the values.
      • asISO8601

        public static java.lang.String asISO8601​(long ms)
        Formats the epoch time in milliseconds as ISO-8601 in UTC.
        Parameters:
        ms - the time in milliseconds.
        Returns:
        date format for the time in milliseconds.