001: /*
002: * The Apache Software License, Version 1.1
003: *
004: *
005: * Copyright (c) 1999,2000 The Apache Software Foundation. All rights
006: * reserved.
007: *
008: * Redistribution and use in source and binary forms, with or without
009: * modification, are permitted provided that the following conditions
010: * are met:
011: *
012: * 1. Redistributions of source code must retain the above copyright
013: * notice, this list of conditions and the following disclaimer.
014: *
015: * 2. Redistributions in binary form must reproduce the above copyright
016: * notice, this list of conditions and the following disclaimer in
017: * the documentation and/or other materials provided with the
018: * distribution.
019: *
020: * 3. The end-user documentation included with the redistribution,
021: * if any, must include the following acknowledgment:
022: * "This product includes software developed by the
023: * Apache Software Foundation (http://www.apache.org/)."
024: * Alternately, this acknowledgment may appear in the software itself,
025: * if and wherever such third-party acknowledgments normally appear.
026: *
027: * 4. The names "Xerces" and "Apache Software Foundation" must
028: * not be used to endorse or promote products derived from this
029: * software without prior written permission. For written
030: * permission, please contact apache@apache.org.
031: *
032: * 5. Products derived from this software may not be called "Apache",
033: * nor may "Apache" appear in their name, without prior written
034: * permission of the Apache Software Foundation.
035: *
036: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
037: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
038: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
039: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
040: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
041: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
042: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
043: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
044: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
045: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
046: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
047: * SUCH DAMAGE.
048: * ====================================================================
049: *
050: * This software consists of voluntary contributions made by many
051: * individuals on behalf of the Apache Software Foundation and was
052: * originally based on software copyright (c) 1999, International
053: * Business Machines, Inc., http://www.apache.org. For more
054: * information on the Apache Software Foundation, please see
055: * <http://www.apache.org/>.
056: */
057:
058: package org.apache.xerces.validators.common;
059:
060: import org.apache.xerces.framework.XMLContentSpec;
061: import org.apache.xerces.utils.ImplementationMessages;
062: import org.apache.xerces.utils.QName;
063: import org.apache.xerces.validators.schema.SchemaGrammar;
064:
065: import org.apache.xerces.validators.schema.SubstitutionGroupComparator;
066:
067: /**
068: * SimpleContentModel is a derivative of the abstract content model base
069: * class that handles a small set of simple content models that are just
070: * way overkill to give the DFA treatment.
071: * <p>
072: * This class handles the following scenarios:
073: * <ul>
074: * <li> a
075: * <li> a?
076: * <li> a*
077: * <li> a+
078: * <li> a,b
079: * <li> a|b
080: * </ul>
081: * <p>
082: * These all involve a unary operation with one element type, or a binary
083: * operation with two elements. These are very simple and can be checked
084: * in a simple way without a DFA and without the overhead of setting up a
085: * DFA for such a simple check.
086: *
087: * @version $Id: SimpleContentModel.java,v 1.13 2001/07/10 14:38:20 sandygao Exp $
088: */
089: public class SimpleContentModel implements XMLContentModel {
090:
091: //
092: // Data
093: //
094:
095: /**
096: * The element decl pool indices of the first (and optional second)
097: * child node. The operation code tells us whether the second child
098: * is used or not.
099: */
100: private QName fFirstChild = new QName();
101:
102: /**
103: * The element decl pool indices of the first (and optional second)
104: * child node. The operation code tells us whether the second child
105: * is used or not.
106: */
107: private QName fSecondChild = new QName();
108:
109: /**
110: * The operation that this object represents. Since this class only
111: * does simple contents, there is only ever a single operation
112: * involved (i.e. the children of the operation are always one or
113: * two leafs.) This is one of the XMLDTDParams.CONTENTSPECNODE_XXX values.
114: */
115: private int fOp;
116:
117: /** Boolean to allow DTDs to validate even with namespace support. */
118: private boolean fDTD;
119:
120: /* this is the SubstitutionGroupComparator object */
121: private SubstitutionGroupComparator comparator = null;
122:
123: //
124: // Constructors
125: //
126:
127: /**
128: * Constructs a simple content model.
129: *
130: * @param firstChildIndex The first child index
131: * @parma secondChildIndex The second child index.
132: * @param cmOp The content model operator.
133: *
134: * @see XMLContentSpec
135: */
136: public SimpleContentModel(QName firstChild, QName secondChild,
137: int cmOp) {
138: this (firstChild, secondChild, cmOp, false);
139: }
140:
141: /**
142: * Constructs a simple content model.
143: *
144: * @param firstChildIndex The first child index
145: * @parma secondChildIndex The second child index.
146: * @param cmOp The content model operator.
147: *
148: * @see XMLContentSpec
149: */
150: public SimpleContentModel(QName firstChild, QName secondChild,
151: int cmOp, boolean dtd) {
152: //
153: // Store away the children and operation. This is all we need to
154: // do the content model check.
155: //
156: // The operation is one of the ContentSpecNode.NODE_XXX values!
157: //
158: fFirstChild.setValues(firstChild);
159: if (secondChild != null) {
160: fSecondChild.setValues(secondChild);
161: } else {
162: fSecondChild.clear();
163: }
164: fOp = cmOp;
165: fDTD = dtd;
166: }
167:
168: // Unique Particle Attribution
169: public void checkUniqueParticleAttribution(SchemaGrammar gram)
170: throws Exception {
171: // rename back
172: fFirstChild.uri = gram.getContentSpecOrgUri(fFirstChild.uri);
173: fSecondChild.uri = gram.getContentSpecOrgUri(fSecondChild.uri);
174:
175: // only possible violation is when it's a choice
176: if (fOp == XMLContentSpec.CONTENTSPECNODE_CHOICE
177: && ElementWildcard.conflict(
178: XMLContentSpec.CONTENTSPECNODE_LEAF,
179: fFirstChild.localpart, fFirstChild.uri,
180: XMLContentSpec.CONTENTSPECNODE_LEAF,
181: fSecondChild.localpart, fSecondChild.uri,
182: comparator)) {
183: }
184: }
185:
186: // Unique Particle Attribution
187:
188: //
189: // XMLContentModel methods
190: //
191:
192: /**
193: * Check that the specified content is valid according to this
194: * content model. This method can also be called to do 'what if'
195: * testing of content models just to see if they would be valid.
196: * <p>
197: * A value of -1 in the children array indicates a PCDATA node. All other
198: * indexes will be positive and represent child elements. The count can be
199: * zero, since some elements have the EMPTY content model and that must be
200: * confirmed.
201: *
202: * @param children The children of this element. Each integer is an index within
203: * the <code>StringPool</code> of the child element name. An index
204: * of -1 is used to indicate an occurrence of non-whitespace character
205: * data.
206: * @param offset Offset into the array where the children starts.
207: * @param length The number of entries in the <code>children</code> array.
208: *
209: * @return The value -1 if fully valid, else the 0 based index of the child
210: * that first failed. If the value returned is equal to the number
211: * of children, then the specified children are valid but additional
212: * content is required to reach a valid ending state.
213: *
214: * @exception Exception Thrown on error.
215: */
216: public int validateContent(QName children[], int offset, int length)
217: throws Exception {
218:
219: //
220: // According to the type of operation, we do the correct type of
221: // content check.
222: //
223: switch (fOp) {
224: case XMLContentSpec.CONTENTSPECNODE_LEAF:
225: // If there is not a child, then report an error at index 0
226: if (length == 0)
227: return 0;
228:
229: // If the 0th child is not the right kind, report an error at 0
230: if (fDTD) {
231: if (children[offset].rawname != fFirstChild.rawname) {
232: return 0;
233: }
234: } else {
235: if (children[offset].uri != fFirstChild.uri
236: || children[offset].localpart != fFirstChild.localpart)
237: return 0;
238: }
239:
240: // If more than one child, report an error at index 1
241: if (length > 1)
242: return 1;
243: break;
244:
245: case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE:
246: //
247: // If there is one child, make sure its the right type. If not,
248: // then its an error at index 0.
249: //
250: if (length == 1) {
251: if (fDTD) {
252: if (children[offset].rawname != fFirstChild.rawname) {
253: return 0;
254: }
255: } else {
256: if (children[offset].uri != fFirstChild.uri
257: || children[offset].localpart != fFirstChild.localpart)
258: return 0;
259: }
260: }
261:
262: //
263: // If the child count is greater than one, then obviously
264: // bad, so report an error at index 1.
265: //
266: if (length > 1)
267: return 1;
268: break;
269:
270: case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE:
271: //
272: // If the child count is zero, that's fine. If its more than
273: // zero, then make sure that all children are of the element
274: // type that we stored. If not, report the index of the first
275: // failed one.
276: //
277: if (length > 0) {
278: if (fDTD) {
279: for (int index = 0; index < length; index++) {
280: if (children[offset + index].rawname != fFirstChild.rawname) {
281: return index;
282: }
283: }
284: } else {
285: for (int index = 0; index < length; index++) {
286: if (children[offset + index].uri != fFirstChild.uri
287: || children[offset + index].localpart != fFirstChild.localpart)
288: return index;
289: }
290: }
291: }
292: break;
293:
294: case XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE:
295: //
296: // If the child count is zero, that's an error so report
297: // an error at index 0.
298: //
299: if (length == 0)
300: return 0;
301:
302: //
303: // Otherwise we have to check them all to make sure that they
304: // are of the correct child type. If not, then report the index
305: // of the first one that is not.
306: //
307: if (fDTD) {
308: for (int index = 0; index < length; index++) {
309: if (children[offset + index].rawname != fFirstChild.rawname) {
310: return index;
311: }
312: }
313: } else {
314: for (int index = 0; index < length; index++) {
315: if (children[offset + index].uri != fFirstChild.uri
316: || children[offset + index].localpart != fFirstChild.localpart)
317: return index;
318: }
319: }
320: break;
321:
322: case XMLContentSpec.CONTENTSPECNODE_CHOICE:
323: //
324: // There must be one and only one child, so if the element count
325: // is zero, return an error at index 0.
326: //
327: if (length == 0)
328: return 0;
329:
330: // If the zeroth element isn't one of our choices, error at 0
331: if (fDTD) {
332: if ((children[offset].rawname != fFirstChild.rawname)
333: && (children[offset].rawname != fSecondChild.rawname)) {
334: return 0;
335: }
336: } else {
337: if ((children[offset].uri != fFirstChild.uri || children[offset].localpart != fFirstChild.localpart)
338: && (children[offset].uri != fSecondChild.uri || children[offset].localpart != fSecondChild.localpart))
339: return 0;
340: }
341:
342: // If there is more than one element, then an error at 1
343: if (length > 1)
344: return 1;
345: break;
346:
347: case XMLContentSpec.CONTENTSPECNODE_SEQ:
348: //
349: // There must be two children and they must be the two values
350: // we stored, in the stored order.
351: //
352: if (length == 2) {
353: if (fDTD) {
354: if (children[offset].rawname != fFirstChild.rawname) {
355: return 0;
356: }
357: if (children[offset + 1].rawname != fSecondChild.rawname) {
358: return 1;
359: }
360: } else {
361: if (children[offset].uri != fFirstChild.uri
362: || children[offset].localpart != fFirstChild.localpart)
363: return 0;
364:
365: if (children[offset + 1].uri != fSecondChild.uri
366: || children[offset + 1].localpart != fSecondChild.localpart)
367: return 1;
368: }
369: } else {
370: if (length > 2) {
371: return 2;
372: }
373:
374: return length;
375: }
376:
377: break;
378:
379: default:
380: throw new CMException(ImplementationMessages.VAL_CST);
381: }
382:
383: // We survived, so return success status
384: return -1;
385: }
386:
387: public int validateContentSpecial(QName children[], int offset,
388: int length) throws Exception {
389:
390: if (comparator == null) {
391: return validateContent(children, offset, length);
392: }
393: //
394: // According to the type of operation, we do the correct type of
395: // content check.
396: //
397: switch (fOp) {
398: case XMLContentSpec.CONTENTSPECNODE_LEAF:
399: // If there is not a child, then report an error at index 0
400: if (length == 0)
401: return 0;
402:
403: // If the 0th child is not the right kind, report an error at 0
404: if (children[offset].uri != fFirstChild.uri
405: || children[offset].localpart != fFirstChild.localpart)
406: if (!comparator.isEquivalentTo(children[offset],
407: fFirstChild))
408: return 0;
409:
410: // If more than one child, report an error at index 1
411: if (length > 1)
412: return 1;
413: break;
414:
415: case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE:
416: //
417: // If there is one child, make sure its the right type. If not,
418: // then its an error at index 0.
419: //
420: if (length == 1
421: && (children[offset].uri != fFirstChild.uri || children[offset].localpart != fFirstChild.localpart))
422: if (!comparator.isEquivalentTo(children[offset],
423: fFirstChild))
424: return 0;
425:
426: //
427: // If the child count is greater than one, then obviously
428: // bad, so report an error at index 1.
429: //
430: if (length > 1)
431: return 1;
432: break;
433:
434: case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE:
435: //
436: // If the child count is zero, that's fine. If its more than
437: // zero, then make sure that all children are of the element
438: // type that we stored. If not, report the index of the first
439: // failed one.
440: //
441: if (length > 0) {
442: for (int index = 0; index < length; index++) {
443: if (children[offset + index].uri != fFirstChild.uri
444: || children[offset + index].localpart != fFirstChild.localpart)
445: if (!comparator.isEquivalentTo(children[offset
446: + index], fFirstChild))
447: return index;
448: }
449: }
450: break;
451:
452: case XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE:
453: //
454: // If the child count is zero, that's an error so report
455: // an error at index 0.
456: //
457: if (length == 0)
458: return 0;
459:
460: //
461: // Otherwise we have to check them all to make sure that they
462: // are of the correct child type. If not, then report the index
463: // of the first one that is not.
464: //
465: for (int index = 0; index < length; index++) {
466: if (children[offset + index].uri != fFirstChild.uri
467: || children[offset + index].localpart != fFirstChild.localpart)
468: if (!comparator.isEquivalentTo(children[offset
469: + index], fFirstChild))
470: return index;
471: }
472: break;
473:
474: case XMLContentSpec.CONTENTSPECNODE_CHOICE:
475: //
476: // There must be one and only one child, so if the element count
477: // is zero, return an error at index 0.
478: //
479: if (length == 0)
480: return 0;
481:
482: // If the zeroth element isn't one of our choices, error at 0
483: if ((children[offset].uri != fFirstChild.uri || children[offset].localpart != fFirstChild.localpart)
484: && (children[offset].uri != fSecondChild.uri || children[offset].localpart != fSecondChild.localpart))
485: if (!comparator.isEquivalentTo(children[offset],
486: fFirstChild)
487: && !comparator.isEquivalentTo(children[offset],
488: fSecondChild))
489: return 0;
490:
491: // If there is more than one element, then an error at 1
492: if (length > 1)
493: return 1;
494: break;
495:
496: case XMLContentSpec.CONTENTSPECNODE_SEQ:
497: //
498: // There must be two children and they must be the two values
499: // we stored, in the stored order.
500: //
501: if (length == 2) {
502: if (children[offset].uri != fFirstChild.uri
503: || children[offset].localpart != fFirstChild.localpart)
504: if (!comparator.isEquivalentTo(children[offset],
505: fFirstChild))
506: return 0;
507:
508: if (children[offset + 1].uri != fSecondChild.uri
509: || children[offset + 1].localpart != fSecondChild.localpart)
510: if (!comparator.isEquivalentTo(
511: children[offset + 1], fSecondChild))
512: return 1;
513: } else {
514: if (length > 2) {
515: return 2;
516: }
517:
518: return length;
519: }
520:
521: break;
522:
523: default:
524: throw new CMException(ImplementationMessages.VAL_CST);
525: }
526:
527: // We survived, so return success status
528: return -1;
529: }
530:
531: public void setSubstitutionGroupComparator(
532: SubstitutionGroupComparator comparator) {
533: this .comparator = comparator;
534: }
535:
536: /**
537: * Returns information about which elements can be placed at a particular point
538: * in the passed element's content model.
539: * <p>
540: * Note that the incoming content model to test must be valid at least up to
541: * the insertion point. If not, then -1 will be returned and the info object
542: * will not have been filled in.
543: * <p>
544: * If, on return, the info.isValidEOC flag is set, then the 'insert after'
545: * element is a valid end of content. In other words, nothing needs to be
546: * inserted after it to make the parent element's content model valid.
547: *
548: * @param fullyValid Only return elements that can be inserted and still
549: * maintain the validity of subsequent elements past the
550: * insertion point (if any). If the insertion point is at
551: * the end, and this is true, then only elements that can
552: * be legal final states will be returned.
553: * @param info An object that contains the required input data for the method,
554: * and which will contain the output information if successful.
555: *
556: * @return The value -1 if fully valid, else the 0 based index of the child
557: * that first failed before the insertion point. If the value
558: * returned is equal to the number of children, then the specified
559: * children are valid but additional content is required to reach a
560: * valid ending state.
561: *
562: * @see InsertableElementsInfo
563: */
564: public int whatCanGoHere(boolean fullyValid,
565: InsertableElementsInfo info) throws Exception {
566:
567: //
568: // For this one, having the empty slot at the insertion point is
569: // a problem. So lets compress the array down. We know that it has
570: // to have at least the empty slot at the insertion point.
571: //
572: for (int index = info.insertAt; index < info.childCount - 1; index++) {
573: info.curChildren[index]
574: .setValues(info.curChildren[index + 1]);
575: }
576: info.childCount--;
577:
578: //
579: // Check the validity of the existing contents. If this is less than
580: // the insert at point, then return failure index right now
581: //
582: final int failedIndex = validateContent(info.curChildren, 0,
583: info.childCount);
584: if ((failedIndex != -1) && (failedIndex < info.insertAt))
585: return failedIndex;
586:
587: // Set any stuff we can know right off the bat for all cases
588: info.canHoldPCData = false;
589:
590: // See how many children we can possibly report
591: if ((fOp == XMLContentSpec.CONTENTSPECNODE_LEAF)
592: || (fOp == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE)
593: || (fOp == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE)
594: || (fOp == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE)) {
595: info.resultsCount = 1;
596: } else if ((fOp == XMLContentSpec.CONTENTSPECNODE_CHOICE)
597: || (fOp == XMLContentSpec.CONTENTSPECNODE_SEQ)) {
598: info.resultsCount = 2;
599: } else {
600: throw new CMException(ImplementationMessages.VAL_CST);
601: }
602:
603: //
604: // If the outgoing arrays are too small or null, create new ones. These
605: // have to be at least the size of the results count.
606: //
607: if ((info.results == null)
608: || (info.results.length < info.resultsCount))
609: info.results = new boolean[info.resultsCount];
610:
611: if ((info.possibleChildren == null)
612: || (info.possibleChildren.length < info.resultsCount)) {
613: info.possibleChildren = new QName[info.resultsCount];
614: for (int i = 0; i < info.possibleChildren.length; i++) {
615: info.possibleChildren[i] = new QName();
616: }
617: }
618:
619: //
620: // Fill in the possible children array, and set all of the associated
621: // results entries to defaults of false.
622: //
623: info.possibleChildren[0].setValues(fFirstChild);
624: info.results[0] = false;
625: if (info.resultsCount == 2) {
626: info.possibleChildren[1].setValues(fSecondChild);
627: info.results[1] = false;
628: }
629:
630: //
631: // Set some defaults so that it does not have to be done redundantly
632: // below in each case.
633: //
634: info.isValidEOC = false;
635:
636: //
637: // Now, for each spec type, lets do the grunt work required. Each of
638: // them is pretty simple, its just making sure of corner cases.
639: //
640: // We know its valid up to the insert point at least and we know that
641: // the insert point is never past the number of children, so this releaves
642: // a lot of checking below.
643: //
644: switch (fOp) {
645: case XMLContentSpec.CONTENTSPECNODE_LEAF:
646: case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE:
647: //
648: // If there are no current children, then insert at has to be
649: // zero, so we can have the one leaf element inserted here.
650: //
651: if (info.childCount == 0) {
652: info.results[0] = true;
653: } else if (info.childCount > 0) {
654: //
655: // If the child count is greater than zero, then inserting
656: // anything cannot be fully valid. But, if not fully valid
657: // checking, it is ok as long as inserting at zero.
658: //
659: if (!fullyValid && (info.insertAt == 0))
660: info.results[0] = true;
661: }
662:
663: if (fOp == XMLContentSpec.CONTENTSPECNODE_LEAF) {
664: // If the insert point is 1, then EOC is valid there
665: if (info.insertAt == 0)
666: info.isValidEOC = true;
667: } else {
668: // Its zero or one, so EOC is valid in either case
669: info.isValidEOC = true;
670: }
671: break;
672:
673: case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE:
674: case XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE:
675: //
676: // The one child is always possible to insert, regardless of
677: // where. The fully valid flag never comes into play since it
678: // cannot become invalid by inserting any number of new
679: // instances of the one element.
680: //
681: info.results[0] = true;
682:
683: //
684: // Its zero/one or more, so EOC is valid in either case but only
685: // after the 0th index for one or more.
686: //
687: if ((fOp == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE)
688: || (info.insertAt > 0)) {
689: info.isValidEOC = true;
690: }
691: break;
692:
693: case XMLContentSpec.CONTENTSPECNODE_CHOICE:
694: //
695: // If the insert point is zero, then either of the two children
696: // can be inserted, unless fully valid is set and there are
697: // already any children.
698: //
699: if (info.insertAt == 0) {
700: if (!fullyValid && (info.childCount == 0)) {
701: info.results[0] = true;
702: info.results[1] = true;
703: }
704: }
705:
706: // EOC is only valid at the end
707: if (info.insertAt == 1)
708: info.isValidEOC = true;
709: break;
710:
711: case XMLContentSpec.CONTENTSPECNODE_SEQ:
712: //
713: // If the insert at is 0, then the first one valid. Else its
714: // the second one.
715: //
716: if (info.insertAt == 0) {
717: //
718: // If fully valid check, then if there are two children,
719: // it cannot be valid. If there is one child, it must be
720: // equal to the second child of the pattern since it will
721: // get pushed up (which means it was a pattern like (x|x)
722: // which is kinda wierd.)
723: //
724: if (fullyValid) {
725: if (info.childCount == 1)
726: info.results[0] = info.curChildren[0].uri == fSecondChild.uri
727: && info.curChildren[0].localpart == fSecondChild.localpart;
728: } else {
729: info.results[0] = true;
730: }
731: } else if (info.insertAt == 1) {
732: // If fully valid, then there cannot be two existing children
733: if (!fullyValid || (info.childCount == 1))
734: info.results[1] = true;
735: }
736:
737: // EOC is only valid at the end
738: if (info.insertAt == 2)
739: info.isValidEOC = true;
740: break;
741:
742: default:
743: throw new CMException(ImplementationMessages.VAL_CST);
744: }
745:
746: // We survived, so return success status
747: return -1;
748: }
749:
750: public ContentLeafNameTypeVector getContentLeafNameTypeVector() {
751: return null;
752: }
753: } // class SimpleContentModel
|