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

org.xtce.toolkit.XTCEPosixTimeHandler Maven / Gradle / Ivy

Go to download

This project contains software to support the Object Management Group (OMG) Space Domain Task Force (SDTF) maintained XML Telemetry and Command Exchange (XTCE) specification.

There is a newer version: 1.1.6
Show newest version
/* Copyright 2015 David Overeem ([email protected])
 * 
 * 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.xtce.toolkit;

import java.lang.reflect.Method;
import java.math.BigInteger;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.BitSet;
import java.util.Date;
import java.util.TimeZone;
import org.omg.space.xtce.AbsoluteTimeDataType;
import org.omg.space.xtce.IntegerDataEncodingType;

/** This class implements UNIX POSIX time to support AbsoluteTimeDataType
 * elements in an XTCE document.
 *
 * 

This class is applicable to AbsoluteTimeType XTCE specifications when * three conditions are met by the XML document:

* *
    *
  • Encoding size in bits of the type element is equal to 64.
  • *
  • Encoding is Unsigned Integer
  • *
  • Epoch of the type element is equal to "1970-01-01" with no specific * time of the day specified (midnight assumed).
  • *
* *

The EU/Calibrated value is implemented to be a UTC string, with no leap * second correction. It is based on the internal system clock of this host. * The Uncalibrated value is the microseconds since midnight 1970-01-01 date. * The raw value is two POSIX unsigned integers, 32 bits of seconds, followed * by 32 bits of microseconds. The BitSet of the raw encoded value will be * equal to that of a "struct timeval" in the C programming language foundation * of many computing platforms.

* *

Although the POSIX specification carries microseconds, the Java * implementation here uses the basic libraries and will only act as far as * the milliseconds.

* * @author dovereem * */ public class XTCEPosixTimeHandler implements XTCEAbsoluteTimeType { /** Default constructor to initialize a handler with the default time * format and time zone. * *

The default time output format is UTC ISO8601 text. This is in the * form of YYYY-MM-dd HH:MM:ss.SSS

* */ public XTCEPosixTimeHandler() { isoTimeFmt_ = "yyyy-MM-dd HH:mm:ss.SSS"; // NOI18N timeZone_ = "GMT"; // NOI18N } /** Constructor that permits changing the default time format and the * time zone information. * * @param timeFormat String containing the time format string suitable * for the Java SimpleDateFormat formatter. * * @param timeZone String containing the time zone identifier string, * suitable for the TimeZone.getTimeZone method in Java. * */ public XTCEPosixTimeHandler( String timeFormat, String timeZone ) { isoTimeFmt_ = timeFormat; timeZone_ = timeZone; } /** Method to determine if an XTCE AbsoluteTimeType, either Parameter or * Argument, is handled by this implementation of the interface. * *

This method returns true when three conditions are met by the XML * that is represented by the JAXB AbsoluteTimeDataType object instance * passed by the caller:

* *
    *
  • Encoding size in bits of the type element is equal to 64.
  • *
  • Encoding is Unsigned Integer
  • *
  • Epoch of the type element is equal to "1970-01-01" with no specific * time of the day specified (midnight assumed).
  • *
* * @param instance AbsoluteTimeDataType object from the JAXB representation * of the XTCE XML document. * * @return boolean indicating if this handler supports/implements handling * for the user provided Absolute Time Type, as specified in the XML. * */ @Override public boolean isApplicable( AbsoluteTimeDataType instance ) { try { IntegerDataEncodingType enc = instance.getEncoding().getIntegerDataEncoding(); // The Epoch element in XTCE 1.1 returns a java.lang.String and // in the proposed 1.2 it returns a ReferenceTimeType.Epoch class // where we need to call getValue(). This reflection allows this // example to support both methods, although a program specific // function could just reduce this to the version of XTCE that is // needed for their local implementation. Object epochElement = instance.getReferenceTime().getEpoch(); String docEpoch; if ( epochElement instanceof String == true ) { docEpoch = (String)epochElement; } else { Method epochGetter = epochElement.getClass().getDeclaredMethod( "getValue" ); docEpoch = (String)epochGetter.invoke( epochElement ); } return ( ( enc.getSizeInBits().longValue() == 64 ) && ( enc.getEncoding().equals( "unsigned" ) == true ) && // NOI18N ( docEpoch.equals( "1970-01-01" ) == true ) ); // NOI18N } catch ( Exception ex ) { // no match if a null pointer is caught or there is trouble with // the getDeclaredMethod/invoke. the net effect of the throw means // that isApplicable() is false. } return false; } /** Retrieve the uncalibrated value of this time item, which can be a * Parameter or Argument, when given the raw binary value. * *

The raw input value is a BitSet of 64 bits in the form of two * 32 bit unsigned integers. The first is the number of seconds since * the UNIX epoch of 1970-01-01 and the seconds in the number of * microseconds within the second. The output String will be an integral * representation of the number of microseconds since 1970-01-01.

* *

This conversion uses only system time capabilities, and as a result * is not leap second corrected.

* * @param rawValue BitSet containing the raw binary value that would * be encoded on the wire or bitfield. The raw binary is always expected * to be in the order read from the stream. * * @return String containing the integral microseconds since epoch. * */ @Override public String getUncalibratedFromRaw( BitSet rawValue ) { String hex = XTCEFunctions.bitSetToHex( rawValue, 8 ); hex = hex.replaceFirst( "0x", "" ); // NOI18N BigInteger secs = new BigInteger( hex.substring( 0, 8 ), 16 ); BigInteger usec = new BigInteger( hex.substring( 8, 16 ), 16 ); secs = secs.multiply( oneThousand_ ).multiply( oneThousand_ ); return "0x" + secs.add( usec ).toString( 16 ); // NOI18N } /** Retrieve the EU calibrated value of this time item, which can be a * Parameter or Argument, when given the uncalibrated value. * *

The uncalibrated input string contains an integral number of * microseconds since the UNIX epoch. The output string is the UTC string * in the form of ISO8601 (YYYY-MM-DD HH:MM:SS.sssss). The timezone is * always UTC/GMT.

* * @param uncalValue String containing the uncalibrated value that is * derived from the encoded value on the wire or bitfield. * * @return String containing the proper EU calibrated representation of the * uncalibrated value provided by the caller. * * @throws NumberFormatException in the event that the uncalibrated value * cannot be converted to an integral number. * */ @Override public String getCalibratedFromUncalibrated( String uncalValue ) { BigInteger usecs = null; if ( uncalValue.startsWith( "0x" ) == true ) { // NOI18N usecs = new BigInteger( uncalValue.replaceFirst( "0x", "" ), 16 ); // NOI18N } else { usecs = new BigInteger( uncalValue ); } BigInteger msecs = usecs.divideAndRemainder( oneThousand_ )[0]; Date javadate = new Date( msecs.longValue() ); DateFormat format = new SimpleDateFormat( isoTimeFmt_ ); format.setTimeZone( TimeZone.getTimeZone( timeZone_ ) ); return format.format( javadate ); } /** Retrieve the raw binary bits for encoding of this time item, which can * be a Parameter or Argument, when given the uncalibrated value. * *

The raw output value is a BitSet of 64 bits in the form of two * 32 bit unsigned integers. The first is the number of seconds since * the UNIX epoch of 1970-01-01 and the seconds in the number of * microseconds within the second. The input String will be an integral * representation of the number of microseconds since 1970-01-01.

* *

This conversion uses only system time capabilities, and as a result * is not leap second corrected.

* * @param uncalValue String containing the uncalibrated representation of * the value. * * @return BitSet containing the raw bits. * * @throws NumberFormatException in the event that the uncalibrated value * cannot be converted to an integral number. * */ @Override public BitSet getRawFromUncalibrated( String uncalValue ) { BigInteger usecs = null; if ( uncalValue.startsWith( "0x" ) == true ) { // NOI18N usecs = new BigInteger( uncalValue.replaceFirst( "0x", "" ), 16 ); // NOI18N } else { usecs = new BigInteger( uncalValue ); } BigInteger secs = usecs.divide( oneThousand_ ).divide( oneThousand_ ); usecs = usecs.subtract( secs.multiply( oneThousand_ ).multiply( oneThousand_ ) ); String hexSeconds = String.format( "%8s", secs.toString( 16 ) ); // NOI18N String hexUsecs = String.format( "%8s", usecs.toString( 16 ) ); // NOI18N hexSeconds = hexSeconds.replaceAll( " ", "0" ); // NOI18N hexUsecs = hexUsecs.replaceAll( " ", "0" ); // NOI18N BigInteger rawInteger = new BigInteger( hexSeconds + hexUsecs, 16 ); BitSet rawBits = new BitSet( 64 ); for ( int iii = 63; iii >= 0; --iii ) { rawBits.set( iii, rawInteger.testBit( iii ) ); } return rawBits; } /** Retrieve the uncalibrated value for this time item, which can be a * Parameter or Argument, when given the EU calibrated value. * *

The uncalibrated output string contains an integral number of * microseconds since the UNIX epoch. The input string is the UTC string * in the form of ISO8601 (YYYY-MM-DD HH:MM:SS.sssss).

* * @param euValue String containing a value of this item represented in * EU/calibrated form. * * @return String containing the uncalibrated value. * * @throws RuntimeException in the event that a checked exception is caught * by this function, with the parsing error text copied. * */ @Override public String getUncalibratedFromCalibrated( String euValue ) { DateFormat format = new SimpleDateFormat( isoTimeFmt_ ); format.setTimeZone( TimeZone.getTimeZone( timeZone_ ) ); try { Date javadate = format.parse( euValue ); BigInteger msec = BigInteger.valueOf( javadate.getTime() ); return "0x" + msec.multiply( oneThousand_ ).toString( 16 ); // NOI18N } catch ( ParseException ex ) { throw new RuntimeException( ex.getLocalizedMessage() ); } } // Private Data Members private static final BigInteger oneThousand_ = new BigInteger( "1000" ); // NOI18N private final String isoTimeFmt_; private final String timeZone_; }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy