001: /*--
002:
003: Copyright (C) 2002-2005 Adrian Price.
004: All rights reserved.
005:
006: Redistribution and use in source and binary forms, with or without
007: modification, are permitted provided that the following conditions
008: are met:
009:
010: 1. Redistributions of source code must retain the above copyright
011: notice, this list of conditions, and the following disclaimer.
012:
013: 2. Redistributions in binary form must reproduce the above copyright
014: notice, this list of conditions, and the disclaimer that follows
015: these conditions in the documentation and/or other materials
016: provided with the distribution.
017:
018: 3. The names "OBE" and "Open Business Engine" must not be used to
019: endorse or promote products derived from this software without prior
020: written permission. For written permission, please contact
021: adrianprice@sourceforge.net.
022:
023: 4. Products derived from this software may not be called "OBE" or
024: "Open Business Engine", nor may "OBE" or "Open Business Engine"
025: appear in their name, without prior written permission from
026: Adrian Price (adrianprice@users.sourceforge.net).
027:
028: THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
029: WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
030: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
031: DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
032: INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
033: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
034: SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
035: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
036: STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
037: IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
038: POSSIBILITY OF SUCH DAMAGE.
039:
040: For more information on OBE, please see
041: <http://obe.sourceforge.net/>.
042:
043: */
044:
045: package org.obe.client.api.repository;
046:
047: import org.obe.util.ClassUtils;
048: import org.xml.sax.EntityResolver;
049:
050: import java.io.Serializable;
051: import java.lang.reflect.Constructor;
052:
053: /**
054: * An abstract base class for meta-data implementations. The meta-data supports
055: * a kind of inheritance; repository entries can reference a parent type (by id)
056: * via their 'type' attribute. Property accessor methods automatically return
057: * the parent property value if the child value is <code>null</code>. N.B.
058: * subclasses' property getters are expected to conform to this pattern.
059: *
060: * @author Adrian Price
061: */
062: public abstract class AbstractMetaData implements Serializable {
063: private static final long serialVersionUID = 3738728655687826825L;
064: /**
065: * Enables field inheritance via the <code>type</code> delegate chain.
066: */
067: public static boolean allowInheritance = true;
068: protected static final String[] NO_ARGS_SIG = {};
069: protected static final Object[] EMPTY_ARGS = {};
070: private transient Constructor _ctor;
071: protected AbstractMetaData _type; // The type of which this is a sub-type.
072: protected String _id;
073: protected String _displayName;
074: protected String _description;
075: protected String _docUrl;
076: protected String _author;
077: protected boolean _threadsafe;
078:
079: protected AbstractMetaData() {
080: }
081:
082: protected AbstractMetaData(String id, String displayName,
083: String description, String docUrl, String author,
084: boolean threadsafe) {
085:
086: _id = id;
087: _displayName = displayName;
088: _description = description;
089: _docUrl = docUrl;
090: _author = author;
091: _threadsafe = threadsafe;
092: }
093:
094: protected final Object createInstance(Object[] ctorArgs)
095: throws RepositoryException {
096:
097: try {
098: // This is all done by reflection to eliminate dependencies of
099: // Client API classes upon engine classes. This method may fail
100: // if called in a client environment.
101: if (_ctor == null) {
102: Class clazz = getClass().getClassLoader().loadClass(
103: getImplClass());
104: Class[] implCtorSig = ClassUtils
105: .classesForNames(getImplCtorSig());
106: _ctor = clazz.getConstructor(implCtorSig);
107: }
108: return _ctor.newInstance(ctorArgs);
109: } catch (Exception e) {
110: throw new RepositoryException(e);
111: }
112: }
113:
114: public abstract Object createInstance(EntityResolver entityResolver)
115: throws RepositoryException;
116:
117: public Object createInstance(EntityResolver entityResolver,
118: Object args) throws RepositoryException {
119:
120: // Default implementation ignores the state parameter.
121: return createInstance(entityResolver);
122: }
123:
124: protected abstract String getImplClass();
125:
126: protected abstract String[] getImplCtorSig();
127:
128: public final String getId() {
129: return _id;
130: }
131:
132: public final void setId(String id) {
133: _id = id;
134: }
135:
136: public final String getDisplayName() {
137: return _displayName != null ? _displayName : _type == null
138: || !allowInheritance ? null : _type.getDisplayName();
139: }
140:
141: public final void setDisplayName(String displayName) {
142: _displayName = displayName;
143: }
144:
145: public final String getDescription() {
146: return _description != null ? _description : _type == null
147: || !allowInheritance ? null : _type.getDescription();
148: }
149:
150: public final void setDescription(String description) {
151: _description = description;
152: }
153:
154: public final String getDocUrl() {
155: return _docUrl != null ? _docUrl : _type == null
156: || !allowInheritance ? null : _type.getDocUrl();
157: }
158:
159: public final void setDocUrl(String docUrl) {
160: _docUrl = docUrl;
161: }
162:
163: public final String getAuthor() {
164: return _author != null ? _author : _type == null
165: || !allowInheritance ? null : _type.getAuthor();
166: }
167:
168: public final void setAuthor(String author) {
169: _author = author;
170: }
171:
172: public final boolean isThreadsafe() {
173: return _threadsafe;
174: }
175:
176: public final boolean getThreadsafe() {
177: return _threadsafe;
178: }
179:
180: public final void setThreadsafe(boolean threadsafe) {
181: _threadsafe = threadsafe;
182: }
183:
184: public final AbstractMetaData getType() {
185: return _type;
186: }
187:
188: public final void setType(AbstractMetaData type) {
189: _type = type;
190: }
191:
192: public String toString() {
193: String className = getClass().getName();
194: className = className.substring(className.lastIndexOf('.') + 1);
195: return className + "[id='" + _id + "',displayName='"
196: + _displayName + "',description='" + _description
197: + "',docUrl='" + _docUrl + "',author='" + _author
198: + "',threadsafe=" + _threadsafe + ",type=" + _type
199: + ']';
200: }
201: }
|