2582bc17db54d5ada9772dac50626b37fc065303
[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 }