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
26package com.sun.xml.internal.ws.api.config.management.policy;
27
28import com.sun.istack.internal.logging.Logger;
29import com.sun.xml.internal.ws.api.server.WSEndpoint;
30import com.sun.xml.internal.ws.policy.PolicyAssertion;
31import com.sun.xml.internal.ws.policy.PolicyMap;
32import com.sun.xml.internal.ws.policy.PolicyConstants;
33import com.sun.xml.internal.ws.policy.sourcemodel.AssertionData;
34import com.sun.xml.internal.ws.policy.spi.AssertionCreationException;
35import com.sun.xml.internal.ws.resources.ManagementMessages;
36
37import java.util.Collection;
38import java.util.HashMap;
39import java.util.Iterator;
40import java.util.LinkedList;
41import java.util.Map;
42import javax.xml.namespace.QName;
43import javax.xml.ws.WebServiceException;
44
45/**
46 * The server-side ManagedService policy assertion.
47 *
48 * @author Fabian Ritzmann
49 */
50public class ManagedServiceAssertion extends ManagementAssertion {
51
52    public static final QName MANAGED_SERVICE_QNAME =
53            new QName(PolicyConstants.SUN_MANAGEMENT_NAMESPACE, "ManagedService");
54
55    private static final QName COMMUNICATION_SERVER_IMPLEMENTATIONS_PARAMETER_QNAME = new QName(
56            PolicyConstants.SUN_MANAGEMENT_NAMESPACE, "CommunicationServerImplementations");
57    private static final QName COMMUNICATION_SERVER_IMPLEMENTATION_PARAMETER_QNAME = new QName(
58            PolicyConstants.SUN_MANAGEMENT_NAMESPACE, "CommunicationServerImplementation");
59    private static final QName CONFIGURATOR_IMPLEMENTATION_PARAMETER_QNAME = new QName(
60            PolicyConstants.SUN_MANAGEMENT_NAMESPACE, "ConfiguratorImplementation");
61    private static final QName CONFIG_SAVER_IMPLEMENTATION_PARAMETER_QNAME = new QName(
62            PolicyConstants.SUN_MANAGEMENT_NAMESPACE, "ConfigSaverImplementation");
63    private static final QName CONFIG_READER_IMPLEMENTATION_PARAMETER_QNAME = new QName(
64            PolicyConstants.SUN_MANAGEMENT_NAMESPACE, "ConfigReaderImplementation");
65    private static final QName CLASS_NAME_ATTRIBUTE_QNAME = new QName("className");
66    /**
67     * The name of the endpointDisposeDelay attribute.
68     */
69    private static final QName ENDPOINT_DISPOSE_DELAY_ATTRIBUTE_QNAME = new QName("endpointDisposeDelay");
70
71    private static final Logger LOGGER = Logger.getLogger(ManagedServiceAssertion.class);
72
73    /**
74     * Return ManagedService assertion if there is one associated with the endpoint.
75     *
76     * @param endpoint The endpoint. Must not be null.
77     * @return The policy assertion if found. Null otherwise.
78     * @throws WebServiceException If computing the effective policy of the endpoint failed.
79     */
80    public static ManagedServiceAssertion getAssertion(WSEndpoint endpoint) throws WebServiceException {
81        LOGGER.entering(endpoint);
82        // getPolicyMap is deprecated because it is only supposed to be used by Metro code
83        // and not by other clients.
84        @SuppressWarnings("deprecation")
85        final PolicyMap policyMap = endpoint.getPolicyMap();
86        final ManagedServiceAssertion assertion = ManagementAssertion.getAssertion(MANAGED_SERVICE_QNAME,
87                policyMap, endpoint.getServiceName(), endpoint.getPortName(), ManagedServiceAssertion.class);
88        LOGGER.exiting(assertion);
89        return assertion;
90    }
91
92    public ManagedServiceAssertion(AssertionData data, Collection<PolicyAssertion> assertionParameters)
93            throws AssertionCreationException {
94        super(MANAGED_SERVICE_QNAME, data, assertionParameters);
95    }
96
97    /**
98     * Returns the value of the management attribute. True if unset or set to "true"
99     * or "on". False otherwise.
100     *
101     * @return The value of the management attribute.
102     */
103    public boolean isManagementEnabled() {
104        final String management = this.getAttributeValue(MANAGEMENT_ATTRIBUTE_QNAME);
105        boolean result = true;
106        if (management != null) {
107            if (management.trim().toLowerCase().equals("on")) {
108                result = true;
109            }
110            else {
111                result = Boolean.parseBoolean(management);
112            }
113        }
114        return result;
115    }
116
117    /**
118     * Returns the value of the endpointDisposeDelay attribute or the default value
119     * otherwise.
120     *
121     * @param defaultDelay The default value that is returned if this attribute is
122     *   not set
123     * @return The value of the endpointDisposeDelay attribute or the default value
124     *   otherwise.
125     */
126    public long getEndpointDisposeDelay(final long defaultDelay) throws WebServiceException {
127        long result = defaultDelay;
128        final String delayText = getAttributeValue(ENDPOINT_DISPOSE_DELAY_ATTRIBUTE_QNAME);
129        if (delayText != null) {
130            try {
131                result = Long.parseLong(delayText);
132            } catch (NumberFormatException e) {
133                throw LOGGER.logSevereException(new WebServiceException(
134                        ManagementMessages.WSM_1008_EXPECTED_INTEGER_DISPOSE_DELAY_VALUE(delayText), e));
135            }
136        }
137        return result;
138    }
139
140    /**
141     * A list of CommunicationServerImplementation elements that were set as
142     * parameters of this assertion.
143     *
144     * @return A list of CommunicationServerImplementation elements that were set as
145     * parameters of this assertion. May be empty.
146     */
147    public Collection<ImplementationRecord> getCommunicationServerImplementations() {
148        final Collection<ImplementationRecord> result = new LinkedList<ImplementationRecord>();
149        final Iterator<PolicyAssertion> parameters = getParametersIterator();
150        while (parameters.hasNext()) {
151            final PolicyAssertion parameter = parameters.next();
152            if (COMMUNICATION_SERVER_IMPLEMENTATIONS_PARAMETER_QNAME.equals(parameter.getName())) {
153                final Iterator<PolicyAssertion> implementations = parameter.getParametersIterator();
154                if (!implementations.hasNext()) {
155                    throw LOGGER.logSevereException(new WebServiceException(
156                            ManagementMessages.WSM_1005_EXPECTED_COMMUNICATION_CHILD()));
157                }
158                while (implementations.hasNext()) {
159                    final PolicyAssertion implementation = implementations.next();
160                    if (COMMUNICATION_SERVER_IMPLEMENTATION_PARAMETER_QNAME.equals(implementation.getName())) {
161                        result.add(getImplementation(implementation));
162                    }
163                    else {
164                        throw LOGGER.logSevereException(new WebServiceException(
165                                ManagementMessages.WSM_1004_EXPECTED_XML_TAG(
166                                COMMUNICATION_SERVER_IMPLEMENTATION_PARAMETER_QNAME, implementation.getName())));
167                    }
168                }
169            }
170        }
171        return result;
172    }
173
174    /**
175     * The ConfiguratorImplementation that was set as parameter of this assertion.
176     *
177     * @return The ConfiguratorImplementation that was set as parameter of this assertion.
178     *   May be null.
179     */
180    public ImplementationRecord getConfiguratorImplementation() {
181        return findImplementation(CONFIGURATOR_IMPLEMENTATION_PARAMETER_QNAME);
182    }
183
184    /**
185     * The ConfigSaverImplementation that was set as parameter of this assertion.
186     *
187     * @return The ConfigSaverImplementation that was set as parameter of this assertion.
188     *   May be null.
189     */
190    public ImplementationRecord getConfigSaverImplementation() {
191        return findImplementation(CONFIG_SAVER_IMPLEMENTATION_PARAMETER_QNAME);
192    }
193
194    /**
195     * The ConfigReaderImplementation that was set as parameter of this assertion.
196     *
197     * @return The ConfigReaderImplementation that was set as parameter of this assertion.
198     *   May be null.
199     */
200    public ImplementationRecord getConfigReaderImplementation() {
201        return findImplementation(CONFIG_READER_IMPLEMENTATION_PARAMETER_QNAME);
202    }
203
204    private ImplementationRecord findImplementation(QName implementationName) {
205        final Iterator<PolicyAssertion> parameters = getParametersIterator();
206        while (parameters.hasNext()) {
207            final PolicyAssertion parameter = parameters.next();
208            if (implementationName.equals(parameter.getName())) {
209                return getImplementation(parameter);
210            }
211        }
212        return null;
213    }
214
215    private ImplementationRecord getImplementation(PolicyAssertion rootParameter) {
216        final String className = rootParameter.getAttributeValue(CLASS_NAME_ATTRIBUTE_QNAME);
217        final HashMap<QName, String> parameterMap = new HashMap<QName, String>();
218        final Iterator<PolicyAssertion> implementationParameters = rootParameter.getParametersIterator();
219        final Collection<NestedParameters> nestedParameters = new LinkedList<NestedParameters>();
220        while (implementationParameters.hasNext()) {
221            final PolicyAssertion parameterAssertion = implementationParameters.next();
222            final QName parameterName = parameterAssertion.getName();
223            if (parameterAssertion.hasParameters()) {
224                final Map<QName, String> nestedParameterMap = new HashMap<QName, String>();
225                final Iterator<PolicyAssertion> parameters = parameterAssertion.getParametersIterator();
226                while (parameters.hasNext()) {
227                    final PolicyAssertion parameter = parameters.next();
228                    String value = parameter.getValue();
229                    if (value != null) {
230                        value = value.trim();
231                    }
232                    nestedParameterMap.put(parameter.getName(), value);
233                }
234                nestedParameters.add(new NestedParameters(parameterName, nestedParameterMap));
235            }
236            else {
237                String value = parameterAssertion.getValue();
238                if (value != null) {
239                    value = value.trim();
240                }
241                parameterMap.put(parameterName, value);
242            }
243        }
244        return new ImplementationRecord(className, parameterMap, nestedParameters);
245    }
246
247
248    /**
249     * Return the implementation class name along with all parameters for the
250     * implementation.
251     */
252    public static class ImplementationRecord {
253
254        private final String implementation;
255        private final Map<QName, String> parameters;
256        private final Collection<NestedParameters> nestedParameters;
257
258        protected ImplementationRecord(String implementation, Map<QName, String> parameters,
259                Collection<NestedParameters> nestedParameters) {
260            this.implementation = implementation;
261            this.parameters = parameters;
262            this.nestedParameters = nestedParameters;
263        }
264
265        public String getImplementation() {
266            return this.implementation;
267        }
268
269        /**
270         * The parameters that were set for this implementation element.
271         *
272         * @return The parameters that were set for this implementation element.
273         *   May be null.
274         */
275        public Map<QName, String> getParameters() {
276            return this.parameters;
277        }
278
279        /**
280         * Implementation elements may contain element parameters that contain
281         * further parameters.
282         *
283         * @return The nested parameters that were set for this implementation element.
284         *   May be null.
285         */
286        public Collection<NestedParameters> getNestedParameters() {
287            return this.nestedParameters;
288        }
289
290        @Override
291        public boolean equals(Object obj) {
292            if (obj == null) {
293                return false;
294            }
295            if (getClass() != obj.getClass()) {
296                return false;
297            }
298            final ImplementationRecord other = (ImplementationRecord) obj;
299            if ((this.implementation == null) ?
300                (other.implementation != null) : !this.implementation.equals(other.implementation)) {
301                return false;
302            }
303            if (this.parameters != other.parameters && (this.parameters == null || !this.parameters.equals(other.parameters))) {
304                return false;
305            }
306            if (this.nestedParameters != other.nestedParameters &&
307                    (this.nestedParameters == null || !this.nestedParameters.equals(other.nestedParameters))) {
308                return false;
309            }
310            return true;
311        }
312
313        @Override
314        public int hashCode() {
315            int hash = 3;
316            hash = 53 * hash + (this.implementation != null ? this.implementation.hashCode() : 0);
317            hash = 53 * hash + (this.parameters != null ? this.parameters.hashCode() : 0);
318            hash = 53 * hash + (this.nestedParameters != null ? this.nestedParameters.hashCode() : 0);
319            return hash;
320        }
321
322        @Override
323        public String toString() {
324            final StringBuilder text = new StringBuilder("ImplementationRecord: ");
325            text.append("implementation = \"").append(this.implementation).append("\", ");
326            text.append("parameters = \"").append(this.parameters).append("\", ");
327            text.append("nested parameters = \"").append(this.nestedParameters).append("\"");
328            return text.toString();
329        }
330
331    }
332
333
334    /**
335     * The nested parameters that may be set as part of an implementation element.
336     */
337    public static class NestedParameters {
338
339        private final QName name;
340        private final Map<QName, String> parameters;
341
342        private NestedParameters(QName name, Map<QName, String> parameters) {
343            this.name = name;
344            this.parameters = parameters;
345        }
346
347        public QName getName() {
348            return this.name;
349        }
350
351        public Map<QName, String> getParameters() {
352            return this.parameters;
353        }
354
355        @Override
356        public boolean equals(Object obj) {
357            if (obj == null) {
358                return false;
359            }
360            if (getClass() != obj.getClass()) {
361                return false;
362            }
363            final NestedParameters other = (NestedParameters) obj;
364            if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
365                return false;
366            }
367            if (this.parameters != other.parameters && (this.parameters == null || !this.parameters.equals(other.parameters))) {
368                return false;
369            }
370            return true;
371        }
372
373        @Override
374        public int hashCode() {
375            int hash = 5;
376            hash = 59 * hash + (this.name != null ? this.name.hashCode() : 0);
377            hash = 59 * hash + (this.parameters != null ? this.parameters.hashCode() : 0);
378            return hash;
379        }
380
381        @Override
382        public String toString() {
383            final StringBuilder text = new StringBuilder("NestedParameters: ");
384            text.append("name = \"").append(this.name).append("\", ");
385            text.append("parameters = \"").append(this.parameters).append("\"");
386            return text.toString();
387        }
388
389    }
390
391}
392