Package xbird.xquery.dm.value.xsi

Source Code of xbird.xquery.dm.value.xsi.DateTimeValue

/*
* @(#)$Id: DateTimeValue.java 3619 2008-03-26 07:23:03Z yui $
*
* Copyright 2006-2008 Makoto YUI
*
* 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.
*
* Contributors:
*     Makoto YUI - initial implementation
*/
package xbird.xquery.dm.value.xsi;

import java.io.*;

import javax.xml.datatype.DatatypeConstants;
import javax.xml.datatype.XMLGregorianCalendar;

import xbird.util.lang.ObjectUtils;
import xbird.xquery.*;
import xbird.xquery.dm.value.AtomicValue;
import xbird.xquery.dm.value.Item;
import xbird.xquery.meta.DynamicContext;
import xbird.xquery.misc.XsDatatypeFactory;
import xbird.xquery.type.AtomicType;
import xbird.xquery.type.TypeTable;
import xbird.xquery.type.xs.DateTimeBaseType;

/**
*
* <DIV lang="en"></DIV>
* <DIV lang="ja"></DIV>
*
* @author Makoto YUI (yuin405+xbird@gmail.com)
* @link http://www.w3.org/TR/xmlschema-2/#dateTime
*/
public class DateTimeValue extends AtomicValue {
    private static final long serialVersionUID = 2749362266774252238L;
    public static final int ID = 7;

    protected/* final */XMLGregorianCalendar value;
    private transient String _canonical = null;

    public DateTimeValue() {
        super();
    }

    public DateTimeValue(String literal, DateTimeBaseType type) {
        super(literal, type);
        this.value = XsDatatypeFactory.createXMLGregorianCalendar(literal);
    }

    public DateTimeValue(XMLGregorianCalendar value, DateTimeBaseType type) {
        super(value.toXMLFormat(), type);
        this.value = value;
    }

    public XMLGregorianCalendar getValue() {
        return value;
    }

    public DateTimeBaseType getDateTimeType() {
        return (DateTimeBaseType) _type;
    }

    public XMLGregorianCalendar toJavaObject() throws XQueryException {
        return value;
    }

    @Override
    public int compareTo(Item trg) {
        if(!(trg instanceof DateTimeValue)) {
            throw new XQRTException("err:XPTY0004", "Imcomparable "
                    + trg.getClass().getSimpleName() + " with DateTimeValue");
        }
        XMLGregorianCalendar trgUri = ((DateTimeValue) trg).value;
        return value.compare(trgUri);
    }

    @SuppressWarnings("unchecked")
    @Override
    public <T extends AtomicValue> T castAs(AtomicType trgType, DynamicContext dynEnv)
            throws XQueryException {
        final int ttid = trgType.getTypeId();
        if(ttid == TypeTable.NOTATION_TID || ttid == TypeTable.ANY_ATOM_TID) {
            throw new StaticError("err:XPST0080", "Illegal target type: " + trgType);
        }
        final AtomicType type = _type;
        if(type == trgType) {
            return (T) this;
        }
        final boolean mayCastable = TypeTable.isMayCastable(type, trgType);
        if(mayCastable) {
            if(trgType instanceof DateTimeBaseType) {
                final DateTimeBaseType dtType = (DateTimeBaseType) trgType;
                return (T) dtType.createInstance(value);
            } else {
                final String sv = stringValue();
                final String literal = trgType.processWhitespace(sv);
                try {
                    return (T) trgType.createInstance(literal, type, dynEnv);
                } catch (RuntimeException e) {
                    throw new DynamicError("err:FORG0001", "cast to '" + trgType + "' failed: "
                            + sv, e);
                }
            }
        }
        throw new DynamicError("err:XPTY0004", "failed to cast '" + _type + "' as '" + trgType
                + "': " + _lexicalValue);
    }

    @Override
    public final String stringValue() {
        return this.toString();
    }

