1 /*
   2  * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.xml.internal.ws.api.wsdl.parser;
  27 
  28 import com.sun.xml.internal.ws.api.WSService;
  29 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLBoundFault;
  30 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLBoundOperation;
  31 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLBoundPortType;
  32 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLFault;
  33 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLInput;
  34 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLMessage;
  35 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLOperation;
  36 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLOutput;
  37 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLPort;
  38 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLPortType;
  39 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLService;
  40 import com.sun.xml.internal.ws.api.pipe.Tube;
  41 import com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser;
  42 
  43 import javax.xml.stream.XMLStreamConstants;
  44 import javax.xml.stream.XMLStreamReader;
  45 import javax.xml.ws.WebServiceException;
  46 
  47 /**
  48  * Extends the WSDL parsing process.
  49  *
  50  * <p>
  51  * This interface is implemented by components that build on top of the JAX-WS RI,
  52  * to participate in the WSDL parsing process that happens in the runtime.
  53  * This allows such components to retrieve information from WSDL extension elements,
  54  * and use that later to, for example, configure {@link Tube}s.
  55  *
  56  *
  57  *
  58  * <h2>How it works?</h2>
  59  * <p>
  60  * Each method on this interface denotes one extension point in WSDL
  61  * (the place where foreign elements/attributes can be added.) A {@link RuntimeWSDLParser}
  62  * starts parsing WSDL with a fixed set of {@link WSDLParserExtension}s, and
  63  * as it finds extension elements/attributes, it calls appropriate callback methods
  64  * to provide a chance for {@link WSDLParserExtension} to parse such
  65  * an extension element.
  66  *
  67  * <p>
  68  * There are two kinds of callbacks.
  69  *
  70  * <h3>Attribute callbacks</h3>
  71  * <p>
  72  * One is for attributes, which ends with the name {@code Attributes}.
  73  * This callback is invoked with {@link XMLStreamReader} that points
  74  * to the start tag of the WSDL element.
  75  *
  76  * <p>
  77  * The callback method can read interesting attributes on it.
  78  * The method must return without advancing the parser to the next token.
  79  *
  80  * <h3>Element callbacks</h3>
  81  * <p>
  82  * The other callback is for extension elements, which ends with the name
  83  * {@code Elements}.
  84  * When a callback is invoked, {@link XMLStreamReader} points to the
  85  * start tag of the extension element. The callback method can do
  86  * one of the following:
  87  *
  88  * <ol>
  89  *  <li>Return {@code false} without moving {@link XMLStreamReader},
  90  *      to indicate that the extension element isn't recognized.
  91  *      This allows the next {@link WSDLParserExtension} to see this
  92  *      extension element.
  93  *  <li>Parse the whole subtree rooted at the element,
  94  *      move the cursor to the {@link XMLStreamConstants#END_ELEMENT} state,
  95  *      and return {@code true}, indicating that the extension
  96  *      element is consumed.
  97  *      No other {@link WSDLParserExtension}s are notified of this extension.
  98  * </ol>
  99  *
 100  * <h3>Parsing in callback</h3>
 101  * <p>
 102  * For each callback, the corresponding WSDL model object is passed in,
 103  * so that {@link WSDLParserExtension} can relate what it's parsing
 104  * to the {@link WSDLModel}. Most likely, extensions can parse
 105  * their data into an {@link WSDLExtension}-derived classes, then
 106  * use {@link WSDLExtensible} interface to hook them into {@link WSDLModel}.
 107  *
 108  * <p>
 109  * Note that since the {@link WSDLModel} itself
 110  * is being built, {@link WSDLParserExtension} may not invoke any of
 111  * the query methods on the WSDL model. Those references are passed just so that
 112  * {@link WSDLParserExtension} can hold on to those references, or put
 113  * {@link WSDLExtensible} objects into the model, not to query it.
 114  *
 115  * <p>
 116  * If {@link WSDLParserExtension} needs to query {@link WSDLModel},
 117  * defer that processing until {@link #finished(WSDLParserExtensionContext)}, when it's
 118  * safe to use {@link WSDLModel} can be used safely.
 119  *
 120  * <p>
 121  * Also note that {@link WSDLParserExtension}s are called in no particular order.
 122  * This interface is not designed for having multiple {@link WSDLParserExtension}s
 123  * parse the same extension element.
 124  *
 125  *
 126  * <h2>Error Handling</h2>
 127  * <p>
 128  * For usability, {@link WSDLParserExtension}s are expected to check possible
 129  * errors in the extension elements that it parses. When an error is found,
 130  * it may throw a {@link WebServiceException} to abort the parsing of the WSDL.
 131  * This exception will be propagated to the user, so it should have
 132  * detailed error messages pointing at the problem.
 133  *
 134  * <h2>Discovery</h2>
 135  * <p>
 136  * The JAX-WS RI locates the implementation of {@link WSDLParserExtension}s
 137  * by using the standard service look up mechanism, in particular looking for
 138  * {@code META-INF/services/com.sun.xml.internal.ws.api.wsdl.parser.WSDLParserExtension}
 139  *
 140  *
 141  * <h2>TODO</h2>
 142  * <p>
 143  * As it's designed today, extensions cannot access to any of the environmental
 144  * information before the parsing begins (such as what {@link WSService} this
 145  * WSDL is being parsed for, etc.) We might need to reconsider this aspect.
 146  * The JAX-WS team waits for feedback on this topic.
 147  *
 148  * @author Kohsuke Kawaguchi
 149  */
 150 public abstract class WSDLParserExtension {
 151 
 152     public void start(WSDLParserExtensionContext context){
 153         // noop
 154     }
 155 
 156     public void serviceAttributes(EditableWSDLService service, XMLStreamReader reader) {
 157         // noop
 158     }
 159 
 160     public boolean serviceElements(EditableWSDLService service, XMLStreamReader reader) {
 161         return false;
 162     }
 163 
 164     public void portAttributes(EditableWSDLPort port, XMLStreamReader reader) {
 165         // noop
 166     }
 167 
 168     public boolean portElements(EditableWSDLPort port, XMLStreamReader reader) {
 169         return false;
 170     }
 171 
 172     public boolean portTypeOperationInput(EditableWSDLOperation op, XMLStreamReader reader) {
 173         return false;
 174     }
 175 
 176     public boolean portTypeOperationOutput(EditableWSDLOperation op, XMLStreamReader reader) {
 177         return false;
 178     }
 179 
 180     public boolean portTypeOperationFault(EditableWSDLOperation op, XMLStreamReader reader) {
 181         return false;
 182     }
 183 
 184     public boolean definitionsElements(XMLStreamReader reader) {
 185         return false;
 186     }
 187 
 188     public boolean bindingElements(EditableWSDLBoundPortType binding, XMLStreamReader reader) {
 189         return false;
 190     }
 191 
 192     public void bindingAttributes(EditableWSDLBoundPortType binding, XMLStreamReader reader) {
 193     }
 194 
 195     public boolean portTypeElements(EditableWSDLPortType portType, XMLStreamReader reader) {
 196         return false;
 197     }
 198 
 199     public void portTypeAttributes(EditableWSDLPortType portType, XMLStreamReader reader) {
 200     }
 201 
 202     public boolean portTypeOperationElements(EditableWSDLOperation operation, XMLStreamReader reader) {
 203         return false;
 204     }
 205 
 206     public void portTypeOperationAttributes(EditableWSDLOperation operation, XMLStreamReader reader) {
 207     }
 208 
 209     public boolean bindingOperationElements(EditableWSDLBoundOperation operation, XMLStreamReader reader) {
 210         return false;
 211     }
 212 
 213     public void bindingOperationAttributes(EditableWSDLBoundOperation operation, XMLStreamReader reader) {
 214     }
 215 
 216     public boolean messageElements(EditableWSDLMessage msg, XMLStreamReader reader) {
 217         return false;
 218     }
 219 
 220     public void messageAttributes(EditableWSDLMessage msg, XMLStreamReader reader) {
 221     }
 222 
 223     public boolean portTypeOperationInputElements(EditableWSDLInput input, XMLStreamReader reader) {
 224         return false;
 225     }
 226 
 227     public void portTypeOperationInputAttributes(EditableWSDLInput input, XMLStreamReader reader) {
 228     }
 229 
 230     public boolean portTypeOperationOutputElements(EditableWSDLOutput output, XMLStreamReader reader) {
 231         return false;
 232     }
 233 
 234     public void portTypeOperationOutputAttributes(EditableWSDLOutput output, XMLStreamReader reader) {
 235     }
 236 
 237     public boolean portTypeOperationFaultElements(EditableWSDLFault fault, XMLStreamReader reader) {
 238         return false;
 239     }
 240 
 241     public void portTypeOperationFaultAttributes(EditableWSDLFault fault, XMLStreamReader reader) {
 242     }
 243 
 244     public boolean bindingOperationInputElements(EditableWSDLBoundOperation operation, XMLStreamReader reader) {
 245         return false;
 246     }
 247 
 248     public void bindingOperationInputAttributes(EditableWSDLBoundOperation operation, XMLStreamReader reader) {
 249     }
 250 
 251     public boolean bindingOperationOutputElements(EditableWSDLBoundOperation operation, XMLStreamReader reader) {
 252         return false;
 253     }
 254 
 255     public void bindingOperationOutputAttributes(EditableWSDLBoundOperation operation, XMLStreamReader reader) {
 256     }
 257 
 258     public boolean bindingOperationFaultElements(EditableWSDLBoundFault fault, XMLStreamReader reader) {
 259         return false;
 260     }
 261 
 262     public void bindingOperationFaultAttributes(EditableWSDLBoundFault fault, XMLStreamReader reader) {
 263     }
 264 
 265     // TODO: complete the rest of the callback
 266 
 267     /**
 268      * Called when the parsing of a set of WSDL documents are all done.
 269      * <p>
 270      * This is the opportunity to do any post-processing of the parsing
 271      * you've done.
 272      *
 273      * @param context  {@link WSDLParserExtensionContext} gives fully parsed {@link WSDLModel}.
 274      */
 275     public void finished(WSDLParserExtensionContext context) {
 276         // noop
 277     }
 278 
 279     public void postFinished(WSDLParserExtensionContext context) {
 280         // noop
 281     }
 282 }