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 <[EMAIL PROTECTED]> * - * 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 <[EMAIL PROTECTED]> + * @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 <[EMAIL PROTECTED]> * - * 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 <[EMAIL PROTECTED]>. * * * * 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 <[EMAIL PROTECTED]> * @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: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>