/* * Copyright 2013 * * 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.openntf.domino.impl; import java.io.Externalizable; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.util.Date; import lotus.domino.NotesException; import org.openntf.domino.DateTime; import org.openntf.domino.Session; import org.openntf.domino.WrapperFactory; import org.openntf.domino.utils.DominoUtils; import org.openntf.domino.utils.Factory; import org.openntf.domino.utils.Factory.SessionType; import com.ibm.icu.util.Calendar; // TODO: Auto-generated Javadoc /** * The Class DateRange. */ /* * Regarding DateRange-s, the behaviour of Notes' Java API is very odd (at least with Notes 9.0.1): * * 1) replaceItemValue works correctly for a value of type DateRange (as it should) * 2) replaceItemValue throws a NotesException (Unknown or unsupported object type in Vector) * if value is a Vector containing DateRange-s (even if the Vector has size 1) * 3) getItemValueDateTimeArray, applied to an item with a single DateRange value, yields a * Vector of size 1 (as it should), but elementAt(0) is null * 4) Analogously, getItemValueDateTimeArray, applied to a multiple DateRange item (generated * e.g. via LotusScript), yields a Vector of size n with all elements null * 5) Finally, getItemValue, applied to a (single or multiple) DateRange item, returns a Vector of size 2*n * containing start and end dates (as DateTime-s) of the DateRange(s). * * On the other hand, in LotusScript everything works well: ReplaceItemValue lets you add an array * of NotesDateRange-s, GetItemValueDateTimeArray returns a correct array of NotesDateRange-s and so on. * * Hence, for dealing with DateRange-s, openNTF Domino has 3 possibilities: * * 1) Every DateRange is wrapped, regardless of whether it's a single value or a Vector of DateRange-s. * Then everything works perfectly, but obviously, there's a considerable overhead. * 2) Or we let openNTF Domino behave like Notes (especially accept only single DateRange-s), with a workaround * to make getItemValueDateTimeArray work correctly for DateRange-s. - Of course, wrapping of Vector-s * containing "many" DateRange-s must then be deactivated. * 3) A mix of 1 and 2: Native Notes Java API is used, whenever it's a single DateRange (comprising the case of * a Vector containing exactly one DateRange), whereas multiple DateRange-s are always wrapped. * * At the moment, the second variant is implemented (without deactivation of wrapping). */ public class DateRange extends BaseNonThreadSafe<org.openntf.domino.DateRange, lotus.domino.DateRange, Session> implements org.openntf.domino.DateRange, lotus.domino.DateRange, Cloneable { // private java.util.Date startDate_; // private java.util.Date endDate_; private DateTime startDateTime_ = null; private DateTime endDateTime_ = null; /* * Constructor used for clone */ protected DateRange(final Session parent) { super(null, parent, NOTES_DATERNG); } /* * Constructor used for clone */ protected DateRange(final DateTime start, final DateTime end, final Session parent) { super(null, parent, NOTES_DATERNG); startDateTime_ = start; endDateTime_ = end; } /** * Instantiates a new outline. * * @param delegate * the delegate * @param parent * the parent * @param wf * the wrapperfactory * @param cppId * the cpp-id */ protected DateRange(final lotus.domino.DateRange delegate, final Session parent) { super(delegate, parent, NOTES_DATERNG); initialize(delegate); //Base.s_recycle(delegate); } private void initialize(final lotus.domino.DateRange delegate) { try { lotus.domino.DateTime sdt = delegate.getStartDateTime(); lotus.domino.DateTime edt = delegate.getEndDateTime(); Base.s_recycle(delegate); if (sdt != null) startDateTime_ = fromLotus(sdt, DateTime.SCHEMA, parent); if (edt != null) endDateTime_ = fromLotus(edt, DateTime.SCHEMA, parent); } catch (NotesException ne) { throw new RuntimeException(ne); } } public Date getEndDate() { if (endDateTime_ == null) return null; return endDateTime_.toJavaDate(); } public Date getStartDate() { if (startDateTime_ == null) return null; return startDateTime_.toJavaDate(); } /* * (non-Javadoc) * * @see org.openntf.domino.DateRange#getEndDateTime() */ @Override public DateTime getEndDateTime() { return endDateTime_; } /* * (non-Javadoc) * * @see org.openntf.domino.impl.Base#getParent() */ @Override public final Session getParent() { return parent; } /* * (non-Javadoc) * * @see org.openntf.domino.DateRange#getStartDateTime() */ @Override public DateTime getStartDateTime() { return startDateTime_; } /* * (non-Javadoc) * * @see org.openntf.domino.DateRange#getText() */ @Override public String getText() { if (startDateTime_ == null || endDateTime_ == null) return ""; return startDateTime_.getLocalTime() + " - " + endDateTime_.getLocalTime(); } public void setEndDate(final java.util.Date date) { endDateTime_ = getAncestorSession().createDateTime(date); } public void setStartDate(final java.util.Date date) { startDateTime_ = getAncestorSession().createDateTime(date); } /* * (non-Javadoc) * * @see org.openntf.domino.DateRange#setEndDateTime(lotus.domino.DateTime) */ @Override public void setEndDateTime(final lotus.domino.DateTime end) { endDateTime_ = fromLotus(end, DateTime.SCHEMA, parent); } /* * (non-Javadoc) * * @see org.openntf.domino.DateRange#setStartDateTime(lotus.domino.DateTime) */ @Override public void setStartDateTime(final lotus.domino.DateTime start) { startDateTime_ = fromLotus(start, DateTime.SCHEMA, parent); } /* * (non-Javadoc) * * @see org.openntf.domino.DateRange#setText(java.lang.String) */ @Override public void setText(final String text) { lotus.domino.DateRange dr = null; lotus.domino.Session rawsession = toLotus(parent); try { dr = rawsession.createDateRange(); dr.setText(text); setStartDateTime(dr.getStartDateTime()); setEndDateTime(dr.getEndDateTime()); } catch (NotesException ne) { DominoUtils.handleException(ne); } finally { Base.s_recycle(dr); } } /* * (non-Javadoc) * * @see org.openntf.domino.impl.Base#getDelegate() */ @Override protected lotus.domino.DateRange getDelegate() { try { lotus.domino.Session rawsession = toLotus(parent); lotus.domino.DateRange ret; if (startDateTime_ != null && endDateTime_ != null) ret = rawsession.createDateRange(startDateTime_.toJavaDate(), endDateTime_.toJavaDate()); else { ret = rawsession.createDateRange(); if (startDateTime_ != null) ret.setStartDateTime(startDateTime_); if (endDateTime_ != null) ret.setEndDateTime(endDateTime_); } return ret; } catch (NotesException ne) { DominoUtils.handleException(ne); return null; } } /* * (non-Javadoc) * * @see org.openntf.domino.types.SessionDescendant#getAncestorSession() */ @Override public final Session getAncestorSession() { return parent; } /* * (non-Javadoc) * * @see org.openntf.domino.ext.DateRange#contains(org.openntf.domino.DateTime) */ @Override public boolean contains(final org.openntf.domino.DateTime dt) { Calendar dtCal = dt.toJavaCal(); Calendar startCal = dt.toJavaCal(); Calendar endCal = dt.toJavaCal(); if (dt.isAnyDate()) { // Compare times only -normalize dates dtCal.set(Calendar.YEAR, 2013); dtCal.set(Calendar.MONTH, 0); dtCal.set(Calendar.DAY_OF_MONTH, 2); startCal.set(Calendar.YEAR, 2013); startCal.set(Calendar.MONTH, 0); startCal.set(Calendar.DAY_OF_MONTH, 2); endCal.set(Calendar.YEAR, 2013); endCal.set(Calendar.MONTH, 0); endCal.set(Calendar.DAY_OF_MONTH, 2); } else if (dt.isAnyTime()) { // Compare dates only - normalize times dtCal.set(Calendar.HOUR_OF_DAY, 12); dtCal.set(Calendar.MINUTE, 0); dtCal.set(Calendar.SECOND, 0); dtCal.set(Calendar.MILLISECOND, 0); startCal.set(Calendar.HOUR_OF_DAY, 12); startCal.set(Calendar.MINUTE, 0); startCal.set(Calendar.SECOND, 0); startCal.set(Calendar.MILLISECOND, 0); endCal.set(Calendar.HOUR_OF_DAY, 12); endCal.set(Calendar.MINUTE, 0); endCal.set(Calendar.SECOND, 0); endCal.set(Calendar.MILLISECOND, 0); } return (dtCal.equals(startCal) || dtCal.after(startCal)) && (dtCal.equals(endCal) || dtCal.before(endCal)); } /* * (non-Javadoc) * * @see org.openntf.domino.ext.DateRange#contains(java.util.Date) */ @Override public boolean contains(final Date date) { Date start = this.getStartDateTime().toJavaDate(); Date end = this.getEndDateTime().toJavaDate(); return (date.equals(start) || date.after(start)) && (date.equals(end) || date.before(end)); } /* (non-Javadoc) * @see java.io.Externalizable#readExternal(java.io.ObjectInput) */ @Override public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException { startDateTime_ = (DateTime) in.readObject(); endDateTime_ = (DateTime) in.readObject(); } /* (non-Javadoc) * @see java.io.Externalizable#writeExternal(java.io.ObjectOutput) */ @Override public void writeExternal(final ObjectOutput out) throws IOException { out.writeObject(startDateTime_); out.writeObject(endDateTime_); } /** * @deprecated needed for {@link Externalizable} - do not use! */ @Deprecated public DateRange() { super(null, Factory.getSession(SessionType.CURRENT), NOTES_DATERNG); } @Override public org.openntf.domino.DateRange clone() { return new DateRange(startDateTime_.clone(), endDateTime_.clone(), getAncestorSession()); } @Override protected final WrapperFactory getFactory() { return parent.getFactory(); } }