Wed, 27 Apr 2016 01:27:09 +0800
Initial load
http://hg.openjdk.java.net/jdk8u/jdk8u/jaxws/
changeset: 657:d47a47f961ee
tag: jdk8u25-b17
1 /*
2 * Copyright (c) 1997, 2010, 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 */
26 package com.sun.xml.internal.ws.policy;
28 import com.sun.xml.internal.ws.policy.sourcemodel.wspolicy.NamespaceVersion;
29 import com.sun.xml.internal.ws.policy.privateutil.LocalizationMessages;
30 import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils;
31 import java.util.Arrays;
32 import java.util.Collection;
33 import java.util.Collections;
34 import java.util.Iterator;
35 import java.util.LinkedList;
36 import java.util.List;
37 import java.util.Set;
38 import java.util.TreeSet;
39 import javax.xml.namespace.QName;
41 /**
42 * A policy represents normalized policy as a wrapper of available policy alternatives represented by
43 * child {@link AssertionSet AssertionSets}.
44 *
45 * @author Fabian Ritzmann, Marek Potociar
46 */
47 public class Policy implements Iterable<AssertionSet> {
48 /**
49 * A string constant used in package private constructor to customize the object's toString() method output.
50 */
51 private static final String POLICY_TOSTRING_NAME = "policy";
53 /**
54 * Constant represents empty list of assertion sets. This represents the content of a 'NULL' policy - a policy with
55 * no alternatives. The constant supports memory effective creation of 'NULL' policy objects.
56 */
57 private static final List<AssertionSet> NULL_POLICY_ASSERTION_SETS = Collections.unmodifiableList(new LinkedList<AssertionSet>());
59 /**
60 * Constant represents list of assertion sets with single empty assertion set. This represents the content of
61 * an 'EMPTY' policy - a policy with a single empty alternative. The constant supports memory effective creation
62 * of 'EMPTY' policy objects.
63 */
64 private static final List<AssertionSet> EMPTY_POLICY_ASSERTION_SETS = Collections.unmodifiableList(new LinkedList<AssertionSet>(Arrays.asList(new AssertionSet[] {AssertionSet.emptyAssertionSet()})));
66 /**
67 * Constant represents empty vocabulary of a 'NULL' or 'EMPTY' policies. The constant supports memory effective
68 * creation of 'NULL' and 'EMPTY' policy objects.
69 */
70 private static final Set<QName> EMPTY_VOCABULARY = Collections.unmodifiableSet(new TreeSet<QName>(PolicyUtils.Comparison.QNAME_COMPARATOR));
72 /**
73 * Constant representation of all 'NULL' policies returned by createNullPolicy() factory method. This is to optimize
74 * the memory footprint.
75 */
76 private static final Policy ANONYMOUS_NULL_POLICY = new Policy(null, null, NULL_POLICY_ASSERTION_SETS, EMPTY_VOCABULARY);
78 /**
79 * Constant representation of all 'EMPTY' policies returned by createEmptyPolicy() factory method. This constant is
80 * to optimize the memory footprint.
81 */
82 private static final Policy ANONYMOUS_EMPTY_POLICY = new Policy(null, null, EMPTY_POLICY_ASSERTION_SETS, EMPTY_VOCABULARY);
84 /**
85 * Policy ID holder
86 */
87 private String policyId;
89 /**
90 * Policy name holder
91 */
92 private String name;
94 /**
95 * Namespace version holder
96 */
97 private NamespaceVersion nsVersion;
99 /**
100 * internal collection of policy alternatives
101 */
102 private final List<AssertionSet> assertionSets;
104 /**
105 * internal collection of policy vocabulary entries (qualified names of all assertion types present in the policy expression)
106 */
107 private final Set<QName> vocabulary;
109 /**
110 * immutable version of policy vocabulary that is made available to clients via getter method
111 */
112 private final Collection<QName> immutableVocabulary;
114 /**
115 * policy object name used in a toString() method. This ensures that Policy class children can customize
116 * (via package private Policy constructors) the toString() method without having to override it.
117 */
118 private final String toStringName;
120 /**
121 * The factory method creates an <b>immutable</b> policy instance which represents a <emph>'nothing allowed'</emph>
122 * policy expression. The policy is created using the latest namespace version supported.
123 *
124 * @return policy instance which represents a <emph>'nothing allowed'</emph> (no policy alternatives).
125 */
126 public static Policy createNullPolicy() {
127 return ANONYMOUS_NULL_POLICY;
128 }
130 /**
131 * The factory method creates an <b>immutable</b> policy instance which represents a <emph>'anything allowed'</emph>
132 * policy expression. The policy is created using the latest namespace version supported.
133 *
134 * @return policy instance which represents a <emph>'anything allowed'</emph> (empty policy alternative with no plicy
135 * assertions prescribed).
136 */
137 public static Policy createEmptyPolicy() {
138 return ANONYMOUS_EMPTY_POLICY;
139 }
141 /**
142 * The factory method creates an <b>immutable</b> policy instance which represents a <emph>'nothing allowed'</emph>
143 * policy expression. The policy is created using the latest namespace version supported.
144 *
145 * @param name global URI of the policy. May be {@code null}.
146 * @param policyId local URI of the policy. May be {@code null}.
147 * @return policy instance which represents a <emph>'nothing allowed'</emph> (no policy alternatives).
148 */
149 public static Policy createNullPolicy(final String name, final String policyId) {
150 if (name == null && policyId == null) {
151 return ANONYMOUS_NULL_POLICY;
152 } else {
153 return new Policy(name, policyId, NULL_POLICY_ASSERTION_SETS, EMPTY_VOCABULARY);
154 }
155 }
157 /**
158 * The factory method creates an <b>immutable</b> policy instance which represents a <emph>'nothing allowed'</emph>
159 * policy expression. The policy is created using the latest namespace version supported.
160 *
161 * @param nsVersion Policy namespace version to be used when marshalling the policy expression
162 * @param name global URI of the policy. May be {@code null}.
163 * @param policyId local URI of the policy. May be {@code null}.
164 * @return policy instance which represents a <emph>'nothing allowed'</emph> (no policy alternatives).
165 */
166 public static Policy createNullPolicy(final NamespaceVersion nsVersion, final String name, final String policyId) {
167 if ((nsVersion == null || nsVersion == NamespaceVersion.getLatestVersion()) && name == null && policyId == null) {
168 return ANONYMOUS_NULL_POLICY;
169 } else {
170 return new Policy(nsVersion, name, policyId, NULL_POLICY_ASSERTION_SETS, EMPTY_VOCABULARY);
171 }
172 }
174 /**
175 * The factory method creates an <b>immutable</b> policy instance which represents a <emph>'anything allowed'</emph>
176 * policy expression. The policy is created using the latest namespace version supported.
177 *
178 * @param name global URI of the policy. May be {@code null}.
179 * @param policyId local URI of the policy. May be {@code null}.
180 *
181 * @return policy instance which represents a <emph>'anything allowed'</emph> (empty policy alternative with no plicy
182 * assertions prescribed).
183 */
184 public static Policy createEmptyPolicy(final String name, final String policyId) {
185 if (name == null && policyId == null) {
186 return ANONYMOUS_EMPTY_POLICY;
187 } else {
188 return new Policy(name, policyId, EMPTY_POLICY_ASSERTION_SETS, EMPTY_VOCABULARY);
189 }
190 }
192 /**
193 * The factory method creates an <b>immutable</b> policy instance which represents a <emph>'anything allowed'</emph>
194 * policy expression. The policy is created using the latest namespace version supported.
195 *
196 * @param nsVersion Policy namespace version to be used when marshalling the policy expression
197 * @param name global URI of the policy. May be {@code null}.
198 * @param policyId local URI of the policy. May be {@code null}.
199 *
200 * @return policy instance which represents a <emph>'anything allowed'</emph> (empty policy alternative with no plicy
201 * assertions prescribed).
202 */
203 public static Policy createEmptyPolicy(final NamespaceVersion nsVersion, final String name, final String policyId) {
204 if ((nsVersion == null || nsVersion == NamespaceVersion.getLatestVersion()) && name == null && policyId == null) {
205 return ANONYMOUS_EMPTY_POLICY;
206 } else {
207 return new Policy(nsVersion, name, policyId, EMPTY_POLICY_ASSERTION_SETS, EMPTY_VOCABULARY);
208 }
209 }
211 /**
212 * The factory method creates an <b>immutable</b> policy instance which represents a policy expression with
213 * alternatives specified by {@code sets} input parameter. If the collection of policy alternatives is null or empty
214 * an object representing a 'NULL' policy expression is returned. However, in such case it is better to use
215 * {@link #createNullPolicy()} factory method directly. The policy is created using the latest namespace version supported.
216 *
217 * @param sets represents the collection of policy alternatives of the policy object created. During the creation of
218 * the new policy object, the content of the alternatives collection is copied into an internal policy object structure,
219 * thus any subsequent operations on the collection will have no impact on the newly constructed policy object.
220 *
221 * @return policy instance which represents the policy with given alternatives.
222 */
223 public static Policy createPolicy(final Collection<AssertionSet> sets) {
224 if (sets == null || sets.isEmpty()) {
225 return createNullPolicy();
226 } else {
227 return new Policy(POLICY_TOSTRING_NAME, sets);
228 }
229 }
231 /**
232 * The factory method creates an <b>immutable</b> policy instance which represents a policy expression with
233 * alternatives specified by {@code sets} input parameter. If the collection of policy alternatives is null or empty
234 * an object representing a 'NULL' policy expression is returned. However, in such case it is better to use
235 * {@link #createNullPolicy(String, String)} factory method directly. The policy is created using the latest namespace version supported.
236 *
237 * @param name global URI of the policy. May be {@code null}.
238 * @param policyId local URI of the policy. May be {@code null}.
239 * @param sets represents the collection of policy alternatives of the policy object created. During the creation of
240 * the new policy object, the content of the alternatives collection is copied into an internal policy object structure,
241 * thus any subsequent operations on the collection will have no impact on the newly constructed policy object.
242 *
243 * @return policy instance which represents the policy with given alternatives.
244 */
245 public static Policy createPolicy(final String name, final String policyId, final Collection<AssertionSet> sets) {
246 if (sets == null || sets.isEmpty()) {
247 return createNullPolicy(name, policyId);
248 } else {
249 return new Policy(POLICY_TOSTRING_NAME, name, policyId, sets);
250 }
251 }
253 /**
254 * The factory method creates an <b>immutable</b> policy instance which represents a policy expression with
255 * alternatives specified by {@code sets} input parameter. If the collection of policy alternatives is null or empty
256 * an object representing a 'NULL' policy expression is returned. However, in such case it is better to use
257 * {@link #createNullPolicy(String, String)} factory method directly. The policy is created using the latest namespace version supported.
258 *
259 * @param nsVersion Policy namespace version to be used when marshalling the policy expression
260 * @param name global URI of the policy. May be {@code null}.
261 * @param policyId local URI of the policy. May be {@code null}.
262 * @param sets represents the collection of policy alternatives of the policy object created. During the creation of
263 * the new policy object, the content of the alternatives collection is copied into an internal policy object structure,
264 * thus any subsequent operations on the collection will have no impact on the newly constructed policy object.
265 *
266 * @return policy instance which represents the policy with given alternatives.
267 */
268 public static Policy createPolicy(NamespaceVersion nsVersion, final String name, final String policyId, final Collection<AssertionSet> sets) {
269 if (sets == null || sets.isEmpty()) {
270 return createNullPolicy(nsVersion, name, policyId);
271 } else {
272 return new Policy(nsVersion, POLICY_TOSTRING_NAME, name, policyId, sets);
273 }
274 }
276 /**
277 * A most flexible policy object constructor that allows private creation of policy objects and direct setting
278 * of all its attributes.
279 *
280 * @param name global URI of the policy. May be {@code null}.
281 * @param policyId local URI of the policy. May be {@code null}.
282 * @param assertionSets represents the collection of policy alternatives of the policy object created. The list is directly
283 * assigned to the policy object internal attribute. Subsequent manipulations on the collection must be handled with
284 * care.
285 * @param vocabulary represents the vocabulary of the policy object. Subsequent manipulations on the collection
286 * must be handled with care.
287 */
288 private Policy(final String name, final String policyId, final List<AssertionSet> assertionSets, final Set<QName> vocabulary) {
289 this.nsVersion = NamespaceVersion.getLatestVersion();
290 this.toStringName = POLICY_TOSTRING_NAME;
291 this.name = name;
292 this.policyId = policyId;
293 this.assertionSets = assertionSets;
294 this.vocabulary = vocabulary;
295 this.immutableVocabulary = Collections.unmodifiableCollection(this.vocabulary);
296 }
298 /**
299 * Constructor that should be overridden by child implementation. The constructor allows for easy toString() output
300 * customization.
301 *
302 * @param toStringName a general name of the object (such as 'policy' or 'nested policy') that will be used in the
303 * toString() method to identify the object.
304 * @param sets represents the collection of policy alternatives of the policy object created. During the creation of
305 * the new policy object, the content of the alternatives collection is copied into an internal policy object structure,
306 * thus any subsequent operations on the collection will have no impact on the newly constructed policy object. The
307 * collection may be {@code null} or empty. In such case a 'NULL' policy object is constructed.
308 */
309 Policy(final String toStringName, final Collection<AssertionSet> sets) {
310 this.nsVersion = NamespaceVersion.getLatestVersion();
311 this.toStringName = toStringName;
313 if (sets == null || sets.isEmpty()) {
314 this.assertionSets = NULL_POLICY_ASSERTION_SETS;
315 this.vocabulary = EMPTY_VOCABULARY;
316 this.immutableVocabulary = EMPTY_VOCABULARY;
317 } else {
318 this.assertionSets = new LinkedList<AssertionSet>();
319 this.vocabulary = new TreeSet<QName>(PolicyUtils.Comparison.QNAME_COMPARATOR);
320 this.immutableVocabulary = Collections.unmodifiableCollection(this.vocabulary);
322 addAll(sets);
323 }
324 }
326 /**
327 * Constructor that should be overridden by child implementation. The constructor allows for easy toString() output
328 * customization.
329 *
330 * @param toStringName a general name of the object (such as 'policy' or 'nested policy') that will be used in the
331 * toString() method to identify the object.
332 * @param name global URI of the policy. May be {@code null}.
333 * @param policyId local URI of the policy. May be {@code null}.
334 * @param sets represents the collection of policy alternatives of the policy object created. During the creation of
335 * the new policy object, the content of the alternatives collection is copied into an internal policy object structure,
336 * thus any subsequent operations on the collection will have no impact on the newly constructed policy object. The
337 * collection may be {@code null} or empty. In such case a 'NULL' policy object is constructed.
338 */
339 Policy(final String toStringName, final String name, final String policyId, final Collection<AssertionSet> sets) {
340 this(toStringName, sets);
341 this.name = name;
342 this.policyId = policyId;
343 }
345 /**
346 * A most flexible policy object constructor that allows private creation of policy objects and direct setting
347 * of all its attributes.
348 *
349 * @param nsVersion Policy namespace version to be used when marshalling the policy expression
350 * @param name global URI of the policy. May be {@code null}.
351 * @param policyId local URI of the policy. May be {@code null}.
352 * @param assertionSets represents the collection of policy alternatives of the policy object created. The list is directly
353 * assigned to the policy object internal attribute. Subsequent manipulations on the collection must be handled with
354 * care.
355 * @param vocabulary represents the vocabulary of the policy object. Subsequent manipulations on the collection
356 * must be handled with care.
357 */
358 private Policy(final NamespaceVersion nsVersion, final String name, final String policyId, final List<AssertionSet> assertionSets, final Set<QName> vocabulary) {
359 this.nsVersion = nsVersion;
360 this.toStringName = POLICY_TOSTRING_NAME;
361 this.name = name;
362 this.policyId = policyId;
363 this.assertionSets = assertionSets;
364 this.vocabulary = vocabulary;
365 this.immutableVocabulary = Collections.unmodifiableCollection(this.vocabulary);
366 }
368 /**
369 * Constructor that should be overridden by child implementation. The constructor allows for easy toString() output
370 * customization.
371 *
372 * @param nsVersion Policy namespace version to be used when marshalling the policy expression
373 * @param toStringName a general name of the object (such as 'policy' or 'nested policy') that will be used in the
374 * toString() method to identify the object.
375 * @param sets represents the collection of policy alternatives of the policy object created. During the creation of
376 * the new policy object, the content of the alternatives collection is copied into an internal policy object structure,
377 * thus any subsequent operations on the collection will have no impact on the newly constructed policy object. The
378 * collection may be {@code null} or empty. In such case a 'NULL' policy object is constructed.
379 */
380 Policy(final NamespaceVersion nsVersion, final String toStringName, final Collection<AssertionSet> sets) {
381 this.nsVersion = nsVersion;
382 this.toStringName = toStringName;
384 if (sets == null || sets.isEmpty()) {
385 this.assertionSets = NULL_POLICY_ASSERTION_SETS;
386 this.vocabulary = EMPTY_VOCABULARY;
387 this.immutableVocabulary = EMPTY_VOCABULARY;
388 } else {
389 this.assertionSets = new LinkedList<AssertionSet>();
390 this.vocabulary = new TreeSet<QName>(PolicyUtils.Comparison.QNAME_COMPARATOR);
391 this.immutableVocabulary = Collections.unmodifiableCollection(this.vocabulary);
393 addAll(sets);
394 }
395 }
397 /**
398 * Constructor that should be overridden by child implementation. The constructor allows for easy toString() output
399 * customization.
400 *
401 * @param nsVersion Policy namespace version to be used when marshalling the policy expression
402 * @param toStringName a general name of the object (such as 'policy' or 'nested policy') that will be used in the
403 * toString() method to identify the object.
404 * @param name global URI of the policy. May be {@code null}.
405 * @param policyId local URI of the policy. May be {@code null}.
406 * @param sets represents the collection of policy alternatives of the policy object created. During the creation of
407 * the new policy object, the content of the alternatives collection is copied into an internal policy object structure,
408 * thus any subsequent operations on the collection will have no impact on the newly constructed policy object. The
409 * collection may be {@code null} or empty. In such case a 'NULL' policy object is constructed.
410 */
411 Policy(final NamespaceVersion nsVersion, final String toStringName, final String name, final String policyId, final Collection<AssertionSet> sets) {
412 this(nsVersion, toStringName, sets);
413 this.name = name;
414 this.policyId = policyId;
415 }
417 /**
418 * Adds single alternative to the internal alternatives set of the policy object.
419 *
420 * @param set assertion set (policy alternative) object to be added. May be {@code null}; in such case the method
421 * returns false.
422 *
423 * @return {@code true} or {@code false} depending on whether the new alternative was added to the policy object or not.
424 */
425 private boolean add(final AssertionSet set) {
426 if (set == null) {
427 return false;
428 }
430 if (this.assertionSets.contains(set)) {
431 return false;
432 } else {
433 this.assertionSets.add(set);
434 this.vocabulary.addAll(set.getVocabulary());
435 return true;
436 }
437 }
439 /**
440 * Adds all alternatives from the input collection of assertion sets to the policy object's internal set of alternatives.
441 * The policy object's vocabulary structure is updated as well.
442 *
443 * @param sets collection of new alternatives. Must NOT be {@code null} or empty. The check for null or empty input
444 * parameter is performed with help of {@code assert} keyword, thus during the testing and development of this class
445 * {@code -ea} switch should be turned on for this class.
446 *
447 * @return {@code true} if all elements in the input collection were added to internal structure, {@code false} otherwise.
448 */
449 private boolean addAll(final Collection<AssertionSet> sets) {
450 assert (sets != null && !sets.isEmpty()) : LocalizationMessages.WSP_0036_PRIVATE_METHOD_DOES_NOT_ACCEPT_NULL_OR_EMPTY_COLLECTION();
452 boolean result = true;
453 for (AssertionSet set : sets) {
454 result &= add(set); // this is here to ensure that vocabulary is built correctly as well
455 }
456 Collections.sort(this.assertionSets);
458 return result;
459 }
461 Collection<AssertionSet> getContent() {
462 return assertionSets;
463 }
465 /**
466 * Returns the policy identifier that serves as a local relative policy URI.
467 *
468 * @return policy identifier - a local relative policy URI. If no policy identifier is set, returns {@code null}.
469 */
470 public String getId() {
471 return policyId;
472 }
474 /**
475 * Returns the policy name that serves as a global policy URI.
476 *
477 * @return policy name - a global policy URI. If no policy name is set, returns {@code null}.
478 */
479 public String getName() {
480 return name;
481 }
483 public NamespaceVersion getNamespaceVersion() {
484 return nsVersion;
485 }
487 /**
488 * Returns the policy ID or if that is null the policy name. May return null
489 * if both attributes are null.
490 *
491 * @see #getId()
492 * @see #getName()
493 * @return The policy ID if it was set, or the name or null if no attribute was set.
494 */
495 public String getIdOrName() {
496 if (policyId != null) {
497 return policyId;
498 }
499 return name;
500 }
502 /**
503 * Method returns how many policy alternatives this policy instance contains.
504 *
505 * @return number of policy alternatives contained in this policy instance
506 */
507 public int getNumberOfAssertionSets() {
508 return assertionSets.size();
509 }
511 /**
512 * A policy usually contains one or more assertion sets. Each assertion set
513 * corresponds to a policy alternative as defined by WS-Policy.
514 *
515 * @return An iterator to iterate through all contained assertion sets
516 */
517 public Iterator<AssertionSet> iterator() {
518 return assertionSets.iterator();
519 }
521 /**
522 * Returns {@code true} if the policy instance represents "nothing allowed" policy expression
523 *
524 * @return {@code true} if the policy instance represents "nothing allowed" policy expression, {@code false} otherwise.
525 */
526 public boolean isNull() {
527 return assertionSets.size() == 0;
528 }
530 /**
531 * Returns {@code true} if the policy instance represents "anything allowed" policy expression
532 *
533 * @return {@code true} if the policy instance represents "anything allowed" policy expression, {@code false} otherwise.
534 */
535 public boolean isEmpty() {
536 return assertionSets.size() == 1 && assertionSets.get(0).isEmpty();
537 }
539 /**
540 * Returns true if the policy contains the assertion names with specified namespace in its vocabulary
541 *
542 * @param namespaceUri the assertion namespace URI (identifying assertion domain)
543 * @return {@code true}, if an assertion with the given name could be found in the policy vocabulary {@code false} otherwise.
544 */
545 public boolean contains(final String namespaceUri) {
546 for (QName entry : vocabulary) {
547 if (entry.getNamespaceURI().equals(namespaceUri)) {
548 return true;
549 }
550 }
552 return false;
553 }
555 /**
556 * Retrieves the vocabulary of this policy expression. The vocabulary is represented by an immutable collection of
557 * unique QName objects. Each of those objects represents single assertion type contained in the policy.
558 *
559 * @return immutable collection of assertion types contained in the policy (a policy vocabulary).
560 */
561 public Collection<QName> getVocabulary() {
562 return immutableVocabulary;
563 }
565 /**
566 * Determines if the policy instance contains the assertion with the name specified in its vocabulary.
567 *
568 * @param assertionName the name of the assertion to be tested.
569 *
570 * @return {@code true} if the assertion with the specified name is part of the policy instance's vocabulary,
571 * {@code false} otherwise.
572 */
573 public boolean contains(final QName assertionName) {
574 return vocabulary.contains(assertionName);
575 }
577 /**
578 * An {@code Object.equals(Object obj)} method override.
579 */
580 @Override
581 public boolean equals(final Object obj) {
582 if (this == obj) {
583 return true;
584 }
586 if (!(obj instanceof Policy)) {
587 return false;
588 }
590 final Policy that = (Policy) obj;
592 boolean result = true;
594 result = result && this.vocabulary.equals(that.vocabulary);
595 result = result && this.assertionSets.size() == that.assertionSets.size() && this.assertionSets.containsAll(that.assertionSets);
597 return result;
598 }
600 /**
601 * An {@code Object.hashCode()} method override.
602 */
603 @Override
604 public int hashCode() {
605 int result = 17;
607 result = 37 * result + vocabulary.hashCode();
608 result = 37 * result + assertionSets.hashCode();
610 return result;
611 }
613 /**
614 * An {@code Object.toString()} method override.
615 */
616 @Override
617 public String toString() {
618 return toString(0, new StringBuffer()).toString();
619 }
621 /**
622 * A helper method that appends indented string representation of this instance to the input string buffer.
623 *
624 * @param indentLevel indentation level to be used.
625 * @param buffer buffer to be used for appending string representation of this instance
626 * @return modified buffer containing new string representation of the instance
627 */
628 StringBuffer toString(final int indentLevel, final StringBuffer buffer) {
629 final String indent = PolicyUtils.Text.createIndent(indentLevel);
630 final String innerIndent = PolicyUtils.Text.createIndent(indentLevel + 1);
631 final String innerDoubleIndent = PolicyUtils.Text.createIndent(indentLevel + 2);
633 buffer.append(indent).append(toStringName).append(" {").append(PolicyUtils.Text.NEW_LINE);
634 buffer.append(innerIndent).append("namespace version = '").append(nsVersion.name()).append('\'').append(PolicyUtils.Text.NEW_LINE);
635 buffer.append(innerIndent).append("id = '").append(policyId).append('\'').append(PolicyUtils.Text.NEW_LINE);
636 buffer.append(innerIndent).append("name = '").append(name).append('\'').append(PolicyUtils.Text.NEW_LINE);
638 buffer.append(innerIndent).append("vocabulary {").append(PolicyUtils.Text.NEW_LINE);
639 if (vocabulary.isEmpty()) {
640 buffer.append(innerDoubleIndent).append("no entries").append(PolicyUtils.Text.NEW_LINE);
641 } else {
642 int index = 1;
643 for (QName entry : vocabulary) {
644 buffer.append(innerDoubleIndent).append(index++).append(". entry = '").append(entry.getNamespaceURI()).append(':').append(entry.getLocalPart()).append('\'').append(PolicyUtils.Text.NEW_LINE);
645 }
646 }
647 buffer.append(innerIndent).append('}').append(PolicyUtils.Text.NEW_LINE);
649 if (assertionSets.isEmpty()) {
650 buffer.append(innerIndent).append("no assertion sets").append(PolicyUtils.Text.NEW_LINE);
651 } else {
652 for (AssertionSet set : assertionSets) {
653 set.toString(indentLevel + 1, buffer).append(PolicyUtils.Text.NEW_LINE);
654 }
655 }
657 buffer.append(indent).append('}');
659 return buffer;
660 }
661 }