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 java.io.IOException;
032: import java.net.URL;
033:
034: import org.jibx.binding.util.StringArray;
035: import org.jibx.runtime.IUnmarshallingContext;
036: import org.jibx.runtime.JiBXException;
037:
038: /**
039: * Model component for <b>include</b> element of binding definition. During
040: * prevalidation this reads the included binding definition. All further
041: * processing of the included components needs to be handled directly by the
042: * tree walking code in {@link org.jibx.binding.model.TreeContext}, since the
043: * components of the included binding need to be treated as though they were
044: * direct children of the container of this element (and accessed in the
045: * appropriate order).
046: *
047: * @author Dennis M. Sosnoski
048: * @version 1.0
049: */
050: public class IncludeElement extends NestingElementBase {
051: /** Enumeration of allowed attribute names */
052: public static final StringArray s_allowedAttributes = new StringArray(
053: new String[] { "path" });
054:
055: /** Path to included binding definition. */
056: private String m_includePath;
057:
058: /** Object model for included binding. */
059: private BindingElement m_binding;
060:
061: /**
062: * Constructor.
063: */
064: public IncludeElement() {
065: super (INCLUDE_ELEMENT);
066: }
067:
068: /**
069: * Set path to included binding.
070: *
071: * @param path
072: */
073: public void setIncludePath(String path) {
074: m_includePath = path;
075: }
076:
077: /**
078: * Get path to included binding.
079: *
080: * @return
081: */
082: public String getIncludePath() {
083: return m_includePath;
084: }
085:
086: /**
087: * Get the included binding model. This call is only valid after
088: * prevalidation.
089: *
090: * @return binding element, or <code>null</code> if redundant include
091: */
092: public BindingElement getBinding() {
093: return m_binding;
094: }
095:
096: //
097: // Validation methods
098:
099: /**
100: * Make sure all attributes are defined.
101: *
102: * @param uctx unmarshalling context
103: * @exception JiBXException on unmarshalling error
104: */
105: private void preSet(IUnmarshallingContext uctx)
106: throws JiBXException {
107: validateAttributes(uctx, s_allowedAttributes);
108: }
109:
110: /* (non-Javadoc)
111: * @see org.jibx.binding.model.ElementBase#prevalidate(org.jibx.binding.model.ValidationContext)
112: */
113: public void prevalidate(ValidationContext vctx) {
114: if (m_includePath == null) {
115: vctx.addFatal("No include path specified");
116: } else {
117: try {
118:
119: // locate the innermost binding element
120: int limit = vctx.getNestingDepth();
121: BindingElement root = null;
122: for (int i = 1; i < limit; i++) {
123: ElementBase parent = vctx.getParentElement(i);
124: if (parent instanceof BindingElement) {
125: root = (BindingElement) parent;
126: break;
127: }
128: }
129: if (root == null) {
130: throw new JiBXException("No binding element found");
131: }
132:
133: // access the included binding as input stream
134: URL base = root.getBaseUrl();
135: URL url = new URL(base, m_includePath);
136: String path = url.toExternalForm();
137: BindingElement real = vctx.getBindingRoot();
138: if (real.addIncludePath(path)) {
139: m_binding = real.getIncludeBinding(url, root, vctx);
140: }
141:
142: } catch (JiBXException e) {
143: vctx.addFatal(e.getMessage());
144: } catch (IOException e) {
145: vctx
146: .addFatal("Error accessing included binding with path \""
147: + m_includePath
148: + "\": "
149: + e.getMessage());
150: }
151: }
152: }
153: }
|