Sonar Fixes, Formatting
[aaf/authz.git] / cadi / core / src / main / java / org / onap / aaf / cadi / wsse / Match.java
1 /**
2  * ============LICENSE_START====================================================
3  * org.onap.aaf
4  * ===========================================================================
5  * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
6  * ===========================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END====================================================
19  *
20  */
21
22 package org.onap.aaf.cadi.wsse;
23
24 import javax.xml.namespace.QName;
25 import javax.xml.stream.XMLStreamException;
26 import javax.xml.stream.events.XMLEvent;
27
28 /**
29  * Match Class allows you to build an automatic Tree of StAX (or StAX like)
30  * Objects for frequent use.
31  *
32  * OBJECT is a type which you which to do some end Actions on, similar to a Visitor pattern, see Action
33  *
34  * Note: We have implemented with XReader and XEvent, rather than StAX for performance reasons.
35  *
36  * @see Action
37  * @see Match
38  * @see XEvent
39  * @see XReader
40  *
41  * @author Jonathan
42  *
43  * @param <OUTPUT>
44  */
45 //@SuppressWarnings("restriction")
46 public class Match<OUTPUT> {
47     private QName qname;
48     private Match<OUTPUT>[] next;
49     private Match<OUTPUT> prev;
50     private Action<OUTPUT> action = null;
51     private boolean stopAfter;
52     private boolean exclusive;
53
54
55     @SafeVarargs
56     public Match(String ns, String name, Match<OUTPUT> ... next) {
57         this.qname = new QName(ns,name);
58         this.next = next;
59         stopAfter = exclusive = false;
60         for (Match<OUTPUT> m : next) { // add the possible tags to look for
61             if (!m.stopAfter)m.prev = this;
62         }
63     }
64
65     public Match<OUTPUT> onMatch(OUTPUT output, XReader reader) throws XMLStreamException {
66         while (reader.hasNext()) {
67             XEvent event = reader.nextEvent();
68             switch(event.getEventType()) {
69                 case XMLEvent.START_ELEMENT:
70                     QName e_qname = event.asStartElement().getName();
71                     //System.out.println("Start - " + e_qname);
72                     boolean match = false;
73                     for (Match<OUTPUT> m : next) {
74                         if (e_qname.equals(m.qname)) {
75                             match=true;
76                             if (m.onMatch(output, reader)==null) {
77                                 return null; // short circuit Parsing
78                             }
79                             break;
80                         }
81                     }
82                     if (exclusive && !match) // When Tag MUST be present, i.e. the Root Tag, versus info we're not interested in
83                         return null;
84                     break;
85                 case XMLEvent.CHARACTERS:
86                     //System.out.println("Data - " +event.asCharacters().getData());
87                     if (action!=null) {
88                         if (!action.content(output,event.asCharacters().getData())) {
89                             return null;
90                         }
91                     }
92                     break;
93                 case XMLEvent.END_ELEMENT:
94                     //System.out.println("End - " + event.asEndElement().getName());
95                     if (event.asEndElement().getName().equals(qname)) {
96                         return prev;
97                     }
98                     break;
99                 case XMLEvent.END_DOCUMENT:
100                     return null; // Exit Chain
101             }
102         }
103         return this;
104     }
105
106     /**
107      * When this Matched Tag has completed, Stop parsing and end
108      * @return
109      */
110     public Match<OUTPUT> stopAfter() {
111         stopAfter = true;
112         return this;
113     }
114
115     /**
116      * Mark that this Object MUST be matched at this level or stop parsing and end
117      *
118      * @param action
119      * @return
120      */
121     public Match<OUTPUT> exclusive() {
122         exclusive = true;
123         return this;
124     }
125
126     public Match<OUTPUT> set(Action<OUTPUT> action) {
127         this.action = action;
128         return this;
129     }
130 }