summaryrefslogtreecommitdiffstats
path: root/authz-core/src/main/java/org/onap/aaf/cssa/rserv/Content.java
blob: 031e8bbea0a756734f01e2386e9e7f4142ebb3ec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/*******************************************************************************
 * ============LICENSE_START====================================================
 * * org.onap.aaf
 * * ===========================================================================
 * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
 * * ===========================================================================
 * * Licensed under the Apache License, Version 2.0 (the "License");
 * * you may not use this file except in compliance with the License.
 * * You may obtain a copy of the License at
 * * 
 *  *      http://www.apache.org/licenses/LICENSE-2.0
 * * 
 *  * Unless required by applicable law or agreed to in writing, software
 * * distributed under the License is distributed on an "AS IS" BASIS,
 * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * * See the License for the specific language governing permissions and
 * * limitations under the License.
 * * ============LICENSE_END====================================================
 * *
 * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
 * *
 ******************************************************************************/
package org.onap.aaf.cssa.rserv;

import java.util.List;

import org.onap.aaf.inno.env.Trans;



/**
 * A Class to hold Service "ContentTypes", and to match incoming "Accept" types from HTTP.
 * 
 * This is a multi-use class built to use the same Parser for ContentTypes and Accept.
 * 
 * Thus, you would create and use "Content.Type" within your service, and use it to match
 * Accept Strings.  What is returned is an Integer (for faster processing), which can be
 * used in a switch statement to act on match different Actions.  The server should
 * know which behaviors match.
 * 
 * "bestMatch" returns an integer for the best match, or -1 if no matches.
 *
 *
 */
public abstract class Content<TRANS extends Trans> {
	public static final String Q = "q";
	protected abstract Pair<String,Pair<HttpCode<TRANS,?>,List<Pair<String,Object>>>> types(HttpCode<TRANS,?> code, String str);
	protected abstract boolean props(Pair<String, Pair<HttpCode<TRANS,?>,List<Pair<String,Object>>>> type, String tag, String value);

	/**
	 * Parse a Content-Type/Accept.  As found, call "types" and "props", which do different
	 * things depending on if it's a Content-Type or Accepts. 
	 * 
	 * For Content-Type, it builds a tree suitable for Comparison
	 * For Accepts, it compares against the tree, and builds an acceptable type list
	 * 
	 * Since this parse code is used for every incoming HTTP transaction, I have removed the implementation
	 * that uses String.split, and replaced with integers evaluating the Byte array.  This results
	 * in only the necessary strings created, resulting in 1/3 better speed, and less 
	 * Garbage collection.
	 * 
	 * @param trans
	 * @param code
	 * @param cntnt
	 * @return
	 */
	protected boolean parse(HttpCode<TRANS,?> code, String cntnt) {
		byte bytes[] = cntnt.getBytes();
		boolean contType=false,contProp=true;
		int cis,cie=-1,cend;
		int sis,sie,send;
		do {
			cis = cie+1;
			cie = cntnt.indexOf(',',cis);
			cend = cie<0?bytes.length:cie;
			// Start SEMIS
			sie=cis-1;
			Pair<String, Pair<HttpCode<TRANS,?>, List<Pair<String, Object>>>> me = null;
			do {
				sis = sie+1;
				sie = cntnt.indexOf(';',sis);
				send = sie>cend || sie<0?cend:sie;
				if(me==null) {
					String semi = new String(bytes,sis,send-sis);
					// trans.checkpoint(semi);
					// Look at first entity within comma group
					// Is this an acceptable Type?
					me=types(code, semi);
					if(me==null) {
						sie=-1; // skip the rest of the processing... not a type
					} else {
						contType=true;
					}
				} else { // We've looped past the first Semi, now process as properties
					// If there are additional elements (more entities within Semi Colons)
					// apply Propertys
					int eq = cntnt.indexOf('=',sis);
					if(eq>sis && eq<send) {
						String tag = new String(bytes,sis,eq-sis);
						String value = new String(bytes,eq+1,send-(eq+1));
						// trans.checkpoint("    Prop " + tag + "=" + value);
						boolean bool =  props(me,tag,value);
						if(!bool) {
							contProp=false;
						}
					}
				}
				// End Property
			} while(sie<=cend && sie>=cis);
			// End SEMIS
		} while(cie>=0);
		return contType && contProp; // for use in finds, True if a type found AND all props matched
	}
	
}