KickJava   Java API By Example, From Geeks To Geeks.

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


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.util.*;
22 import java.util.logging.*;
23
24 import org.openharmonise.commons.cache.*;
25 import org.openharmonise.commons.dsi.*;
26 import org.openharmonise.commons.dsi.ddl.*;
27 import org.openharmonise.commons.dsi.dml.*;
28 import org.openharmonise.commons.xml.XMLPrettyPrint;
29 import org.openharmonise.commons.xml.namespace.NamespaceClashException;
30 import org.openharmonise.rm.*;
31 import org.openharmonise.rm.dsi.DatabaseInfo;
32 import org.openharmonise.rm.factory.*;
33 import org.openharmonise.rm.publishing.*;
34 import org.openharmonise.rm.resources.*;
35 import org.openharmonise.rm.resources.metadata.properties.Property;
36 import org.openharmonise.rm.resources.metadata.properties.ranges.ChildObjectRange;
37 import org.openharmonise.rm.resources.publishing.*;
38 import org.w3c.dom.*;
39
40
41 /**
42  * A concrete implementation of <code>AbstractPropertyInstance</code> to handle
43  * property instances which contain <code>AbstractChildObject</code> values.
44  *
45  * @author Michael Bell
46  * @version $Revision: 1.5 $
47  *
48  */

