All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.bigdata.rdf.internal.constraints.DigestBOp Maven / Gradle / Ivy

/**

Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016.  All rights reserved.

Contact:
     SYSTAP, LLC DBA Blazegraph
     2501 Calvert ST NW #106
     Washington, DC 20008
     [email protected]

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
package com.bigdata.rdf.internal.constraints;

import java.security.MessageDigest;
import java.util.Map;

import org.openrdf.model.Literal;

import com.bigdata.bop.BOp;
import com.bigdata.bop.IBindingSet;
import com.bigdata.bop.IValueExpression;
import com.bigdata.bop.NV;
import com.bigdata.rdf.error.SparqlTypeErrorException;
import com.bigdata.rdf.internal.IV;
import com.bigdata.rdf.internal.XSD;
import com.bigdata.rdf.model.BigdataLiteral;
import com.bigdata.rdf.sparql.ast.GlobalAnnotations;

/**
 * A Digest expression involving a {@link IValueExpression} operand. The
 * operation to be applied to the operands is specified by the
 * {@link DigestBOp.Annotations#OP} annotation.
 */
public class DigestBOp extends IVValueExpression implements INeedsMaterialization {

    private static final long serialVersionUID = 9136864442064392445L;

    public interface Annotations extends IVValueExpression.Annotations {

        /**
         * The operation to be applied to the left operand (required). The value
         * of this annotation is a {@link DigestOp}, such as
         * {@link DigestOp#MD5}.
         * 
         * @see DigestOp
         */
        String OP = DigestBOp.class.getName() + ".op";

    }

    public enum DigestOp {
        MD5, SHA1, SHA224, SHA256, SHA384, SHA512;

    }

    /**
     * 
     * @param left
     *            The left operand.
     * @param right
     *            The right operand.
     * @param op
     *            The annotation specifying the operation to be performed on
     *            those operands.
     */
    public DigestBOp(final IValueExpression left,
            final DigestOp op, final GlobalAnnotations globals) {

        this(new BOp[] { left }, anns(globals, new NV(Annotations.OP, op)));

    }

    /**
     * Required shallow copy constructor.
     * 
     * @param args
     *            The operands.
     * @param op
     *            The operation.
     */
    public DigestBOp(final BOp[] args, final Map anns) {

        super(args, anns);

        if (args.length != 1 || args[0] == null
                || getProperty(Annotations.OP) == null) {

            throw new IllegalArgumentException();

        }

    }

    /**
     * Constructor required for {@link com.bigdata.bop.BOpUtility#deepCopy(FilterNode)}.
     *
     * @param op
     */
    public DigestBOp(final DigestBOp op) {

        super(op);

    }

    private static final char[] hexChar = { '0', '1', '2', '3', '4', '5', '6',
            '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

    public static String toHexString(final byte[] buf) {

        final StringBuilder strBuf = new StringBuilder(buf.length * 2);
        
        for (int i = 0; i < buf.length; i++) {
        
            strBuf.append(hexChar[(buf[i] & 0xf0) >>> 4]); // fill left with
            
            // zero bits
            strBuf.append(hexChar[buf[i] & 0x0f]);
            
        }

        return strBuf.toString();
        
    }

	@Override
	public Requirement getRequirement() {
		return Requirement.SOMETIMES;
	}

	@Override
    public IV get(final IBindingSet bs) throws SparqlTypeErrorException {

        final IV iv = getAndCheckLiteral(0, bs);
        //Recreate since they are not thread safe
        MessageDigest md = null;
        final Literal lit = asLiteral(iv);
        if (lit.getLanguage() == null &&
            (lit.getDatatype() == null || lit.getDatatype().equals(XSD.STRING))) {
            
            try {
                String label = lit.getLabel();
                switch (op()) {
                case MD5:
                    md = MessageDigest.getInstance("MD5");
                    break;
                case SHA1:
                    md = MessageDigest.getInstance("SHA-1");
                    break;
                case SHA224:
                    md = MessageDigest.getInstance("SHA-224");
                    break;
                case SHA256:
                    md = MessageDigest.getInstance("SHA-256");
                    break;
                case SHA384:
                    md = MessageDigest.getInstance("SHA-384");
                    break;
               case SHA512:
                    md = MessageDigest.getInstance("SHA-512");
                    break;
                default:
                    throw new UnsupportedOperationException();
                }
                byte[] bytes = label.getBytes("UTF-8");
                md.update(bytes);
                byte[] digest = md.digest();
                final BigdataLiteral str = getValueFactory().createLiteral(toHexString(digest));
                return super.asIV(str, bs);
            } catch (Exception e) {
                throw new SparqlTypeErrorException();
            }
        }
        throw new SparqlTypeErrorException();
    }


    public DigestOp op() {
        return (DigestOp) getRequiredProperty(Annotations.OP);
    }

    public String toString() {

        final StringBuilder sb = new StringBuilder();
        sb.append(op());
        sb.append("(").append(get(0)).append(")");
        return sb.toString();

    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy