sbDatetimePropertyInfo.cpp
Go to the documentation of this file.
1 /*
2 //
3 // BEGIN SONGBIRD GPL
4 //
5 // This file is part of the Songbird web player.
6 //
7 // Copyright(c) 2005-2008 POTI, Inc.
8 // http://songbirdnest.com
9 //
10 // This file may be licensed under the terms of of the
11 // GNU General Public License Version 2 (the "GPL").
12 //
13 // Software distributed under the License is distributed
14 // on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
15 // express or implied. See the GPL for the specific language
16 // governing rights and limitations.
17 //
18 // You should have received a copy of the GPL along with this
19 // program. If not, go to http://www.gnu.org/licenses/gpl.html
20 // or write to the Free Software Foundation, Inc.,
21 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 //
23 // END SONGBIRD GPL
24 //
25 */
26 
27 #include "sbDatetimePropertyInfo.h"
28 #include "sbStandardOperators.h"
29 
30 #include <nsAutoPtr.h>
31 #include <nsComponentManagerUtils.h>
32 #include <nsServiceManagerUtils.h>
33 
34 #include <prtime.h>
35 #include <prprf.h>
36 
37 #include <sbLockUtils.h>
38 
39 static const char *gsFmtRadix10 = "%lld";
40 static const char *gsSortFmtRadix10 = "%+020lld";
41 
44 
45 NS_INTERFACE_TABLE_HEAD(sbDatetimePropertyInfo)
46 NS_INTERFACE_TABLE_BEGIN
47 NS_INTERFACE_TABLE_ENTRY(sbDatetimePropertyInfo, sbIDatetimePropertyInfo)
48 NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(sbDatetimePropertyInfo, sbIPropertyInfo, sbIDatetimePropertyInfo)
49 NS_INTERFACE_TABLE_END
50 NS_INTERFACE_TABLE_TAIL_INHERITING(sbPropertyInfo)
51 
52 sbDatetimePropertyInfo::sbDatetimePropertyInfo()
53 : mTimeTypeLock(nsnull)
54 , mTimeType(sbIDatetimePropertyInfo::TIMETYPE_UNINITIALIZED)
55 , mMinMaxDateTimeLock(nsnull)
56 , mMinDateTime(0)
57 , mMaxDateTime(LL_MAXINT)
58 , mAppLocaleLock(nsnull)
59 , mDateTimeFormatLock(nsnull)
60 {
61  mType = NS_LITERAL_STRING("datetime");
62 
63  mTimeTypeLock = PR_NewLock();
64  NS_ASSERTION(mTimeTypeLock,
65  "sbDatetimePropertyInfo::mTimeTypeLock failed to create lock!");
66 
67  mMinMaxDateTimeLock = PR_NewLock();
68  NS_ASSERTION(mMinMaxDateTimeLock,
69  "sbDatetimePropertyInfo::mMinMaxDateTimeLock failed to create lock!");
70 
71  mAppLocaleLock = PR_NewLock();
72  NS_ASSERTION(mAppLocaleLock,
73  "sbDatetimePropertyInfo::mAppLocaleLock failed to create lock!");
74 
75  mDateTimeFormatLock = PR_NewLock();
76  NS_ASSERTION(mDateTimeFormatLock,
77  "sbDatetimePropertyInfo::mDateTimeFormatLock failed to create lock!");
78 }
79 
81 {
82  if(mTimeTypeLock) {
83  PR_DestroyLock(mTimeTypeLock);
84  }
86  PR_DestroyLock(mMinMaxDateTimeLock);
87  }
88  if(mAppLocaleLock) {
89  PR_DestroyLock(mAppLocaleLock);
90  }
92  PR_DestroyLock(mDateTimeFormatLock);
93  }
94 }
95 
96 nsresult
98  nsresult rv;
99 
100  rv = sbPropertyInfo::Init();
101  NS_ENSURE_SUCCESS(rv, rv);
102 
103  rv = InitializeOperators();
104  NS_ENSURE_SUCCESS(rv, rv);
105 
106  return NS_OK;
107 }
108 
109 nsresult
111 {
112  nsresult rv;
113  nsAutoString op;
114  nsRefPtr<sbPropertyOperator> propOp;
115 
116  rv = sbPropertyInfo::GetOPERATOR_EQUALS(op);
117  NS_ENSURE_SUCCESS(rv, rv);
118  propOp = new sbPropertyOperator(op, NS_LITERAL_STRING("&smart.date.equal"));
119  NS_ENSURE_TRUE(propOp, NS_ERROR_OUT_OF_MEMORY);
120  rv = mOperators.AppendObject(propOp);
121  NS_ENSURE_SUCCESS(rv, rv);
122 
123  rv = GetOPERATOR_ONDATE(op);
124  NS_ENSURE_SUCCESS(rv, rv);
125  propOp = new sbPropertyOperator(op, NS_LITERAL_STRING("&smart.date.ondate"));
126  NS_ENSURE_TRUE(propOp, NS_ERROR_OUT_OF_MEMORY);
127  rv = mOperators.AppendObject(propOp);
128  NS_ENSURE_SUCCESS(rv, rv);
129 
130  rv = sbPropertyInfo::GetOPERATOR_NOTEQUALS(op);
131  NS_ENSURE_SUCCESS(rv, rv);
132  propOp = new sbPropertyOperator(op, NS_LITERAL_STRING("&smart.date.notequal"));
133  NS_ENSURE_TRUE(propOp, NS_ERROR_OUT_OF_MEMORY);
134  rv = mOperators.AppendObject(propOp);
135  NS_ENSURE_SUCCESS(rv, rv);
136 
137  rv = GetOPERATOR_NOTONDATE(op);
138  NS_ENSURE_SUCCESS(rv, rv);
139  propOp = new sbPropertyOperator(op, NS_LITERAL_STRING("&smart.date.notondate"));
140  NS_ENSURE_TRUE(propOp, NS_ERROR_OUT_OF_MEMORY);
141  rv = mOperators.AppendObject(propOp);
142  NS_ENSURE_SUCCESS(rv, rv);
143 
144  rv = sbPropertyInfo::GetOPERATOR_GREATER(op);
145  NS_ENSURE_SUCCESS(rv, rv);
146  propOp = new sbPropertyOperator(op, NS_LITERAL_STRING("&smart.date.greater"));
147  NS_ENSURE_TRUE(propOp, NS_ERROR_OUT_OF_MEMORY);
148  rv = mOperators.AppendObject(propOp);
149  NS_ENSURE_SUCCESS(rv, rv);
150 
151  rv = GetOPERATOR_AFTERDATE(op);
152  NS_ENSURE_SUCCESS(rv, rv);
153  propOp = new sbPropertyOperator(op, NS_LITERAL_STRING("&smart.date.afterdate"));
154  NS_ENSURE_TRUE(propOp, NS_ERROR_OUT_OF_MEMORY);
155  rv = mOperators.AppendObject(propOp);
156  NS_ENSURE_SUCCESS(rv, rv);
157 
158  rv = sbPropertyInfo::GetOPERATOR_GREATEREQUAL(op);
159  NS_ENSURE_SUCCESS(rv, rv);
160  propOp = new sbPropertyOperator(op, NS_LITERAL_STRING("&smart.date.greaterequal"));
161  NS_ENSURE_TRUE(propOp, NS_ERROR_OUT_OF_MEMORY);
162  rv = mOperators.AppendObject(propOp);
163  NS_ENSURE_SUCCESS(rv, rv);
164 
165  rv = GetOPERATOR_AFTERORONDATE(op);
166  NS_ENSURE_SUCCESS(rv, rv);
167  propOp = new sbPropertyOperator(op, NS_LITERAL_STRING("&smart.date.onafterdate"));
168  NS_ENSURE_TRUE(propOp, NS_ERROR_OUT_OF_MEMORY);
169  rv = mOperators.AppendObject(propOp);
170  NS_ENSURE_SUCCESS(rv, rv);
171 
172  rv = sbPropertyInfo::GetOPERATOR_LESS(op);
173  NS_ENSURE_SUCCESS(rv, rv);
174  propOp = new sbPropertyOperator(op, NS_LITERAL_STRING("&smart.date.less"));
175  NS_ENSURE_TRUE(propOp, NS_ERROR_OUT_OF_MEMORY);
176  rv = mOperators.AppendObject(propOp);
177  NS_ENSURE_SUCCESS(rv, rv);
178 
179  rv = GetOPERATOR_BEFOREDATE(op);
180  NS_ENSURE_SUCCESS(rv, rv);
181  propOp = new sbPropertyOperator(op, NS_LITERAL_STRING("&smart.date.beforedate"));
182  NS_ENSURE_TRUE(propOp, NS_ERROR_OUT_OF_MEMORY);
183  rv = mOperators.AppendObject(propOp);
184  NS_ENSURE_SUCCESS(rv, rv);
185 
186  rv = sbPropertyInfo::GetOPERATOR_LESSEQUAL(op);
187  NS_ENSURE_SUCCESS(rv, rv);
188  propOp = new sbPropertyOperator(op, NS_LITERAL_STRING("&smart.date.lessequal"));
189  NS_ENSURE_TRUE(propOp, NS_ERROR_OUT_OF_MEMORY);
190  rv = mOperators.AppendObject(propOp);
191  NS_ENSURE_SUCCESS(rv, rv);
192 
193  rv = GetOPERATOR_BEFOREORONDATE(op);
194  NS_ENSURE_SUCCESS(rv, rv);
195  propOp = new sbPropertyOperator(op, NS_LITERAL_STRING("&smart.date.onbeforedate"));
196  NS_ENSURE_TRUE(propOp, NS_ERROR_OUT_OF_MEMORY);
197  rv = mOperators.AppendObject(propOp);
198  NS_ENSURE_SUCCESS(rv, rv);
199 
200  rv = GetOPERATOR_INTHELAST(op);
201  NS_ENSURE_SUCCESS(rv, rv);
202  propOp = new sbPropertyOperator(op, NS_LITERAL_STRING("&smart.date.inthelast"));
203  NS_ENSURE_TRUE(propOp, NS_ERROR_OUT_OF_MEMORY);
204  rv = mOperators.AppendObject(propOp);
205  NS_ENSURE_SUCCESS(rv, rv);
206 
207  rv = GetOPERATOR_NOTINTHELAST(op);
208  NS_ENSURE_SUCCESS(rv, rv);
209  propOp = new sbPropertyOperator(op, NS_LITERAL_STRING("&smart.date.notinthelast"));
210  NS_ENSURE_TRUE(propOp, NS_ERROR_OUT_OF_MEMORY);
211  rv = mOperators.AppendObject(propOp);
212  NS_ENSURE_SUCCESS(rv, rv);
213 
214  rv = sbPropertyInfo::GetOPERATOR_BETWEEN(op);
215  NS_ENSURE_SUCCESS(rv, rv);
216  propOp = new sbPropertyOperator(op, NS_LITERAL_STRING("&smart.date.between"));
217  NS_ENSURE_TRUE(propOp, NS_ERROR_OUT_OF_MEMORY);
218  rv = mOperators.AppendObject(propOp);
219  NS_ENSURE_SUCCESS(rv, rv);
220 
221  rv = GetOPERATOR_BETWEENDATES(op);
222  NS_ENSURE_SUCCESS(rv, rv);
223  propOp = new sbPropertyOperator(op, NS_LITERAL_STRING("&smart.date.betweendates"));
224  NS_ENSURE_TRUE(propOp, NS_ERROR_OUT_OF_MEMORY);
225  rv = mOperators.AppendObject(propOp);
226  NS_ENSURE_SUCCESS(rv, rv);
227 
228  return NS_OK;
229 }
230 
231 NS_IMETHODIMP sbDatetimePropertyInfo::Validate(const nsAString & aValue, PRBool *_retval)
232 {
233  NS_ENSURE_ARG_POINTER(_retval);
234 
235  PRInt64 value = 0;
236  NS_ConvertUTF16toUTF8 narrow(aValue);
237  *_retval = PR_TRUE;
238 
239  if(PR_sscanf(narrow.get(), gsFmtRadix10, &value) != 1) {
240  *_retval = PR_FALSE;
241  return NS_OK;
242  }
243 
245  if(value < mMinDateTime ||
246  value > mMaxDateTime) {
247  *_retval = PR_FALSE;
248  }
249 
250  return NS_OK;
251 }
252 
253 NS_IMETHODIMP sbDatetimePropertyInfo::Sanitize(const nsAString & aValue, nsAString & _retval)
254 {
255  return NS_ERROR_NOT_IMPLEMENTED;
256 }
257 
258 NS_IMETHODIMP sbDatetimePropertyInfo::Format(const nsAString & aValue, nsAString & _retval)
259 {
260  PRInt32 timeType = 0;
261  PRInt64 value = 0;
262  NS_ConvertUTF16toUTF8 narrow(aValue);
263 
264  nsresult rv = GetTimeType(&timeType);
265  NS_ENSURE_SUCCESS(rv, rv);
266 
267  if(PR_sscanf(narrow.get(), gsFmtRadix10, &value) != 1) {
268  return NS_ERROR_INVALID_ARG;
269  }
270 
271  {
273  if(value < mMinDateTime ||
274  value > mMaxDateTime) {
275  return NS_ERROR_INVALID_ARG;
276  }
277  }
278 
280  nsAutoString out;
281  sbSimpleAutoLock lockLocale(mAppLocaleLock);
282 
283  if(!mAppLocale) {
284  nsCOMPtr<nsILocaleService> localeService =
285  do_GetService("@mozilla.org/intl/nslocaleservice;1", &rv);
286  NS_ENSURE_SUCCESS(rv, rv);
287 
288  rv = localeService->GetApplicationLocale(getter_AddRefs(mAppLocale));
289  NS_ENSURE_SUCCESS(rv, rv);
290  }
291 
292  sbSimpleAutoLock lockFormatter(mDateTimeFormatLock);
293  if(!mDateTimeFormat) {
294  mDateTimeFormat = do_CreateInstance(NS_DATETIMEFORMAT_CONTRACTID, &rv);
295  NS_ENSURE_SUCCESS(rv, rv);
296  }
297 
298  switch(mTimeType) {
300  {
301  PRExplodedTime explodedTime = {0};
302  PR_ExplodeTime((PRTime) (value * PR_USEC_PER_MSEC), PR_LocalTimeParameters, &explodedTime);
303  rv = mDateTimeFormat->FormatPRExplodedTime(mAppLocale,
304  kDateFormatNone,
305  kTimeFormatSeconds,
306  &explodedTime,
307  out);
308 
309  }
310  break;
311 
313  {
314  PRExplodedTime explodedTime = {0};
315  PR_ExplodeTime((PRTime) (value * PR_USEC_PER_MSEC), PR_LocalTimeParameters, &explodedTime);
316  rv = mDateTimeFormat->FormatPRExplodedTime(mAppLocale,
317  kDateFormatLong,
318  kTimeFormatNone,
319  &explodedTime,
320  out);
321 
322  }
323  break;
324 
326  {
327  PRExplodedTime explodedTime = {0};
328  PR_ExplodeTime((PRTime) (value * PR_USEC_PER_MSEC), PR_LocalTimeParameters, &explodedTime);
329  rv = mDateTimeFormat->FormatPRExplodedTime(mAppLocale,
330  kDateFormatShort,
331  kTimeFormatNoSeconds,
332  &explodedTime,
333  out);
334  }
335  break;
336  }
337 
338  NS_ENSURE_SUCCESS(rv, rv);
339  _retval = out;
340  }
341  else {
342  _retval = aValue;
343  CompressWhitespace(_retval);
344  }
345 
346  return NS_OK;
347 }
348 
349 NS_IMETHODIMP sbDatetimePropertyInfo::MakeSearchable(const nsAString & aValue, nsAString & _retval)
350 {
351  nsresult rv;
352  PRInt64 value = 0;
353  NS_ConvertUTF16toUTF8 narrow(aValue);
354 
355  _retval = aValue;
356  _retval.StripWhitespace();
357 
359 
360  if(PR_sscanf(narrow.get(), gsFmtRadix10, &value) != 1) {
361  _retval = EmptyString();
362  return NS_ERROR_INVALID_ARG;
363  }
364 
365  char out[32] = {0};
366  if(PR_snprintf(out, 32, gsSortFmtRadix10, value) == (PRUint32)-1) {
367  rv = NS_ERROR_FAILURE;
368  _retval = EmptyString();
369  }
370  else {
371  NS_ConvertUTF8toUTF16 wide(out);
372  rv = NS_OK;
373  _retval = wide;
374  }
375 
376  return rv;
377 }
378 
379 NS_IMETHODIMP sbDatetimePropertyInfo::GetTimeType(PRInt32 *aTimeType)
380 {
381  NS_ENSURE_ARG_POINTER(aTimeType);
382 
385  *aTimeType = mTimeType;
386  return NS_OK;
387  }
388 
389  return NS_ERROR_NOT_INITIALIZED;
390 }
391 NS_IMETHODIMP sbDatetimePropertyInfo::SetTimeType(PRInt32 aTimeType)
392 {
393  NS_ENSURE_ARG(aTimeType > sbDatetimePropertyInfo::TIMETYPE_UNINITIALIZED &&
395 
398  mTimeType = aTimeType;
399  return NS_OK;
400  }
401 
402  return NS_ERROR_ALREADY_INITIALIZED;
403 }
404 
405 NS_IMETHODIMP sbDatetimePropertyInfo::GetMinDateTime(PRInt64 *aMinDateTime)
406 {
407  NS_ENSURE_ARG_POINTER(aMinDateTime);
408 
410  *aMinDateTime = mMinDateTime;
411 
412  return NS_OK;
413 }
414 NS_IMETHODIMP sbDatetimePropertyInfo::SetMinDateTime(PRInt64 aMinDateTime)
415 {
416  NS_ENSURE_ARG(aMinDateTime > -1);
417 
419  mMinDateTime = aMinDateTime;
420 
421  return NS_OK;
422 }
423 
424 NS_IMETHODIMP sbDatetimePropertyInfo::GetMaxDateTime(PRInt64 *aMaxDateTime)
425 {
426  NS_ENSURE_ARG_POINTER(aMaxDateTime);
427 
429  *aMaxDateTime = mMaxDateTime;
430 
431  return NS_OK;
432 }
433 NS_IMETHODIMP sbDatetimePropertyInfo::SetMaxDateTime(PRInt64 aMaxDateTime)
434 {
435  NS_ENSURE_ARG(aMaxDateTime > -1);
436 
438  mMaxDateTime = aMaxDateTime;
439 
440  return NS_OK;
441 }
442 
443 NS_IMETHODIMP sbDatetimePropertyInfo::GetOPERATOR_INTHELAST(nsAString & aOPERATOR_INTHELAST)
444 {
445  aOPERATOR_INTHELAST = NS_LITERAL_STRING(SB_OPERATOR_INTHELAST);
446  return NS_OK;
447 }
448 
449 NS_IMETHODIMP sbDatetimePropertyInfo::GetOPERATOR_NOTINTHELAST(nsAString & aOPERATOR_NOTINTHELAST)
450 {
451  aOPERATOR_NOTINTHELAST = NS_LITERAL_STRING(SB_OPERATOR_NOTINTHELAST);
452  return NS_OK;
453 }
454 
455 NS_IMETHODIMP sbDatetimePropertyInfo::GetOPERATOR_ONDATE(nsAString & aOPERATOR_ONDATE)
456 {
457  aOPERATOR_ONDATE = NS_LITERAL_STRING(SB_OPERATOR_ONDATE);
458  return NS_OK;
459 }
460 
461 NS_IMETHODIMP sbDatetimePropertyInfo::GetOPERATOR_NOTONDATE(nsAString & aOPERATOR_NOTONDATE)
462 {
463  aOPERATOR_NOTONDATE = NS_LITERAL_STRING(SB_OPERATOR_NOTONDATE);
464  return NS_OK;
465 }
466 
467 NS_IMETHODIMP sbDatetimePropertyInfo::GetOPERATOR_BEFOREDATE(nsAString & aOPERATOR_BEFOREDATE)
468 {
469  aOPERATOR_BEFOREDATE = NS_LITERAL_STRING(SB_OPERATOR_BEFOREDATE);
470  return NS_OK;
471 }
472 
473 NS_IMETHODIMP sbDatetimePropertyInfo::GetOPERATOR_BEFOREORONDATE(nsAString & aOPERATOR_BEFOREORONDATE)
474 {
475  aOPERATOR_BEFOREORONDATE = NS_LITERAL_STRING(SB_OPERATOR_BEFOREORONDATE);
476  return NS_OK;
477 }
478 
479 NS_IMETHODIMP sbDatetimePropertyInfo::GetOPERATOR_AFTERDATE(nsAString & aOPERATOR_AFTERDATE)
480 {
481  aOPERATOR_AFTERDATE = NS_LITERAL_STRING(SB_OPERATOR_AFTERDATE);
482  return NS_OK;
483 }
484 
485 NS_IMETHODIMP sbDatetimePropertyInfo::GetOPERATOR_AFTERORONDATE(nsAString & aOPERATOR_AFTERORONDATE)
486 {
487  aOPERATOR_AFTERORONDATE = NS_LITERAL_STRING(SB_OPERATOR_AFTERORONDATE);
488  return NS_OK;
489 }
490 
491 NS_IMETHODIMP sbDatetimePropertyInfo::GetOPERATOR_BETWEENDATES(nsAString & aOPERATOR_BETWEENDATES)
492 {
493  aOPERATOR_BETWEENDATES = NS_LITERAL_STRING(SB_OPERATOR_BETWEENDATES);
494  return NS_OK;
495 }
#define SB_OPERATOR_AFTERDATE
#define SB_OPERATOR_ONDATE
#define SB_OPERATOR_AFTERORONDATE
return NS_OK
NS_IMETHOD Format(const nsAString &aValue, nsAString &_retval)
The property information specific to date/time fields.
onPageChanged aValue
Definition: FeedWriter.js:1395
#define SB_OPERATOR_NOTINTHELAST
#define SB_OPERATOR_BEFOREDATE
#define SB_OPERATOR_BEFOREORONDATE
NS_IMETHOD Sanitize(const nsAString &aValue, nsAString &_retval)
NS_IMPL_RELEASE_INHERITED(sbDatetimePropertyInfo, sbPropertyInfo)
const long TIMETYPE_TIME
HH:mm:ss.ms, in localized format. Limited to 24 hour days.
const long TIMETYPE_DATETIME
Long date format, 2007-03-28 12:33:01 , no milliseconds.
nsCOMPtr< nsIDateTimeFormat > mDateTimeFormat
const long TIMETYPE_DATE
2007-03-28 , in localized format
#define SB_OPERATOR_NOTONDATE
static const char * gsFmtRadix10
NS_IMETHOD Validate(const nsAString &aValue, PRBool *_retval)
attribute long timeType
You must initialize this attribute before using this object. If you do not, all methods on this objec...
nsCOMPtr< nsILocale > mAppLocale
An interface used to describe a metadata property for use by the UI and other sbILibrary interfaces (...
NS_IMETHOD MakeSearchable(const nsAString &aValue, nsAString &_retval)
static const char * gsSortFmtRadix10
#define SB_OPERATOR_BETWEENDATES
#define SB_OPERATOR_INTHELAST
countRef value
Definition: FeedWriter.js:1423
nsCOMArray< sbIPropertyOperator > mOperators
NS_IMPL_ADDREF_INHERITED(sbDatetimePropertyInfo, sbPropertyInfo)
const long TIMETYPE_TIMESTAMP
Timestamp format, respects unix time, microsecond format.