You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by co...@apache.org on 2002/05/31 20:05:29 UTC
cvs commit: jakarta-tomcat-connectors/jk/native2/common jk_config_file.c jk_config.c jk_map.c list.mk
costin 2002/05/31 11:05:29
Modified: jk/native2/common jk_config.c jk_map.c list.mk
Added: jk/native2/common jk_config_file.c
Log:
A bit of refactoring.
All workers2.properties parsing/saving code ( i.e. the properties + [ini] extensions )
are now in jk_config_file.
jk_config.c contains all generic methods that 'emulate' the bean ( or ant)-like
configuration of components.
Any alternate config repository can be used - the requirement is to be
able to create a map with component names as keys and an attribute map
as value.
( that's not actually required - you can walk a registry and call processNode
if you want ).
Note that jk_map.c is back to 'map only', and may be deprecated ( since
apr has better maps ). We keep using it for now only because it's stable
and doesn't create problems ( and we can store void * and char *)
Revision Changes Path
1.25 +27 -246 jakarta-tomcat-connectors/jk/native2/common/jk_config.c
Index: jk_config.c
===================================================================
RCS file: /home/cvs/jakarta-tomcat-connectors/jk/native2/common/jk_config.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -r1.24 -r1.25
--- jk_config.c 30 May 2002 18:20:49 -0000 1.24
+++ jk_config.c 31 May 2002 18:05:29 -0000 1.25
@@ -55,100 +55,38 @@
* *
* ========================================================================= */
-/***************************************************************************
- * Description: General purpose config object *
- * Author: Gal Shachor <sh...@il.ibm.com> *
- * Version: $Revision: 1.24 $ *
- ***************************************************************************/
-
+/**
+ * Common methods for processing config data. Independent of the config
+ * storage ( this is a sort of base class ).
+ *
+ * Config is read from the storage as a map, with 'bean names' as keys
+ * and a map of attributes as values.
+ *
+ * We'll process the map creating new objects and calling the setters, similar
+ * with what we do on the java side ( see ant or tomcat ).
+ *
+ * There is also support for update, based on a version number. New objects
+ * or existing objects having a 'ver' attribute will have the setter methods
+ * called with the new values. XXX a reconfig method may be needed to notify.
+ * Backends that support notifications may update directly the changed attributes,
+ * but all components must support the simpler store ( where some attributes
+ * may be set multiple times, since we can't detect individual att changes ).
+ *
+ * Note: The current code assumes a backend that is capable of storing
+ * multi-valued attributes. This makes things hard to port to registry and
+ * some other repositories.
+ *
+ * @author: Gal Shachor <sh...@il.ibm.com>
+ * @author: Costin Manolache
+ */
+
#include "jk_global.h"
#include "jk_map.h"
#include "jk_pool.h"
#include "jk_config.h"
-#define CAPACITY_INC_SIZE (50)
#define LENGTH_OF_LINE (1024)
-static int jk2_config_readFile(jk_env_t *env,
- jk_config_t *cfg,
- int *didReload, int firstTime);
-
-/* ==================== ==================== */
-
-/* Set the config file, read it. The property will also be
- used for storing modified properties.
- */
-static int jk2_config_setConfigFile( jk_env_t *env,
- jk_config_t *cfg,
- jk_workerEnv_t *wEnv,
- char *workerFile)
-{
- cfg->file=workerFile;
-
- return jk2_config_readFile( env, cfg, NULL, JK_TRUE );
-}
-
-/* Experimental. Dangerous. The file param will go away, for security
- reasons - it can save only in the original file.
- */
-static int jk2_config_saveConfig( jk_env_t *env,
- jk_config_t *cfg,
- char *workerFile)
-{
- FILE *fp;
-/* char buf[LENGTH_OF_LINE + 1]; */
- int i,j;
-
- if( workerFile==NULL )
- workerFile=cfg->file;
-
- if( workerFile== NULL )
- return JK_ERR;
-
- fp= fopen(workerFile, "w");
-
- if(fp==NULL)
- return JK_ERR;
-
- env->l->jkLog(env, env->l, JK_LOG_INFO,
- "config.save(): Saving %s\n", workerFile );
-
- /* We'll save only the objects/properties that were set
- via config, and to the original 'string'. That keeps the config
- small ( withou redundant ) and close to the original. Comments
- will be saved/loaded later.
- */
- for( i=0; i < env->_objects->size( env, env->_objects ); i++ ) {
- char *name=env->_objects->nameAt( env, env->_objects, i );
- jk_bean_t *mbean=env->_objects->valueAt( env, env->_objects, i );
-
- if( mbean==NULL || mbean->settings==NULL )
- continue;
-
- if( strcmp( name, mbean->name ) != 0 ) {
- /* It's an alias. */
- continue;
- }
- fprintf( fp, "[%s]\n", mbean->name );
-
- for( j=0; j < mbean->settings->size( env, mbean->settings ); j++ ) {
- char *pname=mbean->settings->nameAt( env, mbean->settings, j);
- /* Don't save redundant information */
- if( strcmp( pname, "name" ) != 0 ) {
- fprintf( fp, "%s=%s\n",
- pname,
- mbean->settings->valueAt( env, mbean->settings, j));
- }
- }
- fprintf( fp, "\n" );
- }
-
- fclose(fp);
-
- return JK_OK;
-}
-
-
/** Interpret the 'name' as [OBJECT].[PROPERTY].
If the [OBJECT] is not found, construct it using
the prefix ( i.e. we'll search for a factory that matches
@@ -168,9 +106,6 @@
jk_bean_t *w = NULL;
char *type=NULL;
char *dot=0;
-/* int i; */
-/* char **comp; */
-/* int nrComp; */
char *lastDot;
char *lastDot1;
@@ -362,9 +297,6 @@
-
-
-
/**
* Replace $(property) in value.
*
@@ -447,7 +379,7 @@
* and any removal may have disastrous consequences. Using critical
* sections would drastically affect the performance.
*/
-static int jk2_config_processConfigData(jk_env_t *env, jk_config_t *cfg,int firstTime )
+int jk2_config_processConfigData(jk_env_t *env, jk_config_t *cfg,int firstTime )
{
int i;
int rc;
@@ -459,7 +391,7 @@
return rc;
}
-static int jk2_config_processNode(jk_env_t *env, jk_config_t *cfg, char *name, int firstTime )
+int jk2_config_processNode(jk_env_t *env, jk_config_t *cfg, char *name, int firstTime )
{
int j;
@@ -515,156 +447,5 @@
cfg->setProperty( env, cfg, bean, pname, pvalue );
}
- return JK_OK;
-}
-
-static int jk2_config_readFile(jk_env_t *env,
- jk_config_t *cfg,
- int *didReload, int firstTime)
-{
- int rc;
- int csOk;
- struct stat statbuf;
-
- if( didReload!=NULL )
- *didReload=JK_FALSE;
-
- if( cfg->file==NULL ) {
- env->l->jkLog(env, env->l, JK_LOG_ERROR,
- "config.update(): No config file\n" );
- return JK_ERR;
- }
-
- rc=stat(cfg->file, &statbuf);
- if (rc == -1) {
- env->l->jkLog(env, env->l, JK_LOG_ERROR,
- "config.update(): Can't find config file %s\n", cfg->file );
- return JK_ERR;
- }
-
- if( !firstTime && statbuf.st_mtime < cfg->mtime ) {
- if( cfg->mbean->debug > 0 )
- env->l->jkLog(env, env->l, JK_LOG_ERROR,
- "config.update(): No reload needed %s %ld %ld\n", cfg->file,
- cfg->mtime, statbuf.st_mtime );
- return JK_OK;
- }
-
- JK_ENTER_CS(&cfg->cs, csOk);
-
- if(csOk !=JK_TRUE) {
- env->l->jkLog(env, env->l, JK_LOG_ERROR,
- "cfg.update() Can't enter critical section\n");
- return JK_ERR;
- }
-
- /* Check if another thread has updated the config */
-
- rc=stat(cfg->file, &statbuf);
- if (rc == -1) {
- env->l->jkLog(env, env->l, JK_LOG_ERROR,
- "config.update(): Can't find config file %s", cfg->file );
- JK_LEAVE_CS(&cfg->cs, csOk);
- return JK_ERR;
- }
-
- if( ! firstTime && statbuf.st_mtime <= cfg->mtime ) {
- JK_LEAVE_CS(&cfg->cs, csOk);
- return JK_OK;
- }
-
- env->l->jkLog(env, env->l, JK_LOG_INFO,
- "cfg.update() Updating config %s %d %d\n",
- cfg->file, cfg->mtime, statbuf.st_mtime);
-
- jk2_map_default_create(env, &cfg->cfgData, env->tmpPool);
-
- rc=jk2_map_read(env, cfg->cfgData , cfg->file );
-
- if( rc==JK_OK ) {
- env->l->jkLog(env, env->l, JK_LOG_INFO,
- "config.setConfig(): Reading properties %s %d\n",
- cfg->file, cfg->cfgData->size( env, cfg->cfgData ) );
- } else {
- env->l->jkLog(env, env->l, JK_LOG_ERROR,
- "config.setConfig(): Error reading properties %s\n",
- cfg->file );
- JK_LEAVE_CS(&cfg->cs, csOk);
- return JK_ERR;
- }
-
- rc=jk2_config_processConfigData( env, cfg, firstTime );
-
- if( didReload!=NULL )
- *didReload=JK_TRUE;
-
- cfg->mtime= statbuf.st_mtime;
-
- JK_LEAVE_CS(&cfg->cs, csOk);
- return rc;
-}
-
-
-static int jk2_config_update(jk_env_t *env,
- jk_config_t *cfg, int *didReload)
-{
- return jk2_config_readFile( env, cfg, didReload, JK_FALSE );
-}
-
-/** Set a property for this config object
- */
-static int JK_METHOD jk2_config_setAttribute( struct jk_env *env, struct jk_bean *mbean,
- char *name, void *valueP)
-{
- jk_config_t *cfg=mbean->object;
- char *value=valueP;
-
- if( strcmp( name, "file" )==0 ) {
- return jk2_config_setConfigFile(env, cfg, cfg->workerEnv, value);
- } else if( strcmp( name, "debugEnv" )==0 ) {
- env->debug=atoi( value );
- } else if( strcmp( name, "save" )==0 ) {
- /* Experimental. Setting save='foo' will save the current config in
- foo
- */
- return jk2_config_saveConfig(env, cfg, value);
- } else {
- return JK_ERR;
- }
- return JK_OK;
-}
-
-
-int JK_METHOD jk2_config_factory( jk_env_t *env, jk_pool_t *pool,
- jk_bean_t *result,
- const char *type, const char *name)
-{
- jk_config_t *_this;
- int i;
-
- _this=(jk_config_t *)pool->alloc(env, pool, sizeof(jk_config_t));
- if( _this == NULL )
- return JK_ERR;
- _this->pool = pool;
-
- _this->setPropertyString=jk2_config_setPropertyString;
- _this->update=jk2_config_update;
- _this->setProperty=jk2_config_setProperty;
- _this->save=jk2_config_saveConfig;
- _this->mbean=result;
- _this->processNode=jk2_config_processNode;
- _this->ver=0;
-
- result->object=_this;
- result->setAttribute=jk2_config_setAttribute;
-
- JK_INIT_CS(&(_this->cs), i);
- if (!i) {
- env->l->jkLog(env, env->l, JK_LOG_ERROR,
- "config.factory(): Can't init CS\n");
- return JK_ERR;
- }
-
-
return JK_OK;
}
1.20 +49 -194 jakarta-tomcat-connectors/jk/native2/common/jk_map.c
Index: jk_map.c
===================================================================
RCS file: /home/cvs/jakarta-tomcat-connectors/jk/native2/common/jk_map.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- jk_map.c 18 May 2002 22:34:01 -0000 1.19
+++ jk_map.c 31 May 2002 18:05:29 -0000 1.20
@@ -58,7 +58,7 @@
/***************************************************************************
* Description: General purpose map object *
* Author: Gal Shachor <sh...@il.ibm.com> *
- * Version: $Revision: 1.19 $ *
+ * Version: $Revision: 1.20 $ *
***************************************************************************/
#include "jk_global.h"
@@ -77,11 +77,6 @@
int size;
} jk_map_private_t;
-static int jk2_map_default_realloc(jk_env_t *env, jk_map_t *m);
-
-
-
-
static void *jk2_map_default_get(jk_env_t *env, jk_map_t *m,
const char *name)
{
@@ -101,6 +96,46 @@
return NULL;
}
+/* Make space for more elements
+ */
+static int jk2_map_default_realloc(jk_env_t *env, jk_map_t *m)
+{
+ jk_map_private_t *mPriv=m->_private;
+
+ if(mPriv->size >= mPriv->capacity) {
+ char **names;
+ void **values;
+ int capacity = mPriv->capacity + CAPACITY_INC_SIZE;
+
+ names = (char **)m->pool->calloc(env, m->pool,
+ sizeof(char *) * capacity);
+ values = (void **)m->pool->calloc(env, m->pool,
+ sizeof(void *) * capacity);
+
+ if( names== NULL || values==NULL ) {
+ env->l->jkLog(env, env->l, JK_LOG_ERROR,
+ "map.realloc(): AllocationError\n");
+ return JK_ERR;
+ }
+ m->keys=names;
+ m->values=values;
+
+ if (mPriv->capacity && mPriv->names)
+ memcpy(names, mPriv->names, sizeof(char *) * mPriv->capacity);
+
+ if (mPriv->capacity && mPriv->values)
+ memcpy(values, mPriv->values, sizeof(void *) * mPriv->capacity);
+
+ mPriv->names = ( char **)names;
+ mPriv->values = ( void **)values;
+ mPriv->capacity = capacity;
+
+ return JK_OK;
+ }
+
+ return JK_OK;
+}
+
static int jk2_map_default_put(jk_env_t *env, jk_map_t *m,
const char *name, void *value,
@@ -243,146 +278,6 @@
}
-/* ==================== */
-/* Reading / parsing.
- */
-
-static void jk2_trim_prp_comment(char *prp)
-{
- char *comment = strchr(prp, '#');
- if(comment) {
- *comment = '\0';
- }
-}
-
-static int jk2_trim(char *s)
-{
- int i;
-
- for(i = strlen(s) - 1 ; (i >= 0) && isspace(s[i]) ; i--)
- ;
-
- s[i + 1] = '\0';
-
- for(i = 0 ; ('\0' != s[i]) && isspace(s[i]) ; i++)
- ;
-
- if(i > 0) {
- strcpy(s, &s[i]);
- }
-
- return strlen(s);
-}
-
-
-
-int jk2_map_parseProperty(jk_env_t *env, jk_map_t *m, char **section, char *prp )
-{
- int rc = JK_ERR;
- char *v;
- jk_map_t *prefNode=NULL;
-
- jk2_trim_prp_comment(prp);
-
- if( jk2_trim(prp)==0 )
- return JK_OK;
-
- /* Support windows-style 'sections' - for cleaner config
- */
- if( (prp[0] == '[') ) {
- v=strchr(prp, ']' );
- *v='\0';
- jk2_trim( v );
- prp++;
-
- *section=m->pool->pstrdup(env, m->pool, prp);
-
- jk2_map_default_create( env, &prefNode, m->pool );
-
- m->add( env, m, *section, prefNode);
-
- return JK_OK;
- }
-
- v = strchr(prp, '=');
- if(v==NULL)
- return JK_OK;
-
- *v = '\0';
- v++;
-
- if(strlen(v)==0 || strlen(prp)==0)
- return JK_OK;
-
- if (*section!=NULL){
- prefNode=m->get( env, m, *section);
- }else{
- prefNode=m;
- }
-
- if( prefNode==NULL )
- return JK_ERR;
-
- /* fprintf(stderr, "Adding [%s] %s=%s\n", cfg->section, prp, v ); */
- prefNode->add( env, prefNode, m->pool->pstrdup(env, m->pool, prp),
- m->pool->pstrdup(env, m->pool, v));
-
- return JK_OK;
-}
-
-/** Read a query string into the map
- */
-int jk2_map_queryRead(jk_env_t *env, jk_map_t *m, const char *query)
-{
- char *sep;
- char *value;
- char *qry=m->pool->pstrdup( env, m->pool, query );
-
- while( qry != NULL ) {
- sep=strchr( qry, '&');
- if( sep !=NULL ) {
- *sep='\0';
- sep++;
- }
-
- value = strchr(qry, '=');
- if(value==NULL) {
- value="";
- } else {
- *value = '\0';
- value++;
- }
- m->add( env, m, m->pool->pstrdup( env, m->pool, qry ),
- m->pool->pstrdup( env, m->pool, value ));
- qry=sep;
- }
- return JK_OK;
-}
-
-/** Read the config file
- */
-int jk2_map_read(jk_env_t *env, jk_map_t *m,const char *file)
-{
- FILE *fp;
- char buf[LENGTH_OF_LINE + 1];
- char *prp;
- char *section=NULL;
- if(m==NULL || file==NULL )
- return JK_ERR;
-
- fp= fopen(file, "r");
-
- if(fp==NULL)
- return JK_ERR;
-
- while(NULL != (prp = fgets(buf, LENGTH_OF_LINE, fp))) {
- jk2_map_parseProperty( env, m, §ion, prp );
- }
-
- fclose(fp);
- return JK_OK;
-}
-
/* ==================== */
/* Internal utils */
@@ -393,15 +288,21 @@
jk_map_t *_this;
jk_map_private_t *mPriv;
- if( m== NULL )
+ if( m== NULL ) {
+ env->l->jkLog(env, env->l, JK_LOG_ERROR,
+ "map.create(): NullPointerException\n");
return JK_ERR;
+ }
_this=(jk_map_t *)pool->calloc(env, pool, sizeof(jk_map_t));
mPriv=(jk_map_private_t *)pool->calloc(env, pool, sizeof(jk_map_private_t));
*m=_this;
- if( _this == NULL || mPriv==NULL )
+ if( _this == NULL || mPriv==NULL ) {
+ env->l->jkLog(env, env->l, JK_LOG_ERROR,
+ "map.create(): AllocationError\n");
return JK_ERR;
+ }
_this->pool = pool;
_this->_private=mPriv;
@@ -424,49 +325,3 @@
return JK_OK;
}
-/* int map_free(jk_map_t **m) */
-/* { */
-/* int rc = JK_ERR; */
-
-/* if(m && *m) { */
-/* (*m)->pool->close((*m)->pool); */
-/* rc = JK_OK; */
-/* *m = NULL; */
-/* } */
-/* return rc; */
-/* } */
-
-
-static int jk2_map_default_realloc(jk_env_t *env, jk_map_t *m)
-{
- jk_map_private_t *mPriv=m->_private;
-
- if(mPriv->size == mPriv->capacity) {
- char **names;
- void **values;
- int capacity = mPriv->capacity + CAPACITY_INC_SIZE;
-
- names = (char **)m->pool->calloc(env, m->pool,
- sizeof(char *) * capacity);
- values = (void **)m->pool->calloc(env, m->pool,
- sizeof(void *) * capacity);
-
- m->keys=names;
- m->values=values;
- if(values && names) {
- if (mPriv->capacity && mPriv->names)
- memcpy(names, mPriv->names, sizeof(char *) * mPriv->capacity);
-
- if (mPriv->capacity && mPriv->values)
- memcpy(values, mPriv->values, sizeof(void *) * mPriv->capacity);
-
- mPriv->names = ( char **)names;
- mPriv->values = ( void **)values;
- mPriv->capacity = capacity;
-
- return JK_OK;
- }
- }
-
- return JK_ERR;
-}
1.2 +3 -0 jakarta-tomcat-connectors/jk/native2/common/list.mk
Index: list.mk
===================================================================
RCS file: /home/cvs/jakarta-tomcat-connectors/jk/native2/common/list.mk,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- list.mk 24 May 2002 07:18:31 -0000 1.1
+++ list.mk 31 May 2002 18:05:29 -0000 1.2
@@ -4,6 +4,7 @@
${JK}jk_channel_socket${OEXT}\
${JK}jk_channel_un${OEXT}\
${JK}jk_config${OEXT}\
+${JK}jk_config_file${OEXT}\
${JK}jk_endpoint${OEXT}\
${JK}jk_env${OEXT}\
${JK}jk_handler_logon${OEXT}\
@@ -13,6 +14,8 @@
${JK}jk_md5${OEXT}\
${JK}jk_msg_ajp${OEXT}\
${JK}jk_mutex${OEXT}\
+${JK}jk_mutex_proc${OEXT}\
+${JK}jk_mutex_thread${OEXT}\
${JK}jk_nwmain${OEXT}\
${JK}jk_objCache${OEXT}\
${JK}jk_pool${OEXT}\
1.1 jakarta-tomcat-connectors/jk/native2/common/jk_config_file.c
Index: jk_config_file.c
===================================================================
/* ========================================================================= *
* *
* The Apache Software License, Version 1.1 *
* *
* Copyright (c) 1999-2001 The Apache Software Foundation. *
* All rights reserved. *
* *
* ========================================================================= *
* *
* Redistribution and use in source and binary forms, with or without modi- *
* fication, are permitted provided that the following conditions are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice *
* notice, this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. The end-user documentation included with the redistribution, if any, *
* must include the following acknowlegement: *
* *
* "This product includes software developed by the Apache Software *
* Foundation <http://www.apache.org/>." *
* *
* Alternately, this acknowlegement may appear in the software itself, if *
* and wherever such third-party acknowlegements normally appear. *
* *
* 4. The names "The Jakarta Project", "Jk", and "Apache Software *
* Foundation" must not be used to endorse or promote products derived *
* from this software without prior written permission. For written *
* permission, please contact <ap...@apache.org>. *
* *
* 5. Products derived from this software may not be called "Apache" nor may *
* "Apache" appear in their names without prior written permission of the *
* Apache Software Foundation. *
* *
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES *
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY *
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
* THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY *
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL *
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS *
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) *
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, *
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN *
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
* POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= *
* *
* This software consists of voluntary contributions made by many indivi- *
* duals on behalf of the Apache Software Foundation. For more information *
* on the Apache Software Foundation, please see <http://www.apache.org/>. *
* *
* ========================================================================= */
/**
* Description: File based configuration.
*
* @author: Gal Shachor <sh...@il.ibm.com>
* @author: Costin Manolache
*/
#include "jk_global.h"
#include "jk_map.h"
#include "jk_pool.h"
#include "jk_config.h"
#define LENGTH_OF_LINE (1024)
/*
*/
static int jk2_config_file_saveConfig( jk_env_t *env,
jk_config_t *cfg, char *workerFile )
{
FILE *fp;
int i,j;
if( workerFile==NULL )
workerFile=cfg->file;
if( workerFile== NULL )
return JK_ERR;
fp= fopen(workerFile, "w");
if(fp==NULL)
return JK_ERR;
env->l->jkLog(env, env->l, JK_LOG_INFO,
"config.save(): Saving %s\n", workerFile );
/* We'll save only the objects/properties that were set
via config, and to the original 'string'. That keeps the config
small ( withou redundant ) and close to the original. Comments
will be saved/loaded later.
*/
for( i=0; i < env->_objects->size( env, env->_objects ); i++ ) {
char *name=env->_objects->nameAt( env, env->_objects, i );
jk_bean_t *mbean=env->_objects->valueAt( env, env->_objects, i );
if( mbean==NULL || mbean->settings==NULL )
continue;
if( strcmp( name, mbean->name ) != 0 ) {
/* It's an alias. */
continue;
}
fprintf( fp, "[%s]\n", mbean->name );
for( j=0; j < mbean->settings->size( env, mbean->settings ); j++ ) {
char *pname=mbean->settings->nameAt( env, mbean->settings, j);
/* Don't save redundant information */
if( strcmp( pname, "name" ) != 0 ) {
fprintf( fp, "%s=%s\n",
pname,
mbean->settings->valueAt( env, mbean->settings, j));
}
}
fprintf( fp, "\n" );
}
fclose(fp);
return JK_OK;
}
/* ==================== */
/* Reading / parsing.
*/
static void jk2_trim_prp_comment(char *prp)
{
char *comment = strchr(prp, '#');
if(comment) {
*comment = '\0';
}
}
static int jk2_trim(char *s)
{
int i;
for(i = strlen(s) - 1 ; (i >= 0) && isspace(s[i]) ; i--)
;
s[i + 1] = '\0';
for(i = 0 ; ('\0' != s[i]) && isspace(s[i]) ; i++)
;
if(i > 0) {
strcpy(s, &s[i]);
}
return strlen(s);
}
int jk2_config_file_parseProperty(jk_env_t *env, jk_map_t *m, char **section, char *prp )
{
int rc = JK_ERR;
char *v;
jk_map_t *prefNode=NULL;
jk2_trim_prp_comment(prp);
if( jk2_trim(prp)==0 )
return JK_OK;
/* Support windows-style 'sections' - for cleaner config
*/
if( (prp[0] == '[') ) {
v=strchr(prp, ']' );
*v='\0';
jk2_trim( v );
prp++;
*section=m->pool->pstrdup(env, m->pool, prp);
jk2_map_default_create( env, &prefNode, m->pool );
m->add( env, m, *section, prefNode);
return JK_OK;
}
v = strchr(prp, '=');
if(v==NULL)
return JK_OK;
*v = '\0';
v++;
if(strlen(v)==0 || strlen(prp)==0)
return JK_OK;
if (*section!=NULL){
prefNode=m->get( env, m, *section);
}else{
prefNode=m;
}
if( prefNode==NULL )
return JK_ERR;
/* fprintf(stderr, "Adding [%s] %s=%s\n", cfg->section, prp, v ); */
prefNode->add( env, prefNode, m->pool->pstrdup(env, m->pool, prp),
m->pool->pstrdup(env, m->pool, v));
return JK_OK;
}
/** Read the config file
*/
int jk2_config_file_read(jk_env_t *env, jk_map_t *m,const char *file)
{
FILE *fp;
char buf[LENGTH_OF_LINE + 1];
char *prp;
char *section=NULL;
if(m==NULL || file==NULL )
return JK_ERR;
fp= fopen(file, "r");
if(fp==NULL)
return JK_ERR;
while(NULL != (prp = fgets(buf, LENGTH_OF_LINE, fp))) {
jk2_config_file_parseProperty( env, m, §ion, prp );
}
fclose(fp);
return JK_OK;
}
static int jk2_config_file_readFile(jk_env_t *env,
jk_config_t *cfg,
int *didReload, int firstTime)
{
int rc;
int csOk;
struct stat statbuf;
if( didReload!=NULL )
*didReload=JK_FALSE;
if( cfg->file==NULL ) {
env->l->jkLog(env, env->l, JK_LOG_ERROR,
"config.update(): No config file\n" );
return JK_ERR;
}
rc=stat(cfg->file, &statbuf);
if (rc == -1) {
env->l->jkLog(env, env->l, JK_LOG_ERROR,
"config.update(): Can't find config file %s\n", cfg->file );
return JK_ERR;
}
if( !firstTime && statbuf.st_mtime < cfg->mtime ) {
if( cfg->mbean->debug > 0 )
env->l->jkLog(env, env->l, JK_LOG_ERROR,
"config.update(): No reload needed %s %ld %ld\n", cfg->file,
cfg->mtime, statbuf.st_mtime );
return JK_OK;
}
if( cfg->cs == NULL ) {
jk_bean_t *jkb=env->createBean2(env, cfg->mbean->pool,"threadMutex", NULL);
if( jkb != NULL && jkb->object != NULL ) {
cfg->cs=jkb->object;
jkb->init(env, jkb );
}
}
if( cfg->cs != NULL )
cfg->cs->lock( env, cfg->cs );
/* Check if another thread has updated the config */
rc=stat(cfg->file, &statbuf);
if (rc == -1) {
env->l->jkLog(env, env->l, JK_LOG_ERROR,
"config.update(): Can't find config file %s", cfg->file );
if( cfg->cs != NULL )
cfg->cs->unLock( env, cfg->cs );
return JK_ERR;
}
if( ! firstTime && statbuf.st_mtime <= cfg->mtime ) {
if( cfg->cs != NULL )
cfg->cs->unLock( env, cfg->cs );
return JK_OK;
}
env->l->jkLog(env, env->l, JK_LOG_INFO,
"cfg.update() Updating config %s %d %d\n",
cfg->file, cfg->mtime, statbuf.st_mtime);
/** The map will be lost - all objects must be saved !
*/
jk2_map_default_create(env, &cfg->cfgData, env->tmpPool);
rc=jk2_config_file_read(env, cfg->cfgData , cfg->file );
if( rc==JK_OK ) {
env->l->jkLog(env, env->l, JK_LOG_INFO,
"config.setConfig(): Reading properties %s %d\n",
cfg->file, cfg->cfgData->size( env, cfg->cfgData ) );
} else {
env->l->jkLog(env, env->l, JK_LOG_ERROR,
"config.setConfig(): Error reading properties %s\n",
cfg->file );
if( cfg->cs != NULL )
cfg->cs->unLock( env, cfg->cs );
return JK_ERR;
}
rc=jk2_config_processConfigData( env, cfg, firstTime );
if( didReload!=NULL )
*didReload=JK_TRUE;
cfg->mtime= statbuf.st_mtime;
if( cfg->cs != NULL )
cfg->cs->unLock( env, cfg->cs );
return rc;
}
static int jk2_config_file_update(jk_env_t *env,
jk_config_t *cfg, int *didReload)
{
return jk2_config_file_readFile( env, cfg, didReload, JK_FALSE );
}
/** Set a property for this config object
*/
static int JK_METHOD jk2_config_file_setAttribute( struct jk_env *env, struct jk_bean *mbean,
char *name, void *valueP)
{
jk_config_t *cfg=mbean->object;
char *value=valueP;
if( strcmp( name, "file" )==0 ) {
cfg->file=value;
return jk2_config_file_readFile( env, cfg, NULL, JK_TRUE );
} else if( strcmp( name, "debugEnv" )==0 ) {
env->debug=atoi( value );
} else if( strcmp( name, "save" )==0 ) {
return jk2_config_file_saveConfig(env, cfg, value);
} else {
return JK_ERR;
}
return JK_OK;
}
int JK_METHOD jk2_config_file_factory( jk_env_t *env, jk_pool_t *pool,
jk_bean_t *result,
const char *type, const char *name)
{
jk_config_t *_this;
jk_bean_t *jkb;
int i;
_this=(jk_config_t *)pool->alloc(env, pool, sizeof(jk_config_t));
if( _this == NULL )
return JK_ERR;
_this->pool = pool;
_this->ver=0;
_this->setPropertyString=jk2_config_setPropertyString;
_this->setProperty=jk2_config_setProperty;
_this->processNode=jk2_config_processNode;
_this->cs=NULL;
_this->update=jk2_config_file_update;
_this->save=jk2_config_file_saveConfig;
result->object=_this;
result->setAttribute=jk2_config_file_setAttribute;
_this->mbean=result;
return JK_OK;
}
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>