Update AAF Version 1.0.0
[aaf/authz.git] / authz-core / src / main / java / com / att / cssa / rserv / Content.java
1 /*******************************************************************************\r
2  * ============LICENSE_START====================================================\r
3  * * org.onap.aaf\r
4  * * ===========================================================================\r
5  * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.\r
6  * * ===========================================================================\r
7  * * Licensed under the Apache License, Version 2.0 (the "License");\r
8  * * you may not use this file except in compliance with the License.\r
9  * * You may obtain a copy of the License at\r
10  * * \r
11  *  *      http://www.apache.org/licenses/LICENSE-2.0\r
12  * * \r
13  *  * Unless required by applicable law or agreed to in writing, software\r
14  * * distributed under the License is distributed on an "AS IS" BASIS,\r
15  * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
16  * * See the License for the specific language governing permissions and\r
17  * * limitations under the License.\r
18  * * ============LICENSE_END====================================================\r
19  * *\r
20  * * ECOMP is a trademark and service mark of AT&T Intellectual Property.\r
21  * *\r
22  ******************************************************************************/\r
23 package com.att.cssa.rserv;\r
24 \r
25 import java.util.List;\r
26 \r
27 import com.att.inno.env.Trans;\r
28 \r
29 \r
30 \r
31 /**\r
32  * A Class to hold Service "ContentTypes", and to match incoming "Accept" types from HTTP.\r
33  * \r
34  * This is a multi-use class built to use the same Parser for ContentTypes and Accept.\r
35  * \r
36  * Thus, you would create and use "Content.Type" within your service, and use it to match\r
37  * Accept Strings.  What is returned is an Integer (for faster processing), which can be\r
38  * used in a switch statement to act on match different Actions.  The server should\r
39  * know which behaviors match.\r
40  * \r
41  * "bestMatch" returns an integer for the best match, or -1 if no matches.\r
42  *\r
43  *\r
44  */\r
45 public abstract class Content<TRANS extends Trans> {\r
46         public static final String Q = "q";\r
47         protected abstract Pair<String,Pair<HttpCode<TRANS,?>,List<Pair<String,Object>>>> types(HttpCode<TRANS,?> code, String str);\r
48         protected abstract boolean props(Pair<String, Pair<HttpCode<TRANS,?>,List<Pair<String,Object>>>> type, String tag, String value);\r
49 \r
50         /**\r
51          * Parse a Content-Type/Accept.  As found, call "types" and "props", which do different\r
52          * things depending on if it's a Content-Type or Accepts. \r
53          * \r
54          * For Content-Type, it builds a tree suitable for Comparison\r
55          * For Accepts, it compares against the tree, and builds an acceptable type list\r
56          * \r
57          * Since this parse code is used for every incoming HTTP transaction, I have removed the implementation\r
58          * that uses String.split, and replaced with integers evaluating the Byte array.  This results\r
59          * in only the necessary strings created, resulting in 1/3 better speed, and less \r
60          * Garbage collection.\r
61          * \r
62          * @param trans\r
63          * @param code\r
64          * @param cntnt\r
65          * @return\r
66          */\r
67         protected boolean parse(HttpCode<TRANS,?> code, String cntnt) {\r
68                 byte bytes[] = cntnt.getBytes();\r
69                 boolean contType=false,contProp=true;\r
70                 int cis,cie=-1,cend;\r
71                 int sis,sie,send;\r
72                 do {\r
73                         cis = cie+1;\r
74                         cie = cntnt.indexOf(',',cis);\r
75                         cend = cie<0?bytes.length:cie;\r
76                         // Start SEMIS\r
77                         sie=cis-1;\r
78                         Pair<String, Pair<HttpCode<TRANS,?>, List<Pair<String, Object>>>> me = null;\r
79                         do {\r
80                                 sis = sie+1;\r
81                                 sie = cntnt.indexOf(';',sis);\r
82                                 send = sie>cend || sie<0?cend:sie;\r
83                                 if(me==null) {\r
84                                         String semi = new String(bytes,sis,send-sis);\r
85                                         // trans.checkpoint(semi);\r
86                                         // Look at first entity within comma group\r
87                                         // Is this an acceptable Type?\r
88                                         me=types(code, semi);\r
89                                         if(me==null) {\r
90                                                 sie=-1; // skip the rest of the processing... not a type\r
91                                         } else {\r
92                                                 contType=true;\r
93                                         }\r
94                                 } else { // We've looped past the first Semi, now process as properties\r
95                                         // If there are additional elements (more entities within Semi Colons)\r
96                                         // apply Propertys\r
97                                         int eq = cntnt.indexOf('=',sis);\r
98                                         if(eq>sis && eq<send) {\r
99                                                 String tag = new String(bytes,sis,eq-sis);\r
100                                                 String value = new String(bytes,eq+1,send-(eq+1));\r
101                                                 // trans.checkpoint("    Prop " + tag + "=" + value);\r
102                                                 boolean bool =  props(me,tag,value);\r
103                                                 if(!bool) {\r
104                                                         contProp=false;\r
105                                                 }\r
106                                         }\r
107                                 }\r
108                                 // End Property\r
109                         } while(sie<=cend && sie>=cis);\r
110                         // End SEMIS\r
111                 } while(cie>=0);\r
112                 return contType && contProp; // for use in finds, True if a type found AND all props matched\r
113         }\r
114         \r
115 }\r