49 public class ChildObjectPropertyInstance
50     extends AbstractPropertyInstance
51     implements Publishable {
52
53     /**
54      * Internal cache of mappings between <code>AbstractChildObject</code>
55      * implementations and their database tables.
56      */

57     private static Map m_childObj_table_mappings = new Hashtable();
58     protected final static String JavaDoc CLMN_OBJECT_ID = "object_id";
59     
60     /**
61      * Logger for this class
62      */

63     private static final Logger m_logger = Logger.getLogger(ChildObjectPropertyInstance.class.getName());
64
65     /**
66      * Constructs a property instance.
67      */

68     public ChildObjectPropertyInstance() {
69         super();
70
71     }
72
73     /**
74      * Constructs a property instance with a data store interface.
75      *
76      * @param dbint the data store interface
77      */

78     public ChildObjectPropertyInstance(AbstractDataStoreInterface dbint) {
79         super(dbint);
80
81     }
82
83     /**
84      * Constructs a property instance with a data store interface and a
85      * reference to the <code>Profile</code> which will contain this instance.
86      *
87      * @param dbintrf the data store interface
88      * @param profile the owner <code>Profile</code>
89      */

90     public ChildObjectPropertyInstance(
91         AbstractDataStoreInterface dbintrf,
92         Profile profile) {
93         super(dbintrf, profile);
94
95     }
96
97     /**
98      * Constructs a property instance with a data store interface, a reference
99      * to the <code>Profile</code> which will contain this instance and a
100      * reference to the <code>Property</code> of which this is property instance
101      * is an instance of.
102      *
103      * @param dbintrf the data store interface
104      * @param nPropertyId the id of the <code>Property</code>
105      * @param profile the owner <code>Profile</code>
106      */

107     public ChildObjectPropertyInstance(
108         AbstractDataStoreInterface dbintrf,
109         int nPropertyId,
110         Profile profile) {
111         super(dbintrf, nPropertyId, profile);
112     }
113
114     /**
115      * Constructs a property instance with a data store interface and referenec
116      * to the <code>Property</code> it is an instance of.
117      *
118      * @param dbintrf the data store interface
119      * @param prop the <code>Property</code> this is an instance of
120      */

121     public ChildObjectPropertyInstance(
122         AbstractDataStoreInterface dbintrf,
123         Property prop) {
124         super(dbintrf, prop);
125     }
126
127     /**
128      * Constructs a property instance with a data store interface, a
129      * reference to the <code>Profile</code> which will contain this object
130      * and a reference to the <code>Property</code> which this object is an
131      * instance of.
132      *
133      * @param dbintrf the data store interface
134      * @param property the <code>Property</code>
135      * @param profile the owner <code>Profile</code>
136      */

137     public ChildObjectPropertyInstance(
138         AbstractDataStoreInterface dbintrf,
139         Property property,
140         Profile profile) {
141         super(dbintrf, property, profile);
142
143     }
144
145     /**
146      * Adds the given <code>AbstractChildObject</code> as a value to this
147      * property instance.
148      *
149      * @param child the new value to add to this property instance
150      *
151      * @throws InvalidPropertyValueException if the value given is invalid
152      */

153     public void addValue(AbstractChildObject child)
154         throws PopulateException {
155         if (child != null && isValidValue(child)) {
156             try {
157                 CachePointer ptr =
158                     CacheHandler.getInstance(m_dsi).getCachePointer(child);
159
160                 super.addValue(ptr);
161
162             } catch (CacheException e) {
163                 throw new InvalidPropertyValueException(
164                     "Unable to get cache pointer",
165                     e);
166             }
167         }
168     }
169
170     /**
171      * Adds the given <code>AbstractChildObject</code> as a value to this
172      * property instance with the specified id.
173      *
174      * @param child the new value to add to this property instance
175      * @param nId the id to associate with this value
176      *
177      * @throws InvalidPropertyValueException if the value given is invalid
178      */

179     public void addValue(AbstractChildObject child, int nId)
180         throws PopulateException {
181         if (child != null && isValidValue(child)) {
182             try {
183                 CachePointer ptr =
184                     CacheHandler.getInstance(m_dsi).getCachePointer(child);
185
186                 super.addValue(ptr, nId);
187             } catch (CacheException e) {
188                 throw new InvalidPropertyValueException(
189                     "Unable to get cache pointer",
190                     e);
191             }
192         }
193
194     }
195
196     /**
197      * Removes the specified <code>AbstractChildObject</code> from
198      * this property instance's list of values.
199      *
200      * @param child the value to remove
201      *
202      * @throws InvalidPropertyValueException if the specified value
203      * is an invalid value for this property instance
204      */

205     public void removeValue(AbstractChildObject child)
206         throws InvalidPropertyValueException {
207
208         try {
209             CachePointer ptr =
210                 CacheHandler.getInstance(m_dsi).getCachePointer(child);
211
212             super.removeValue(ptr);
213         } catch (CacheException e) {
214             throw new InvalidPropertyValueException(e.getLocalizedMessage(), e);
215         }
216     }
217
218     /* (non-Javadoc)
219      * @see org.openharmonise.rm.publishing.Publishable#populate(org.w3c.dom.Element, org.openharmonise.rm.publishing.State)
220      */

221     public void populate(Element xmlElement, State state)
222         throws PopulateException {
223         String JavaDoc sTagName = xmlElement.getTagName();
224         Text txt = null;
225
226         if (sTagName.equals(TAG_PROP_INSTANCE_VALUES) == true) {
227             NodeList nodes = xmlElement.getChildNodes();
228             boolean bChildFound = false;
229
230             for (int i = 0; i < nodes.getLength(); i++) {
231                 if (nodes.item(i).getNodeType() != Node.ELEMENT_NODE) {
232                     continue;
233                 }
234                 Element tmpEl = (Element) nodes.item(i);
235                 sTagName = tmpEl.getTagName();
236                 
237                 if (sTagName.equals(TAG_ATTACH) == true){
238                     NodeList attachNodes = tmpEl.getChildNodes();
239                     for (int j = 0; j < attachNodes.getLength(); j++) {
240                         if (attachNodes.item(j).getNodeType() != Node.ELEMENT_NODE) {
241                             continue;
242                         }
243                         Element attEl = (Element) attachNodes.item(j);
244                         populateChild(attEl, state);
245                     }
246                 } else if (sTagName.equals(TAG_DETACH) == true) {
247                     NodeList detachNodes = tmpEl.getChildNodes();
248                     for (int j = 0; j < detachNodes.getLength(); j++) {
249                         if (detachNodes.item(j).getNodeType() != Node.ELEMENT_NODE) {
250                             continue;
251                         }
252                         Element attEl = (Element) detachNodes.item(j);
253                         populateChild(attEl, state, true);
254                     }
255                 } else {
256                     if(bChildFound == false){
257                         this.clearValues();
258                     }
259                     populateChild(tmpEl, state);
260                     bChildFound = true;
261                 }
262             }
263         } else {
264             super.populate(xmlElement, state);
265         }
266     }
267     private void populateChild(Element childEl, State state)
268         throws PopulateException {
269         
270         populateChild(childEl, state, false);
271     }
272     private void populateChild(Element childEl, State state, boolean bRemove)
273         throws PopulateException {
274         try {
275             Publishable pubObj =
276                 HarmoniseObjectFactory.instantiatePublishableObject(
277                     this.m_dsi,
278                     childEl,
279                     state);
280             
281             if(pubObj != null) {
282                 pubObj.populate(childEl, state);
283                 if(bRemove){
284                     removeValue((AbstractChildObject) pubObj);
285                 } else {
286                     addValue((AbstractChildObject) pubObj);
287                 }
288             } else {
289                 XMLPrettyPrint xpp = new XMLPrettyPrint();
290                 
291                 try {
292                     throw new PopulateException(xpp.printNode(childEl));
293                 } catch (PopulateException e) {
294                     m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
295                 } catch (NamespaceClashException e) {
296                     m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
297                 }
298             }
299         } catch (InvalidPropertyValueException iv_e) {
300             throw new PopulateException(
301                 "Invalid value for PropertyInstance" ,iv_e);
302         } catch (HarmoniseFactoryException e) {
303             throw new PopulateException(
304                 "Problem occured instantiating value",e);
305         } catch (ClassCastException JavaDoc cce) {
306             throw new PopulateException(
307                 "Invalid value for PropertyInstance",cce);
308         }
309     }
310
311     /* (non-Javadoc)
312      * @see org.openharmonise.rm.publishing.Publishable#publish(org.w3c.dom.Element, org.openharmonise.rm.publishing.HarmoniseOutput, org.openharmonise.rm.publishing.State)
313      */

314     public Element publish(Element formEl, HarmoniseOutput xmlDoc, State state)
315         throws PublishException {
316
317         Element resultEl = null;
318         String JavaDoc sTagname = formEl.getTagName();
319
320         if (sTagname.equals(TAG_PROP_INSTANCE_VALUES) == true) {
321             resultEl = xmlDoc.createElement(TAG_PROP_INSTANCE_VALUES);
322
323             if (m_values != null) {
324                 NodeList templateNodes =
325                     formEl.getElementsByTagName(Template.TAG_TEMPLATE);
326                 Element templateEl = (Element) templateNodes.item(0);
327                 Template template = null;
328                 Element publishTemplateEl = null;
329
330                 int nPageId = -2;
331
332                 if (templateEl != null) {
333                     try {
334                         template =
335                             (Template) HarmoniseObjectFactory.instantiateHarmoniseObject(
336                                 m_dsi,
337                                 templateEl,
338                                 state);
339                         NodeList pageNodes =
340                             templateEl.getElementsByTagName(WebPage.TAG_PAGE);
341
342                         if (pageNodes.getLength() > 0) {
343                             nPageId =
344                                 Integer.parseInt(
345                                     ((Element) pageNodes.item(0)).getAttribute(
346                                         AbstractObject.ATTRIB_ID));
347                         }
348                     } catch (HarmoniseFactoryException e) {
349                         throw new PublishException(e.getLocalizedMessage(), e);
350                     }
351                 }
352
353                 if (template != null) {
354                     try {
355                         publishTemplateEl = template.getTemplateRootElement();
356                     } catch (DataAccessException e) {
357                         throw new PublishException(e.getLocalizedMessage(), e);
358                     }
359                 } else {
360                     //if there isn't a template, create a simple one
361
//to publish the object name only
362
publishTemplateEl =
363                         xmlDoc.createElement(
364                             AbstractObject.TAG_HARMONISE_OBJECT);
365                     Element nameEl =
366                         xmlDoc.createElement(AbstractObject.TAG_NAME);
367                     publishTemplateEl.appendChild(nameEl);
368                     Element displayNameEl =
369                         xmlDoc.createElement(
370                             AbstractChildObject.TAG_DISPLAY_NAME);
371                     publishTemplateEl.appendChild(displayNameEl);
372                 }
373
374                 Text txt = null;
375                 for (int j = 0; j < m_values.size(); j++) {
376                     try {
377                         AbstractChildObject tmpChild =
378                             (AbstractChildObject) ((CachePointer) m_values
379                                 .get(j))
380                                 .getObject();
381
382                         Element childEl = null;
383
384                         childEl =
385                             tmpChild.publish(publishTemplateEl, xmlDoc, state);
386
387                         if (childEl != null) {
388                             resultEl.appendChild(childEl);
389                         }
390
391                     } catch (CacheException e) {
392                         throw new PublishException(e);
393                     }
394
395                 }
396                 if (nPageId > 0) {
397                     xmlDoc.addPageIdToLinkNode(
398                         state.getLoggedInUser(),
399                         resultEl,
400                         nPageId);
401                 }
402             }
403         } else {
404             resultEl = super.publish(formEl, xmlDoc, state);
405         }
406
407         if (resultEl == null) {
408             resultEl = xmlDoc.createElement(TAG_ERROR);
409             resultEl.appendChild(
410                 xmlDoc.createTextNode("Problem publishing " + sTagname));
411         }
412
413         return resultEl;
414     }
415
416     /* (non-Javadoc)
417      * @see org.openharmonise.rm.publishing.Publishable#publish(org.openharmonise.rm.resources.publishing.Template, org.openharmonise.rm.publishing.HarmoniseOutput, org.openharmonise.rm.publishing.State)
418      */

419     public Element publish(Template template, HarmoniseOutput xmlDoc, State state)
420         throws PublishException {
421         return super.publish(template, xmlDoc, state);
422     }
423
424     /* (non-Javadoc)
425      * @see org.openharmonise.rm.metadata.AbstractPropertyInstance#setDBTable(org.openharmonise.rm.metadata.Profile)
426      */

427     protected void setDBTable(Profile profile) {
428         //get table extension
429

430         try {
431             Property prop = getProperty();
432
433             if (prop != null) {
434
435                 try {
436
437                     ChildObjectRange range =
438                         (ChildObjectRange) getProperty().getRange();
439
440                     AbstractChildObject child = null;
441
442                     if (m_profile != null) {
443                         child =
444                             (AbstractChildObject) m_profile.getProfiledObject();
445                     }
446
447                     String JavaDoc sClassname =
448                         range.getChildObjectValueClassName(child);
449
450                     m_sDataTable = getDBTableName(profile, sClassname);
451                 } catch (DataStoreException e) {
452                     throw new IllegalStateException JavaDoc("Property had inappropriate range object for this property instance");
453                 } catch (DataAccessException e) {
454                     throw new IllegalStateException JavaDoc("Property had inappropriate range object for this property instance");
455                 }
456             }
457         } catch (DataAccessException e) {
458             throw new IllegalStateException JavaDoc(e.getLocalizedMessage());
459         }
460     }
461
462     /* (non-Javadoc)
463      * @see org.openharmonise.rm.metadata.AbstractPropertyInstance#match(org.openharmonise.rm.metadata.AbstractPropertyInstance)
464      */

465     public boolean match(AbstractPropertyInstance propInst)
466         throws ProfileException {
467         boolean bMatch = false;
468
469         if (propInst instanceof ChildObjectPropertyInstance) {
470             List vals = getValues();
471             List otherVals = propInst.getValues();
472             
473             Iterator thisIter = vals.iterator();
474
475             if ((m_sOperator.equals("=") && vals.size() == otherVals.size())
476                     || m_sOperator.equalsIgnoreCase("contains")){
477                 
478                 while (thisIter.hasNext()) {
479                     AbstractChildObject child = (AbstractChildObject) thisIter.next();
480                     
481                     if(otherVals.contains(child) == false) {
482                         bMatch = false;
483                         break;
484                     } else if(bMatch == false) {
485                         bMatch = true;
486                     }
487                     
488                 }
489             }
490             
491         }
492         return bMatch;
493     }
494
495     /*-------------------------------------------------------------------------------------
496     Protected Methods
497     --------------------------------------------------------------------------------------*/

498
499     /* (non-Javadoc)
500      * @see org.openharmonise.rm.metadata.AbstractPropertyInstance#getColumnForData()
501      */

502     protected ColumnRef getColumnForData() throws DataStoreException {
503         return getInstanceColumnRef(TAG_VALUE, isHistorical());
504     }
505
506     /* (non-Javadoc)
507      * @see org.openharmonise.rm.metadata.AbstractPropertyInstance#getValueToStoreForValue(java.lang.Object)
508      */

509     protected Object JavaDoc getValueToStoreForValue(Object JavaDoc val)
510         throws ProfileException {
511         Integer JavaDoc intVal = null;
512
513         CachePointer ptr = (CachePointer) val;
514         int nChildId = Integer.parseInt((String JavaDoc) ptr.getKey());
515
516         if (nChildId > 0) {
517             intVal = new Integer JavaDoc(nChildId);
518         } else {
519             throw new InvalidPropertyInstanceException("Child object value with invalid id - 0");
520         }
521
522         return intVal;
523     }
524
525     /* (non-Javadoc)
526      * @see org.openharmonise.rm.dsi.DataStoreObject#getInstanceJoinConditions(java.lang.String, boolean)
527      */

528     public JoinConditions getInstanceJoinConditions(
529         String JavaDoc sObjectTag,
530         boolean bIsOuter)
531         throws DataStoreException {
532         return null;
533     }
534
535     /* (non-Javadoc)
536      * @see org.openharmonise.rm.dsi.DataStoreObject#getInstanceColumnRef(java.lang.String, boolean)
537      */

538     public ColumnRef getInstanceColumnRef(String JavaDoc sColumn, boolean bIsHist)
539         throws DataStoreException {
540         ColumnRef returnColRef = null;
541         String JavaDoc sDBTable = getDBTableName();
542
543         if (sColumn.equals(TAG_VALUE) == true
544             || sColumn.equals(CLMN_OBJECT_ID) == true) {
545             returnColRef =
546                 new ColumnRef(sDBTable, CLMN_OBJECT_ID, ColumnRef.NUMBER);
547         }
548
549         if (returnColRef != null) {
550             return returnColRef;
551         } else {
552             return super.getInstanceColumnRef(sColumn, bIsHist);
553         }
554     }
555
556     /* (non-Javadoc)
557      * @see org.openharmonise.rm.dsi.DataStoreObject#processResultSet(org.openharmonise.commons.dsi.CachedResultSet, org.openharmonise.commons.dsi.dml.SelectStatement)
558      */

559     public List processResultSet(
560         CachedResultSet resultSet,
561         SelectStatement select) {
562         // do nothing as this isn't implemented in Profile
563
return null;
564     }
565
566     /* (non-Javadoc)
567      * @see org.openharmonise.rm.dsi.DataStoreObject#processResultSet(org.openharmonise.commons.dsi.CachedResultSet, org.openharmonise.commons.dsi.dml.SelectStatement, int)
568      */

569     public List processResultSet(
570         CachedResultSet resultSet,
571         SelectStatement select,
572         int limit) {
573             // do nothing as this isn't implemented in Profile
574
return null;
575     }
576
577     /**
578      * Returns the database table for the property instance which will be
579      * attached to the specified <code>Profile</code> and contain values
580      * of the type specified by the given class name.
581      *
582      * The table name is determined by the profile database table name
583      * and the type of <code>AbstractChildObject</code>.
584      *
585      * @param profile the owning <code>Profile</code>
586      * @param sClassname the class name of the
587      * <code>AbstractChildObject</code> value for the property instance
588      * @return the database table for the property instance
589      *
590      * @throws DataStoreException if there is an error obtaining the database
591      * table name for the given <code>AbstractChildObject</code> class name
592      */

593     public static String JavaDoc getDBTableName(Profile profile, String JavaDoc sClassname)
594         throws DataStoreException {
595         StringBuffer JavaDoc sDataTable = new StringBuffer JavaDoc();
596
597         String JavaDoc sExt = (String JavaDoc) m_childObj_table_mappings.get(sClassname);
598
599         if (sExt == null) {
600             String JavaDoc sTable = DatabaseInfo.getInstance().getTableName(sClassname);
601             sExt = "_" + sTable;
602             m_childObj_table_mappings.put(sClassname, sExt);
603         }
604
605         if (profile.isHistorical() == true) {
606             AbstractProfiledObject profObj = profile.getProfiledObject();
607             sDataTable
608                 .append(profObj.getDBTableName())
609                 .append(Profile.EXT_PROFILE)
610                 .append(sExt)
611                 .append(EXT_HIST);
612         } else {
613             sDataTable.append(profile.getDBTableName()).append(sExt);
614         }
615
616         return sDataTable.toString();
617     }
618
619     /**
620      * Returns the name of the property instance data base table
621      * for holding <code>AbstractChildObject</code> value references from
622      * the given table name and the parent profile.
623      *
624      * The table name is determined by the profile database table name
625      * and the given table name.
626      *
627      * The given table name must be the table name associated to a
628      * <code>AbstractChildObject</code> such as <code>Document</code>,
629      * <code>User</code>, etc.
630      *
631      * @param profile the owner <code>Profile</code>
632      * @param sTable the name of the table associated to a
633      * <code>AbstractChildObject</code>
634      * @return the name of the property instance data base table
635      */

636     public static String JavaDoc constructDBTableName(Profile profile, String JavaDoc sTable) {
637         StringBuffer JavaDoc sDataTable = new StringBuffer JavaDoc();
638
639         String JavaDoc sExt = "_" + sTable;
640
641         if (profile.isHistorical() == true) {
642             AbstractProfiledObject profObj = profile.getProfiledObject();
643             sDataTable
644                 .append(profObj.getDBTableName())
645                 .append(Profile.EXT_PROFILE)
646                 .append(sExt)
647                 .append(EXT_HIST);
648         } else {
649             sDataTable.append(profile.getDBTableName()).append(sExt);
650         }
651
652         return sDataTable.toString();
653     }
654
655     /* (non-Javadoc)
656      * @see org.openharmonise.rm.dsi.DataStoreObject#getDBTableName()
657      */

658     public String JavaDoc getDBTableName() {
659         if (m_sDataTable == null) {
660             try {
661
662                 ChildObjectRange range =
663                     (ChildObjectRange) getProperty().getRange();
664
665                 AbstractChildObject child = null;
666
667                 if (m_profile != null) {
668                     child = (AbstractChildObject) m_profile.getProfiledObject();
669                 }
670
671                 String JavaDoc sClassname = range.getChildObjectValueClassName(child);
672                 m_sDataTable = getDBTableName(m_profile, sClassname);
673
674             } catch (DataStoreException e) {
675                 throw new IllegalStateException JavaDoc("Property had inappropriate range object for this property instance");
676             } catch (DataAccessException e) {
677                 throw new IllegalStateException JavaDoc("Property had inappropriate range object for this property instance");
678             }
679         }
680
681         return m_sDataTable;
682     }
683
684     /**
685      * Returns <code>true</code> if the child is a valid value for this
686      * property instance, otherwise <code>false</code>.
687      *
688      * Note: If the child is found not to exist and is an existing value it will
689      * be removed from the database.
690      *
691      * @param child the potential value
692      * @return <code>true</code> if the child is a valid value
693      * @throws InvalidPropertyValueException if the object doesn't exist
694      * or there was an error determining the status of the object
695      */

696     private boolean isValidValue(AbstractChildObject child)
697         throws InvalidPropertyValueException {
698         boolean bIsValid = true;
699
700         if (child.getId() > 0) {
701             try {
702                 if (childExists(child) == true) {
703                     bIsValid = child.isLiveVersion();
704                 } else {
705                     bIsValid = false;
706                 }
707
708             } catch (DataAccessException e) {
709                 throw new InvalidPropertyValueException(
710                     "Couldn't determine status of child object",
711                     e);
712             } catch (DataStoreException e) {
713                 throw new InvalidPropertyValueException(
714                     "Child doesn't exit and had trouble removing it",
715                     e);
716             }
717
718             if (bIsValid == false) {
719                 throw new InvalidPropertyValueException("Child object must be live to add as value");
720             }
721         } else {
722             bIsValid = false;
723         }
724
725         return bIsValid;
726     }
727
728     /* (non-Javadoc)
729      * @see org.openharmonise.rm.metadata.AbstractPropertyInstance#getValue()
730      */

731     public Object JavaDoc getValue() {
732         AbstractChildObject child = null;
733         try {
734             child =
735                 (AbstractChildObject) ((CachePointer) super.getValue())
736                     .getObject();
737         } catch (CacheException e) {
738             m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
739         }
740
741         return child;
742     }
743
744     /* (non-Javadoc)
745      * @see org.openharmonise.rm.metadata.AbstractPropertyInstance#getValue(int)
746      */

747     public Object JavaDoc getValue(int nIndex) {
748         AbstractChildObject child = null;
749         try {
750             CachePointer ptr = (CachePointer) super.getValue(nIndex);
751             child = (AbstractChildObject) ptr.getObject();
752             if (childExists(child) == false) {
753                 child = null;
754             }
755         } catch (CacheException e) {
756             m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
757         } catch (DataStoreException e) {
758             m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
759         }
760
761         return child;
762     }
763
764     /* (non-Javadoc)
765      * @see org.openharmonise.rm.metadata.AbstractPropertyInstance#getValues()
766      */

767     public List getValues() {
768         List result = new ArrayList();
769         List ptrs = super.getValues();
770
771         Iterator iter = ptrs.iterator();
772
773         while (iter.hasNext()) {
774             Object JavaDoc obj = iter.next();
775
776             CachePointer ptr = (CachePointer) obj;
777             try {
778                 AbstractChildObject child =
779                     (AbstractChildObject) ptr.getObject();
780                 //add child if it still exists otherwise get rid of it
781
if (childExists(child) == true) {
782                     result.add(child);
783                 }
784
785             } catch (CacheException e) {
786                 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
787             } catch (DataStoreException e) {
788                 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
789             }
790         }
791
792         return result;
793     }
794
795     /* (non-Javadoc)
796      * @see org.openharmonise.rm.metadata.AbstractPropertyInstance#setValues(java.util.List)
797      */

798     public void setValues(List values) throws InvalidPropertyValueException {
799         List ptrs = new ArrayList();
800
801         Iterator iter = values.iterator();
802
803         try {
804             while (iter.hasNext()) {
805                 Object JavaDoc tmpObj = iter.next();
806                 if (tmpObj instanceof AbstractChildObject) {
807                     AbstractChildObject child = (AbstractChildObject) tmpObj;
808                     ptrs.add(
809                         CacheHandler.getInstance(m_dsi).getCachePointer(child));
810                 } else if (tmpObj instanceof CachePointer) {
811                     ptrs.add(tmpObj);
812                 }
813
814             }
815         } catch (CacheException e) {
816             m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
817             throw new InvalidPropertyValueException(e);
818         }
819
820         super.setValues(ptrs);
821     }
822
823     /**
824      * Returns <code>true</code> if child exists, otherwise, if we're in the
825      * process of populating the object, then remove the reference from
826      * the database.
827      *
828      * @param child the child object
829      * @return <code>true</code> if child exists
830      * @throws DataStoreException if there is an error removing the child
831      * from the database
832      */

833     private boolean childExists(AbstractChildObject child)
834         throws DataStoreException {
835         boolean bExists = child.exists();
836
837         if (bExists == false && isPopulated() == false) {
838             removeChildReferences(child);
839         }
840
841         return bExists;
842     }
843
844     /**
845      * Removes the reference to child from the property instance database
846      * table, used to discard invalid references.
847      *
848      * @param child the child whose reference is to be removed
849      * @throws DataStoreException if there is an error deleting data from
850      * the database
851      */

852     protected void removeChildReferences(AbstractChildObject child)
853         throws DataStoreException {
854         int nIndex = -1;
855         int i = 0;
856
857         Iterator iter = m_values.iterator();
858         boolean bFound = false;
859         while (iter.hasNext() && bFound == false) {
860             CachePointer ptr = (CachePointer) iter.next();
861
862             if (ptr.getKey().equals(String.valueOf(child.getId()))) {
863                 nIndex = i;
864                 bFound = true;
865             }
866
867             i++;
868         }
869
870         if (bFound == true && m_valueIds.size() > nIndex) {
871             DeleteStatement delete = new DeleteStatement();
872
873             delete.addWhereCondition(getColumnForData(), "=", child.getId());
874
875             delete.addWhereCondition(
876                 getInstanceColumnRef(CLMN_ID, isHistorical()),
877                 "=",
878                 ((Integer JavaDoc) m_valueIds.get(nIndex)).intValue());
879
880             m_dsi.execute(delete);
881
882             if (m_values.size() > nIndex) {
883                 m_values.remove(nIndex);
884             }
885             if (m_valueIds.size() > nIndex) {
886                 m_valueIds.remove(nIndex);
887             }
888         }
889
890     }
891     
892     /**
893      * Creates table for property instances associated to the specified
894      * profile table and with the given table name.
895      *
896      * @param dsi the data store interface
897      * @param sProfileTable the profile table name
898      * @param sTableName the new table name
899      * @throws DataStoreException if an error occurs creating the table
900      */

901     public static void generateTable(AbstractDataStoreInterface dsi,String JavaDoc sProfileTable, String JavaDoc sTableName) throws DataStoreException {
902         
903         TableDefinition tblDef = new TableDefinition(sTableName);
904         
905         tblDef.addColumn(CLMN_ID,true,ColumnDefinition.NUMBER);
906         ColumnDefinition profRef = new ColumnDefinition(CLMN_PROFILE_ID,ColumnDefinition.NUMBER);
907         profRef.addForeignKey(sProfileTable);
908         tblDef.addColumn(profRef);
909         tblDef.addColumn(CLMN_PROPERTY_ID,ColumnDefinition.NUMBER);
910         tblDef.addColumn(CLMN_OBJECT_ID,ColumnDefinition.NUMBER);
911         tblDef.addColumn(CLMN_VERSION_COMMENT,ColumnDefinition.TEXT,true);
912         
913         dsi.createTable(tblDef);
914     }
915
916     /**
917      * Returns the name of the property instance table for objects of
918      * type <i>domainClass</i> which have relationships to objects
919      * of type <i>valueClass</i>.
920      *
921      * @param domainClass the class name of the profile object
922      * @param valueClass the class name of the objects which will be values of the property instance
923      * @param bIsHist <code>true</code> if the table is historical
924      * @return the name of the property instance table
925      * @throws DataAccessException if an error occurs constructing the
926      * table name
927      */

928     public static String JavaDoc getDBTableName(String JavaDoc domainClass, String JavaDoc valueClass, boolean bIsHist) throws DataAccessException {
929         StringBuffer JavaDoc str = new StringBuffer JavaDoc();
930         try {
931             DatabaseInfo dbinf = DatabaseInfo.getInstance();
932             str.append(dbinf.getTableName(domainClass));
933             str.append(Profile.EXT_PROFILE);
934             str.append("_");
935             str.append(dbinf.getTableName(valueClass));
936             
937             if(bIsHist == true) {
938                 str.append(Profile.EXT_HIST);
939             }
940         } catch (DataStoreException e) {
941             throw new DataAccessException(e);
942         }
943         
944         return str.toString();
945     }
946
947     /**
948      * Creates the table required to hold property instances for the profiled
949      * object of type <i>domainClass</i> and with values of type
950      * <i>valueClass</i>
951      *
952      * @param m_dsi the data store interface
953      * @param domainClass the class name of the profiled object
954      * @param valueClass the class name of the values of the property instance
955      * @param bIsHist <code>true</code> if the table is historical
956      * @throws DataStoreException if there is an error creating the new
957      * database table
958      * @throws DataAccessException if there is an error constructing
959      * the details of the new table
960      */

961     public static void createTable(AbstractDataStoreInterface dsi, String JavaDoc domainClass, String JavaDoc valueClass, boolean bIsHist) throws DataAccessException, DataStoreException {
962         generateTable(dsi,Profile.getTableName(domainClass, bIsHist), getDBTableName(domainClass, valueClass, bIsHist));
963     }
964     
965 }
966
Popular Tags