2 * ============LICENSE_START====================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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====================================================
22 package org.onap.aaf.auth.rserv;
24 import java.util.ArrayList;
25 import java.util.Iterator;
26 import java.util.List;
28 import org.onap.aaf.misc.env.Trans;
31 * Find Acceptable Paths and place them where TypeCode can evaluate.
33 * If there are more than one, TypeCode will choose based on "q" value
38 class Acceptor<TRANS extends Trans> {
39 private List<Pair<String, Pair<HttpCode<TRANS,?>, List<Pair<String, Object>>>>> types;
40 List<Pair<String, Pair<HttpCode<TRANS,?>, List<Pair<String, Object>>>>> acceptable;
42 public Acceptor(List<Pair<String, Pair<HttpCode<TRANS,?>, List<Pair<String, Object>>>>> types) {
44 acceptable = new ArrayList<>();
47 private boolean eval(HttpCode<TRANS,?> code, String str, List<String> props) {
48 // int plus = str.indexOf('+');
52 for (Pair<String, Pair<HttpCode<TRANS,?>, List<Pair<String, Object>>>> type : types) {
54 if (type.x.equals(str)) {
55 for (Iterator<String> iter = props.iterator();ok && iter.hasNext();) {
56 ok = props(type,iter.next(),iter.next());
64 // } else { // Handle Accepts with "+" as in application/xaml+xml
65 // int prev = str.indexOf('/')+1;
66 // String first = str.substring(0,prev);
69 // nstr = first + (plus<0?str.substring(prev):str.substring(prev,plus));
71 // for (Pair<String, Pair<HttpCode<TRANS,?>, List<Pair<String, Object>>>> type : types) {
72 // if (type.x.equals(nstr)) {
73 // acceptable.add(type);
78 // plus=str.indexOf('+', prev);
91 private boolean props(Pair<String, Pair<HttpCode<TRANS,?>, List<Pair<String, Object>>>> type, String tag, String value) {
94 for (Pair<String,Object> prop : type.y.y){
95 if (tag.equals(prop.x)) {
96 if (tag.equals("charset")) {
97 return prop.x==null?false:prop.y.equals(value.toLowerCase()); // return True if Matched
98 } else if (tag.equals("version")) {
99 return prop.y.equals(new Version(value)); // Note: Version Class knows Minor Version encoding
100 } else if (tag.equals(Content.Q)) { // replace Q value
102 type.y.y.get(0).y=Float.parseFloat(value);
103 } catch (NumberFormatException e) {
104 rv=false; // need to do something to make Sonar happy. But nothing to do.
108 return value.equals(prop.y);
119 * Note: I'm processing by index to avoid lots of memory creation, which speeds things
120 * up for this time critical section of code.
125 protected boolean parse(HttpCode<TRANS, ?> code, String cntnt) {
126 byte bytes[] = cntnt.getBytes();
131 ArrayList<String> props = new ArrayList<>();
133 // Clear these in case more than one Semi
134 props.clear(); // on loop, do not want mixed properties
137 cis = cie+1; // find comma start
138 while (cis<bytes.length && Character.isSpaceChar(bytes[cis]))++cis;
139 cie = cntnt.indexOf(',',cis); // find comma end
140 cend = cie<0?bytes.length:cie; // If no comma, set comma end to full length, else cie
141 while (cend>cis && Character.isSpaceChar(bytes[cend-1]))--cend;
145 sis = sie+1; // semi start is one after previous end
146 while (sis<bytes.length && Character.isSpaceChar(bytes[sis]))++sis;
147 sie = cntnt.indexOf(';',sis);
148 send = sie>cend || sie<0?cend:sie; // if the Semicolon is after the comma, or non-existent, use comma end, else keep
149 while (send>sis && Character.isSpaceChar(bytes[send-1]))--send;
150 if (name==null) { // first entry in Comma set is the name, not a property
151 name = new String(bytes,sis,send-sis);
152 } else { // We've looped past the first Semi, now process as properties
153 // If there are additional elements (more entities within Semi Colons)
155 int eq = cntnt.indexOf('=',sis);
156 if (eq>sis && eq<send) {
157 props.add(new String(bytes,sis,eq-sis));
158 props.add(new String(bytes,eq+1,send-(eq+1)));
162 } while (sie<=cend && sie>=cis); // End SEMI processing
163 // Now evaluate Comma set and return if true
164 if (eval(code,name,props))return true; // else loop again to check next comma
165 } while (cie>=0); // loop to next comma
166 return false; // didn't get even one match