KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openharmonise > rm > metadata > GeneralPropertyInstance


1 /*
2  * The contents of this file are subject to the
3  * Mozilla Public License Version 1.1 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at http://www.mozilla.org/MPL/
6  *
7  * Software distributed under the License is distributed on an "AS IS"
8  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
9  * See the License for the specific language governing rights and
10  * limitations under the License.
11  *
12  * The Initial Developer of the Original Code is Simulacra Media Ltd.
13  * Portions created by Simulacra Media Ltd are Copyright (C) Simulacra Media Ltd, 2004.
14  *
15  * All Rights Reserved.
16  *
17  * Contributor(s):
18  */

19 package org.openharmonise.rm.metadata;
20
21 import java.text.*;
22 import java.util.*;
23 import java.util.logging.*;
24
25 import org.openharmonise.commons.dsi.*;
26 import org.openharmonise.commons.dsi.dml.*;
27 import org.openharmonise.rm.*;
28 import org.openharmonise.rm.publishing.*;
29 import org.openharmonise.rm.resources.AbstractProfiledObject;
30 import org.openharmonise.rm.resources.metadata.properties.Property;
31 import org.openharmonise.rm.resources.metadata.properties.ranges.*;
32 import org.w3c.dom.*;
33
34
35 /**
36  * PropertyInstance class for profile data held in string format in the
37  * database.
38  *
39  * @author Michael Bell
40  * @version $Revision: 1.5 $
41  *
42  */

