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.net.*;
022: import java.util.*;
023:
024: import org.openharmonise.commons.xml.*;
025: import org.openharmonise.rm.metadata.*;
026: import org.openharmonise.rm.resources.*;
027: import org.w3c.dom.*;
028:
029: /**
030: * Class which generates the appropriate <code>Range</code> implementation
031: * for a given object description.
032: *
033: * @author Michael Bell
034: * @version $Revision: 1.1 $
035: *
036: */
037: public class RangeFactory {
038:
039: /**
040: * The singleton instance of this class.
041: */
042: private static RangeFactory m_instance = null;
043:
044: /**
045: * A <code>Map</code> of range descriptions and their associated range class names
046: */
047: private Map m_rangeMappings = new Hashtable();
048:
049: private static Map m_RangeTagMap = new Hashtable();
050:
051: static {
052: m_RangeTagMap.put(
053: AbsoluteChildObjectRange.TAG_ABSOLUTECHILDOBJECT_RANGE,
054: AbsoluteChildObjectRange.class);
055: m_RangeTagMap.put(BooleanRange.TAG_BOOLEAN_RANGE,
056: BooleanRange.class);
057: m_RangeTagMap.put(DateRange.TAG_DATE_RANGE, DateRange.class);
058: m_RangeTagMap.put(FloatRange.TAG_FLOAT_RANGE, FloatRange.class);
059: m_RangeTagMap.put(IntegerRange.TAG_INTEGER_RANGE,
060: IntegerRange.class);
061: m_RangeTagMap.put(ProfileRange.TAG_PROFILE_RANGE,
062: ProfileRange.class);
063: m_RangeTagMap.put(
064: RelativeChildObjectRange.TAG_RELATIVECHILDOBJECT_RANGE,
065: RelativeChildObjectRange.class);
066: m_RangeTagMap.put(StringRange.TAG_STRING_RANGE,
067: StringRange.class);
068: m_RangeTagMap.put(URIRange.TAG_URI_RANGE, URIRange.class);
069: }
070:
071: /**
072: * Constructs a new <code>RangeFactory</code>.
073: */
074: private RangeFactory() {
075:
076: }
077:
078: /**
079: * Returns the singleton instance of <code>RangeFactory</code>.
080: *
081: * @return the singleton instance of <code>RangeFactory</code>
082: */
083: public static RangeFactory getInstance() {
084: if (m_instance == null) {
085: m_instance = new RangeFactory();
086: }
087:
088: return m_instance;
089: }
090:
091: /**
092: * Returns the particular <code>Range</code> implementation which is
093: * appropriate for the range description given.
094: *
095: * Note: the range description is assumed to be a class name.
096: *
097: * @param sRangeDesc a class name which will determine which
098: * <code>Range</code> implementation should be returned
099: * @return a <code>Range</code> implementation appropriate to the
100: * specified class name
101: * @throws ClassNotFoundException if the class loader can not find the
102: * <code>Range</code> <code>Class</code>
103: */
104: public Range getRange(String sRangeDesc)
105: throws ClassNotFoundException, InvalidRangeObjectException {
106: Range result = null;
107:
108: if (sRangeDesc != null) {
109:
110: Class clss;
111:
112: clss = Class.forName(sRangeDesc);
113:
114: if (String.class.isAssignableFrom(clss) == true) {
115: result = new StringRange();
116: } else if (Date.class.isAssignableFrom(clss) == true) {
117: result = new DateRange();
118: } else if (Integer.class.isAssignableFrom(clss) == true) {
119: result = new IntegerRange();
120: } else if (Float.class.isAssignableFrom(clss) == true) {
121: result = new FloatRange();
122: } else if (AbstractChildObject.class.isAssignableFrom(clss)) {
123: result = new AbsoluteChildObjectRange(sRangeDesc);
124: } else if (Profile.class.isAssignableFrom(clss)) {
125: result = new ProfileRange();
126: } else if (Boolean.class.isAssignableFrom(clss)) {
127: result = new BooleanRange();
128: } else if (URL.class.isAssignableFrom(clss)) {
129: result = new URIRange();
130: } else if (Range.class.isAssignableFrom(clss)) {
131: try {
132: result = (Range) clss.newInstance();
133: } catch (InstantiationException e) {
134: throw new InvalidRangeObjectException(
135: "Range object invalid - " + sRangeDesc);
136: } catch (IllegalAccessException e) {
137: throw new InvalidRangeObjectException(
138: "Range object invalid - " + sRangeDesc);
139: }
140:
141: } else {
142: if (m_rangeMappings.containsKey(sRangeDesc) == true) {
143: String sRangeClassName = (String) m_rangeMappings
144: .get(sRangeDesc);
145: try {
146: result = (Range) Class.forName(sRangeClassName)
147: .newInstance();
148: } catch (InstantiationException e) {
149: throw new InvalidRangeObjectException(
150: "Range object invalid - " + sRangeDesc);
151: } catch (IllegalAccessException e) {
152: throw new InvalidRangeObjectException(
153: "Range object invalid - " + sRangeDesc);
154: }
155: } else {
156: throw new InvalidRangeObjectException(
157: "Range object invalid - " + sRangeDesc);
158: }
159: }
160: }
161:
162: return result;
163: }
164:
165: /**
166: * Adds a mapping between a specified class name and a <code>Range</code>
167: * class name.
168: *
169: * @param sClassname the class name which will map to the specified
170: * <code>Range</code>
171: * @param sRangeClassName the <code>Range</code> implementation class name
172: */
173: public void addNewRange(String sClassname, String sRangeClassName) {
174:
175: m_rangeMappings.put(sClassname, sRangeClassName);
176: }
177:
178: /**
179: * Adds a mapping between a specified class name, a <code>Range</code>
180: * class name and an XML tag name.
181: *
182: * @param sClassname the class name which will map to the specified
183: * <code>Range</code>
184: * @param sRangeClassName the <code>Range</code> implementation class name
185: * @param sTagname the XML tag name
186: */
187: public void addNewRange(String sClassname, String sRangeClassName,
188: String sTagname) throws ClassNotFoundException {
189:
190: m_rangeMappings.put(sClassname, sRangeClassName);
191: m_RangeTagMap.put(sTagname, Class.forName(sRangeClassName));
192: }
193:
194: /**
195: * Returns <code>true</code> if the specified XML tag name is
196: * associated to a <code>Range</code> implementation.
197: *
198: * @param sTagname the XML tag name
199: * @return <code>true</code> if the specified XML tag name is
200: * associated to a <code>Range</code> implementation
201: */
202: static public boolean isRangeTagName(String sTagname) {
203: return m_RangeTagMap.containsKey(sTagname);
204: }
205:
206: /**
207: * Returns the appropriate <code>Range</code> implementation for the
208: * specified XML element.
209: *
210: * @param xmlElement the range XML element
211: * @return the appropriate <code>Range</code> implementation
212: * @throws InvalidRangeObjectException if no appropriate range exists
213: * @throws ClassNotFoundException if the class loader can not find the
214: * associated <code>Range</code> class
215: */
216: public Range getRange(Element xmlElement)
217: throws InvalidRangeObjectException {
218: Range range = null;
219: String sTagname = xmlElement.getTagName();
220:
221: if (sTagname.equals(AbstractRange.TAG_RANGE)) {
222: Element objEl = XMLUtils.getFirstNamedChild(xmlElement,
223: AbstractRange.TAG_RANGE_OBJECT);
224:
225: if (objEl != null) {
226: String sObjName = objEl.getFirstChild().getNodeValue();
227: try {
228: range = getRange(sObjName);
229: } catch (ClassNotFoundException e) {
230: throw new InvalidRangeObjectException(
231: "Unable to instantiate range class for "
232: + sObjName);
233: }
234: } else {
235: throw new InvalidRangeObjectException(
236: "No range object defined");
237: }
238: } else if (isRangeTagName(sTagname)) {
239: Class rangeClass = (Class) m_RangeTagMap.get(sTagname);
240:
241: try {
242: range = (Range) rangeClass.newInstance();
243: } catch (InstantiationException e) {
244: throw new InvalidRangeObjectException(
245: "Unable to instantiate range class "
246: + rangeClass.getName());
247: } catch (IllegalAccessException e) {
248: throw new InvalidRangeObjectException(
249: "Unable to instantiate range class "
250: + rangeClass.getName());
251: }
252: }
253:
254: return range;
255: }
256: }
|