Github user ejwhite922 commented on a diff in the pull request:

    https://github.com/apache/incubator-rya/pull/124#discussion_r90066459
  
    --- Diff: 
dao/mongodb.rya/src/main/java/org/apache/rya/mongodb/document/util/DocumentVisibilityUtil.java
 ---
    @@ -0,0 +1,316 @@
    +/*
    + * 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.rya.mongodb.document.util;
    +
    +import static com.google.common.base.Preconditions.checkNotNull;
    +
    +import java.util.ArrayList;
    +import java.util.List;
    +
    +import org.apache.log4j.Logger;
    +import org.apache.rya.mongodb.MongoDbRdfConstants;
    +import org.apache.rya.mongodb.document.visibility.Authorizations;
    +import org.apache.rya.mongodb.document.visibility.ByteSequence;
    +import org.apache.rya.mongodb.document.visibility.DocumentVisibility;
    +import org.apache.rya.mongodb.document.visibility.DocumentVisibility.Node;
    +import 
org.apache.rya.mongodb.document.visibility.DocumentVisibility.NodeType;
    +import org.apache.rya.mongodb.document.visibility.VisibilityEvaluator;
    +import org.apache.rya.mongodb.document.visibility.VisibilityParseException;
    +
    +import com.google.common.base.Charsets;
    +import com.google.common.collect.Lists;
    +import com.mongodb.BasicDBList;
    +
    +/**
    + * Utility methods for converting boolean expressions between an Accumulo 
column
    + * visibility string style and a multidimensional array that can be used
    + * in MongoDB expressions.
    + */
    +public final class DocumentVisibilityUtil {
    +    private static final Logger log = 
Logger.getLogger(DocumentVisibilityUtil.class);
    +
    +    /**
    +     * Private constructor to prevent instantiation.
    +     */
    +    private DocumentVisibilityUtil() {
    +    }
    +
    +    /**
    +     * Converts a boolean string expression into a multidimensional
    +     * array representation of the boolean expression.
    +     * @param booleanString the boolean string expression.
    +     * @return the multidimensional array representation of the boolean
    +     * expression.
    +     */
    +    public static Object[] toMultidimensionalArray(final String 
booleanString) {
    +        final DocumentVisibility dv = new 
DocumentVisibility(booleanString);
    +        return toMultidimensionalArray(dv);
    +    }
    +
    +    /**
    +     * Converts a {@link DocumentVisibility} object into a multidimensional
    +     * array representation of the boolean expression.
    +     * @param dv the {@link DocumentVisibility}. (not {@code null})
    +     * @return the multidimensional array representation of the boolean
    +     * expression.
    +     */
    +    public static Object[] toMultidimensionalArray(final 
DocumentVisibility dv) {
    +        checkNotNull(dv);
    +        final byte[] expression = dv.flatten();
    +        final DocumentVisibility flattenedDv = 
DisjunctiveNormalFormConverter.createDnfDocumentVisibility(expression);
    +        final Object[] result = 
toMultidimensionalArray(flattenedDv.getParseTree(), expression);
    +        return result;
    +    }
    +
    +    /**
    +     * Converts a {@link Node} and its corresponding expression into a
    +     * multidimensional array representation of the boolean expression.
    +     * @param node the {@link Node}. (not {@code null})
    +     * @param expression the expression byte array.
    +     * @return the multidimensional array representation of the boolean
    +     * expression.
    +     */
    +    public static Object[] toMultidimensionalArray(final Node node, final 
byte[] expression) {
    +        checkNotNull(node);
    +        final List<Object> array = new ArrayList<>();
    +
    +        if (node.getChildren().isEmpty() && node.getType() == 
NodeType.TERM) {
    +            final String data = getTermNodeData(node);
    +            array.add(data);
    +        }
    +
    +        log.trace("Children size: " + node.getChildren().size() + " Type: 
" + node.getType());
    +        for (final Node child : node.getChildren()) {
    +            switch (child.getType()) {
    +                case EMPTY:
    +                case TERM:
    +                    String data;
    +                    if (child.getType() == NodeType.TERM) {
    +                        data = getTermNodeData(child);
    +                    } else {
    +                        data = "";
    +                    }
    +                    if (node.getType() == NodeType.OR) {
    +                        array.add(Lists.newArrayList(data).toArray(new 
Object[0]));
    +                    } else {
    +                        array.add(data);
    +                    }
    +                    break;
    +                case OR:
    +                case AND:
    +                    array.add(toMultidimensionalArray(child, expression));
    +                    break;
    +                default:
    +                    break;
    +            }
    +        }
    +
    +        return array.toArray(new Object[0]);
    +    }
    +
    +    public static String nodeToBooleanString(final Node node) {
    +        boolean isFirst = true;
    +        final StringBuilder sb = new StringBuilder();
    +        if (node.getType() == NodeType.TERM) {
    +            final String data = getTermNodeData(node);
    +            sb.append(data);
    +        }
    +        if (node.getType() == NodeType.AND) {
    +            sb.append("(");
    +        }
    +        for (final Node child : node.getChildren()) {
    +            if (isFirst) {
    +                isFirst = false;
    +            } else {
    +                if (node.getType() == NodeType.OR) {
    +                    sb.append("|");
    +                } else if (node.getType() == NodeType.AND) {
    +                    sb.append("&");
    +                }
    +            }
    +            switch (child.getType()) {
    +                case EMPTY:
    +                    sb.append("");
    +                    break;
    +                case TERM:
    +                    final String data = getTermNodeData(child);
    +                    sb.append(data);
    +                    break;
    +                case OR:
    +                    sb.append("(");
    +                    sb.append(nodeToBooleanString(child));
    +                    sb.append(")");
    +                    break;
    +                case AND:
    +                    sb.append(nodeToBooleanString(child));
    +                    break;
    +                default:
    +                    break;
    +            }
    +        }
    +        if (node.getType() == NodeType.AND) {
    +            sb.append(")");
    +        }
    +
    +        return sb.toString();
    +    }
    +
    +    /**
    +     * Converts a multidimensional array object representation of the 
document
    +     * visibility boolean expression into a string.
    +     * @param object the multidimensional array object representing the
    +     * document visibility boolean expression.
    +     * @return the boolean string expression.
    +     */
    +    public static String multidimensionalArrayToBooleanString(final 
Object[] object) {
    +        final String booleanString = 
multidimensionalArrayToBooleanStringInternal(object);
    +
    +        // Simplify and clean up the formatting.
    +        final DocumentVisibility dv = 
DisjunctiveNormalFormConverter.createDnfDocumentVisibility(booleanString);
    +        final byte[] bytes = dv.flatten();
    +        final String result = new String(bytes, Charsets.UTF_8);
    +
    +        return result;
    +    }
    +
    +    private static String 
multidimensionalArrayToBooleanStringInternal(final Object[] object) {
    +        final StringBuilder sb = new StringBuilder();
    +
    +        int count = 0;
    +        boolean isAnd = false;
    +        for (final Object child : object) {
    +            if (child instanceof String) {
    +                isAnd = true;
    +                if (count > 0) {
    +                    sb.append("&");
    +                }
    +                sb.append(child);
    +            } else if (child instanceof Object[]) {
    +                if (count > 0 && isAnd) {
    +                    sb.append("&");
    +                }
    +                final Object[] obj = (Object[]) child;
    +                sb.append("(");
    +                
sb.append(multidimensionalArrayToBooleanStringInternal(obj));
    +                sb.append(")");
    +            }
    +
    +            if (object.length > 1 && count + 1 < object.length && !isAnd) {
    +                sb.append("|");
    +            }
    +            count++;
    +        }
    +
    +        return sb.toString();
    +    }
    +
    +    /**
    +     * Conditionally adds quotes around a string.
    +     * @param data the string to add quotes to.
    +     * @param addQuotes {@code true} to add quotes. {@code false} to leave 
the
    +     * string as is.
    +     * @return the quoted string if {@code addQuotes} is {@code true}.
    +     * Otherwise, returns the string as is.
    +     */
    +    public static String addQuotes(final String data, final boolean 
addQuotes) {
    +        if (addQuotes) {
    +            return "\"" + data + "\"";
    +        } else {
    +            return data;
    +        }
    +    }
    +
    +    /**
    +     * Returns the term node's data.
    +     * @param node the {@link Node}.
    +     * @return the term node's data.
    +     */
    +    public static String getTermNodeData(final Node node) {
    +        final boolean isQuotedTerm = 
node.getExpression()[node.getTermStart()] == '"';
    +        final ByteSequence bs = node.getTerm(node.getExpression());
    +        final String data = addQuotes(new String(bs.toArray(), 
Charsets.UTF_8), isQuotedTerm);
    +        return data;
    +    }
    +
    +    /**
    +     * Checks if the user's authorizations allows them to have access to 
the
    +     * provided document based on its document visibility.
    +     * @param authorizations the {@link Authorizations}.
    +     * @param documentVisibility the document visibility byte expression.
    +     * @return {@code true} if the user has access to the document.
    +     * {@code false} otherwise.
    +     */
    +    public static boolean doesUserHaveDocumentAccess(final Authorizations 
authorizations, final byte[] documentVisibilityExpression) {
    +        final byte[] expression = documentVisibilityExpression != null ? 
documentVisibilityExpression : MongoDbRdfConstants.EMPTY_DV.getExpression();
    +        final DocumentVisibility documentVisibility = new 
DocumentVisibility(expression);
    +        return doesUserHaveDocumentAccess(authorizations, 
documentVisibility);
    +    }
    +
    +    /**
    +     * Checks if the user's authorizations allows them to have access to 
the
    +     * provided document based on its document visibility.
    +     * @param authorizations the {@link Authorizations}.
    +     * @param documentVisibility the {@link DocumentVisibility}.
    +     * @return {@code true} if the user has access to the document.
    +     * {@code false} otherwise.
    +     */
    +    public static boolean doesUserHaveDocumentAccess(final Authorizations 
authorizations, final DocumentVisibility documentVisibility) {
    +        return doesUserHaveDocumentAccess(authorizations, 
documentVisibility, true);
    +    }
    +
    +    /**
    +     * Checks if the user's authorizations allows them to have access to 
the
    +     * provided document based on its document visibility.
    +     * @param authorizations the {@link Authorizations}.
    +     * @param documentVisibility the {@link DocumentVisibility}.
    +     * @param doesEmptyAccessPass {@code true} if an empty authorization 
pass
    +     * allows access to everything. {@code false} otherwise.
    +     * @return {@code true} if the user has access to the document.
    +     * {@code false} otherwise.
    +     */
    +    public static boolean doesUserHaveDocumentAccess(final Authorizations 
authorizations, final DocumentVisibility documentVisibility, final boolean 
doesEmptyAccessPass) {
    +        final Authorizations userAuths = authorizations != null ? 
authorizations : MongoDbRdfConstants.ALL_AUTHORIZATIONS;
    +        final VisibilityEvaluator visibilityEvaluator = new 
VisibilityEvaluator(userAuths);
    +        boolean accept = false;
    +        if (doesEmptyAccessPass && 
MongoDbRdfConstants.ALL_AUTHORIZATIONS.equals(userAuths)) {
    +            accept = true;
    +        } else {
    +            try {
    +                accept = visibilityEvaluator.evaluate(documentVisibility);
    +            } catch (final VisibilityParseException e) {
    +                log.error("Could not parse document visibility.");
    +            }
    +        }
    +
    +        return accept;
    +    }
    +
    +    public static Object[] convertBasicDBListToObjectArray(final 
BasicDBList basicDbList) {
    --- End diff --
    
    Done.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---

Reply via email to