| /******************************************************************************** |
| * Copyright (c) 2015-2020 Contributors to the Eclipse Foundation |
| * |
| * See the NOTICE file(s) distributed with this work for additional |
| * information regarding copyright ownership. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0. |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| ********************************************************************************/ |
| |
| package org.eclipse.mdm.nodeprovider.entity; |
| |
| import java.time.LocalDateTime; |
| import java.time.temporal.TemporalAdjusters; |
| |
| import org.eclipse.mdm.api.base.adapter.Attribute; |
| import org.eclipse.mdm.api.base.model.Value; |
| import org.eclipse.mdm.api.base.model.ValueType; |
| import org.eclipse.mdm.api.base.query.ComparisonOperator; |
| import org.eclipse.mdm.api.base.query.Condition; |
| import org.eclipse.mdm.api.base.search.ContextState; |
| |
| public enum ValuePrecision { |
| |
| EXACT { |
| @Override |
| public void applyOn(Value value) { |
| // Intentionally empty |
| } |
| |
| @Override |
| public Condition getCondition(ContextState contextState, Attribute attribute, Object value) { |
| return ComparisonOperator.EQUAL.create(contextState, attribute, value); |
| } |
| }, |
| YEAR { |
| @Override |
| public void applyOn(Value value) { |
| ValuePrecision.applyDate(value, YEAR); |
| } |
| |
| @Override |
| public Condition getCondition(ContextState contextState, Attribute attribute, Object value) { |
| return getDateCondition(contextState, attribute, value, YEAR); |
| } |
| }, |
| MONTH { |
| @Override |
| public void applyOn(Value value) { |
| ValuePrecision.applyDate(value, MONTH); |
| } |
| |
| @Override |
| public Condition getCondition(ContextState contextState, Attribute attribute, Object value) { |
| return getDateCondition(contextState, attribute, value, MONTH); |
| } |
| }, |
| DAY { |
| @Override |
| public void applyOn(Value value) { |
| ValuePrecision.applyDate(value, DAY); |
| } |
| |
| @Override |
| public Condition getCondition(ContextState contextState, Attribute attribute, Object value) { |
| return getDateCondition(contextState, attribute, value, DAY); |
| } |
| }, |
| HOUR { |
| @Override |
| public void applyOn(Value value) { |
| ValuePrecision.applyDate(value, HOUR); |
| } |
| |
| @Override |
| public Condition getCondition(ContextState contextState, Attribute attribute, Object value) { |
| return getDateCondition(contextState, attribute, value, HOUR); |
| } |
| }, |
| MINUTE { |
| @Override |
| public void applyOn(Value value) { |
| ValuePrecision.applyDate(value, MINUTE); |
| } |
| |
| @Override |
| public Condition getCondition(ContextState contextState, Attribute attribute, Object value) { |
| return getDateCondition(contextState, attribute, value, MINUTE); |
| } |
| }; |
| |
| /** |
| * Applies this {@link ValuePrecision} to given {@link Value}s value, if |
| * acceptable for related {@link ValueType}. |
| * |
| * @param value the value |
| */ |
| abstract public void applyOn(Value value); |
| |
| abstract public Condition getCondition(ContextState contextState, Attribute attribute, Object value); |
| |
| /** |
| * Applies this {@link ValuePrecision} to given {@link Value}s value, for |
| * {@link ValueType.DATE}. |
| * |
| * @param value the value |
| */ |
| private static void applyDate(Value value, ValuePrecision precision) { |
| if (value.getValueType() == ValueType.DATE) { |
| LocalDateTime dateTime = value.extract(); |
| if (dateTime != null) { |
| switch (precision) { |
| case YEAR: |
| dateTime = dateTime.with(TemporalAdjusters.firstDayOfYear()); |
| // no break intentionally; |
| case MONTH: |
| dateTime = dateTime.with(TemporalAdjusters.firstDayOfMonth()); |
| // no break intentionally; |
| case DAY: |
| dateTime = dateTime.withHour(0); |
| // no break intentionally; |
| case HOUR: |
| dateTime = dateTime.withMinute(0); |
| // no break intentionally; |
| case MINUTE: |
| dateTime = dateTime.withSecond(0); |
| break; |
| default: |
| // Intentionally empty. |
| } |
| value.set(dateTime); |
| } |
| } |
| } |
| |
| private static Condition getDateCondition(ContextState contextState, Attribute attribute, Object value, |
| ValuePrecision precision) { |
| if (attribute.getValueType() == ValueType.DATE) { |
| LocalDateTime start = (LocalDateTime) value; |
| LocalDateTime end; |
| switch (precision) { |
| case YEAR: |
| end = start.plusYears(1); |
| break; |
| case MONTH: |
| end = start.plusMonths(1); |
| break; |
| case DAY: |
| end = start.plusDays(1); |
| break; |
| case HOUR: |
| end = start.plusHours(1); |
| break; |
| case MINUTE: |
| end = start.plusMinutes(1); |
| break; |
| default: |
| end = start.plusNanos(1); |
| } |
| return ComparisonOperator.BETWEEN.create(contextState, attribute, |
| new LocalDateTime[] { start, end.minusNanos(1) }); |
| } else { |
| return ComparisonOperator.EQUAL.create(contextState, attribute, value); |
| } |
| } |
| } |