KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openharmonise > rm > resources > metadata > properties > Property


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.metadata.properties;
20
21 import java.sql.*;
22 import java.util.*;
23 import java.util.logging.*;
24
25 import org.openharmonise.commons.cache.CacheException;
26 import org.openharmonise.commons.dsi.*;
27 import org.openharmonise.commons.dsi.dml.*;
28 import org.openharmonise.rm.*;
29 import org.openharmonise.rm.dsi.*;
30 import org.openharmonise.rm.metadata.ChildObjectPropertyInstance;
31 import org.openharmonise.rm.publishing.*;
32 import org.openharmonise.rm.resources.*;
33 import org.openharmonise.rm.resources.lifecycle.*;
34 import org.openharmonise.rm.resources.metadata.properties.domains.Domain;
35 import org.openharmonise.rm.resources.metadata.properties.ranges.*;
36 import org.w3c.dom.*;
37
38
39 /**
40  * Class which represents a metadata property in the Harmonise framework, having
41  * a <code>Range</code> which determines what values an instance of this
42  * <code>Property</code> may have and a set of <code>Domain</code>s which
43  * determine what objects may have an instance of this <code>Property</code>.
44  *
45  * @author Michael Bell
46  * @version $Revision: 1.5 $
47  *
48  */

49 public class Property
50     extends AbstractChildObject
51     implements Publishable, Editable, DataStoreObject, Cloneable JavaDoc {
52
53     // XML tags for Properties
54
/**
55      * The property XML element name
56      */

57     public static final String JavaDoc TAG_PROPERTY = "Property";
58     
59     /**
60      * The domain list XML element name
61      */

62     public static final String JavaDoc TAG_DOMAIN_LIST = "DomainList";
63     
64     /**
65      * The description XML attribute name
66      */

67     public static final String JavaDoc ATTRIB_DESCRIPTION = "description";
68     
69     /**
70      * The operator XML attribute name
71      */

72     public static final String JavaDoc ATTRIB_OPERATOR = "operator";
73
74     //DB constants
75
/**
76      * The property database table name
77      */

78     private static final String JavaDoc TBL_PROPERTY = "property";
79     
80     /**
81      * The range object database column name
82      */

83     private static final String JavaDoc CLMN_RANGE_OBJECT = "range_object";
84     
85     /**
86      * The range details column name
87      */

88     private static final String JavaDoc CLMN_RANGE_DETAILS = "range_details";
89
90     /**
91      * The constant value for the type field for <code>Property</code>
92      */

93     protected static String JavaDoc TYPE_PROPERTY = Property.class.getName();
94
95     //member fields
96
/**
97      * The <code>Range</code> for this <code>Property</code>
98      */

99     protected Range m_range = null;
100     
101     /**
102      * The <code>List</code> of <code>Domain</code>s for this <code>Property</code>
103      */

104     protected List m_domains = null;
105     
106     /**
107      * The <code>List</code> of <code>Domain</code>s that have to be added
108      * at the next save operation
109      */

110     protected List m_add_domains = null;
111     
112     /**
113      * The <code>List</code> of <code>Domain</code>s that have to be removed
114      * at the next save operation
115      */

116     protected List m_remove_domains = null;
117     
118     /**
119      * <code>boolean</code> flag to indicate whether the <code>List</code> of
120      * <code>Domain</code>s has been populated
121      */

122     protected boolean m_bIsDomainPopulated = false;
123     
124     /**
125      * Logger for this class
126      */

127     static private Logger m_logger = Logger.getLogger(AbstractObject.class.getName());
128     
129
130     //initialiser block
131
{
132         m_domains = new Vector();
133         m_remove_domains = new Vector();
134         m_add_domains = new Vector();
135     }
136
137     //static initialiser block
138
static {
139         DatabaseInfo.getInstance().registerTableName(
140             Property.class.getName(),
141             TBL_PROPERTY);
142     }
143
144     /**
145      * Constructs a new <code>Property</code>
146      *
147      */

148     public Property() {
149         super();
150     }
151
152     /**
153      * Constructs a <code>Property</code> with an interface to the data store.
154      *
155      * @param dbintrf the data store interface
156      */

157     public Property(AbstractDataStoreInterface dbintrf) {
158         super(dbintrf);
159
160     }
161
162     /**
163      * Constructs a known existing <code>Property</code> with an interface to the
164      * data store.
165      *
166      * @param dbintrf the data store interface
167      * @param nId the id of the <code>Property</code>
168      */

169     public Property(AbstractDataStoreInterface dbintrf, int nId) {
170         super(dbintrf, nId);
171
172     }
173
174     /**
175      * Constructs <code>Property</code> with the specified id and unique key
176      * which may be historical.
177      *
178      * @param dbintrf the data store interface
179      * @param nId the <code>Property</code> id
180      * @param nKey the unique key of the <code>Property</code>
181      * @param bIsHist <code>true</code> if the <code>Property</code> is to be
182      * a historical version
183      */

184     public Property(
185         AbstractDataStoreInterface dbintrf,
186         int nId,
187         int nKey,
188         boolean bIsHist) {
189         super(dbintrf, nId, nKey, bIsHist);
190     }
191
192     /* (non-Javadoc)
193      * @see java.lang.Object#clone()
194      */

195     public Object JavaDoc clone() {
196         Property other = null;
197
198         try {
199             fullPopulate();
200
201             other = (Property) super.clone();
202
203             if(m_range != null) {
204                 other.setRange((Range) m_range.clone());
205             }
206             
207             if(m_domains != null) {
208                 Iterator iter = m_domains.iterator();
209
210                 other.m_domains = new Vector();
211
212                 while(iter.hasNext()) {
213                     Domain domain = (Domain) iter.next();
214     
215                     other.m_domains.add(domain.clone());
216                 }
217             }
218             
219         } catch (PopulateException e) {
220             throw new IllegalStateException JavaDoc(
221                 "Clone failed:" + e.getLocalizedMessage());
222         } catch (CloneNotSupportedException JavaDoc e) {
223             throw new IllegalStateException JavaDoc(
224                 "Clone failed:" + e.getLocalizedMessage());
225         }
226
227         return other;
228
229     }
230
231     /**
232      * Returns the <code>Range</code> of this <code>Property</code>.
233      *
234      * @return the <code>Range</code> of this <code>Property</code>.
235      */

236     public Range getRange() throws DataAccessException {
237         if (isPopulated() == false) {
238             try {
239                 populateFromDatabase();
240             } catch (PopulateException e) {
241                 throw new DataAccessException(
242                     "Error occured populating object",e);
243             }
244         }
245
246         return m_range;
247     }
248
249     /**
250      * Sets the <code>Range</code> for this <code>Property</code>.
251      *
252      * @param range the <code>Range</code> for this <code>Property</code>
253      * @throws PopulateException if an error occurs populating this <code>Property</code>
254      */

255     public void setRange(Range range) throws PopulateException {
256         if (isPopulated() == false) {
257             populateFromDatabase();
258         }
259
260         if ((m_range == null && range != null) || m_range.equals(range) == false) {
261             m_range = range;
262             setIsChanged(true);
263         }
264     }
265
266     /**
267      * Returns the list of domain restrictions on this <code>Property</code>.
268      *
269      * @return the list of domain restrictions on this <code>Property</code>
270      * @throws DataAccessException if there is an error populating the domains
271      * from the database
272      */

273     public List getDomains() throws DataAccessException {
274         if (m_bIsDomainPopulated == false) {
275             try {
276                 populateDomainFromDatabase();
277             } catch (PopulateException e) {
278                 throw new DataAccessException(
279                     "Error occured populating domains",e);
280             }
281         }
282
283         return m_domains;
284     }
285
286     /**
287      * Adds the given <code>Domain</code> to this <code>Property</code>.
288      *
289      * @param domain the <code>Domain</code> to add
290      * @throws PopulateException if there is an error populating the domains
291      * from the database
292      */

293     public void addDomain(Domain domain) throws PopulateException {
294         if (m_bIsDomainPopulated == false) {
295             populateDomainFromDatabase();
296         }
297
298         if (m_domains.contains(domain) == false) {
299             
300             if(m_logger.isLoggable(Level.FINE)) {
301                 try {
302                     StringBuffer JavaDoc sbuf = new StringBuffer JavaDoc();
303                     
304                     sbuf.append("Adding domain {class - ")
305                         .append(domain.getDomainClass())
306                         .append(", path restrictions - ")
307                         .append(domain.getDetails())
308                         .append("} to property ")
309                         .append(getName());
310                     
311                     m_logger.logp(Level.FINE, this.getClass().getName(), "addDomain", sbuf.toString());
312                 } catch (DataAccessException e) {
313                     m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
314                 }
315             }
316             
317             if(m_range != null && m_range instanceof BooleanRange) {
318                 domain.setMaxOccurs(1);
319             }
320             
321             m_add_domains.add(domain);
322             try {
323                 if (isChanged() == false) {
324                     setIsChanged(true);
325                 }
326             } catch (DataAccessException e) {
327                 throw new PopulateException(
328                     "Error occurred populating property: ",
329                     e);
330             }
331         }
332     }
333
334     /**
335      * Removes the given <code>Domain</code> from this <code>Property</code>.
336      *
337      * @param domain the <code>Domain</code> to remove
338      * @throws PopulateException if an error occurs populating the list
339      * of <code>Domain</code>s
340      */

341     public void removeDomain(Domain domain) throws PopulateException {
342         if (m_bIsDomainPopulated == false) {
343             populateDomainFromDatabase();
344         }
345
346         if (m_domains.contains(domain) == true) {
347             m_remove_domains.add(domain);
348             try {
349                 if (isChanged() == false) {
350                     setIsChanged(true);
351                 }
352             } catch (DataAccessException e) {
353                 throw new PopulateException(
354                     "Error occurred populating property",e);
355             }
356         }
357     }
358
359     /**
360      * Sets the complete list of <code>Domain</code>s for this <code>Property</code>,
361      * overwriting the current list
362      *
363      * @param domains the list of new <code>Domain</code>s
364      * @throws PopulateException if there is an error populating the list of
365      * <code>Domain</code>s
366      */

367     public void setDomains(List domains) throws PopulateException {
368         if(m_bIsDomainPopulated == false) {
369             populateDomainFromDatabase();
370         }
371         
372         if (m_domains.equals(domains) == false) {
373             setIsChanged(true);
374             m_add_domains = new Vector(domains);
375             m_remove_domains.addAll(m_domains);
376         }
377
378         
379     }
380     
381     /**
382      * Returns <code>true</code> if the specified
383      * <code>AbstarctProfiledObject</code> can have an instance of this
384      * <code>Property</code> in its <code>Profile</code>.
385      *
386      * @param obj the profiled object
387      * @return <code>true</code> if this <code>Property</code> can be applied
388      * to the specified profiled object
389      * @throws DataAccessException if an error occurs populating the <code>Domain</code>s
390      * of this <code>Property</code>
391      */

392     public boolean isValidProfiledObject(AbstractProfiledObject obj) throws DataAccessException {
393         boolean bIsValid = false;
394         
395         Iterator iter = getDomains().iterator();
396         
397         boolean bFound = false;
398         
399         while (iter.hasNext() && bFound == false) {
400             Domain domain = (Domain) iter.next();
401             
402             if(domain.getDomainClass().equals(obj.getClass().getName()) == true) {
403                 bIsValid = domain.isValid(obj);
404                 bFound = true;
405             }
406         }
407         
408         return bIsValid;
409     }
410
411     /* (non-Javadoc)
412      * @see org.openharmonise.rm.dsi.DataStoreObject#getInstanceJoinConditions(java.lang.String, boolean)
413      */

414     public JoinConditions getInstanceJoinConditions(
415         String JavaDoc sObjectTag,
416         boolean bIsOuter)
417         throws DataStoreException {
418         return null;
419     }
420
421     /* (non-Javadoc)
422      * @see org.openharmonise.rm.dsi.DataStoreObject#getInstanceColumnRef(java.lang.String, boolean)
423      */

424     public ColumnRef getInstanceColumnRef(String JavaDoc sColumn, boolean bIsHist)
425         throws DataStoreException {
426         ColumnRef returnColRef = null;
427
428         String JavaDoc sTable = getDBTableName();
429
430         if (bIsHist == true) {
431             sTable = getHistoricalDBTableName();
432         }
433
434         if (sColumn.equals(CLMN_RANGE_OBJECT) == true) {
435             returnColRef =
436                 new ColumnRef(sTable, CLMN_RANGE_OBJECT, ColumnRef.TEXT);
437         } else if (sColumn.equals(CLMN_RANGE_DETAILS) == true) {
438             returnColRef =
439                 new ColumnRef(sTable, CLMN_RANGE_DETAILS, ColumnRef.TEXT);
440         } else {
441             returnColRef = super.getInstanceColumnRef(sColumn, bIsHist);
442         }
443
444         if (returnColRef != null) {
445             return returnColRef;
446         } else {
447             throw new InvalidColumnReferenceException(
448                 "No column of the name [" + sColumn + "] in Property");
449         }
450     }
451     
452
453     /* (non-Javadoc)
454      * @see org.openharmonise.rm.resources.AbstractObject#markAsNew()
455      */

456     public void markAsNew() throws PopulateException {
457         if(m_domains != null) {
458             Iterator iter = m_domains.iterator();
459             
460             while (iter.hasNext()) {
461                 Domain domain = (Domain) iter.next();
462                 domain.markAsNew();
463             }
464         }
465         super.markAsNew();
466     }
467
468
469     /* (non-Javadoc)
470      * @see org.openharmonise.rm.resources.AbstractEditableObject#delete(boolean)
471      */

472     protected void delete(boolean bDeleteHist)
473         throws
474             DataAccessException,
475             EditException,
476             PopulateException,
477             DataStoreException {
478
479         List domains = getDomains();
480         
481         Iterator iter = domains.iterator();
482         
483         while (iter.hasNext()) {
484             Domain domain = (Domain) iter.next();
485             domain.delete();
486         }
487
488         super.delete(bDeleteHist);
489     }
490
491     /* (non-Javadoc)
492      * @see org.openharmonise.rm.publishing.Publishable#populate(org.w3c.dom.Element, org.openharmonise.rm.publishing.State)
493      */

494     public void populate(Element xmlElement, State state)
495         throws PopulateException {
496
497         String JavaDoc sTemp = "";
498         String JavaDoc sTagName = xmlElement.getTagName();
499
500         if (sTagName.equals(TAG_PROPERTY)) {
501             sTemp = xmlElement.getAttribute(ATTRIB_ID);
502
503             if (!sTemp.equals("")) {
504                 m_nId = Integer.parseInt(sTemp);
505             }
506
507             sTemp = xmlElement.getAttribute(ATTRIB_NAME);
508
509             if (sTemp.equals("") == false) {
510                 try {
511                     setName(sTemp);
512                 } catch (InvalidNameException e) {
513                     throw new PopulateException(e);
514                 }
515             }
516
517             sTemp = xmlElement.getAttribute(ATTRIB_DESCRIPTION);
518
519             if (sTemp.equals("") == false) {
520                 setSummary(xmlElement.getAttribute(ATTRIB_DESCRIPTION));
521             }
522
523             NodeList nodes = xmlElement.getChildNodes();
524
525             for (int i = 0; i < nodes.getLength(); i++) {
526                 if (nodes.item(i).getNodeType() != Node.ELEMENT_NODE) {
527                     continue;
528                 }
529
530                 Element el = (Element) nodes.item(i);
531                 populate(el, state);
532             }
533         } else if(RangeFactory.isRangeTagName(sTagName) == true) {
534             try {
535                 Range range = RangeFactory.getInstance().getRange(xmlElement);
536                 ((Publishable)range).populate(xmlElement, state);
537                 setRange(range);
538             } catch (InvalidRangeObjectException e) {
539                 throw new PopulateException(e);
540             }
541         } else if(sTagName.equals(TAG_DOMAIN_LIST)) {
542             NodeList domEls = xmlElement.getChildNodes();
543             
544             for (int i = 0; i < domEls.getLength(); i++) {
545                 if(domEls.item(i).getNodeType() == Node.ELEMENT_NODE) {
546                     Element domEl = (Element) domEls.item(i);
547                 
548                     Domain domain = new Domain(m_dsi);
549                     domain.populate(domEl, state);
550                     m_add_domains.add(domain);
551                 }
552             }
553             
554         } else {
555             super.populate(xmlElement, state);
556         }
557     }
558
559     /* (non-Javadoc)
560      * @see org.openharmonise.rm.publishing.Publishable#publish(org.w3c.dom.Element, org.openharmonise.rm.publishing.HarmoniseOutput, org.openharmonise.rm.publishing.State)
561      */

562     public Element publish(Element topEl, HarmoniseOutput xmlDoc, State state)
563         throws PublishException {
564         if (isPopulated() == false) {
565             try {
566                 populateFromDatabase();
567             } catch (PopulateException e) {
568                 throw new PublishException(
569                     "Error occured populating object", e);
570             }
571         }
572
573         Element docEl = null;
574         NodeList nodes = null;
575         Text txt = null;
576         String JavaDoc sTagName = topEl.getTagName();
577
578         if (sTagName.equals(TAG_PROPERTY)) {
579             docEl = xmlDoc.createElement(sTagName);
580
581             String JavaDoc sTemp = "";
582
583             try {
584                 sTemp = getName();
585
586                 if ((sTemp == null) || sTemp.equalsIgnoreCase("")) {
587                     sTemp = topEl.getAttribute(ATTRIB_NAME);
588                 }
589
590                 docEl.setAttribute(ATTRIB_NAME, sTemp);
591
592                 sTemp = getSummary();
593
594                 if (!sTemp.equalsIgnoreCase("") && (sTemp != null)) {
595                     docEl.setAttribute(ATTRIB_DESCRIPTION, sTemp);
596                 }
597             } catch (DataAccessException e) {
598                 throw new PublishException(
599                     "Error occured accessing data",e);
600             }
601
602             sTemp = topEl.getAttribute(ATTRIB_OPERATOR);
603
604             if (sTemp.equalsIgnoreCase("") == false && (sTemp != null)) {
605                 docEl.setAttribute(ATTRIB_OPERATOR, sTemp);
606             }
607
608             nodes = topEl.getChildNodes();
609         } else if(sTagName.equals(TAG_DOMAIN_LIST)) {
610             // deal with domain
611
docEl = xmlDoc.createElement(sTagName);
612             
613             Element domEl = (Element)topEl.getElementsByTagName(Domain.TAG_DOMAIN).item(0);
614             if(domEl==null){
615                 domEl = xmlDoc.createElement(Domain.TAG_DOMAIN);
616                 Element tempEl = xmlDoc.createElement(Domain.TAG_DOMAIN_DETAILS);
617                 domEl.appendChild(tempEl);
618                 tempEl = xmlDoc.createElement(Domain.TAG_DOMAIN_OBJECT);
619                 domEl.appendChild(tempEl);
620             }
621             if(this.m_bIsDomainPopulated == false){
622                 try {
623                     this.populateDomainFromDatabase();
624                 } catch (PopulateException e) {
625                     throw new PublishException(e);
626                 }
627             }
628             
629             if(m_domains != null) {
630                 for (Iterator iter = m_domains.iterator(); iter.hasNext();) {
631                     Domain dom = (Domain) iter.next();
632                     docEl.appendChild(dom.publish(domEl, xmlDoc, state));
633                 }
634             }
635             
636         } else if(sTagName.equals(AbstractRange.TAG_RANGE)) {
637             //deal with range
638
if(m_range != null) {
639                 docEl = ((AbstractRange)m_range).publish(topEl, xmlDoc, state);
640             } else {
641                 docEl = xmlDoc.createElement(sTagName);
642             }
643             
644         } else { //add on any other nodes
645
docEl = super.publish(topEl, xmlDoc, state);
646         }
647
648         // recurse through the children if there are any
649
Element formEl;
650         Element el;
651
652         if (nodes != null) {
653             for (int i = 0; i < nodes.getLength(); i++) {
654                 if (nodes.item(i).getNodeType() != Node.ELEMENT_NODE) {
655                     continue;
656                 }
657                 formEl = (Element) nodes.item(i);
658                 el = publish(formEl, xmlDoc, state);
659
660                 if (el != null) {
661                     docEl.appendChild(el);
662                 }
663             }
664         }
665
666         return docEl;
667     }
668
669     /* (non-Javadoc)
670      * @see org.openharmonise.rm.dsi.DataStoreObject#getDBTableName()
671      */

672     public String JavaDoc getDBTableName() {
673         return TBL_PROPERTY;
674     }
675
676     /* (non-Javadoc)
677      * @see org.openharmonise.rm.publishing.Publishable#getTagName()
678      */

679     public String JavaDoc getTagName() {
680         return TAG_PROPERTY;
681     }
682
683     /*-----------------------------------------------------------------
684       protected methods
685       -----------------------------------------------------------------*/

686
687     /* (non-Javadoc)
688      * @see org.openharmonise.rm.resources.AbstractObject#fullPopulate()
689      */

690     protected void fullPopulate() throws PopulateException {
691         if (isPopulated() == false) {
692             populateFromDatabase();
693         }
694
695         if (m_bIsDomainPopulated == false) {
696             populateDomainFromDatabase();
697         }
698
699         super.fullPopulate();
700     }
701
702     /**
703      * Populates the list of <code>Domain</code>s from the database for this
704      * <code>Property</code>.
705      *
706      * @throws PopulateException if there is an error populating the data
707      * from the database
708      */

709     protected synchronized void populateDomainFromDatabase() throws PopulateException {
710         if (isPopulated() == false) {
711             populateFromDatabase();
712         }
713
714         if (m_bIsDomainPopulated == false) {
715             
716             if(m_logger.isLoggable(Level.FINE)) {
717                 try {
718                     m_logger.logp(Level.FINE, this.getClass().getName(), "populateDomainFromDatabase", "populating domains for object, key - " + getKey());
719                 } catch (DataAccessException e) {
720                     m_logger.log(Level.WARNING,"Problem logging domain population",e);
721                 }
722             }
723
724             boolean bIsHist = isHistorical();
725             ResultSet rs = null;
726
727             SelectStatement select = new SelectStatement();
728
729             try {
730                 select.addSelectColumn(
731                     getDomainColumnRef(Domain.CLMN_DOMAIN_OBJECT, bIsHist));
732                 select.addSelectColumn(
733                     getDomainColumnRef(Domain.CLMN_DOMAIN_ID, bIsHist));
734                 select.addSelectColumn(
735                     getDomainColumnRef(Domain.CLMN_MIN_OCCURS, bIsHist));
736                 select.addSelectColumn(
737                     getDomainColumnRef(Domain.CLMN_MAX_OCCURS, bIsHist));
738                 select.addSelectColumn(
739                         getDomainColumnRef(Domain.CLMN_DEPTH, bIsHist));
740                 select.addWhereCondition(
741                     getDomainColumnRef(Domain.CLMN_PROPERTY_KEY, bIsHist),
742                     "=",
743                     m_nObjectKey);
744
745             } catch (DataStoreException e) {
746                 throw new PopulateException(
747                     "Error occure building query for domain",e);
748             }
749             try {
750                 rs = m_dsi.execute(select);
751
752                 while (rs.next()) {
753                     Domain domain = new Domain(m_dsi);
754
755                     domain.setDomainClass(rs.getString(1));
756                     domain.setId(rs.getInt(2));
757                     domain.setMinOccurs(rs.getInt(3));
758                     domain.setMaxOccurs(rs.getInt(4));
759                     domain.setDepth(rs.getInt(5));
760           
761                     m_domains.add(domain);
762                 }
763
764                 m_bIsDomainPopulated = true;
765             } catch (DataStoreException e) {
766                 throw new PopulateException(
767                     "Error occure processing query for domain",e);
768             } catch (SQLException e) {
769                 throw new PopulateException(
770                     "Error occure processing query for domain",e);
771             } finally {
772                 if (rs != null) {
773                     try {
774                         rs.close();
775                     } catch (SQLException e) {
776                         throw new PopulateException(
777                             "Error occur closing result set",e);
778                     }
779                 }
780             }
781         }
782     }
783
784     /* (non-Javadoc)
785      * @see org.openharmonise.rm.resources.AbstractEditableObject#update()
786      */

787     protected void update() throws EditException, DataStoreException {
788
789         // remove what's to be removed
790
if (m_remove_domains.size() > 0) {
791
792             //now save
793
Iterator iter = m_remove_domains.iterator();
794             DeleteStatement delete = new DeleteStatement();
795             boolean bIsHist = isHistorical();
796
797             while (iter.hasNext()) {
798                 Domain domain = (Domain) iter.next();
799
800                 domain.delete();
801
802                 m_domains.remove(domain);
803             }
804
805             m_remove_domains.clear();
806         }
807
808         //add what's to be added
809
if (m_add_domains.size() > 0) {
810             //now save
811
Iterator iter = m_add_domains.iterator();
812
813             while (iter.hasNext()) {
814                 Domain domain = (Domain) iter.next();
815
816                 domain.save(this);
817                 m_domains.add(domain);
818             }
819             m_add_domains.clear();
820         }
821         
822         //check for current range and domain
823
for (Iterator iter = m_domains.iterator(); iter.hasNext();) {
824             Domain domain = (Domain) iter.next();
825             checkDomainAndRange(domain);
826         }
827         
828         super.update();
829
830     }
831
832     /* (non-Javadoc)
833      * @see org.openharmonise.rm.resources.AbstractEditableObject#saveNonCoreData()
834      */

835     protected void saveNonCoreData() throws EditException {
836         // nothing to do, no non core data
837

838     }
839
840     /* (non-Javadoc)
841      * @see org.openharmonise.rm.resources.AbstractChildObject#getParentObjectClassName()
842      */

843     public String JavaDoc getParentObjectClassName() {
844
845         return PropertyGroup.class.getName();
846     }
847
848     /* (non-Javadoc)
849      * @see org.openharmonise.rm.resources.AbstractObject#addColumnsToPopulateQuery(org.openharmonise.commons.dsi.dml.SelectStatement, boolean)
850      */

851     protected void addColumnsToPopulateQuery(
852         SelectStatement select,
853         boolean bIsHist)
854         throws DataStoreException {
855
856         super.addColumnsToPopulateQuery(select, bIsHist);
857
858         select.addSelectColumn(
859             getInstanceColumnRef(CLMN_RANGE_OBJECT, bIsHist));
860         select.addSelectColumn(
861             getInstanceColumnRef(CLMN_RANGE_DETAILS, bIsHist));
862     }
863
864     /* (non-Javadoc)
865      * @see org.openharmonise.rm.resources.AbstractObject#populateFromResultSetRow(java.sql.ResultSet, org.openharmonise.commons.dsi.dml.SelectStatement)
866      */

867     protected void populateFromResultSetRow(
868         ResultSet rs,
869         SelectStatement select)
870         throws PopulateException {
871
872         if (isPopulated() == false) {
873
874             super.populateFromResultSetRow(rs, select);
875
876             List cols = select.getSelectColumns();
877             ColumnRef colref = null;
878
879             try {
880                 ColumnRefCache cache = ColumnRefCache.getInstance();
881
882                 boolean bIsHist = isHistorical();
883
884                 colref = cache.getColumnRef(this, CLMN_RANGE_OBJECT, bIsHist);
885
886                 if (select.containsSelectColumn(colref) == true) {
887                     String JavaDoc sRangeObject =
888                         rs.getString(select.getResultSetIndex(colref));
889
890                     m_range = RangeFactory.getInstance().getRange(sRangeObject);
891
892                     colref =
893                         cache.getColumnRef(this, CLMN_RANGE_DETAILS, bIsHist);
894
895                     if (select.containsSelectColumn(colref) == true && m_range != null) {
896                         String JavaDoc sRangeDetails =
897                             rs.getString(select.getResultSetIndex(colref));
898
899                         m_range.setDetails(sRangeDetails);
900                     }
901                 }
902             } catch (SQLException e) {
903                 throw new PopulateException(
904                     "Error occured populating range",
905                     e);
906             } catch (ClassNotFoundException JavaDoc e) {
907                 throw new PopulateException(
908                     "Error occured generating range from factory",
909                     e);
910             } catch (CacheException e) {
911                 throw new PopulateException(
912                     "Error occured with cache",
913                     e);
914             } catch (InvalidRangeObjectException e) {
915                 throw new PopulateException(
916                     "Error occured generating range from factory",
917                     e);
918             }
919         }
920     }
921
922     /* (non-Javadoc)
923      * @see org.openharmonise.rm.resources.AbstractEditableObject#addDataToSave(org.openharmonise.commons.dsi.dml.InsertStatement)
924      */

925     protected void addDataToSave(InsertStatement insert)
926         throws DataStoreException {
927         boolean bIsHist = isHistorical();
928
929         super.addDataToSave(insert);
930
931         if(m_range != null) {
932         
933             insert.addColumnValue(
934                 getInstanceColumnRef(CLMN_RANGE_OBJECT, bIsHist),
935                 m_range.getObject());
936     
937             String JavaDoc sRangeDetails = m_range.getDetails();
938       
939             if (sRangeDetails != null) {
940                 insert.addColumnValue(
941                         getInstanceColumnRef(CLMN_RANGE_DETAILS, bIsHist), sRangeDetails);
942                     
943             }
944             
945         }
946     }
947
948     /* (non-Javadoc)
949      * @see org.openharmonise.rm.resources.AbstractEditableObject#saveCoreData()
950      */

951     protected void saveCoreData() throws EditException {
952
953         if(m_bIsDomainPopulated == false) {
954             try {
955                 populateDomainFromDatabase();
956             } catch (PopulateException e) {
957                 throw new EditException(e.getLocalizedMessage(),e);
958             }
959         }
960
961         //first must work out what domains have to be saved
962

963         m_domains.removeAll(m_remove_domains);
964
965         m_domains.addAll(m_add_domains);
966
967         //now save
968
Iterator iter = m_domains.iterator();
969
970         while (iter.hasNext()) {
971             Domain domain = (Domain) iter.next();
972             
973             checkDomainAndRange(domain);
974
975             domain.save(this);
976         }
977
978         m_remove_domains.clear();
979         m_add_domains.clear();
980
981         super.saveCoreData();
982     }
983
984
985
986     /*-----------------------------------------------------------------
987       Private methods
988       -----------------------------------------------------------------*/

989
990     /**
991      * Returns the appropriate <code>ColumnRef</code> for the specified column
992      * of the domain database table.
993      *
994      * @param sCol the database column name
995      * @param bIsHist <code>true</code> if the reference to return should be to
996      * the historical table
997      * @return the column reference for the specified column name of the
998      * domain table
999      */

1000    private ColumnRef getDomainColumnRef(String JavaDoc sCol, boolean bIsHist)
1001        throws DataStoreException {
1002        String JavaDoc sTable = Domain.TBL_NAME;
1003        ColumnRef colref = null;
1004
1005        if (bIsHist == true) {
1006            sTable = sTable + EXT_HIST;
1007        }
1008
1009        if (sCol.equals(Domain.CLMN_DOMAIN_OBJECT) == true) {
1010            colref = new ColumnRef(sTable, sCol, ColumnRef.TEXT);
1011        } else if (sCol.equals(Domain.CLMN_PROPERTY_KEY) == true) {
1012            colref = new ColumnRef(sTable, sCol, ColumnRef.NUMBER);
1013        } else if (sCol.equals(Domain.CLMN_MIN_OCCURS) == true) {
1014            colref = new ColumnRef(sTable, sCol, ColumnRef.NUMBER);
1015        } else if (sCol.equals(Domain.CLMN_MAX_OCCURS) == true) {
1016            colref = new ColumnRef(sTable, sCol, ColumnRef.NUMBER);
1017        } else if (sCol.equals(Domain.CLMN_DOMAIN_ID) == true) {
1018            colref = new ColumnRef(sTable, sCol, ColumnRef.NUMBER);
1019        } else if (sCol.equals(Domain.CLMN_DEPTH) == true) {
1020            colref = new ColumnRef(sTable, sCol, ColumnRef.NUMBER);
1021        } else {
1022            throw new InvalidColumnReferenceException();
1023        }
1024
1025        return colref;
1026    }
1027
1028    /* (non-Javadoc)
1029     * @see org.openharmonise.rm.resources.AbstractObject#setHistorical(boolean)
1030     */

1031    public void setHistorical(boolean bIsHistorical) {
1032        if (m_bIsDomainPopulated == true) {
1033            Iterator iter = m_domains.iterator();
1034            while (iter.hasNext()) {
1035                Domain domain = (Domain) iter.next();
1036                domain.setHistorical(bIsHistorical);
1037            }
1038        }
1039
1040        super.setHistorical(bIsHistorical);
1041    }
1042
1043    /* (non-Javadoc)
1044     * @see org.openharmonise.rm.resources.AbstractObject#isChanged()
1045     */

1046    public boolean isChanged() throws DataAccessException {
1047        boolean bIsChanged = false;
1048
1049        Iterator domIter = m_domains.iterator();
1050
1051        while (domIter.hasNext()) {
1052            Domain domain = (Domain) domIter.next();
1053            if (domain.isChanged() == true) {
1054                bIsChanged = true;
1055                setIsChanged(true);
1056            }
1057        }
1058        
1059        if(bIsChanged == false && m_range != null) {
1060            bIsChanged = m_range.isChanged();
1061        }
1062
1063        if (bIsChanged == false) {
1064            bIsChanged = super.isChanged();
1065        }
1066
1067        return bIsChanged;
1068    }
1069
1070    /**
1071     * Returns the <code>Domain</code> of this <code>Property</code> which
1072     * matches the specified <code>AbstractProfiledObject</code>.
1073     *
1074     * @param profObj the profiled object
1075     * @return the <code>Domain</code> which matches the specified
1076     * <code>AbstractProfiledObject</code>
1077     * @throws DataAccessException if an error occurs populating the list
1078     * of <code>Domain</code>s
1079     */

1080    public Domain getDomain(AbstractProfiledObject profObj) throws DataAccessException {
1081        if(m_bIsDomainPopulated == false) {
1082            try {
1083                populateDomainFromDatabase();
1084            } catch (PopulateException e) {
1085                throw new DataAccessException(e.getLocalizedMessage(),e);
1086            }
1087        }
1088        Domain result = null;
1089        
1090        Iterator iter = m_domains.iterator();
1091        boolean bFound = false;
1092        while (iter.hasNext()) {
1093            Domain domain = (Domain) iter.next();
1094            
1095            if(domain.isValid(profObj)) {
1096                bFound = true;
1097                result = domain;
1098            }
1099            
1100        }
1101        
1102        return result;
1103    }
1104    
1105    /**
1106     * Checks domain had valid data given the current property range.
1107     *
1108     * @param domain the domain to check
1109     * @throws EditException if an error occurs
1110     */

1111    protected void checkDomainAndRange(Domain domain) throws EditException {
1112        
1113        if(m_range != null && m_range instanceof BooleanRange) {
1114            domain.setMaxOccurs(1);
1115        } else if(m_range != null && m_range instanceof AbsoluteChildObjectRange) {
1116            try {
1117                String JavaDoc sDomainClass = domain.getDomainClass();
1118                Class JavaDoc domainClass = Class.forName( sDomainClass);
1119                String JavaDoc sValueClass = ((ChildObjectRange)m_range).getChildObjectValueClassName(domainClass);
1120                
1121                String JavaDoc sTableName = ChildObjectPropertyInstance.getDBTableName(sDomainClass, sValueClass,isHistorical());
1122                
1123                if(m_dsi.isTableExist(sTableName) == false) {
1124                    ChildObjectPropertyInstance.createTable(m_dsi,sDomainClass, sValueClass,isHistorical());
1125                }
1126            
1127            } catch (ClassNotFoundException JavaDoc e) {
1128                throw new EditException(e);
1129            } catch (DataAccessException e) {
1130                throw new EditException(e);
1131            } catch (DataStoreException e) {
1132                throw new EditException(e);
1133            }
1134            
1135        }
1136    }
1137
1138    /**
1139     * @param domainObject
1140     * @param domainDetails
1141     * @throws DataAccessException
1142     */

1143    public Domain getDomain(String JavaDoc domainObject, String JavaDoc domainDetails) throws DataAccessException {
1144        if(m_bIsDomainPopulated == false) {
1145            try {
1146                populateDomainFromDatabase();
1147            } catch (PopulateException e) {
1148                throw new DataAccessException(e.getLocalizedMessage(),e);
1149            }
1150        }
1151        Domain result = null;
1152        
1153        Iterator iter = m_domains.iterator();
1154        boolean bFound = false;
1155        while (iter.hasNext()) {
1156            Domain domain = (Domain) iter.next();
1157
1158            if(domainObject.equals(domain.getDomainClass()) && domain.getDetails().contains(domainDetails)) {
1159                bFound = true;
1160                result = domain;
1161            }
1162            
1163        }
1164        
1165        return result;
1166        
1167    }
1168    
1169    /* (non-Javadoc)
1170     * @see org.openharmonise.rm.resources.AbstractObject#setName(java.lang.String)
1171     */

1172    public void setName(String JavaDoc sName) throws InvalidNameException {
1173        
1174        //ensure name is valid
1175
if(isNameUnique(sName) == false) {
1176            throw new InvalidNameException(sName + " already a property name");
1177        }
1178        
1179        super.setName(sName);
1180    }
1181
1182    /**
1183     * Returns <code>true</code> if this name is unique.
1184     *
1185     * @param sName the proposed name
1186     * @return <code>true</code> if this name is unique
1187     */

1188    private boolean isNameUnique(String JavaDoc sName) {
1189        
1190        boolean bIsUnique = true;
1191        ResultSet rs = null;
1192        
1193        SelectStatement select = new SelectStatement();
1194        
1195        try {
1196            ColumnRef nameCol = getInstanceColumnRef(TAG_NAME,isHistorical());
1197            
1198            select.addSelectColumn(nameCol);
1199            
1200            select.addWhereCondition(nameCol, "=", sName);
1201            
1202            if(m_nId > 0) {
1203                select.addWhereCondition(getInstanceColumnRef(ATTRIB_ID,isHistorical()), "!=", m_nId);
1204                
1205                select.addWhereCondition(getInstanceColumnRef(TAG_LIVE_VERSION,isHistorical()), "!=", m_nId);
1206            }
1207            
1208            rs = m_dsi.execute(select);
1209            
1210            if(rs.next()) {
1211                bIsUnique = false;
1212            }
1213            
1214        } catch (DataStoreException e) {
1215            m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
1216        } catch (SQLException e) {
1217            m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
1218        } finally {
1219            if(rs != null) {
1220                try {
1221                    rs.close();
1222                } catch (SQLException e) {
1223                    m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
1224                }
1225            }
1226        }
1227        
1228        
1229        return bIsUnique;
1230    }
1231
1232}
1233
Popular Tags