43 public class GeneralPropertyInstance
44     extends AbstractPropertyInstance
45     implements Publishable {
46
47     /**
48      * <code>String</code> constant for the extension used to name the database
49      * table corresponding to this property instance type. The naming convention
50      * for this property instance type is as follows:
51      *
52      * Profile.getTableName() + EXT_DATA
53      */

54     private static final String JavaDoc EXT_DATA = "_data";
55     
56     /**
57      * The name of the database column containing the property instance values
58      */

59     protected static final String JavaDoc CLMN_VALUE = "value";
60     
61     /**
62      * Date format for converting <code>String</code> values to <code>Date</code>
63      * values if the <code>String</code> does not parse to a <code>long</code>
64      * and the value should include the time
65      */

66     private static final String JavaDoc DATETIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss G";
67     
68     /**
69      * Date format for converting <code>String</code> values to <code>Date</code>
70      * values if the <code>String</code> does not parse to a <code>long</code>
71      * and the value does not include the time
72      */

73     private static final String JavaDoc DATE_FORMAT = "yyyy-MM-dd G";
74
75     /**
76      * Data XML element name
77      */

78     public static final String JavaDoc TAG_DATA = "Data";
79     
80     /**
81      * Date format attribute used to specify the date format to be used
82      * when publishing dates
83      */

84     public static final String JavaDoc ATTRIB_DATEFORMAT = "dateFormat";
85     
86     /**
87      * Logger for this class
88      */

89     private static final Logger m_logger = Logger.getLogger(GeneralPropertyInstance.class.getName());
90     
91     /**
92      * Constructs a property instance
93      */

94     public GeneralPropertyInstance() {
95         super();
96
97     }
98
99     /**
100      * Constructs a property instance with an interface to the data store.
101      *
102      * @param dbint the data store interface
103      */

104     public GeneralPropertyInstance(AbstractDataStoreInterface dbint) {
105         super(dbint);
106
107     }
108
109     /**
110       * Constructs a property instance with an interface to
111       * the data store and a reference to the <code>Profile</code> which
112       * will contain this property instance.
113       *
114       * @param dbintrf the data store interface
115       * @param profile the owner <code>Profile</code>
116       */

117     public GeneralPropertyInstance(
118         AbstractDataStoreInterface dbintrf,
119         Profile profile) {
120         super(dbintrf, profile);
121
122     }
123
124     /**
125      * Constructs an <code>GeneralPropertyInstance</code> which has an interface to
126      * the database, has a reference to it's owner <code>Profile</code> and the
127      * <code>Property</code> associated to this instance.
128      *
129      * @param dbintrf the data store inteface
130      * @param nPropertyId the id of the <code>Property</code> that this object is an instance of
131      * @param profile the owner <code>Profile</code>
132      */

133     public GeneralPropertyInstance(
134         AbstractDataStoreInterface dbintrf,
135         int nPropertyId,
136         Profile profile) {
137         super(dbintrf, nPropertyId, profile);
138
139     }
140
141     /**
142      * Constructs a property instance of the specified <code>Property</code>
143      * with an interface to the data store.
144      *
145      * @param dbintrf the data store interface
146      * @param prop the <code>Property</code> that this object is an instance of
147      */

148     public GeneralPropertyInstance(
149         AbstractDataStoreInterface dbintrf,
150         Property prop) {
151         super(dbintrf, prop);
152     }
153
154     /**
155      * Constructs an <code>GeneralPropertyInstance</code> which has an interface to
156      * the data store, has a reference to its owner <code>Profile</code> and the
157      * <code>Property</code> associated to this instance.
158      *
159      * @param dbintrf the data store interface
160      * @param property the <code>Property</code>
161      * @param profile the owner <code>Profile</code>
162      */

163     public GeneralPropertyInstance(
164         AbstractDataStoreInterface dbintrf,
165         Property property,
166         Profile profile) {
167         super(dbintrf, property, profile);
168
169     }
170
171     
172     /* (non-Javadoc)
173      * @see org.openharmonise.rm.publishing.Publishable#populate(org.w3c.dom.Element, org.openharmonise.rm.publishing.State)
174      */

175     public void populate(Element xmlElement, State state)
176         throws PopulateException {
177
178         String JavaDoc sTagName = xmlElement.getTagName();
179         Text txt = null;
180         NodeList nodes = null;
181         boolean bTagFound = false;
182
183         if (sTagName.equals(TAG_PROP_INSTANCE_VALUES) == true) {
184             nodes = xmlElement.getChildNodes();
185
186             for (int i = 0; i < nodes.getLength(); i++) {
187                 if (nodes.item(i).getNodeType() == Node.TEXT_NODE) {
188                   continue;
189                 }
190                 Element elNext = (Element) nodes.item(i);
191                 if(elNext.getTagName().equals(TAG_DATA) && bTagFound == false){
192                     this.clearValues();
193                     bTagFound = true;
194                 }
195                 populate(elNext, state);
196             }
197         } else if (sTagName.equals(TAG_ATTACH) == true) {
198             nodes = xmlElement.getChildNodes();
199             
200             for (int i = 0; i < nodes.getLength(); i++) {
201                 if (nodes.item(i).getNodeType() == Node.TEXT_NODE) {
202                   continue;
203                 }
204                 Element elNext = (Element) nodes.item(i);
205                 
206                 populate(elNext, state);
207             }
208         } else if (sTagName.equals(TAG_DETACH) == true) {
209             nodes = xmlElement.getChildNodes();
210
211             for (int i = 0; i < nodes.getLength(); i++) {
212                 if (nodes.item(i).getNodeType() == Node.TEXT_NODE) {
213                   continue;
214                 }
215                 Element elNext = (Element) nodes.item(i);
216                 
217                 if(elNext.getTagName().equals(TAG_DATA)){
218                     txt = (Text) elNext.getFirstChild();
219                     this.removeValue(txt.getNodeValue());
220                 }
221             }
222         } else if (sTagName.equals(TAG_DATA) == true) {
223             txt = (Text) xmlElement.getFirstChild();
224             try {
225
226                 addValue(txt.getNodeValue());
227             } catch (InvalidPropertyValueException e) {
228                 throw new PopulateException(
229                     "Invalid value for PropertyInstance",e);
230             }
231         } else {
232             super.populate(xmlElement, state);
233         }
234     }
235
236     /* (non-Javadoc)
237      * @see org.openharmonise.rm.publishing.Publishable#publish(org.w3c.dom.Element, org.openharmonise.rm.publishing.HarmoniseOutput, org.openharmonise.rm.publishing.State)
238      */

239     public Element publish(Element formEl, HarmoniseOutput xmlDoc, State state)
240         throws PublishException {
241
242         Element resultEl = null;
243         String JavaDoc sTagname = formEl.getTagName();
244
245         if(sTagname.equals(TAG_PROP_INSTANCE_VALUES)) {
246             resultEl = xmlDoc.createElement(TAG_PROP_INSTANCE_VALUES);
247             
248             String JavaDoc sDateFormat = null;
249             try {
250                 Range range = this.getProperty().getRange();
251                 if (range instanceof DateRange) {
252                     
253                     sDateFormat = formEl.getAttribute(ATTRIB_DATEFORMAT);
254                     
255                     if(sDateFormat == null || sDateFormat.length() == 0) {
256                         // use the DateRange formatting strings for display purposes
257
if(((DateRange)range).includeTime()){
258                             sDateFormat = DateRange.DATETIME_FORMAT;
259                         } else {
260                             sDateFormat = DateRange.DATE_FORMAT;
261                         }
262                     }
263                     
264                 }
265             } catch (DataAccessException e) {
266                 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
267             }
268
269             if (m_values != null) {
270                 Element valueEl = null;
271                 Text txt = null;
272                 for (int j = 0; j < m_values.size(); j++) {
273                     valueEl = xmlDoc.createElement(TAG_DATA);
274
275                     if (m_values.size() > 0) {
276                         
277                         String JavaDoc sValue = null;
278                         if(sDateFormat != null){
279                             SimpleDateFormat format = new SimpleDateFormat(sDateFormat);
280                             Date date = (Date)m_values.get(j);
281                             sValue = format.format(date);
282                         } else {
283                             sValue = (String JavaDoc) m_values.get(j);
284                         }
285                         txt = xmlDoc.createTextNode(sValue);
286                         valueEl.appendChild(txt);
287                     }
288                     
289                     resultEl.appendChild(valueEl);
290                 }
291             }
292         } else {
293             resultEl = super.publish(formEl, xmlDoc, state);
294         }
295
296         if (resultEl == null) {
297             resultEl = xmlDoc.createElement(TAG_ERROR);
298             resultEl.appendChild(
299                 xmlDoc.createTextNode("Problem publishing " + sTagname));
300         }
301
302         return resultEl;
303     }
304
305     /**
306      * Returns a list of processed values for this property instance. This method
307      * is applicable for those values which are formulas which can be calculated
308      * at runtime.
309      *
310      * @return the list of values which have been processed
311      * @throws DataAccessException if an error occurs accessing the property
312      * associated to this instance
313      */

314     public List getCalculatedValues() throws DataAccessException {
315         List values = null;
316
317         if (getProperty().getRange().getObject().equals(Date.class.getName())
318             == false) {
319             values = m_values;
320         } else {
321             values = new Vector(m_values.size());
322
323             for (int i = 0; i < m_values.size(); i++) {
324                 Object JavaDoc valObj = m_values.get(i);
325                 
326                 if(valObj instanceof String JavaDoc) {
327                     try {
328                         values.add(parseDate((String JavaDoc)valObj));
329                     } catch (ParseException e) {
330                         //can't parse just copy the data over
331
m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
332                         values.add(m_values.get(i));
333                     }
334                 } else if(valObj instanceof Date) {
335                     values.add(String.valueOf(((Date) valObj).getTime()));
336                 }
337             }
338         }
339
340         return values;
341     }
342
343     /* (non-Javadoc)
344      * @see org.openharmonise.rm.metadata.AbstractPropertyInstance#match(org.openharmonise.rm.metadata.AbstractPropertyInstance)
345      */

346     public boolean match(AbstractPropertyInstance propInst)
347         throws ProfileException {
348         boolean bMatch = true;
349
350         List otherValues = propInst.getValues();
351         if (m_values.size() == 0 || otherValues.size() == 0) {
352             bMatch = false;
353         } else if (m_property_ptr.equals(propInst.m_property_ptr) == false) {
354             bMatch = false;
355         } else if (
356             m_sOperator.equals(">")
357                 || m_sOperator.equals("<")
358                 || m_sOperator.equals(">=")
359                 || m_sOperator.equals("<=")) {
360             try {
361                 if (getProperty()
362                     .getRange()
363                     .getObject()
364                     .equals(Number JavaDoc.class.getName())
365                     == true) {
366                     int nTemp1 = Integer.parseInt((String JavaDoc) otherValues.get(0));
367                     int nTemp2 = Integer.parseInt((String JavaDoc) m_values.get(0));
368
369                     if ((m_sOperator.equals(">") && (nTemp1 > nTemp2) == false)
370                         || (m_sOperator.equals("<") && (nTemp1 < nTemp2) == false)
371                         || (m_sOperator.equals(">=")
372                             && (nTemp1 >= nTemp2) == false)
373                         || (m_sOperator.equals("<=")
374                             && (nTemp1 <= nTemp2) == false)) {
375                         bMatch = false;
376                     }
377                 }
378             } catch (DataAccessException e) {
379                 throw new ProfileException(
380                     "Error occured accessing property range",e);
381             }
382         } else if (
383             m_sOperator.equals("=")
384                 && (false
385                     == ((String JavaDoc) otherValues.get(0)).equalsIgnoreCase(
386                         (String JavaDoc) m_values.get(0)))) {
387             bMatch = false;
388         } else if (
389             m_sOperator.equals("!=")
390                 && ((String JavaDoc) otherValues.get(0)).equalsIgnoreCase(
391                     (String JavaDoc) m_values.get(0))) {
392             bMatch = false;
393         } else if (m_sOperator.equals("CONTAINS")) {
394             String JavaDoc sTemp1 = (String JavaDoc) m_values.get(0);
395             String JavaDoc sTemp2 = (String JavaDoc) otherValues.get(0);
396
397             if (sTemp1.indexOf(sTemp1) < 0) {
398                 bMatch = false;
399             }
400         } else if (m_sOperator.equals("BETWEEN")) {
401             try {
402                 if (getProperty()
403                     .getRange()
404                     .getObject()
405                     .equals(Number JavaDoc.class.getName())
406                     == true) {
407                     int nTemp1 = Integer.parseInt((String JavaDoc) otherValues.get(0));
408                     int nTemp2 = Integer.parseInt((String JavaDoc) m_values.get(0));
409                     int nTemp3 = Integer.parseInt((String JavaDoc) m_values.get(1));
410
411                     if ((nTemp2 < nTemp3)) {
412                         if ((nTemp2 < nTemp1 && nTemp1 < nTemp3) == false) {
413                             bMatch = false;
414                         }
415                     } else {
416                         if ((nTemp3 < nTemp1 && nTemp1 < nTemp2) == false) {
417                             bMatch = false;
418                         }
419                     }
420                 }
421             } catch (DataAccessException e) {
422                 throw new ProfileException(
423                     "Error occured accessing property range",e);
424             }
425         } else if (m_sOperator.equals("STARTS_WITH")) {
426             String JavaDoc sTemp1 = (String JavaDoc) m_values.get(0);
427             String JavaDoc sTemp2 = (String JavaDoc) otherValues.get(0);
428
429             if (sTemp1.startsWith(sTemp2) == false) {
430                 bMatch = false;
431             }
432         } else if (m_sOperator.equals("IN") || m_sOperator.equals("NOT IN")) {
433             boolean bCheck = false;
434
435             for (int j = 0; j < otherValues.size(); j++) {
436                 for (int k = 0; k < m_values.size(); k++) {
437                     if (((String JavaDoc) m_values.get(k))
438                         .trim()
439                         .equals(((String JavaDoc) otherValues.get(j)).trim())) {
440                         bCheck = true;
441                     }
442                 }
443             }
444
445             if ((m_sOperator.equals("NOT IN") && bCheck)
446                 || (m_sOperator.equals("IN") && bCheck == false)) {
447                 bMatch = false;
448             }
449         }
450
451         return bMatch;
452     }
453
454     /* (non-Javadoc)
455      * @see org.openharmonise.rm.dsi.DataStoreObject#getInstanceColumnRef(java.lang.String, boolean)
456      */

457     public ColumnRef getInstanceColumnRef(String JavaDoc sColumn, boolean bIsHist)
458         throws DataStoreException {
459         ColumnRef returnColRef = null;
460         String JavaDoc sDBTable = getDBTableName();
461
462         if (sColumn.equals(TAG_VALUE) == true
463             || sColumn.equals(CLMN_VALUE) == true) {
464             returnColRef = new ColumnRef(sDBTable, CLMN_VALUE, ColumnRef.TEXT);
465         }
466
467         if (returnColRef != null) {
468             return returnColRef;
469         } else {
470             return super.getInstanceColumnRef(sColumn, bIsHist);
471         }
472     }
473
474     /* (non-Javadoc)
475      * @see org.openharmonise.rm.dsi.DataStoreObject#getInstanceJoinConditions(java.lang.String, boolean)
476      */

477     public JoinConditions getInstanceJoinConditions(
478         String JavaDoc sObjectTag,
479         boolean bIsOuter)
480         throws DataStoreException {
481         throw new UnsupportedOperationException JavaDoc("Not implemented");
482     }
483
484     /* (non-Javadoc)
485      * @see org.openharmonise.rm.dsi.DataStoreObject#processResultSet(org.openharmonise.commons.dsi.CachedResultSet, org.openharmonise.commons.dsi.dml.SelectStatement)
486      */

487     public List processResultSet(
488         CachedResultSet resultSet,
489         SelectStatement select) {
490         throw new UnsupportedOperationException JavaDoc("Not implemented");
491     }
492
493     /* (non-Javadoc)
494      * @see org.openharmonise.rm.dsi.DataStoreObject#processResultSet(org.openharmonise.commons.dsi.CachedResultSet, org.openharmonise.commons.dsi.dml.SelectStatement, int)
495      */

496     public List processResultSet(
497         CachedResultSet resultSet,
498         SelectStatement select,
499         int limit) {
500         throw new UnsupportedOperationException JavaDoc("Not implemented");
501     }
502
503     /**
504      * Adds a <code>Date</code> value to this instance.
505      *
506      * @param date the date
507      * @throws InvalidPropertyValueException if the given value is invalid
508      */

509     public void addValue(java.util.Date JavaDoc date)
510         throws PopulateException {
511         if (date != null) {
512             super.addValue(date);
513         }
514     }
515
516     /**
517      * Adds a <code>String</code> value to this instance.
518      *
519      * @param sValue the value to add
520      * @throws InvalidPropertyValueException if the given value is invalid
521      */

522     public void addValue(String JavaDoc sValue) throws PopulateException {
523         if (sValue != null && sValue.trim().equals("") == false) {
524             try {
525                 Range range = this.getProperty().getRange();
526                 
527                 Object JavaDoc objVal = sValue;
528                 
529                 if (range instanceof DateRange) {
530                     objVal = getDateValue(sValue);
531                 }
532                 
533                 if(range instanceof BooleanRange
534                         && m_values != null
535                         && m_values.size() > 0) {
536                     throw new InvalidPropertyValueException("Boolean property can only have one value");
537                 }
538                 
539                 super.addValue(objVal);
540                 
541             } catch (DataAccessException e) {
542                 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
543             } catch (InvalidPropertyValueException e) {
544                 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
545             }
546         }
547     }
548
549     /**
550      * Returns a <code>Date</code> object representation of the given <code>String</code>.
551      *
552      * @param sVal the <code>String</code> value
553      * @return the <code>Date</code> obtained by parsing the <code>String</code>
554      * @throws DataAccessException if an error occurs parsing the <code>String</code>
555      * or accessing the associated <code>Property</code>
556      */

557     public Date getDateValue(String JavaDoc sVal) throws DataAccessException {
558         Date dtVal = null;
559
560         Range range = this.getProperty().getRange();
561
562         if (range instanceof DateRange) {
563
564             try {
565                 long lDate = Long.parseLong(sVal);
566                 dtVal = new Date(lDate);
567             } catch (NumberFormatException JavaDoc e) {
568                 //assume the date was represented in the other format
569
SimpleDateFormat format = null;
570                 DateRange dtRange = (DateRange) range;
571                 if (dtRange.includeTime() == true) {
572                     format = new SimpleDateFormat(DATETIME_FORMAT);
573                 } else {
574                     format = new SimpleDateFormat(DATE_FORMAT);
575                 }
576
577                 try {
578                     dtVal = format.parse(sVal);
579                 } catch (ParseException pe) {
580                     throw new DataAccessException(
581                         "Problem parsing date as a string",
582                         pe);
583                 }
584             }
585
586         } else {
587             throw new DataAccessException(
588                 "Invalid request: this is not a date property instance - "
589                     + range.getClass().getName());
590         }
591
592         return dtVal;
593     }
594
595     /**
596      * Removes the specified value from this instance
597      *
598      * @param sValue the value to remove
599      */

600     public void removeValue(String JavaDoc sValue) {
601         if (m_values != null) {
602             super.removeValue(sValue);
603         }
604     }
605     
606     /**
607      * Returns a <code>boolean</code> value for an instance of a property with a
608      * boolean range.
609      *
610      * @return a boolean value for this property instance
611      * @throws DataAccessException if an error occurs accessing the property
612      * associated to this instance
613      */

614     public boolean getBooleanValue() throws DataAccessException {
615         boolean bool = false;
616         
617         if(m_values.size()>0 && getProperty().getRange() instanceof BooleanRange) {
618             bool = Boolean.valueOf((String JavaDoc) m_values.get(0)).booleanValue();
619         }
620         
621         return bool;
622     }
623
624     /*-------------------------------------------------------------------------------------
625     Protected Methods
626     --------------------------------------------------------------------------------------*/

627
628     /**
629      * Parses a date formula, creating a string representation of the absolute date.
630      *
631      * @param sDateFormula the date formula to be parsed
632      * @return the resultant date
633      * @throws ParseException if an error occurs parsing the date formula
634      *
635      */

636     protected String JavaDoc parseDate(String JavaDoc sDateFormula) throws ParseException {
637         String JavaDoc sDate = null;
638         String JavaDoc sOperator = null;
639         String JavaDoc sPeriod = null;
640         GregorianCalendar calendar = null;
641         java.text.SimpleDateFormat JavaDoc formatter = null;
642
643         // the formulas must follow the following BNF:
644
// datecalculation = datedescriptor [ " + " | " - " period]
645
// datedescriptor = datetime | "today" | "now"
646
// datetime = [number "-" number "-" number] [" " number ":" number ":" number]
647
// period = ["P" ["Y" number] ["M" number] ["D" number]] ["T" ["H" number] ["M" number] ["S" number]]
648
// first need to separate the datedescriptor, operator and period
649
if ((sDateFormula.indexOf(" +") >= 0)
650             || (sDateFormula.indexOf(" -") >= 0)) {
651             StringTokenizer tokenizer = new StringTokenizer(sDateFormula, " ");
652
653             String JavaDoc sNext = null;
654             StringBuffer JavaDoc sDateRecorder = new StringBuffer JavaDoc();
655             StringBuffer JavaDoc sPeriodRecorder = new StringBuffer JavaDoc();
656             boolean bRecordingDate = true;
657
658             while (tokenizer.hasMoreElements()) {
659                 sNext = tokenizer.nextToken();
660
661                 if (sNext.equals("+") || sNext.equals("-")) {
662                     sOperator = sNext;
663                     bRecordingDate = false;
664                 } else if (bRecordingDate) {
665                     sDateRecorder.append(sNext);
666                 } else {
667                     sPeriodRecorder.append(sNext);
668                 }
669             }
670
671             sDate = sDateRecorder.toString();
672             sPeriod = sPeriodRecorder.toString();
673         } else {
674             sDate = sDateFormula;
675         }
676
677         // process the special date tokens and create a calendar representing them
678
if (sDate.equalsIgnoreCase("today")) {
679             // set it to today
680
calendar = new GregorianCalendar();
681             calendar.setTime(new java.util.Date JavaDoc());
682             formatter = new java.text.SimpleDateFormat JavaDoc(DATE_FORMAT);
683
684             // ensure that equality will work with the reduced precision
685
if ((m_sOperator != null) && m_sOperator.equals("=")) {
686                 m_sOperator = "STARTS_WITH";
687             }
688         } else if (sDate.equalsIgnoreCase("now")) {
689             // set it to now
690
calendar = new GregorianCalendar();
691             calendar.setTime(new java.util.Date JavaDoc());
692             formatter = new java.text.SimpleDateFormat JavaDoc(DATETIME_FORMAT);
693         }
694
695         // we only have a calculation to do if we have both an operator and a period
696
if ((sOperator != null) && (sPeriod != null)) {
697             // this is the case where we have an absolute date in the formula
698
// this is done here so the degenerate case where we just have a datetime
699
// falls straight through
700
if (calendar == null) {
701                 // create it
702
calendar = new GregorianCalendar();
703                 calendar.setTime(formatter.parse(sDate));
704                 formatter = new java.text.SimpleDateFormat JavaDoc(DATETIME_FORMAT);
705             }
706
707             char[] caPeriod = sPeriod.toCharArray();
708             StringBuffer JavaDoc sNumber = new StringBuffer JavaDoc();
709             boolean bDate = true;
710             // true if we are doing date fields, false if we are in time
711
char cNext = 0;
712
713             for (int i = 0; i < caPeriod.length; i++) {
714                 cNext = caPeriod[i];
715
716                 // 'P' and 'T' just affect the interpretation of 'M'
717
if (cNext == 'P') { // date
718
bDate = true;
719                 } else if (cNext == 'T') { // time
720
bDate = false;
721                 } else if (cNext == 'Y') { // year
722
changeDate(
723                         calendar,
724                         Calendar.YEAR,
725                         sOperator,
726                         Integer.parseInt(sNumber.toString()));
727                     sNumber = new StringBuffer JavaDoc();
728                 } else if (cNext == 'M') { // month or minute
729

730                     if (bDate) {
731                         changeDate(
732                             calendar,
733                             Calendar.MONTH,
734                             sOperator,
735                             Integer.parseInt(sNumber.toString()));
736                     } else {
737                         changeDate(
738                             calendar,
739                             Calendar.MINUTE,
740                             sOperator,
741                             Integer.parseInt(sNumber.toString()));
742                     }
743
744                     sNumber = new StringBuffer JavaDoc();
745                 } else if (cNext == 'D') { // day of the month
746
changeDate(
747                         calendar,
748                         Calendar.DATE,
749                         sOperator,
750                         Integer.parseInt(sNumber.toString()));
751                     sNumber = new StringBuffer JavaDoc();
752                 } else if (cNext == 'H') { // hour
753
changeDate(
754                         calendar,
755                         Calendar.HOUR_OF_DAY,
756                         sOperator,
757                         Integer.parseInt(sNumber.toString()));
758                     sNumber = new StringBuffer JavaDoc();
759                 } else if (cNext == 'S') { // second
760
changeDate(
761                         calendar,
762                         Calendar.SECOND,
763                         sOperator,
764                         Integer.parseInt(sNumber.toString()));
765                     sNumber = new StringBuffer JavaDoc();
766                 } else if (Character.isDigit(cNext)) {
767                     sNumber.append(cNext);
768                 }
769
770                 // should probably throw an exception if we find something else
771
}
772         }
773
774         // convert calendar to a string, if we used it
775
if (calendar != null) {
776             sDate = formatter.format(calendar.getTime());
777         }
778
779         return sDate;
780     }
781
782     /**
783      * Returns the name of database table for a property instance associated to
784      * the given <code>Profile</code>.
785      *
786      * @param prof the <code>Profile</code> which will be the associated to the property #
787      * instance
788      * @return the database table name for the property instance
789      */

790     static protected String JavaDoc getDBTableName(Profile prof) {
791         StringBuffer JavaDoc sTable = new StringBuffer JavaDoc();
792
793         if (prof.isHistorical() == true) {
794             AbstractProfiledObject profObj = prof.getProfiledObject();
795             sTable
796                 .append(profObj.getDBTableName())
797                 .append(Profile.EXT_PROFILE)
798                 .append(EXT_DATA)
799                 .append(EXT_HIST);
800         } else {
801             sTable.append(prof.getDBTableName()).append(EXT_DATA);
802         }
803
804         return sTable.toString();
805     }
806
807     /* (non-Javadoc)
808      * @see org.openharmonise.rm.metadata.AbstractPropertyInstance#setDBTable(org.openharmonise.rm.metadata.Profile)
809      */

810     protected void setDBTable(Profile profile) {
811         m_sDataTable = getDBTableName(profile);
812
813     }
814
815     /* (non-Javadoc)
816      * @see org.openharmonise.rm.metadata.AbstractPropertyInstance#getColumnForData()
817      */

818     protected ColumnRef getColumnForData() throws DataStoreException {
819
820         return getInstanceColumnRef(TAG_VALUE, isHistorical());
821     }
822
823     /* (non-Javadoc)
824      * @see org.openharmonise.rm.metadata.AbstractPropertyInstance#getValueToStoreForValue(java.lang.Object)
825      */

826     protected Object JavaDoc getValueToStoreForValue(Object JavaDoc val)
827         throws ProfileException {
828         String JavaDoc sVal = null;
829
830         if (val instanceof String JavaDoc) {
831             sVal = (String JavaDoc) val;
832         } else if (val instanceof Date) {
833             sVal = String.valueOf(((Date) val).getTime());
834         }
835
836         return sVal;
837     }
838
839     /**
840      * Adds a value to this instance.
841      *
842      * @param sValue the value to add
843      * @throws InvalidPropertyValueException if the given valus is invalid
844      */

845     protected void addValue(String JavaDoc sValue, int nId)
846         throws PopulateException {
847         if (sValue.trim().equals("") == false) {
848             try {
849                 Range range = this.getProperty().getRange();
850
851                 if (range instanceof DateRange) {
852                     super.addValue(getDateValue(sValue), nId);
853                 } else {
854                     super.addValue(sValue, nId);
855                 }
856             } catch (DataAccessException e) {
857                 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
858             } catch (InvalidPropertyValueException e) {
859                 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
860             }
861         }
862     }
863
864     /**
865      * Changes date in the given calendar by the delta value given.
866      *
867      * @param calendar calander representing date
868      * @param nField the time field
869      * @param sOperator '+' or '-'
870      * @param nDelta the amount of date or time to be added to the field
871      */

872     protected void changeDate(
873         Calendar calendar,
874         int nField,
875         String JavaDoc sOperator,
876         int nDelta) {
877         if (sOperator.equals("-")) {
878             nDelta = 0 - nDelta;
879         }
880
881         calendar.add(nField, nDelta);
882     }
883     
884     /**
885      * Returns the name of the database table for a property instance associated
886      * to the given <code>AbstractProfileObject</code>.
887      *
888      * @param profObj the profiled object
889      * @return the database table name for the property instance
890      */

891     public static String JavaDoc getDBTableName(String JavaDoc sClassname) throws DataStoreException {
892         StringBuffer JavaDoc sbuf = new StringBuffer JavaDoc();
893     
894         sbuf.append(Profile.getTableName(sClassname,false));
895         sbuf.append(EXT_DATA);
896     
897         return sbuf.toString();
898     }
899     
900     /**
901      * Returns the name of the database table for a property instance associated
902      * to the given <code>AbstractProfileObject</code>.
903      *
904      * @param profObj the profiled object
905      * @return the database table name for the property instance
906      */

907     public static String JavaDoc getDBTableName(AbstractProfiledObject profObj) {
908         StringBuffer JavaDoc sbuf = new StringBuffer JavaDoc();
909         
910         sbuf.append(Profile.getDBTableName(profObj));
911         sbuf.append(EXT_DATA);
912         
913         return sbuf.toString();
914     }
915
916 }
917
Popular Tags