1 /*
   2  * Copyright (c) 1997, 2011, 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.policy.subject;
  27 
  28 import javax.xml.namespace.QName;
  29 
  30 import com.sun.istack.internal.logging.Logger;
  31 import com.sun.xml.internal.ws.resources.BindingApiMessages;
  32 
  33 /**
  34  * Experimental: This class identifies WSDL scopes. That allows to attach and
  35  * retrieve elements to and from WSDL scopes.
  36  *
  37  * @author Fabian Ritzmann
  38  */
  39 public class BindingSubject {
  40 
  41     /**
  42      * For message subjects, this needs to be set to one of the values INPUT, OUTPUT
  43      * or FAULT. Any other subject has the message type NO_MESSAGE.
  44      */
  45     private enum WsdlMessageType {
  46         NO_MESSAGE,
  47         INPUT,
  48         OUTPUT,
  49         FAULT
  50     }
  51 
  52     /**
  53      * Identifies the scope to which this subject belongs. See WS-PolicyAttachment
  54      * for an explanation on WSDL scopes.
  55      *
  56      * The SERVICE scope is not actually used and only listed here for completeness
  57      * sake.
  58      */
  59     private enum WsdlNameScope {
  60         SERVICE,
  61         ENDPOINT,
  62         OPERATION,
  63         MESSAGE
  64     }
  65 
  66     private static final Logger LOGGER = Logger.getLogger(BindingSubject.class);
  67 
  68     private final QName name;
  69     private final WsdlMessageType messageType;
  70     private final WsdlNameScope nameScope;
  71     private final BindingSubject parent;
  72 
  73     BindingSubject(final QName name, final WsdlNameScope scope, final BindingSubject parent) {
  74         this(name, WsdlMessageType.NO_MESSAGE, scope, parent);
  75     }
  76 
  77     BindingSubject(final QName name, final WsdlMessageType messageType, final WsdlNameScope scope, final BindingSubject parent) {
  78         this.name = name;
  79         this.messageType = messageType;
  80         this.nameScope = scope;
  81         this.parent = parent;
  82     }
  83 
  84     public static BindingSubject createBindingSubject(QName bindingName) {
  85         return new BindingSubject(bindingName, WsdlNameScope.ENDPOINT, null);
  86     }
  87 
  88     public static BindingSubject createOperationSubject(QName bindingName, QName operationName) {
  89         final BindingSubject bindingSubject = createBindingSubject(bindingName);
  90         return new BindingSubject(operationName, WsdlNameScope.OPERATION, bindingSubject);
  91     }
  92 
  93     public static BindingSubject createInputMessageSubject(QName bindingName, QName operationName, QName messageName) {
  94         final BindingSubject operationSubject = createOperationSubject(bindingName, operationName);
  95         return new BindingSubject(messageName, WsdlMessageType.INPUT, WsdlNameScope.MESSAGE, operationSubject);
  96     }
  97 
  98     public static BindingSubject createOutputMessageSubject(QName bindingName, QName operationName, QName messageName) {
  99         final BindingSubject operationSubject = createOperationSubject(bindingName, operationName);
 100         return new BindingSubject(messageName, WsdlMessageType.OUTPUT, WsdlNameScope.MESSAGE, operationSubject);
 101     }
 102 
 103     public static BindingSubject createFaultMessageSubject(QName bindingName, QName operationName, QName messageName) {
 104         if (messageName == null) {
 105             throw LOGGER.logSevereException(new IllegalArgumentException(BindingApiMessages.BINDING_API_NO_FAULT_MESSAGE_NAME()));
 106         }
 107         final BindingSubject operationSubject = createOperationSubject(bindingName, operationName);
 108         return new BindingSubject(messageName, WsdlMessageType.FAULT, WsdlNameScope.MESSAGE, operationSubject);
 109     }
 110 
 111     public QName getName() {
 112         return this.name;
 113     }
 114 
 115     public BindingSubject getParent() {
 116         return this.parent;
 117     }
 118 
 119     public boolean isBindingSubject() {
 120         if (this.nameScope == WsdlNameScope.ENDPOINT) {
 121             return this.parent == null;
 122         }
 123         else {
 124             return false;
 125         }
 126     }
 127 
 128     public boolean isOperationSubject() {
 129         if (this.nameScope == WsdlNameScope.OPERATION) {
 130             if (this.parent != null) {
 131                 return this.parent.isBindingSubject();
 132             }
 133         }
 134         return false;
 135     }
 136 
 137     public boolean isMessageSubject() {
 138         if (this.nameScope == WsdlNameScope.MESSAGE) {
 139             if (this.parent != null) {
 140                 return this.parent.isOperationSubject();
 141             }
 142         }
 143         return false;
 144     }
 145 
 146     public boolean isInputMessageSubject() {
 147         return isMessageSubject() && (this.messageType == WsdlMessageType.INPUT);
 148     }
 149 
 150     public boolean isOutputMessageSubject() {
 151         return isMessageSubject() && (this.messageType == WsdlMessageType.OUTPUT);
 152     }
 153 
 154     public boolean isFaultMessageSubject() {
 155         return isMessageSubject() && (this.messageType == WsdlMessageType.FAULT);
 156     }
 157 
 158     @Override
 159     public boolean equals(final Object that) {
 160         if (this == that) {
 161             return true;
 162         }
 163 
 164         if (that == null || !(that instanceof BindingSubject)) {
 165             return false;
 166         }
 167 
 168         final BindingSubject thatSubject = (BindingSubject) that;
 169         boolean isEqual = true;
 170 
 171         isEqual = isEqual && ((this.name == null) ? thatSubject.name == null : this.name.equals(thatSubject.name));
 172         isEqual = isEqual && this.messageType.equals(thatSubject.messageType);
 173         isEqual = isEqual && this.nameScope.equals(thatSubject.nameScope);
 174         isEqual = isEqual && ((this.parent == null) ? thatSubject.parent == null : this.parent.equals(thatSubject.parent));
 175 
 176         return isEqual;
 177     }
 178 
 179     @Override
 180     public int hashCode() {
 181         int result = 23;
 182 
 183         result = 29 * result + ((this.name == null) ? 0 : this.name.hashCode());
 184         result = 29 * result + this.messageType.hashCode();
 185         result = 29 * result + this.nameScope.hashCode();
 186         result = 29 * result + ((this.parent == null) ? 0 : this.parent.hashCode());
 187 
 188         return result;
 189     }
 190 
 191     @Override
 192     public String toString() {
 193         final StringBuilder result = new StringBuilder("BindingSubject[");
 194         result.append(this.name).append(", ").append(this.messageType);
 195         result.append(", ").append(this.nameScope).append(", ").append(this.parent);
 196         return result.append("]").toString();
 197     }
 198 
 199 }