001: /*
002: Copyright (c) 2004-2006, 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 java.util.ArrayList;
032:
033: /**
034: * Model visitor for handling item registration. This works with the {@link
035: * org.jibx.binding.model.ValidationContext} class to handle registration of
036: * items which can be referenced by name or by function (such as ID values
037: * within an object structure). The only items of this type which are not
038: * handled by this visitor are <b>format</b> definitions. The formats need to be
039: * accessed during prevalidation, so they're registered during that pass.
040: *
041: * @author Dennis M. Sosnoski
042: * @version 1.0
043: */
044: public class RegistrationVisitor extends ModelVisitor {
045: /** Validation context running this visitor. */
046: private final ValidationContext m_context;
047:
048: /**
049: * Constructor.
050: *
051: * @param vctx validation context that will run this visitor
052: */
053: public RegistrationVisitor(ValidationContext vctx) {
054: m_context = vctx;
055: }
056:
057: /**
058: * Visit binding model tree to handle registration.
059: *
060: * @param root node of tree to be visited
061: */
062: public void visitTree(ElementBase root) {
063:
064: // first add all namespace declarations to contexts
065: m_context.tourTree(root, new ModelVisitor() {
066:
067: /**
068: * Add namespace definition to containing context.
069: *
070: * @param node
071: * @return continue expansion flag
072: */
073: public boolean visit(NamespaceElement node) {
074: ValidationProblem problem = m_context
075: .getCurrentDefinitions().addNamespace(node);
076: if (problem != null) {
077: m_context.addProblem(problem);
078: }
079: return super .visit(node);
080: }
081:
082: /**
083: * Block expansion once a structure-type element is reached.
084: *
085: * @param node
086: * @return <code>false</code>
087: */
088: public boolean visit(StructureElementBase node) {
089: return false;
090: }
091:
092: });
093:
094: // next handle adding references to table
095: m_context.tourTree(root, this );
096:
097: // then handle mapping extension linkages with separate pass
098: m_context.tourTree(root, new ModelVisitor() {
099:
100: // expand mapping elements in case child mappings are present
101: public boolean visit(MappingElement node) {
102: node.validateExtension(m_context);
103: return true;
104: }
105:
106: // don't bother expanding structure elements
107: public boolean visit(StructureElementBase node) {
108: return false;
109: }
110:
111: });
112: }
113:
114: /* (non-Javadoc)
115: * @see org.jibx.binding.model.ModelVisitor#visit(org.jibx.binding.model.ContainerElementBase)
116: */
117: public boolean visit(ContainerElementBase node) {
118: if (node.getLabel() != null) {
119: ValidationProblem problem = m_context.getBindingRoot()
120: .getDefinitions().addNamedStructure(node);
121: if (problem != null) {
122: m_context.addProblem(problem);
123: }
124: }
125: return super .visit(node);
126: }
127:
128: /* (non-Javadoc)
129: * @see org.jibx.binding.model.ModelVisitor#visit(org.jibx.binding.model.TemplateElementBase)
130: */
131: public boolean visit(TemplateElementBase node) {
132:
133: // check for a top-level definition
134: if (m_context.getParentElement() instanceof BindingElement) {
135:
136: // add all namespace declarations from binding to template
137: DefinitionContext pctx = m_context.getParentElement()
138: .getDefinitions();
139: if (pctx != null) {
140: ArrayList nss = pctx.getNamespaces();
141: if (nss != null) {
142: DefinitionContext nctx = node.getDefinitions();
143: if (nctx == null) {
144: nctx = new DefinitionContext(pctx);
145: node.setDefinitions(nctx);
146: }
147: for (int i = 0; i < nss.size(); i++) {
148: nctx
149: .addNamespace((NamespaceElement) nss
150: .get(i));
151: }
152: }
153: }
154: }
155: return super .visit(node);
156: }
157:
158: /* (non-Javadoc)
159: * @see org.jibx.binding.model.ModelVisitor#visit(org.jibx.binding.model.IncludeElement)
160: */
161: public boolean visit(IncludeElement node) {
162:
163: // merge namespaces from containing binding into included binding
164: BindingElement contain = (BindingElement) m_context
165: .getParentElement();
166: BindingElement binding = node.getBinding();
167: if (binding != null) {
168: contain.getDefinitions().injectNamespaces(
169: binding.getDefinitions());
170: }
171: return super .visit(node);
172: }
173:
174: /* (non-Javadoc)
175: * @see org.jibx.binding.model.ModelVisitor#visit(org.jibx.binding.model.MappingElement)
176: */
177: public boolean visit(MappingElement node) {
178: DefinitionContext dctx = m_context.getCurrentDefinitions();
179: dctx.addTemplate(node, m_context);
180: if (!node.isAbstract()) {
181:
182: // force name validation to set the namespace information
183: NameAttributes name = node.getNameAttributes();
184: name.validate(m_context);
185: if (name != null && name.getName() != null) {
186: dctx.addMappedName(name, node, m_context);
187: }
188: }
189: return super .visit(node);
190: }
191:
192: /* (non-Javadoc)
193: * @see org.jibx.binding.model.ModelVisitor#visit(org.jibx.binding.model.TemplateElement)
194: */
195: public boolean visit(TemplateElement node) {
196: m_context.getCurrentDefinitions().addTemplate(node, m_context);
197: return super.visit(node);
198: }
199: }
|