KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openharmonise > rm > resources > AbstractProfiledObject


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.resources;
20
21 import java.sql.*;
22 import java.util.*;
23 import java.util.logging.*;
24
25 import org.openharmonise.commons.dsi.*;
26 import org.openharmonise.commons.dsi.dml.SelectStatement;
27 import org.openharmonise.rm.*;
28 import org.openharmonise.rm.dsi.DataStoreObject;
29 import org.openharmonise.rm.factory.HarmoniseObjectFactory;
30 import org.openharmonise.rm.metadata.*;
31 import org.openharmonise.rm.publishing.*;
32 import org.openharmonise.rm.resources.lifecycle.*;
33 import org.openharmonise.rm.resources.metadata.properties.Property;
34 import org.w3c.dom.*;
35
36
37 /**
38  * Abstract class which adds metadata functionality to the
39  * <code>AbstractEditableObject</code> class.
40  *
41  * @author Michael Bell
42  * @version $Revision: 1.4 $
43  *
44  */

45 public abstract class AbstractProfiledObject
46     extends AbstractEditableObject
47     implements Editable, Publishable, DataStoreObject, Cloneable JavaDoc {
48     private static final String JavaDoc CONST_TRUE = "true";
49     /**
50      * Flag which determines whether profile restrictions should be ignored
51      * during a change of status
52      */

53     private boolean m_bIgnoreProfileRestrictions = false;
54     /**
55      * The default profile name
56      */

57     public static final String JavaDoc DEFAULT_PROFILE_NAME = "default";
58     /**
59      * <code>Map</code> of all profiles this profiled object has. The profiles are
60      * keyed by their name field
61      */

62     protected Map m_profiles = null;
63     /**
64      * The <code>Map</code> key of the default profile
65      */

66     protected String JavaDoc m_sDefaultKey = null;
67     /**
68      * List of profiles to be removed during the next <code>save()</code> operation
69      */

70     protected List m_profiles2Remove = null;
71     
72     /**
73      * Logger for this class
74      */

75     private static final Logger m_logger = Logger.getLogger(AbstractProfiledObject.class.getName());
76     
77     //initialiser block
78
{
79         m_profiles = Collections.synchronizedMap(new HashMap());
80         m_profiles2Remove = new Vector();
81     }
82
83     /**
84      * Constructs a new or anonymous resource without an interface
85      * to the database
86      */

87     public AbstractProfiledObject() {
88         super();
89     }
90
91     /** Constructor for a new or anonymous resource.
92      *
93      * @param dbintrf the data store interface
94      */

95     public AbstractProfiledObject(AbstractDataStoreInterface dbintrf) {
96         super(dbintrf);
97
98     }
99
100     /**
101       * Standard constructor for an existing resource,
102       * registering an <code>AbstractDataStoreInterface</code> to use
103       * with all database communications.
104       *
105       * @param dbintrf the interface to the database
106       * @param nId the id of the resource
107      */

108     public AbstractProfiledObject(
109         AbstractDataStoreInterface dbintrf,
110         int nId) {
111         super(dbintrf, nId);
112
113     }
114
115     /**
116      * Standard constructor for an existing resource which may be historical.
117      *
118      * @param dbintrf the interface to the database
119      * @param nId the id of the resource
120      * @param nKey the unique key of the resource
121      * @param bIsHist <code>true</code> if the resource is historical
122      */

123     public AbstractProfiledObject(
124         AbstractDataStoreInterface dbintrf,
125         int nId,
126         int nKey,
127         boolean bIsHist) {
128         super(dbintrf, nId, nKey, bIsHist);
129
130     }
131
132     /**
133      * Returns a list of this resource's <code>Profile</code>s.
134      *
135      * @return a list of this resource's <code>Profile</code>s
136      * @throws DataAccessException if an error occurs populating this resource
137      */

138     public List getProfiles() throws DataAccessException {
139         if (m_bIsPopulated == false) {
140             try {
141                 populateFromDatabase();
142             } catch (PopulateException e) {
143                 throw new DataAccessException(e.getLocalizedMessage());
144             }
145         }
146
147         return new Vector((Collection) m_profiles.values());
148     }
149
150     /**
151      * Returns a <code>Map</code> of profiles.
152      *
153      * @return <code>Map</code> of profiles, keyed by their profile names
154      * @throws DataAccessException if an error occurs populating this object
155      */

156     public Map getProfilesMap() throws DataAccessException {
157         if (m_bIsPopulated == false) {
158             try {
159                 populateFromDatabase();
160             } catch (PopulateException e) {
161                 throw new DataAccessException(e.getLocalizedMessage());
162             }
163         }
164
165         return new Hashtable(m_profiles);
166     }
167
168     /* (non-Javadoc)
169      * @see org.openharmonise.rm.resources.AbstractObject#isChanged()
170      */

171     public boolean isChanged() throws DataAccessException {
172         boolean bReturn = super.isChanged();
173
174         if (bReturn == false) {
175             Iterator iter = m_profiles.values().iterator();
176
177             Profile nextProf;
178
179             while (iter.hasNext() && bReturn == false) {
180                 nextProf = (Profile) iter.next();
181
182                 if (nextProf.isChanged()
183                     || (nextProf.getId() == NOTDBSAVED_ID)) {
184                     bReturn = true;
185                     setIsChanged(bReturn);
186                 }
187             }
188         }
189
190         return bReturn;
191     }
192
193     /**
194      * Set the profiles of this object.
195      *
196      * @param profiles the list profiles
197      *
198      * @throws InvalidProfileException if an invalid profile is found in the list,
199      * for example if a profile does not have a valid name
200      */

201     protected void setProfiles(List profiles) throws InvalidProfileException {
202         if (m_bIsPopulated) {
203             m_bIsChanged = true;
204         }
205
206         Iterator iter = profiles.iterator();
207
208         m_profiles.clear();
209
210         while (iter.hasNext()) {
211             Profile tmpProf = (Profile) iter.next();
212             String JavaDoc sName = null;
213
214             try {
215
216                 sName = tmpProf.getName();
217
218             } catch (DataAccessException da_e) {
219                 throw new InvalidProfileException(
220                     "Couldn't access profile name",da_e);
221             }
222
223             m_profiles.put(sName, tmpProf);
224         }
225     }
226
227     /**
228      * Sets the profiles of this object.
229      *
230      * @param profiles a <code>Map</code> of profiles
231      */

232     protected void setProfiles(Map profiles) {
233         if (m_bIsPopulated) {
234             m_bIsChanged = true;
235         }
236
237         m_profiles.clear();
238
239         Iterator iter = profiles.keySet().iterator();
240
241         while (iter.hasNext()) {
242             Object JavaDoc key = iter.next();
243
244             m_profiles.put(key, profiles.get(key));
245         }
246     }
247
248     /**
249      * Returns the default <code>Profile</code> for this object.
250      *
251      * @return the default <code>Profile</code> for this object
252      *
253      * @throws DataAccessException if an error occurs populating this object
254      */

255     public Profile getProfile() throws DataAccessException {
256         Profile profileReturn = null;
257
258         if ((m_profiles != null) && (m_sDefaultKey != null)) {
259             profileReturn = (Profile) m_profiles.get(m_sDefaultKey);
260         } else if (
261             (m_bIsPopulated == false)
262                 && (m_nId != AbstractObject.NOTDBSAVED_ID)
263                 && (m_profiles == null || m_profiles.size() == 0)) {
264
265             try {
266                 populateFromDatabase();
267             } catch (PopulateException e) {
268                 throw new DataAccessException(
269                     "Problem occured populating profile",e);
270             }
271             profileReturn = getProfile();
272         } else if ((m_profiles != null) && (m_profiles.size() > 0)) {
273             Iterator iter = m_profiles.values().iterator();
274
275             profileReturn = (Profile) iter.next();
276         }
277
278         return profileReturn;
279     }
280     
281     /**
282      * Returns the property instance of the given name from the default
283      * profile.
284      *
285      * @param sPropName the name of the property
286      * @return the property instance corresponding to the property name
287      * @throws InvalidPropertyInstanceException if the property is invalid
288      * for this object
289      * @throws DataAccessException if there is an error populating this
290      * object
291      */

292     public AbstractPropertyInstance getPropertyInstance(String JavaDoc sPropName) throws InvalidPropertyInstanceException, DataAccessException {
293         AbstractPropertyInstance propInst = null;
294         List profs = getProfiles();
295         
296         Iterator iter = profs.iterator();
297         
298         while (iter.hasNext() && propInst == null) {
299             Profile prof = (Profile) iter.next();
300             
301             propInst = prof.getPropertyInstance(sPropName);
302         }
303         
304         return propInst;
305     }
306     
307
308     /**
309      * Returns the <code>AbstractPropertyInstance</code> associated
310      * with the specified <code>Property</code> from a <code>Profile</code>
311      * of this object.
312      *
313      * @param prop
314      * @return
315      * @throws InvalidPropertyInstanceException
316      * @throws DataAccessException
317      */

318     public AbstractPropertyInstance getPropertyInstance(Property prop) throws InvalidPropertyInstanceException, DataAccessException {
319         AbstractPropertyInstance propInst = null;
320         List profs = getProfiles();
321         
322         Iterator iter = profs.iterator();
323         
324         while (iter.hasNext() && propInst == null) {
325             Profile prof = (Profile) iter.next();
326             
327             propInst = prof.getPropertyInstance(prop);
328         }
329         
330         return propInst;
331     }
332
333     /** Sets the default <code>Profile</code>.
334      *
335      * @param profile the default <code>Profile</code>
336      *
337      * @throws InvalidProfileException if the profile name is invalid
338      */

339     public void setProfile(Profile profile) throws InvalidProfileException {
340         String JavaDoc sNewKey = null;
341
342         profile.setProfiledObject(this);
343
344         try {
345             sNewKey = profile.getName();
346         } catch (DataAccessException e) {
347             throw new InvalidProfileException(
348                 "Error occured get name of profile",e);
349         }
350         
351         if(sNewKey == null || sNewKey.length() == 0) {
352             sNewKey = DEFAULT_PROFILE_NAME;
353             try {
354                 profile.setName(sNewKey);
355             } catch (InvalidNameException e) {
356                 throw new InvalidProfileException(e);
357             }
358         }
359
360         if ((m_sDefaultKey != null)
361             && (m_sDefaultKey.equals(sNewKey) == false)) {
362             Profile oldDefProf = (Profile) m_profiles.get(m_sDefaultKey);
363             oldDefProf.setIsDefault(false);
364
365             if (m_bIsPopulated) {
366                 oldDefProf.setIsChanged(true);
367             }
368         }
369
370         if (sNewKey.equals(m_sDefaultKey) == false) {
371             m_sDefaultKey = sNewKey;
372             profile.setIsDefault(true);
373             m_profiles.put(m_sDefaultKey, profile);
374
375             if (m_bIsPopulated) {
376                 profile.setIsChanged(true);
377             }
378         } else {
379             m_sDefaultKey = sNewKey;
380             profile.setIsDefault(true);
381             m_profiles.put(m_sDefaultKey, profile);
382
383             if (m_bIsPopulated) {
384                 profile.setIsChanged(true);
385             }
386         }
387     }
388
389     /**
390      * Returns the <code>Profile</code> of this object
391      * with the specified name.
392      *
393      * @param sName the name of the profile
394      * @return the profile with the specified name
395      * @throws DataAccessException if an error occurs populating this object
396      */

397     public Profile getProfile(String JavaDoc sName) throws DataAccessException {
398         Profile profileReturn = null;
399
400         if (m_profiles != null) {
401             profileReturn = (Profile) m_profiles.get(sName);
402         }
403
404         if ((m_bIsPopulated == false) && (profileReturn == null)) {
405             try {
406                 populateFromDatabase();
407             } catch (PopulateException e) {
408                 throw new DataAccessException(
409                     "Error occured populating profiles",e);
410             }
411             profileReturn = getProfile(sName);
412         }
413
414         return profileReturn;
415     }
416
417     /**
418      * Returns the number of profiles.
419      *
420      * @return the number of profiles
421      *
422      * @throws DataAccessException if an error occurs populating this object
423      */

424     public int getNumProfiles() throws DataAccessException {
425         if (m_bIsPopulated == false) {
426             try {
427                 populateFromDatabase();
428             } catch (PopulateException e) {
429                 throw new DataAccessException(e.getLocalizedMessage());
430             }
431         }
432
433         if (m_profiles != null) {
434             return m_profiles.size();
435         } else {
436             return 0;
437         }
438     }
439
440     /**
441      * Add the given <code>Profile</code> to this object.
442      *
443      * @param profile the new <code>Profile</code> to add.
444      *
445      * @throws InvalidProfileException if the given profile is invalid,
446      * for example if the profile has an invalid name
447      */

448     public void addProfile(Profile profile) throws InvalidProfileException {
449         try {
450
451             String JavaDoc sProfName = profile.getName();
452
453             if (m_profiles.containsKey(sProfName) == true) {
454                 throw new InvalidProfileException("Can't have 2 profiles of the same name");
455             }
456
457             // set the profiled object to be the
458
// current object
459
profile.setProfiledObject(this);
460
461             //if profiles empty set profile as default
462
if ((m_profiles.size() == 0) || (profile.isDefault() == true)) {
463                 setProfile(profile);
464             } else {
465                 m_profiles.put(sProfName, profile);
466             }
467         } catch (InvalidProfileException ip_e) {
468             throw ip_e;
469         } catch (DataAccessException da_e) {
470             throw new InvalidProfileException(
471                 "Error occured getting data from new profile:",da_e);
472         }
473     }
474
475     /**
476      * Removes the specified <code>Profile</code> from this object.
477      *
478      * @param sProfile the <code>Profile</code> to remove
479      *
480      * @throws DataAccessException if there was an error populating this
481      * object
482      */

483     public void removeProfile(String JavaDoc sProfile) throws DataAccessException {
484         if (m_bIsPopulated == false) {
485             try {
486                 populateFromDatabase();
487             } catch (PopulateException e) {
488                 throw new DataAccessException(e.getLocalizedMessage());
489             }
490         }
491
492         Object JavaDoc prof = m_profiles.remove(sProfile); // get the profile
493

494         if (prof != null) {
495             m_profiles2Remove.add(prof);
496             setIsChanged(true); // the object was changed
497
}
498     }
499
500     /**
501      * Sets the <code>Profile</code> with the specified name
502      * as the default.
503      *
504      * @param sProfile the name of the <code>Profile</code> to be the default
505      *
506      * @throws InvalidProfileException if the named <code>Profile</code> does
507      * not exist
508      * @throws DataAccessException if there is an error populating this object
509      */

510     protected void setDefaultProfile(String JavaDoc sName)
511         throws InvalidProfileException, DataAccessException {
512
513         if (m_bIsPopulated == false) {
514             try {
515                 populateFromDatabase();
516             } catch (PopulateException e) {
517                 throw new DataAccessException(e.getLocalizedMessage());
518             }
519         }
520
521         if (m_profiles.containsKey(sName)) {
522             m_sDefaultKey = sName;
523         } else {
524             throw new InvalidProfileException("Profile does not exist");
525         }
526     }
527
528     /* (non-Javadoc)
529      * @see org.openharmonise.rm.resources.AbstractEditableObject#delete(boolean)
530      */

531     protected void delete(boolean bDeleteHistory)
532         throws
533             DataStoreException,
534             DataAccessException,
535             EditException,
536             PopulateException {
537
538         if (isPopulated() == false) {
539             populateFromDatabase();
540         }
541
542         Iterator iter = m_profiles.keySet().iterator();
543
544         while (iter.hasNext()) {
545             String JavaDoc proName = (String JavaDoc) iter.next();
546             Profile pro = (Profile) m_profiles.get(proName);
547             try {
548                 pro.delete();
549             } catch (ProfileException e) {
550                 throw new EditException(
551                     "Error occured deleting profile",e);
552             }
553         }
554
555         m_profiles.clear();
556
557         super.delete(bDeleteHistory);
558     }
559
560     /* (non-Javadoc)
561      * @see org.openharmonise.rm.publishing.Publishable#populate(org.w3c.dom.Element, org.openharmonise.rm.publishing.State)
562      */

563     public void populate(Element xmlElement, State state)
564         throws PopulateException {
565         String JavaDoc sTagName = xmlElement.getTagName();
566         Text txt = null;
567         Profile pro = null;
568
569         if (sTagName.equals(Profile.TAG_PROFILE)) {
570             try {
571
572                 String JavaDoc sProName = xmlElement.getAttribute(Profile.ATTRIB_NAME);
573
574                 if ((sProName != null) && (sProName.equals("") == false)) {
575                     pro = getProfile(sProName);
576                 } else {
577                     pro = getProfile();
578                 }
579
580                 boolean bIsNewProfile = false;
581
582                 if (pro == null) {
583                     bIsNewProfile = true;
584                     pro = new Profile(m_dsi,this);
585                 }
586
587                 pro.populate(xmlElement, state);
588
589                 if (xmlElement
590                     .getAttribute(Profile.ATTRIB_DEFAULT)
591                     .equals(Profile.IS_DEFAULT_PROFILE_VALUE)) {
592                     setProfile(pro);
593                 } else if (bIsNewProfile == true) {
594                     addProfile(pro);
595                 }
596             } catch (DataAccessException da_e) {
597                 throw new PopulateException(
598                     "Error occured accessing data",da_e);
599             } catch (InvalidProfileException e) {
600                 throw new PopulateException(
601                     "Populating profile" ,e);
602             }
603         } else {
604             super.populate(xmlElement, state);
605         }
606     }
607
608     /* (non-Javadoc)
609      * @see org.openharmonise.rm.publishing.Publishable#publish(org.w3c.dom.Element, org.openharmonise.rm.publishing.HarmoniseOutput, org.openharmonise.rm.publishing.State)
610      */

611     public Element publish(Element topEl, HarmoniseOutput xmlDoc, State state)
612         throws PublishException {
613         String JavaDoc sTagName = topEl.getTagName();
614         Element docEl = null;
615         Text txt = null;
616
617         // deal with tags that will be needed by all objects
618
if (sTagName.equals(Profile.TAG_PROFILE)) {
619             try {
620                 Profile pro = null;
621
622                 if (topEl
623                     .getAttribute(Profile.ATTRIB_DEFAULT)
624                     .equals(CONST_TRUE)) {
625                     //get default profile
626
pro = getProfile();
627
628                 } else {
629                     String JavaDoc sProName = topEl.getAttribute(Profile.ATTRIB_NAME);
630
631                     if ((sProName != null) && (sProName.equals("") == false)) {
632
633                         pro = getProfile(sProName);
634                     }
635                 }
636
637                 if (pro != null) {
638                     docEl = pro.publish(topEl, xmlDoc, state);
639
640                 } else {
641                     pro = new Profile(m_dsi, this);
642                     docEl = pro.publish(topEl, xmlDoc, state);
643                 }
644             } catch (DataAccessException da_e) {
645                 throw new PublishException(
646                     "Error occured accessing profile",da_e);
647             }
648         } else {
649             // if we get here then nothing processes this tag, so pass it up
650
docEl = super.publish(topEl, xmlDoc, state);
651         }
652
653         return docEl;
654     }
655
656     /**
657      * Returns <code>true</code> if the specified profile is this object's
658      * default profile.
659      *
660      * @param prof the profile to test default status on
661      * @return <code>true</code> if the specified profile is the default
662      */

663     public boolean isDefaultProfile(Profile prof) {
664         ColumnRef returnColRef = null;
665
666         Profile defaultProf = (Profile) m_profiles.get(m_sDefaultKey);
667
668         return defaultProf.equals(prof);
669     }
670
671     /* (non-Javadoc)
672      * @see org.openharmonise.rm.dsi.DataStoreObject#processResultSet(org.openharmonise.commons.dsi.CachedResultSet, org.openharmonise.commons.dsi.dml.SelectStatement)
673      */

674     public List processResultSet(
675         CachedResultSet rs,
676         SelectStatement select) {
677         return processResultSet(rs, select, -1);
678     }
679
680     /* (non-Javadoc)
681      * @see org.openharmonise.rm.dsi.DataStoreObject#processResultSet(org.openharmonise.commons.dsi.CachedResultSet, org.openharmonise.commons.dsi.dml.SelectStatement, int)
682      */

683     public List processResultSet(
684         CachedResultSet rs,
685         SelectStatement select,
686         int nLimit) {
687
688         Vector rObjs = new Vector(16);
689
690         int nResultCount = 0;
691
692         try {
693             int nId = -1;
694             Vector vIds = new Vector(16);
695             AbstractProfiledObject pobj = null;
696             String JavaDoc sIdColName = null;
697
698             while (rs.next()) {
699                 if ((nLimit < 0 || nResultCount < nLimit)) {
700                     try {
701                         sIdColName =
702                             this
703                                 .getInstanceColumnRef(
704                                     AbstractObject.ATTRIB_ID,
705                                     false)
706                                 .getColumn();
707                         nId = rs.getInt(sIdColName);
708
709                         if (vIds.contains(new Integer JavaDoc(nId)) == false) {
710                             pobj =
711                                 (
712                                     AbstractProfiledObject) HarmoniseObjectFactory
713                                         .instantiatePublishableObject(
714                                     this.m_dsi,
715                                     this.getClass().getName(),
716                                     nId);
717                         }
718
719                         if (rs.hasCurrentRowBeenRead() == false) {
720                             
721
722                             pobj.populateFromResultSetRow(rs, select);
723
724                             rs.markCurrentRowAsRead();
725                             rs.clearRow(sIdColName);
726                         }
727
728                         if (vIds.contains(new Integer JavaDoc(nId)) == false) {
729                             rObjs.add(pobj);
730                             vIds.add(new Integer JavaDoc(nId));
731                         }
732                     } catch (Exception JavaDoc e) {
733                         m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
734                     }
735                 } else {
736                     break;
737                 }
738
739                 nResultCount++;
740             }
741         } catch (Exception JavaDoc e) {
742             m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
743         }
744
745         return rObjs;
746     }
747
748     /* (non-Javadoc)
749      * @see java.lang.Object#clone()
750      */

751     public Object JavaDoc clone() {
752         // Note: if exception is thrown it is gonna cause problems with
753
//saving, etc so I've elected to throw a RuntimeException
754
AbstractProfiledObject other = null;
755
756         try {
757
758             if (!m_bIsPopulated) {
759                 populateFromDatabase();
760             }
761
762             Profile nextProfile = null;
763             other = (AbstractProfiledObject) super.clone();
764
765             //create deep copy clone of Profiles Hashtable
766
Hashtable hshProfs = new Hashtable();
767             Iterator iter = m_profiles.values().iterator();
768             int nP = 0;
769
770             while (iter.hasNext()) {
771                 nextProfile = (Profile) iter.next();
772
773                 Profile profClone = (Profile) nextProfile.clone();
774                 profClone.setProfiledObject(other);
775                 hshProfs.put(profClone.getName(), profClone);
776             }
777
778             other.m_profiles = new Hashtable(hshProfs);
779
780             //if there's a default profile set it
781
if (m_profiles.size() > 0) {
782                 
783                 Profile oProf = getProfile();
784                 String JavaDoc sName = oProf.getName();
785                 other.setDefaultProfile(sName);
786             }
787
788         } catch (DataAccessException da_e) {
789             throw new IllegalStateException JavaDoc(
790                 "Problem occured during clone" + da_e.getLocalizedMessage());
791         } catch (PopulateException pop_e) {
792             throw new IllegalStateException JavaDoc(
793                 "Problem occured during clone" + pop_e.getLocalizedMessage());
794         } catch (InvalidProfileException ip_e) {
795             throw new IllegalStateException JavaDoc(
796                 "Problem occured during clone" + ip_e.getLocalizedMessage());
797         }
798
799         return other;
800     }
801
802     /* (non-Javadoc)
803      * @see org.openharmonise.rm.resources.AbstractObject#markAsNew()
804      */

805     public void markAsNew() throws PopulateException {
806         super.markAsNew();
807
808         Profile nextProfile = null;
809         Iterator iter = null;
810
811         try {
812             iter = getProfiles().iterator();
813         } catch (DataAccessException e) {
814             throw new PopulateException(e.getLocalizedMessage());
815         }
816
817         while (iter.hasNext()) {
818             nextProfile = (Profile) iter.next();
819
820             nextProfile.markAsNew();
821             
822         }
823     }
824
825     /* (non-Javadoc)
826      * @see org.openharmonise.rm.resources.AbstractObject#clear()
827      */

828     public void clear() {
829         super.clear();
830         m_profiles.clear();
831         m_sDefaultKey = null;
832     }
833
834     /*----------------------------------------------------------------------
835     Protected Functions
836     -----------------------------------------------------------------------*/

837
838     /* (non-Javadoc)
839      * @see org.openharmonise.rm.resources.AbstractObject#populateFromResultSetRow(java.sql.ResultSet, org.openharmonise.commons.dsi.dml.SelectStatement)
840      */

841     protected void populateFromResultSetRow(
842         ResultSet rs,
843         SelectStatement select)
844         throws PopulateException {
845         if (isPopulated() == false) {
846             super.populateFromResultSetRow(rs, select);
847             try {
848                 String JavaDoc sTemp = null;
849                 int nTemp = -1;
850                 java.sql.Date JavaDoc dTemp = null;
851                 ColumnRef colref = null;
852
853                 colref = Profile.getColumnRef(this, TAG_NAME);
854
855                 if (select.containsSelectColumn(colref) == true) {
856
857                     String JavaDoc sProfileName =
858                         rs.getString(select.getResultSetIndex(colref));
859
860                     if ((sProfileName != null)
861                         && (sProfileName.length() > 0)) {
862                         Profile prof2pop = null;
863
864                         if (m_profiles.containsKey(sProfileName) == true) {
865                             prof2pop = (Profile) m_profiles.get(sProfileName);
866                         } else {
867                             colref = Profile.getColumnRef(this, ATTRIB_ID);
868                             
869                             
870
871                             int nProfId = -1;
872
873                             if (select.containsSelectColumn(colref) == true) {
874                                 nProfId =
875                                     rs.getInt(select.getResultSetIndex(colref));
876                             }
877                             
878                             String JavaDoc sProfileClass = Profile.class.getName();
879                             colref = Profile.getColumnRef(this, ATTRIB_TYPE);
880                             
881                             if (select.containsSelectColumn(colref) == true) {
882                                 sTemp =
883                                     rs.getString(select.getResultSetIndex(colref));
884                                     
885                                 if(sTemp != null && sTemp.length() > 0) {
886                                     sProfileClass = sTemp;
887                                 }
888                             }
889                             
890                             //get profile instance
891
prof2pop = (Profile) Class.forName(sProfileClass).newInstance();
892                             
893                             //populate profile
894
prof2pop.setProfiledObject(this);
895                             prof2pop.setDataStoreInterface(m_dsi);
896                             prof2pop.setName(sProfileName);
897                             if(isHistorical() == true) {
898                                 prof2pop.setHistorical(true);
899                             }
900                             if (nProfId > 0) {
901                                 prof2pop.setId(nProfId);
902                             }
903
904                             addProfile(prof2pop);
905
906                         }
907
908                         
909                         AbstractObject ao = (AbstractObject) prof2pop;
910                         ao.populateFromResultSetRow(rs, select);
911                     }
912
913                     
914                 }
915
916             } catch (DataStoreException ds_e) {
917                 throw new PopulateException(
918                     "Error occured accessing data",ds_e);
919             } catch (InvalidProfileException da_e) {
920                 throw new PopulateException(
921                     "Error occured adding profile",da_e);
922             } catch (SQLException sql_e) {
923                 throw new PopulateException(
924                     "Error occured adding profile",sql_e);
925             } catch (InstantiationException JavaDoc e) {
926                 throw new PopulateException(
927                     "Error occured creating new profile",e);
928             } catch (IllegalAccessException JavaDoc e) {
929                 throw new PopulateException(
930                     "Error occured creating new profile",e);
931             } catch (ClassNotFoundException JavaDoc e) {
932                 throw new PopulateException(
933                     "Error occured creating new profile",e);
934             } catch (InvalidNameException e) {
935                 throw new PopulateException(e);
936             }
937         }
938     }
939
940     /* (non-Javadoc)
941      * @see org.openharmonise.rm.resources.AbstractEditableObject#saveCoreData()
942      */

943     protected void saveCoreData() throws EditException {
944         try {
945             if (isChanged() == true) {
946
947                 Profile nextProfile = null;
948                 int nNextId = 0;
949                 Iterator iter = m_profiles.values().iterator();
950                 List profiles = new ArrayList();
951
952                 while (iter.hasNext()) {
953                     profiles.add((Profile) iter.next());
954                 }
955
956                 iter = profiles.iterator();
957
958                 while (iter.hasNext()) {
959                     nextProfile = (Profile) iter.next();
960                     nNextId = nextProfile.getId();
961                     nextProfile = nextProfile.save(this);
962
963                     //test to see if profile has changed
964
if (nextProfile.getId() != nNextId) {
965                         // set the new profile at this position
966
m_profiles.put(nextProfile.getName(), nextProfile);
967                     }
968                 }
969
970             }
971         } catch (DataAccessException da_e) {
972             throw new EditException("Error accessing profile's data:", da_e);
973         } catch (ProfileException prof_e) {
974             throw new EditException("Error saving core data:", prof_e);
975         }
976     }
977
978     /* (non-Javadoc)
979      * @see org.openharmonise.rm.resources.AbstractEditableObject#update()
980      */

981     protected void update() throws DataStoreException, EditException {
982         super.update();
983
984         Profile prof2Remove = null;
985
986         // delete the profiles waiting to be deleted
987
try {
988             for (Iterator profiles = m_profiles2Remove.iterator();
989                 profiles.hasNext();
990                 ) {
991                 // get the next profile
992
prof2Remove = (Profile) profiles.next();
993                 
994                 prof2Remove.delete(); // delete the profile
995
}
996         } catch (ProfileException pe) {
997             throw new EditException(pe.getLocalizedMessage());
998         }
999
1000        Profile nextProfile = null;
1001        Iterator iter = m_profiles.values().iterator();
1002
1003        while (iter.hasNext()) {
1004            nextProfile = (Profile) iter.next();
1005
1006            try {
1007
1008                if (nextProfile.isNew() == true) {
1009                    nextProfile.save(this);
1010                } else {
1011                    nextProfile.update();
1012                }
1013            } catch (PopulateException pop_e) {
1014                throw new DataStoreException(pop_e.getLocalizedMessage(),pop_e);
1015            } catch (ProfileException prof_e) {
1016                throw new DataStoreException(prof_e.getLocalizedMessage(),prof_e);
1017            }
1018        }
1019
1020        // clear the profiles to be removed
1021
m_profiles2Remove.clear();
1022    }
1023
1024    /* (non-Javadoc)
1025     * @see org.openharmonise.rm.resources.AbstractObject#fullPopulate()
1026     */

1027    protected void fullPopulate() throws PopulateException {
1028        super.fullPopulate();
1029        fillProfiles();
1030    }
1031
1032    /**
1033     * Fully populates all profiles.
1034     *
1035     * @throws PopulateException if there is an error populating a profile
1036     */

1037    protected void fillProfiles() throws PopulateException {
1038        Profile nextProfile = null;
1039        int nNextId = 0;
1040        Iterator iter = m_profiles.values().iterator();
1041
1042        while (iter.hasNext()) {
1043            nextProfile = (Profile) iter.next();
1044            try {
1045                nextProfile.fillProfileData();
1046            } catch (ProfileException prof_e) {
1047                throw new PopulateException(prof_e);
1048            }
1049
1050        }
1051    }
1052
1053    /**
1054     * Sets whether all profiles are historical.
1055     *
1056     * @param bIsHistorical <code>true</code> of all profiles are to be historical
1057     */

1058    protected void setProfilesHistorical(boolean bIsHistorical) {
1059        Profile nextProfile = null;
1060        int nNextId = 0;
1061        Iterator iter = m_profiles.values().iterator();
1062
1063        while (iter.hasNext()) {
1064            nextProfile = (Profile) iter.next();
1065            nextProfile.setHistorical(bIsHistorical);
1066        }
1067    }
1068
1069    /**
1070     * Returns <code>true</code> if object contains a profile of the
1071     * specified name.
1072     *
1073     * @param sName the name of a profile
1074     * @return <code>true</code> if object contains a profile of the
1075     * specified name
1076     */

1077    protected boolean isProfileLoaded(String JavaDoc sName) {
1078        return (
1079            (m_profiles != null)
1080                && (m_profiles.size() > 0)
1081                && m_profiles.get(sName) != null);
1082    }
1083
1084    /* (non-Javadoc)
1085     * @see org.openharmonise.rm.resources.AbstractObject#addColumnsToPopulateQuery(org.openharmonise.commons.dsi.dml.SelectStatement, boolean)
1086     */

1087    protected void addColumnsToPopulateQuery(
1088        SelectStatement select,
1089        boolean bIsHist)
1090        throws DataStoreException {
1091        super.addColumnsToPopulateQuery(select, bIsHist);
1092
1093        select.addSelectColumn(Profile.getColumnRef(this, TAG_NAME));
1094        select.addSelectColumn(Profile.getColumnRef(this, ATTRIB_ID));
1095        select.addSelectColumn(Profile.getColumnRef(this, ATTRIB_TYPE));
1096        select.addOuterJoinCondition(
1097            Profile.getColumnRef(this, Profile.ATTRIB_OBJECT_KEY),
1098            getInstanceColumnRef(ATTRIB_KEY, bIsHist));
1099        
1100        
1101        //this ensures that only top level profiles are found
1102
select.addWhereCondition(ProfilePropertyInstance.getColumnRef(this, ProfilePropertyInstance.TAG_VALUE,isHistorical()), "is", null);
1103    }
1104
1105
1106    /* (non-Javadoc)
1107     * @see org.openharmonise.rm.resources.AbstractObject#setHistorical(boolean)
1108     */

1109    public void setHistorical(boolean bIsHistorical) {
1110        super.setHistorical(bIsHistorical);
1111
1112        if (m_profiles != null) {
1113            
1114            // get the iterator
1115
Iterator profilesIter = m_profiles.values().iterator();
1116            
1117            
1118            // holds the temporary profile
1119
Profile prof = null;
1120            Iterator propertiesIter = null;
1121            
1122            while (profilesIter.hasNext() == true) {
1123                prof = (Profile) profilesIter.next();
1124                prof.setHistorical(bIsHistorical);
1125            }
1126        }
1127    }
1128    
1129    /* (non-Javadoc)
1130     * @see java.lang.Object#toString()
1131     */

1132    public String JavaDoc toString() {
1133        StringBuffer JavaDoc strbuf = new StringBuffer JavaDoc();
1134        strbuf.append(super.toString());
1135        
1136        Iterator iter = m_profiles.keySet().iterator();
1137        
1138        while (iter.hasNext()) {
1139            String JavaDoc sKey = (String JavaDoc) iter.next();
1140            Profile prof = (Profile) m_profiles.get(sKey);
1141            strbuf.append("\n").append(sKey).append(" - ").append("[").append(prof.toString()).append("]");
1142        }
1143        
1144        return strbuf.toString();
1145    }
1146
1147    /* (non-Javadoc)
1148     * @see org.openharmonise.rm.resources.lifecycle.Editable#changeStatus(org.openharmonise.rm.resources.lifecycle.Status)
1149     */

1150    public Editable changeStatus(Status status) throws EditException {
1151        //check profiles for valid data for approval
1152

1153        if(isPopulated() == false) {
1154            try {
1155                populateFromDatabase();
1156            } catch (PopulateException e) {
1157                throw new EditException(e.getLocalizedMessage(),e);
1158            }
1159        }
1160        
1161        if(m_bIgnoreProfileRestrictions == false) {
1162            boolean bIsProfilesValid = true;
1163            
1164            Iterator iter = m_profiles.values().iterator();
1165            
1166            //the assumption here is that the object will always have a profile
1167
//obviously if the object has no profile no validity checks will be
1168
//made
1169
while (iter.hasNext() && bIsProfilesValid == true) {
1170                Profile prof = (Profile) iter.next();
1171                
1172                try {
1173                    bIsProfilesValid = prof.isValid(this);
1174                } catch (DataAccessException e) {
1175                    throw new EditException(e.getLocalizedMessage(),e);
1176                }
1177                
1178            }
1179                    
1180            if(bIsProfilesValid == false) {
1181                throw new StatusChangeNotAllowedException("Profiles not valid for status change");
1182            }
1183        }
1184                
1185        return super.changeStatus(status);
1186    }
1187    
1188    /**
1189     * Sets whether to allow object to have status approved even if profile
1190     * restrictions have been broken.
1191     *
1192     * @param bIgnore <code>true</code> if profile restrictoins are
1193     * to ignored during a change of status
1194     */

1195    public void ignoreProfileRestrictions(boolean bIgnore) {
1196        m_bIgnoreProfileRestrictions = bIgnore;
1197    }
1198
1199}
Popular Tags