public static ImmutableDocument wrap(Document document) { return new ImmutableDocument(document.getData()); } }
/** * Returns the first ancestor found of the specified type to the specified * document when walking up the tree. If there was no ancestor of the * specified type and the root was reached, an empty {@code Optional} is * returned. * * @param <E> ancestor type * @param document the starting point * @param clazz the ancestor type to look for * @return first ancestor found or empty */ public static <E extends Document> Optional<E> ancestor( final Document document, final Class<E> clazz) { requireNonNull(document); requireNonNull(clazz); return document.ancestors() .filter(clazz::isInstance) .map(clazz::cast) .findFirst(); }
/** * Creates and returns a new raw map on a specified key in the specified * document. This might involve creating a new list if no such existed * already. If children already existed on that key, the new one is simply * added to the end of the list. * * @param parent the parent to create it in * @param key the key to create it under * @return the newly creating raw child map */ public static Map<String, Object> newDocument(Document parent, String key) { requireNonNull(parent); requireNonNull(key); final List<Map<String, Object>> children = parent.get(key) .map(DocumentUtil::castToDocumentList) .orElseGet(() -> { final List<Map<String, Object>> list = new CopyOnWriteArrayList<>(); parent.put(key, list); return list; }); final Map<String, Object> child = new ConcurrentSkipListMap<>(); children.add(child); return child; }
locate(loaded).collect(toList()).forEach(doc -> { if (delete) { doc.getParent().ifPresent(parent -> { final Collection<? extends Map<String, Object>> coll; if (doc instanceof Dbms) { coll = (Collection<? extends Map<String, Object>>) parent.getData().get(Project.DBMSES); } else if (doc instanceof Schema) { coll =(Collection<? extends Map<String, Object>>) parent.getData().get(Dbms.SCHEMAS); } else if (doc instanceof Table) { coll = (Collection<? extends Map<String, Object>>) parent.getData().get(Schema.TABLES); } else if (doc instanceof Column) { coll = (Collection<? extends Map<String, Object>>) parent.getData().get(Table.COLUMNS); } else if (doc instanceof PrimaryKeyColumn) { coll = (Collection<? extends Map<String, Object>>) parent.getData().get(Table.PRIMARY_KEY_COLUMNS); } else if (doc instanceof IndexColumn) { coll = (Collection<? extends Map<String, Object>>) parent.getData().get(Index.INDEX_COLUMNS); } else if (doc instanceof ForeignKeyColumn) { coll = (Collection<? extends Map<String, Object>>) parent.getData().get(ForeignKey.FOREIGN_KEY_COLUMNS); } else if (doc instanceof ForeignKey) { coll = (Collection<? extends Map<String, Object>>) parent.getData().get(ForeignKey.FOREIGN_KEY_COLUMNS); } else if (doc instanceof Index) { coll = (Collection<? extends Map<String, Object>>) parent.getData().get(Table.INDEXES); } else { getLog().error("Doc was of type " + doc.getClass()); final String id = doc.getAsString("id").orElseGet(() -> doc.getAsString("name").orElseThrow(() -> new RuntimeException("No id in document."))); if (coll.removeIf(d -> d.get("id").equals(id))) { edits.increment();
/** * Returns a {@code Stream} of every ancestor to this {@code Document}, * beginning with the first ancestor (the root) and ending with the parent * of this {@code Document}. * <p> * This stream can typically not be short-circuited and operations on it * will therefore have a complexity of {@code O(n)}. * * @return a stream of ancestors, from the root to the parent */ default Stream<Document> ancestors() { final List<Document> ancestors = new ArrayList<>(); Document parent = this; while ((parent = parent.getParent().orElse(null)) != null) { ancestors.add(parent); } Collections.reverse(ancestors); return ancestors.stream(); } }
metadata.add(Metadata.RESOURCE_NAME_KEY, p_document.getDocName()); TikaInputStream inputStream = TikaInputStream.get(p_document.getData(), metadata);
private boolean checkIf(Document doc, String param, String value) { final Pattern pattern = Pattern.compile(value); return doc.get(param) .map(Object::toString) .filter(pattern.asPredicate()) .isPresent(); }
/** * Returns an {@code Exception} supplier for when no attribute could be * found on a specified key in a specified document. * * @param document the document * @param key the key * @return the {@code Exception} supplier */ public static Supplier<NoSuchElementException> newNoSuchElementExceptionFor( Document document, String key) { return () -> new NoSuchElementException( "An attribute with the key '" + key + "' could not be found in " + document + " with name (" + Optional.ofNullable(document) .flatMap(doc -> doc.getAsString("name")) .orElse("null") + ")" ); }
/** * Traverses all the documents at and below the specified document in a * tree. Traversal is done depth first. The order of sub-document traversal * within a specific Document is unspecified (For example, a tables columns * may be traversed in any order). * * @param document the document to start at * @return stream of descendants */ @SuppressWarnings("unchecked") public static Stream<? extends Document> traverseOver(Document document) { requireNonNull(document); return Trees.traverse( document, d -> d.children(), Trees.TraversalOrder.DEPTH_FIRST_PRE ); }
private boolean matches(Document document, String where) { final String lastWhere; if (StringUtils.isBlank(where)) { return true; } else if (where.contains(PATH_SEPARATOR)) { final int index = where.lastIndexOf(PATH_SEPARATOR); final String parentIds = where.substring(0, index).trim(); lastWhere = where.substring(index + PATH_SEPARATOR.length()).trim(); final Optional<? extends Document> parent = document.getParent(); if (parent.isPresent()) { if (!matches(parent.get(), parentIds)) { return false; } } } else { lastWhere = where.trim(); } final int index = lastWhere.indexOf(SET_OPERATOR); final String key, value; if (index == -1) { key = "id"; value = "^" + lastWhere + "$"; } else { key = lastWhere.substring(0, index); value = lastWhere.substring(index + SET_OPERATOR.length()); } return checkIf(document, key, value); }
/** * Returns the children on the specified key, instantiated using the * specified constructor. This instance will be used as parent to the * constructor. * * @param <P> the parent type * @param <T> the child type * @param key the key * @param constructor the child constructor to use * @return a stream of constructed children * * @see #children() */ default <P extends Document, T extends Document> Stream<T> children( String key, BiFunction<P, Map<String, Object>, T> constructor) { final List<Map<String, Object>> list = get(key) .map(DocumentUtil::castToDocumentList) .orElse(null); if (list == null) { return Stream.empty(); } else { @SuppressWarnings("unchecked") final P thizz = (P)this; return list.stream().map(map -> constructor.apply(thizz, map)); } }
/** * Generates a new default name for the specified child by appending an * unique number to the {@link HasMainInterface#mainInterface()} of that * document. * <p> * This method will only suggest a new name for the specified child, not set * it. * * @param <C> the child type * @param childDocument the child to name * @return the suggested name for that child */ default <C extends Document & HasName & HasMainInterface> String defaultNameFor(C childDocument) { int counter = 1; String nameCandidate; do { nameCandidate = childDocument.mainInterface().getSimpleName() + counter++; } while ( children() .map(child -> child.getAsString(NAME)) .anyMatch(nameCandidate::equals) ); return nameCandidate; } }
/** * Creates a deep copy of the raw map in the specified document and wrap it * in a new typed document using the specified constructor. * * @param <DOC> the document type * @param document the document * @param constructor the document constructor * @return the copy */ public static <DOC extends Document> DOC deepCopy( DOC document, Function<Map<String, Object>, DOC> constructor) { return constructor.apply(deepCopyMap(document.getData())); }
/** * Returns {@code true} if the specified document and all its ancestors are * enabled. If at least one ancestor is not enabled, {@code false} is * returned. * * @param document the document to test * @return {@code true} if enabled, else {@code false} */ public static boolean isAllAncestorsEnabled(Document document) { return HasEnabled.test(document) && document.ancestors() .noneMatch(doc -> !HasEnabled.test(doc)); }
private Object parse(Document doc, String param, String value) { final Optional<Object> current = doc.get(param); final Object newValue; if (current.isPresent()) {
/** * Returns a stream of child documents to a specified document by using the * supplied constructor. * * @param <E> the expected child type * @param document the parent document * @param childConstructor child constructor * @return stream of children */ @SuppressWarnings("unchecked") public static <E extends Document> Stream<E> childrenOf( final Document document, final BiFunction<Document, Map<String, Object>, E> childConstructor) { requireNonNull(document); requireNonNull(childConstructor); return document.getData().values().stream() .filter(obj -> obj instanceof List<?>) .map(list -> (List<Object>) list) .flatMap(Collection::stream) .filter(obj -> obj instanceof Map<?, ?>) .map(map -> (Map<String, Object>) map) .map(map -> childConstructor.apply(document, map)); }
/** * Returns this node or one of the ancestor nodes if it matches the * specified {@code Class}. If no such node exists, an * {@code IllegalStateException} is thrown. * * @param <E> the type of the class to match * @param clazz the class to match * @return the node found */ private <E extends Document & HasMainInterface> Optional<E> documentOfType(Class<E> clazz) { requireNonNull(clazz); if (clazz.isAssignableFrom(document().mainInterface())) { @SuppressWarnings("unchecked") final E result = (E) document(); return Optional.of(result); } return document() .ancestors() .filter(clazz::isInstance) .map(clazz::cast) .findAny(); } }
/** * Helps documents to format a {@code toString()}-method. * * @param document the document * @return the string */ public static String toStringHelper(Document document) { return document.getClass().getSimpleName() + " {" + MapStream.of(document.getData()) .mapValue(VALUE_MAPPER) .map((k, v) -> "\"" + k + "\": " + (v == null ? "null" : (v instanceof String ? ("\"" + v + "\"") : v.toString()))) .collect(joining(", ")) + "}"; }