CubeId { @NonNull public static CubeId root(@NonNull String... dimensionIds) throws IllegalArgumentException { for (String o : dimensionIds) { if (o == null) { throw new IllegalArgumentException("Dimensions cannot be null"); } } return dimensionIds.length == 0 ? VOID : new CubeId(dimensionIds.clone(), Arrays2.EMPTY_STRING_ARRAY); } private  CubeId(@NonNull String[] dimensionIds, @NonNull String[] dimensionsValues); @NonNull static CubeId root(@NonNull String... dimensionIds); @NonNull static CubeId root(@NonNull List<String> dimensionIds); @NonNegative int getLevel(); @NonNegative int getMaxLevel(); @NonNull String getDimensionValue(@NonNegative int index); @NonNull Stream<String> getDimensionValueStream(); @NonNull String getDimensionId(@NonNegative int index); @NonNegative int getDepth(); boolean isRoot(); boolean isSeries(); boolean isVoid(); @NonNull CubeId child(@NonNull String... dimensionValues); boolean isAncestorOf(@NonNull CubeId input); @Override String toString(); @Override boolean equals(Object obj); @Override int hashCode();  }
@Test @SuppressWarnings("null") public void testFactories() { assertThatThrownBy(() -> CubeId.root((String[]) null)).isInstanceOf(NullPointerException.class); assertThatThrownBy(() -> CubeId.root("hello", (String) null)).isInstanceOf(IllegalArgumentException.class); assertThatThrownBy(() -> CubeId.root((List<String>) null)).isInstanceOf(NullPointerException.class); assertThatThrownBy(() -> CubeId.root(Arrays.asList("hello", null))).isInstanceOf(IllegalArgumentException.class); }