001: /*
002: Copyright (c) 2004-2007, Dennis M. Sosnoski
003: All rights reserved.
004:
005: Redistribution and use in source and binary forms, with or without modification,
006: are permitted provided that the following conditions are met:
007:
008: * Redistributions of source code must retain the above copyright notice, this
009: list of conditions and the following disclaimer.
010: * Redistributions in binary form must reproduce the above copyright notice,
011: this list of conditions and the following disclaimer in the documentation
012: and/or other materials provided with the distribution.
013: * Neither the name of JiBX nor the names of its contributors may be used
014: to endorse or promote products derived from this software without specific
015: prior written permission.
016:
017: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
018: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
019: WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
020: DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
021: ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
022: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
023: LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
024: ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
025: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
026: SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
027: */
028:
029: package org.jibx.binding.model;
030:
031: import org.jibx.binding.util.StringArray;
032:
033: /**
034: * Model component for elements that define the binding structure for an object
035: * property. This is the base class for <i>structure</i> and <i>collection</i>
036: * elements.
037: *
038: * @author Dennis M. Sosnoski
039: */
040: public abstract class StructureElementBase extends ContainerElementBase
041: implements IComponent {
042: /** Enumeration of allowed attribute names */
043: public static final StringArray s_allowedAttributes = new StringArray(
044: new StringArray(PropertyAttributes.s_allowedAttributes,
045: NameAttributes.s_allowedAttributes),
046: ContainerElementBase.s_allowedAttributes);
047:
048: /** Property attributes information for nesting. */
049: private PropertyAttributes m_propertyAttrs;
050:
051: /** Name attributes information for nesting. */
052: private NameAttributes m_nameAttrs;
053:
054: /**
055: * Constructor.
056: *
057: * @param type element type code
058: */
059: protected StructureElementBase(int type) {
060: super (type);
061: m_nameAttrs = new NameAttributes();
062: m_propertyAttrs = new PropertyAttributes();
063: }
064:
065: //
066: // Name attribute delegate methods
067:
068: /**
069: * Get name.
070: *
071: * @return name text
072: */
073: public String getName() {
074: return m_nameAttrs.getName();
075: }
076:
077: /**
078: * Set name.
079: *
080: * @param name text for name
081: */
082: public void setName(String name) {
083: m_nameAttrs.setName(name);
084: }
085:
086: /**
087: * Get specified namespace URI.
088: *
089: * @return namespace URI (<code>null</code> if not set)
090: */
091: public String getUri() {
092: return m_nameAttrs.getUri();
093: }
094:
095: /**
096: * Set namespace URI.
097: *
098: * @param uri namespace URI (<code>null</code> if not set)
099: */
100: public void setUri(String uri) {
101: m_nameAttrs.setUri(uri);
102: }
103:
104: /**
105: * Get specified namespace prefix.
106: *
107: * @return namespace prefix (<code>null</code> if not set)
108: */
109: public String getPrefix() {
110: return m_nameAttrs.getPrefix();
111: }
112:
113: /**
114: * Set namespace prefix.
115: *
116: * @param prefix namespace prefix (<code>null</code> if not set)
117: */
118: public void setPrefix(String prefix) {
119: m_nameAttrs.setPrefix(prefix);
120: }
121:
122: /**
123: * Get effective namespace information. This call is only meaningful after
124: * validation.
125: *
126: * @return effective namespace information
127: */
128: public NamespaceElement getNamespace() {
129: return m_nameAttrs.getNamespace();
130: }
131:
132: //
133: // Property attribute delegate methods
134:
135: /**
136: * Get usage name.
137: *
138: * @return usage name
139: */
140: public String getUsageName() {
141: return m_propertyAttrs.getUsageName();
142: }
143:
144: /**
145: * Get usage value. This call is only meaningful after validation.
146: *
147: * @return usage value
148: */
149: public int getUsage() {
150: return m_propertyAttrs.getUsage();
151: }
152:
153: /**
154: * Set usage name.
155: *
156: * @param name usage name
157: */
158: public void setUsageName(String name) {
159: m_propertyAttrs.setUsageName(name);
160: }
161:
162: /**
163: * Check if property is defined. This method is only meaningful after
164: * validation.
165: *
166: * @return <code>true</code> if property defined, <code>false</code> if not
167: */
168: public boolean hasProperty() {
169: return m_propertyAttrs.hasProperty();
170: }
171:
172: /**
173: * Get declared type name.
174: *
175: * @return type name (or <code>null</code> if none)
176: */
177: public String getDeclaredType() {
178: return m_propertyAttrs.getDeclaredType();
179: }
180:
181: /**
182: * Set declared type name.
183: *
184: * @param type name (or <code>null</code> if none)
185: */
186: public void setDeclaredType(String type) {
187: m_propertyAttrs.setDeclaredType(type);
188: }
189:
190: /**
191: * Get field name.
192: *
193: * @return field name (or <code>null</code> if none)
194: */
195: public String getFieldName() {
196: return m_propertyAttrs.getFieldName();
197: }
198:
199: /**
200: * Get field information. This call is only meaningful after validation.
201: *
202: * @return field information (or <code>null</code> if none)
203: */
204: public IClassItem getField() {
205: return m_propertyAttrs.getField();
206: }
207:
208: /**
209: * Set field name.
210: *
211: * @param field field name (or <code>null</code> if none)
212: */
213: public void setFieldName(String field) {
214: m_propertyAttrs.setFieldName(field);
215: }
216:
217: /**
218: * Get test method name.
219: *
220: * @return test method name (or <code>null</code> if none)
221: */
222: public String getTestName() {
223: return m_propertyAttrs.getTestName();
224: }
225:
226: /**
227: * Get test method information. This call is only meaningful after
228: * validation.
229: *
230: * @return test method information (or <code>null</code> if none)
231: */
232: public IClassItem getTest() {
233: return m_propertyAttrs.getTest();
234: }
235:
236: /**
237: * Set test method name.
238: *
239: * @param test test method name (or <code>null</code> if none)
240: */
241: public void setTestName(String test) {
242: m_propertyAttrs.setTestName(test);
243: }
244:
245: /**
246: * Get get method name.
247: *
248: * @return get method name (or <code>null</code> if none)
249: */
250: public String getGetName() {
251: return m_propertyAttrs.getGetName();
252: }
253:
254: /**
255: * Get get method information. This call is only meaningful after
256: * validation.
257: *
258: * @return get method information (or <code>null</code> if none)
259: */
260: public IClassItem getGet() {
261: return m_propertyAttrs.getGet();
262: }
263:
264: /**
265: * Get type for value loaded to stack. This call is only meaningful after
266: * validation.
267: *
268: * @return get value type (or <code>null</code> if none)
269: */
270: public IClass getGetType() {
271: return m_propertyAttrs.getGetType();
272: }
273:
274: /**
275: * Set get method name.
276: *
277: * @param get get method name (or <code>null</code> if none)
278: */
279: public void setGetName(String get) {
280: m_propertyAttrs.setGetName(get);
281: }
282:
283: /**
284: * Get set method name.
285: *
286: * @return set method name (or <code>null</code> if none)
287: */
288: public String getSetName() {
289: return m_propertyAttrs.getSetName();
290: }
291:
292: /**
293: * Get set method information. This call is only meaningful after
294: * validation.
295: *
296: * @return set method information (or <code>null</code> if none)
297: */
298: public IClassItem getSet() {
299: return m_propertyAttrs.getSet();
300: }
301:
302: /**
303: * Get type for value stored from stack. This call is only meaningful after
304: * validation.
305: *
306: * @return set value type (or <code>null</code> if none)
307: */
308: public IClass getSetType() {
309: return m_propertyAttrs.getSetType();
310: }
311:
312: /**
313: * Set set method name.
314: *
315: * @param set set method name (or <code>null</code> if none)
316: */
317: public void setSetName(String set) {
318: m_propertyAttrs.setSetName(set);
319: }
320:
321: /**
322: * Check if this structure implicitly uses the containing object. This call
323: * is only meaningful after prevalidation.
324: *
325: * @return <code>true</code> if using the containing object,
326: * <code>false</code> if own object
327: * @see org.jibx.binding.model.ContainerElementBase#isImplicit()
328: */
329: public boolean isImplicit() {
330: return m_propertyAttrs.isImplicit();
331: }
332:
333: //
334: // Implementation methods
335:
336: /* (non-Javadoc)
337: * @see org.jibx.binding.model.ElementBase#isOptional()
338: */
339: public boolean isOptional() {
340: return m_propertyAttrs.getUsage() == PropertyAttributes.OPTIONAL_USAGE;
341: }
342:
343: /* (non-Javadoc)
344: * @see org.jibx.binding.model.ContainerElementBase#hasObject()
345: */
346: public boolean hasObject() {
347: return !isImplicit() || getDeclaredType() != null;
348: }
349:
350: //
351: // Implementation of methods from IComponent interface (used in extensions)
352:
353: /* (non-Javadoc)
354: * @see org.jibx.binding.model.IComponent#hasAttribute()
355: */
356: public boolean hasAttribute() {
357: if (m_nameAttrs.getName() != null) {
358: return false;
359: } else {
360: return getAttributeComponents().size() > 0;
361: }
362: }
363:
364: /* (non-Javadoc)
365: * @see org.jibx.binding.model.IComponent#hasContent()
366: */
367: public boolean hasContent() {
368: if (m_nameAttrs.getName() != null) {
369: return true;
370: } else {
371: return getContentComponents().size() > 0;
372: }
373: }
374:
375: /* (non-Javadoc)
376: * @see org.jibx.binding.model.IComponent#hasName()
377: */
378: public boolean hasName() {
379: return m_nameAttrs.getName() != null;
380: }
381:
382: /* (non-Javadoc)
383: * @see org.jibx.binding.model.IComponent#getType()
384: */
385: public IClass getType() {
386: return m_propertyAttrs.getType();
387: }
388:
389: /* (non-Javadoc)
390: * @see org.jibx.binding.model.ContainerElementBase#getType()
391: */
392: public IClass getObjectType() {
393: return getType();
394: }
395:
396: //
397: // Validation methods
398:
399: /* (non-Javadoc)
400: * @see org.jibx.binding.model.ElementBase#prevalidate(org.jibx.binding.model.ValidationContext)
401: */
402: public void prevalidate(ValidationContext vctx) {
403: m_nameAttrs.prevalidate(vctx);
404: m_propertyAttrs.prevalidate(vctx);
405: if (!vctx.isSkipped(this )) {
406: super .prevalidate(vctx);
407: }
408: }
409:
410: /* (non-Javadoc)
411: * @see org.jibx.binding.model.ElementBase#validate(org.jibx.binding.model.ValidationContext)
412: */
413: public void validate(ValidationContext vctx) {
414:
415: // validate the attribute groups
416: m_nameAttrs.validate(vctx);
417: m_propertyAttrs.validate(vctx);
418: if (!vctx.isSkipped(this )) {
419:
420: // check for way of constructing object instance on input
421: if (m_propertyAttrs.hasProperty() && children().size() > 0) {
422: verifyConstruction(vctx, m_propertyAttrs.getType());
423: }
424:
425: // check use of text values in children of structure with name
426: SequenceVisitor visitor = new SequenceVisitor(this , vctx);
427: TreeContext tctx = vctx.getChildContext();
428: tctx.tourTree(this , visitor);
429:
430: // finish with superclass validation
431: super.validate(vctx);
432: }
433: }
434: }
|