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