/* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * 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 org.kie.dmn.feel.runtime.functions; import java.math.BigDecimal; import java.time.DateTimeException; import java.time.Duration; import java.time.LocalTime; import java.time.OffsetTime; import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalField; import java.time.temporal.TemporalQueries; import org.kie.dmn.api.feel.runtime.events.FEELEvent; import org.kie.dmn.api.feel.runtime.events.FEELEvent.Severity; import org.kie.dmn.feel.runtime.events.InvalidParametersEvent; import org.kie.dmn.feel.runtime.functions.FEELFnResult; public class TimeFunction extends BaseFEELFunction { public TimeFunction() { super( "time" ); } public FEELFnResult<TemporalAccessor> invoke(@ParameterName("from") String val) { if ( val == null ) { return FEELFnResult.ofError(new InvalidParametersEvent(Severity.ERROR, "from", "cannot be null")); } try { return FEELFnResult.ofResult( DateTimeFormatter.ISO_TIME.parseBest( val, OffsetTime::from, LocalTime::from ) ); } catch (DateTimeException e) { return FEELFnResult.ofError(new InvalidParametersEvent(Severity.ERROR, "from", "time-parsing exception", e)); } } private static final BigDecimal NANO_MULT = BigDecimal.valueOf( 1000000000 ); public FEELFnResult<TemporalAccessor> invoke( @ParameterName("hour") Number hour, @ParameterName("minute") Number minute, @ParameterName("second") Number seconds, @ParameterName("offset") Duration offset) { if ( hour == null ) { return FEELFnResult.ofError(new InvalidParametersEvent(Severity.ERROR, "hour", "cannot be null")); } if ( minute == null ) { return FEELFnResult.ofError(new InvalidParametersEvent(Severity.ERROR, "minute", "cannot be null")); } if ( seconds == null ) { return FEELFnResult.ofError(new InvalidParametersEvent(Severity.ERROR, "seconds", "cannot be null")); } try { int nanosecs = 0; if( seconds instanceof BigDecimal ) { BigDecimal secs = (BigDecimal) seconds; nanosecs = secs.subtract( secs.setScale( 0, BigDecimal.ROUND_DOWN ) ).multiply( NANO_MULT ).intValue(); } if ( offset == null ) { return FEELFnResult.ofResult( LocalTime.of( hour.intValue(), minute.intValue(), seconds.intValue(), nanosecs ) ); } else { return FEELFnResult.ofResult( OffsetTime.of( hour.intValue(), minute.intValue(), seconds.intValue(), nanosecs, ZoneOffset.ofTotalSeconds( (int) offset.getSeconds() ) ) ); } } catch (DateTimeException e) { return FEELFnResult.ofError(new InvalidParametersEvent(Severity.ERROR, "time-parsing exception", e)); } } public FEELFnResult<TemporalAccessor> invoke(@ParameterName("from") TemporalAccessor date) { if ( date == null ) { return FEELFnResult.ofError(new InvalidParametersEvent(Severity.ERROR, "from", "cannot be null")); } try { if( date.query( TemporalQueries.offset() ) == null ) { return FEELFnResult.ofResult( LocalTime.from( date ) ); } else { return FEELFnResult.ofResult( OffsetTime.from( date ) ); } } catch (DateTimeException e) { return FEELFnResult.ofError(new InvalidParametersEvent(Severity.ERROR, "from", "time-parsing exception", e)); } } }