KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > jk > apr > AprImpl


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16  
17 package org.apache.jk.apr;
18
19 import java.io.FileOutputStream JavaDoc;
20 import java.io.IOException JavaDoc;
21 import java.io.PrintStream JavaDoc;
22 import java.util.Hashtable JavaDoc;
23 import org.apache.jk.core.JkHandler;
24 import org.apache.jk.core.MsgContext;
25 import org.apache.jk.core.JkChannel;
26
27 /** Implements the interface with the APR library. This is for internal-use
28  * only. The goal is to use 'natural' mappings for user code - for example
29  * java.net.Socket for unix-domain sockets, etc.
30  *
31  */

32 public class AprImpl extends JkHandler { // This will be o.a.t.util.handler.TcHandler - lifecycle and config
33
static AprImpl aprSingleton=null;
34
35     String JavaDoc baseDir;
36     String JavaDoc aprHome;
37     String JavaDoc soExt="so";
38
39     static boolean ok=true;
40     boolean initialized=false;
41     // Handlers for native callbacks
42
Hashtable JavaDoc jkHandlers=new Hashtable JavaDoc();
43
44     // Name of the so used in inprocess mode
45
String JavaDoc jniModeSo="inprocess";
46     // name of the so used by java. If not set we'll loadLibrary("jkjni" ),
47
// if set we load( nativeSo )
48
String JavaDoc nativeSo;
49     
50     public AprImpl() {
51         aprSingleton=this;
52     }
53     
54     // -------------------- Properties --------------------
55

56     /** Native libraries are located based on base dir.
57      * XXX Add platform, version, etc
58      */

59     public void setBaseDir(String JavaDoc s) {
60         baseDir=s;
61     }
62     
63     public void setSoExt(String JavaDoc s ) {
64         soExt=s;
65     }
66     
67     // XXX maybe install the jni lib in apr-home ?
68
public void setAprHome( String JavaDoc s ) {
69         aprHome=s;
70     }
71
72     /** Add a Handler for jni callbacks.
73      */

74     public void addJkHandler(String JavaDoc type, JkHandler cb) {
75         jkHandlers.put( type, cb );
76     }
77     
78     /** Name of the so used in inprocess mode
79      */

80     public void setJniModeSo(String JavaDoc jniModeSo ) {
81         this.jniModeSo=jniModeSo;
82     }
83
84     /** name of the so used by java. If not set we'll loadLibrary("jkjni" ),
85         if set we load( nativeSo )
86     */

87     public void setNativeSo( String JavaDoc nativeSo ) {
88         this.nativeSo=nativeSo;
89     }
90
91     /** Sets the System.out stream */
92     
93     public static void setOut( String JavaDoc filename ) {
94         try{
95             if( filename !=null ){
96                 System.setOut( new PrintStream JavaDoc(new FileOutputStream JavaDoc(filename )));
97             }
98         }catch (Throwable JavaDoc th){
99         }
100     }
101     /** Sets the System.err stream */
102     
103     public static void setErr( String JavaDoc filename ) {
104         try{
105             if( filename !=null ){
106                 System.setErr( new PrintStream JavaDoc(new FileOutputStream JavaDoc(filename )));
107             }
108         }catch (Throwable JavaDoc th){
109         }
110     }
111
112     // -------------------- Apr generic utils --------------------
113
/** Initialize APR
114      */

115     public native int initialize();
116
117     public native int terminate();
118
119     /* -------------------- Access to the jk_env_t -------------------- */
120
121     /* The jk_env_t provide temporary storage ( pool ), logging, common services
122      */

123     
124     /* Return a jk_env_t, used to keep the execution context ( temp pool, etc )
125      */

126     public native long getJkEnv();
127
128     /** Clean the temp pool, put back the env in the pool
129      */

130     public native void releaseJkEnv(long xEnv);
131
132     /* -------------------- Interface to the jk_bean object -------------------- */
133     /* Each jk component is 'wrapped' as a bean, with a specified lifecycle
134      *
135      */

136     
137     /** Get a native component
138      * @return 0 if the component is not found.
139      */

140     public native long getJkHandler(long xEnv, String JavaDoc compName );
141
142     public native long createJkHandler(long xEnv, String JavaDoc compName );
143
144     public native int jkSetAttribute( long xEnv, long componentP, String JavaDoc name, String JavaDoc val );
145
146     public native String JavaDoc jkGetAttribute( long xEnv, long componentP, String JavaDoc name );
147     
148     public native int jkInit( long xEnv, long componentP );
149
150     public native int jkDestroy( long xEnv, long componentP );
151     
152     /** Send the packet to the C side. On return it contains the response
153      * or indication there is no response. Asymetrical because we can't
154      * do things like continuations.
155      */

156     public static native int jkInvoke(long xEnv, long componentP, long endpointP,
157                                       int code, byte data[], int off, int len, int raw);
158
159     /** Recycle an endpoint after use.
160      */

161     public native void jkRecycle(long xEnv, long endpointP);
162
163     // -------------------- Called from C --------------------
164
// XXX Check security, add guard or other protection
165
// It's better to do it the other way - on init 'push' AprImpl into
166
// the native library, and have native code call instance methods.
167

168     public static Object JavaDoc createJavaContext(String JavaDoc type, long cContext) {
169         // XXX will be an instance method, fields accessible directly
170
AprImpl apr=aprSingleton;
171         JkChannel jkH=(JkChannel)apr.jkHandlers.get( type );
172         if( jkH==null ) return null;
173
174         MsgContext ep=jkH.createMsgContext();
175
176         ep.setSource( jkH );
177         
178         ep.setJniContext( cContext );
179         return ep;
180     }
181
182     /** Return a buffer associated with the ctx.
183      */

184     public static byte[] getBuffer( Object JavaDoc ctx, int id ) {
185         return ((MsgContext)ctx).getBuffer( id );
186     }
187
188     public static int jniInvoke( long jContext, Object JavaDoc ctx ) {
189         try {
190             MsgContext ep=(MsgContext)ctx;
191             ep.setJniEnv( jContext );
192             ep.setType( 0 );
193             return ((MsgContext)ctx).execute();
194         } catch( Throwable JavaDoc ex ) {
195             ex.printStackTrace();
196             return -1;
197         }
198     }
199
200     // -------------------- Initialization --------------------
201

202     public void init() throws IOException JavaDoc {
203         try {
204             initialized=true;
205             loadNative();
206
207             initialize();
208             jkSetAttribute(0, 0, "channel:jni", "starting");
209             
210             log.info("JK: Initialized apr" );
211             
212         } catch( Throwable JavaDoc t ) {
213             throw new IOException JavaDoc( t.toString() );
214         }
215         ok=true;
216     }
217
218     public boolean isLoaded() {
219         if( ! initialized ) {
220             try {
221                 init();
222             } catch( Throwable JavaDoc t ) {
223                 log.info("Apr not loaded: " + t);
224             }
225         }
226         return ok;
227     }
228
229     static boolean jniMode=false;
230
231     
232     public static void jniMode() {
233         jniMode=true;
234     }
235
236     /** This method of loading the libs doesn't require setting
237      * LD_LIBRARY_PATH. Assuming a 'right' binary distribution,
238      * or a correct build all files will be in their right place.
239      *
240      * The burden is on our code to deal with platform specific
241      * extensions and to keep the paths consistent - not easy, but
242      * worth it if it avoids one extra step for the user.
243      *
244      * Of course, this can change to System.load() and putting the
245      * libs in LD_LIBRARY_PATH.
246      */

247     public void loadNative() throws Throwable JavaDoc {
248         if( aprHome==null )
249             aprHome=baseDir;
250
251         // XXX Update for windows
252
if( jniMode ) {
253             /* In JNI mode we use mod_jk for the native functions.
254                This seems the cleanest solution that works with multiple
255                VMs.
256             */

257             if (jniModeSo.equals("inprocess")) {
258                 ok=true;
259                 return;
260             }
261             try {
262                 log.info("Loading " + jniModeSo);
263                 if( jniModeSo!= null ) System.load( jniModeSo );
264             } catch( Throwable JavaDoc ex ) {
265                 // ignore
266
//ex.printStackTrace();
267
return;
268             }
269             ok=true;
270             return;
271         }
272         
273             /*
274               jkjni _must_ be linked with apr and crypt -
275               this seem the only ( decent ) way to support JDK1.4 and
276               JDK1.3 at the same time
277               try {
278                   System.loadLibrary( "crypt" );
279               } catch( Throwable ex ) {
280                   // ignore
281                   ex.printStackTrace();
282               }
283               try {
284                   System.loadLibrary( "apr" );
285               } catch( Throwable ex ) {
286                   System.out.println("can't load apr, that's fine");
287                   ex.printStackTrace();
288               }
289             */

290         try {
291             if( nativeSo == null ) {
292                 // This will load libjkjni.so or jkjni.dll in LD_LIBRARY_PATH
293
log.debug("Loading jkjni from " + System.getProperty("java.library.path"));
294                 System.loadLibrary( "jkjni" );
295             } else {
296                 System.load( nativeSo );
297             }
298         } catch( Throwable JavaDoc ex ) {
299             ok=false;
300             //ex.printStackTrace();
301
throw ex;
302         }
303     }
304
305     public void loadNative(String JavaDoc libPath) {
306         try {
307             System.load( libPath );
308         } catch( Throwable JavaDoc ex ) {
309             ok=false;
310             if( log.isDebugEnabled() )
311                 log.debug( "Error loading native library ", ex);
312         }
313     }
314     private static org.apache.commons.logging.Log log=
315         org.apache.commons.logging.LogFactory.getLog( AprImpl.class );
316 }
317
Popular Tags