    @Override
    public String toString() {
        if(_canonical == null) {
            final DateTimeBaseType targetType = getDateTimeType();
            final boolean settime = targetType.isTimeSet();
            if(settime) {
                final int hour = value.getHour();
                if(hour == 24 && value.getMinute() == 0 && value.getSecond() == 0) {
                    // 2004-03-31T24:00:00" => "2004-04-01T00:00:00"
                    value.add(XsDatatypeFactory.getDatatypeFactory().newDuration(true, 0, 0, 0, 0, 0, 1));
                    value.setSecond(0);
                }
            }
            final StringBuilder buf = new StringBuilder(128);
            if(targetType.isDateSet()) {
                final boolean yset = targetType.isYearSet();
                final boolean mset = targetType.isMonthSet();
                final boolean dset = targetType.isDaySet();
                if(yset) {
                    final int year = value.getYear();
                    if(year != DatatypeConstants.FIELD_UNDEFINED) {
                        if(year == 0) {// There is no year 0, and '0000' is not a valid lexical representation
                            appendPaddedZeros(1, 4, buf);
                        } else if(year < 0) {
                            buf.append('-');
                            appendPaddedZeros(-year, 4, buf);
                        } else {
                            appendPaddedZeros(year, 4, buf);
                        }
                    } else {
                        buf.append('-');
                    }
                } else if(mset || dset) {
                    buf.append('-');
                }
                if(mset) {
                    buf.append('-');
                    int month = value.getMonth();
                    if(month != DatatypeConstants.FIELD_UNDEFINED) {
                        appendPaddedZeros(month, 2, buf);
                    }
                } else if(dset) {
                    buf.append('-');
                }
                if(dset) {
                    buf.append('-');
                    int day = value.getDay();
                    if(day != DatatypeConstants.FIELD_UNDEFINED) {
                        appendPaddedZeros(day, 2, buf);
                    }
                }
                if(settime) {
                    buf.append('T');
                }
            }
            if(settime) {
                final int hour = value.getHour();
                if(hour == DatatypeConstants.FIELD_UNDEFINED) {
                    buf.append("00:00:00");
                } else {
                    appendPaddedZeros(hour, 2, buf);
                    buf.append(':');
                    final int minute = value.getMinute();
                    assert (minute != DatatypeConstants.FIELD_UNDEFINED);
                    appendPaddedZeros(minute, 2, buf);
                    buf.append(':');
                    final int second = value.getSecond();
                    assert (second != DatatypeConstants.FIELD_UNDEFINED);
                    appendPaddedZeros(second, 2, buf);
                    int millisec = value.getMillisecond();
                    if(millisec != DatatypeConstants.FIELD_UNDEFINED && millisec != 0) {
                        buf.append('.');
                        String ms = Integer.toString(millisec);
                        // remove trailing zeros
                        int last = ms.length();
                        while(--last > 0) {
                            if(ms.charAt(last) != '0') {
                                break;
                            }
                        }
                        String trimed = ms.substring(0, last + 1);
                        buf.append(trimed);
                    }
                }
            }
            int tz = value.getTimezone();
            if(tz != DatatypeConstants.FIELD_UNDEFINED) {
                if(tz == 0) {
                    buf.append('Z');
                } else if(tz != DatatypeConstants.FIELD_UNDEFINED) {
                    if(tz < 0) {
                        buf.append('-');
                        tz *= -1;
                    } else {
                        buf.append('+');
                    }
                    appendPaddedZeros(tz / 60, 2, buf);
                    buf.append(':');
                    appendPaddedZeros(tz % 60, 2, buf);
                }
            }
            String res = buf.toString();
            this._canonical = res;
            return res;
        }
        return _canonical;
    }

    private static void appendPaddedZeros(final int value, final int digits, final StringBuilder buf) {
        final String s = Integer.toString(value);
        for(int i = s.length(); i < digits; i++) {//padding
            buf.append('0');
        }
        buf.append(s);
    }

    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        this._lexicalValue = ObjectUtils.readString(in);
        this._type = AtomicType.readAtomicType(in);
        this.value = (XMLGregorianCalendar) in.readObject();
    }

    public void writeExternal(ObjectOutput out) throws IOException {
        ObjectUtils.writeString(out, _lexicalValue);
        _type.writeExternal(out);
        out.writeObject(value); //TODO XMLGregorianCalendar might not be Serializable
    }

    @Override
    public int getIdentifier() {
        return ID;
    }

}
TOP

Related Classes of xbird.xquery.dm.value.xsi.DateTimeValue

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.