Fixing the ClassLoader.defineClass() method issue that could not find the necessary...
[jpf-core.git] / src / peers / gov / nasa / jpf / vm / JPF_sun_net_www_protocol_http_Handler.java
1 /*
2  * Copyright (C) 2014, United States Government, as represented by the
3  * Administrator of the National Aeronautics and Space Administration.
4  * All rights reserved.
5  *
6  * The Java Pathfinder core (jpf-core) platform is licensed under the
7  * Apache License, Version 2.0 (the "License"); you may not use this file except
8  * in compliance with the License. You may obtain a copy of the License at
9  * 
10  *        http://www.apache.org/licenses/LICENSE-2.0. 
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and 
16  * limitations under the License.
17  */
18
19 package gov.nasa.jpf.vm;
20
21 import gov.nasa.jpf.Config;
22 import gov.nasa.jpf.JPF;
23 import gov.nasa.jpf.JPFConfigException;
24 import gov.nasa.jpf.annotation.MJI;
25 import gov.nasa.jpf.util.JPFLogger;
26 import gov.nasa.jpf.util.StringMatcher;
27
28 /**
29  * native peer to configure concrete URLConnection classes for specific URLs
30  *
31  * We use model class configuration in case somebody wants to implement logic
32  * in there that requires backtracking, and doesn't want to do this on the
33  * native peer level
34  *
35  * example config:
36  *   http.connection= http://*.dtd => gov.nasa.jpf.CachedROHttpConnection, http://foo.com/* -- x.y.MyHttpConnection
37  */
38 public class JPF_sun_net_www_protocol_http_Handler extends NativePeer {
39
40   static JPFLogger logger = JPF.getLogger("http");
41
42
43   static class MapEntry {
44     StringMatcher matcher;
45     String clsName;
46
47     MapEntry (StringMatcher m, String c){
48       matcher = m;
49       clsName = c;
50     }
51   }
52
53   MapEntry[] map;
54
55   public JPF_sun_net_www_protocol_http_Handler (Config conf){
56     String[] specs = conf.getCompactTrimmedStringArray("http.connection");
57     if (specs != null){
58       map = new MapEntry[specs.length];
59
60       for (int i=0; i<specs.length; i++){
61         String s = specs[i];
62         MapEntry e = null;
63
64         int idx = s.indexOf("--");
65         if (idx > 0 && idx < (s.length() - 3)){
66           String pattern = s.substring(0, idx).trim();
67           String clsName = s.substring(idx+2).trim();
68
69           if (!pattern.isEmpty() && !clsName.isEmpty()){
70             StringMatcher matcher = new StringMatcher(pattern);
71             e = new MapEntry(matcher, clsName);
72
73             logger.info("mapping URL pattern ", pattern, " to ", clsName);
74           }
75         }
76
77         if (e == null){
78           throw new JPFConfigException("not a valid http.connection spec: " + s);
79         }
80
81         map[i] = e;
82       }
83     }
84
85   }
86
87   @MJI
88   public int getConnectionClass__Ljava_lang_String_2__Ljava_lang_Class_2 (MJIEnv env, int objref, int surlRef){
89     String url = env.getStringObject(surlRef);
90
91     if (map != null){
92       for (int i = 0; i < map.length; i++) {
93         if (map[i].matcher.matches(url)) {
94           String clsName = map[i].clsName;
95
96           ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
97
98           // this might re-execute if there is a clinit
99           int clsObjRef = JPF_java_lang_Class.getClassObject(env, ci);
100
101           if (clsObjRef != MJIEnv.NULL){
102             logger.info("using ", clsName, " for URL ", url);
103           }
104           return clsObjRef;
105         }
106       }
107     }
108
109     // didn't find any match
110     return MJIEnv.NULL;
111   }
112 }