001: /*
002: * The contents of this file are subject to the
003: * Mozilla Public License Version 1.1 (the "License");
004: * you may not use this file except in compliance with the License.
005: * You may obtain a copy of the License at http://www.mozilla.org/MPL/
006: *
007: * Software distributed under the License is distributed on an "AS IS"
008: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
009: * See the License for the specific language governing rights and
010: * limitations under the License.
011: *
012: * The Initial Developer of the Original Code is Simulacra Media Ltd.
013: * Portions created by Simulacra Media Ltd are Copyright (C) Simulacra Media Ltd, 2004.
014: *
015: * All Rights Reserved.
016: *
017: * Contributor(s):
018: */
019: package org.openharmonise.rm.resources.metadata.properties.ranges;
020:
021: import java.util.*;
022:
023: import org.openharmonise.commons.dsi.AbstractDataStoreInterface;
024: import org.openharmonise.rm.*;
025: import org.openharmonise.rm.factory.*;
026: import org.openharmonise.rm.metadata.*;
027: import org.openharmonise.rm.publishing.*;
028: import org.openharmonise.rm.resources.AbstractParentObject;
029: import org.openharmonise.rm.resources.metadata.properties.PropertyGroup;
030: import org.w3c.dom.Element;
031:
032: /**
033: * Class which represents a <code>Property</code> range which is
034: * restricted to <code>Profile</code> values.
035: *
036: * @author Michael Bell
037: * @version $Revision: 1.3 $
038: *
039: */
040: public class ProfileRange extends AbstractRange implements Range,
041: Publishable {
042:
043: /**
044: * Profile range tag name
045: */
046: public final static String TAG_PROFILE_RANGE = "ProfileRange";
047:
048: /**
049: * Path restriction XML tag name
050: */
051: public final static String TAG_PATH_RESTRICTION = "PathRestriction";
052:
053: /**
054: * The separator character used to separate range restrictions when compiling
055: * the <code>String</code> representation for the database details field
056: */
057: static final private String SEPARATOR = "|";
058:
059: /**
060: * The list of paths of <code>PropertyGroup</code>s that have
061: * <code>Property</code> children whose instances can be added to the
062: * <code>Profile</code> values in this range
063: */
064: private List m_property_restrictions = null;
065:
066: /**
067: * Constructs a new <code>ProfileRange</code>,
068: *
069: */
070: public ProfileRange() {
071: super (Profile.class.getName(), null);
072: }
073:
074: /**
075: * Constructs a <code>ProfileRange</code> with the specified class type and
076: * other restrictions,
077: *
078: * @param sObjClassName the class name of the values of this range. This will
079: * normally be the class name of <code>Profile</code> but could
080: * concievably be the class name of a subclass of <code>Profile</code>
081: * @param sDetails a <code>String</code> representation of the non class
082: * type restrictions
083: */
084: public ProfileRange(String sObjClassName, String sDetails) {
085: super (sObjClassName, sDetails);
086: }
087:
088: /* (non-Javadoc)
089: * @see org.openharmonise.rm.resources.metadata.properties.ranges.Range#isValid(java.lang.Object)
090: */
091: public boolean isValid(Object obj) {
092: return (obj instanceof Profile);
093: }
094:
095: /* (non-Javadoc)
096: * @see java.lang.Object#equals(java.lang.Object)
097: */
098: public boolean equals(Object obj) {
099: boolean bResult = false;
100:
101: if (obj instanceof ProfileRange) {
102: bResult = super .equals(obj);
103: }
104:
105: return bResult;
106: }
107:
108: /**
109: * Returns a list of paths of <code>PropertyGroup</code>s whose <code>Property</code>
110: * children can be added to <code>Profile</code> values of this range,
111: *
112: * @return a list of paths of <code>PropertyGroup</code>s
113: */
114: public List getAllowedPropertyParents() {
115: return new ArrayList(m_property_restrictions);
116: }
117:
118: /**
119: * Sets the list of paths of <code>PropertyGroup</code>s whose <code>Property</code>
120: * children can be added to <code>Profile</code> values of this range,
121: *
122: * @param allowedParents a list of paths of <code>PropertyGroup</code>s
123: */
124: public void setAllowedPropertyParents(List allowedParents) {
125: if ((m_property_restrictions == null && allowedParents != null)
126: || m_property_restrictions.equals(allowedParents) == false) {
127: m_property_restrictions = new ArrayList(allowedParents);
128: isChanged(true);
129: }
130:
131: }
132:
133: /**
134: * Adds an individual path to the current list of <code>PropertyGroup</code>
135: * paths whose <code>Property</code> children can be added to the
136: * <code>Profile</code> values of this range.
137: *
138: * @param sPath the <code>PropertyGroup</code> path
139: */
140: public void addAllowedPropertyParent(String sPath) {
141: if (m_property_restrictions == null) {
142: m_property_restrictions = new ArrayList();
143: }
144:
145: if (m_property_restrictions.contains(sPath) == false) {
146: m_property_restrictions.add(sPath);
147: isChanged(true);
148: }
149: }
150:
151: /* (non-Javadoc)
152: * @see org.openharmonise.rm.resources.metadata.properties.ranges.Range#getDetails()
153: */
154: public String getDetails() {
155: if (isChanged()) {
156: StringBuffer strbuf = new StringBuffer();
157: if (m_property_restrictions != null) {
158: Iterator iter = m_property_restrictions.iterator();
159:
160: while (iter.hasNext()) {
161: String sPath = (String) iter.next();
162: strbuf.append(sPath);
163:
164: if (iter.hasNext()) {
165: strbuf.append(SEPARATOR);
166: }
167: }
168:
169: }
170: super .setDetails(strbuf.toString());
171: }
172:
173: return super .getDetails();
174: }
175:
176: /* (non-Javadoc)
177: * @see org.openharmonise.rm.resources.metadata.properties.ranges.Range#setDetails(java.lang.String)
178: */
179: public void setDetails(String sDetails) {
180: if (m_property_restrictions == null) {
181: m_property_restrictions = new ArrayList();
182: }
183:
184: if (sDetails != null) {
185: StringTokenizer tokenizer = new StringTokenizer(sDetails,
186: SEPARATOR);
187:
188: int i = 0;
189: int nTmp = 0;
190: while (tokenizer.hasMoreTokens()) {
191: String token = tokenizer.nextToken();
192:
193: if (token != null && token.length() > 0) {
194: m_property_restrictions.add(token);
195: }
196: }
197: }
198: super .setDetails(sDetails);
199: }
200:
201: /**
202: * Returns the properties whose instances can be added to the
203: * <code>Profile</code> values of this range.
204: *
205: * @param dsi the data store interface
206: * @return the properties whose instances can be added to the
207: * <code>Profile</code> values of this range
208: * @throws DataAccessException if an error occurs instantiating the
209: * <code>PropertyGroup</code>s or getting the children of those
210: * <code>PropertyGroup</code>s
211: */
212: public List getAllowedProperties(AbstractDataStoreInterface dsi)
213: throws DataAccessException {
214: List props = new Vector();
215:
216: List propGroupPaths = this .getAllowedPropertyParents();
217:
218: Iterator iter = propGroupPaths.iterator();
219:
220: while (iter.hasNext()) {
221: String sPath = (String) iter.next();
222:
223: try {
224: PropertyGroup propGroup = (PropertyGroup) HarmoniseObjectFactory
225: .instantiateHarmoniseObject(dsi,
226: PropertyGroup.class.getName(), sPath);
227:
228: if (propGroup != null) {
229: props
230: .addAll(propGroup
231: .getChildrenByType(AbstractParentObject.LEAF_NODES));
232: } else {
233: handleInvalidParentRestriction(sPath);
234: }
235:
236: } catch (HarmoniseFactoryException e) {
237: throw new DataAccessException(e.getLocalizedMessage(),
238: e);
239: }
240:
241: }
242:
243: return props;
244: }
245:
246: /**
247: * Handle an invalid path.
248: *
249: * @param path the invalid path
250: */
251: private void handleInvalidParentRestriction(String path) {
252: if (m_property_restrictions != null && path != null) {
253: m_property_restrictions.remove(path);
254: }
255: }
256:
257: /* (non-Javadoc)
258: * @see org.openharmonise.rm.resources.metadata.properties.ranges.Range#getPropertyInstanceClass()
259: */
260: public Class getPropertyInstanceClass()
261: throws ClassNotFoundException {
262: return ProfilePropertyInstance.class;
263: }
264:
265: /* (non-Javadoc)
266: * @see org.openharmonise.rm.publishing.Publishable#getTagName()
267: */
268: public String getTagName() {
269: return TAG_PROFILE_RANGE;
270: }
271:
272: /* (non-Javadoc)
273: * @see org.openharmonise.rm.publishing.Publishable#populate(org.w3c.dom.Element, org.openharmonise.rm.publishing.State)
274: */
275: public void populate(Element xmlElement, State state)
276: throws PopulateException {
277: String sTagname = xmlElement.getTagName();
278:
279: if (sTagname.equals(TAG_PATH_RESTRICTION)) {
280: String sPath = xmlElement.getFirstChild().getNodeValue();
281: addAllowedPropertyParent(sPath.trim());
282: } else {
283: super.populate(xmlElement, state);
284: }
285:
286: }
287:
288: }
|