NfsTime.java
/**
* Copyright 2016-2018 Dell Inc. or its subsidiaries. All rights reserved.
*
* <p>Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. A copy of the License is located at
*
* <p>http://www.apache.org/licenses/LICENSE-2.0.txt
*
* <p>or in the "license" file accompanying this file. This file 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 com.emc.ecs.nfsclient.nfs;
import com.emc.ecs.nfsclient.rpc.Xdr;
import java.util.Calendar;
/**
* NFS time getter and setter handling, as specified by RFC 1813
* (https://tools.ietf.org/html/rfc1813).
*
* @author seibed
*/
public class NfsTime implements NfsRequest, NfsResponse {
/**
* For setting the time, this indicates a noop - the corresponding attribute should not be
* changed. Specified by RFC 1813 (https://tools.ietf.org/html/rfc1813).
*/
private static final int DO_NOT_CHANGE_TIME = 0;
/**
* For setting the time, this indicates that time should be set to current server time; no data is
* provided by the client. Specified by RFC 1813 (https://tools.ietf.org/html/rfc1813).
*/
private static final int SET_TO_SERVER_TIME = 1;
/**
* This is the default, and indicates that the time attribute is set to the time passed by the
* client. Specified by RFC 1813 (https://tools.ietf.org/html/rfc1813).
*/
private static final int SET_TO_CLIENT_TIME = 2;
/**
* This usually indicates a guard time - attributes should be changed only if the object's ctime
* matches the associated time, as specified by RFC 1813 (https://tools.ietf.org/html/rfc1813).
*/
private static final int IS_BARE_TIME = -1;
/**
* This constant is the NfsTime passed to setters to indicate that the time should not be changed.
*/
public static final NfsTime DO_NOT_CHANGE = new NfsTime(0, DO_NOT_CHANGE_TIME);
/**
* This constant is the NfsTime passed to setters to indicate that the time should be reset to the
* current server time.
*/
public static final NfsTime SET_TO_CURRENT_ON_SERVER = new NfsTime(0, SET_TO_SERVER_TIME);
private long seconds; // uint32
private long nanoseconds; // uint32
private final int _timeSettingType;
/** Create a new NfsTime for the current time. */
public NfsTime() {
this(Calendar.getInstance().getTimeInMillis());
}
/**
* Create a new NfsTime for the setting time corresponding to milliseconds.
*
* @param milliseconds same as for java.util.Date.
*/
public NfsTime(long milliseconds) {
this(milliseconds, true);
}
/**
* Create a new NfsTime for the setting or guard time corresponding to milliseconds.
*
* @param milliseconds same as for java.util.Date.
* @param isSettingTime true if the time is to be used for setting a value, false if not (e.g.,
* guard time)
*/
public NfsTime(long milliseconds, boolean isSettingTime) {
this(milliseconds, isSettingTime ? SET_TO_CLIENT_TIME : IS_BARE_TIME);
}
private NfsTime(long milliseconds, int timeSettingType) {
_timeSettingType = timeSettingType;
if (captureTime()) {
seconds = milliseconds / 1000;
nanoseconds = (milliseconds - seconds * 1000) * 1000000;
} else {
seconds = 0;
nanoseconds = 0;
}
}
/** Returns true if this is a bare time (with no time setting type), false otherwise. */
public boolean isBareTime() {
return IS_BARE_TIME == _timeSettingType;
}
/** {@inheritDoc} */
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("timeSettingType:").append(_timeSettingType);
sb.append(", [seconds :").append(seconds);
sb.append(" nseconds: ").append(nanoseconds);
sb.append("]");
return sb.toString();
}
/** {@inheritDoc} */
@Override
public void marshalling(Xdr xdr) {
if (!isBareTime()) {
xdr.putInt(_timeSettingType);
}
if (captureTime()) {
xdr.putUnsignedInt(seconds);
xdr.putUnsignedInt(nanoseconds);
}
}
/** {@inheritDoc} */
@Override
public void unmarshalling(Xdr xdr) {
seconds = xdr.getUnsignedInt();
nanoseconds = xdr.getUnsignedInt();
}
/** Returns time in milliseconds, same as java.util.Calendar. */
public long getTimeInMillis() {
return seconds * 1000 + nanoseconds / 1000000;
}
/**
* @return true if the time in milliseconds will be used, false otherwise.
*/
private boolean captureTime() {
return (IS_BARE_TIME == _timeSettingType || SET_TO_CLIENT_TIME == _timeSettingType);
}
}