/* * Copyright 2015 by Thomas Lottermann * * Licensed 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 notaql.engines.mongodb.evaluation; import notaql.datamodel.*; import notaql.datamodel.fixation.Fixation; import notaql.engines.mongodb.model.vdata.HashFunctionVData; import notaql.evaluation.Evaluator; import notaql.evaluation.EvaluatorService; import notaql.evaluation.ValueEvaluationResult; import notaql.model.EvaluationException; import notaql.model.vdata.VData; import notaql.evaluation.values.ResolvingUtils; import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; /** * Allows calculating a hash code */ public class HashFunctionVDataEvaluator implements Evaluator { private static final long serialVersionUID = -4658960416178787343L; @Override public List<ValueEvaluationResult> evaluate(VData vData, Fixation fixation) { assert vData instanceof HashFunctionVData; final HashFunctionVData functionVData = (HashFunctionVData) vData; final VData pathVData = functionVData.getPath(); final List<ValueEvaluationResult> eval = EvaluatorService.getInstance().evaluate(pathVData, fixation); if(eval.stream().anyMatch(r -> ResolvingUtils.isUnresolved(r.getValue()))) throw new EvaluationException("Aggregation functions are not allowed in HASH"); if(eval.stream().anyMatch(r -> !(r.getValue() instanceof AtomValue<?>))) throw new EvaluationException("HASH() expects a atom value as argument"); final MessageDigest md5; try { md5 = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { throw new EvaluationException(e); } return eval.stream().map( r -> new ValueEvaluationResult( new StringValue( new BigInteger( 1, md5.digest(((AtomValue) r.getValue()).getValue().toString().getBytes()) ).toString(16) ), r.getFixation() ) ).collect(Collectors.toList()); } @Override public boolean canReduce(VData vData) { return false; } @Override public List<Class<? extends VData>> getProcessedClasses() { return Arrays.asList(HashFunctionVData.class); } }