/* * $Id: iso2788.c,v 1.2 2004/09/15 11:39:27 jan Exp $ * * Copyright (c) 2002 Jan Algermissen * See the file "COPYING" for copying permission. * */ #include #include #include #include #include #include #include #define SAM_NAME "http://purl.org/tm/CORE/" #define HRY_NAME "http://purl.org/tm/HRY/" /* */ static int _handle_line(void *self,const char* line, int isFinal); static void _delete(void**); static int _handle(void *v,const char *rel, const char *other); typedef struct iso2788data *T; struct iso2788data { /* processing model stuff */ Omnivore omnivore; TMTopicMap topicmap; char *current_name; /* TMTopic current_topic; */ struct TMSubject current_sbj; TMList models; TMList rules; TMList ignores; TMProperty Psirs; TMProperty Pbasenames; TMProperty Pasidp; }; static TMError _add_topic(T self, const char *name,const char *label); static char *models[] = { SAM_NAME, HRY_NAME, /* you may #include stuff here */ NULL }; static char *ignores[] = { NULL, }; struct rule { int n; char *rel; char *at; char *active; char *passive; char *at_sym; /* surely enough for 'rule6-active' etc. */ char *active_sym; char *passive_sym; int is_loaded; /* FIXME: flag to mark static vs alloced rules to handle dealloc! */ }; static struct rule rules[] = { { 0, "NT", HRY_NAME"at-superclass-subclass",HRY_NAME"role-superclass",HRY_NAME"role-subclass",NULL,NULL,NULL}, { 0, "HI", SAM_NAME"at-class-instance",SAM_NAME"role-class",SAM_NAME"role-instance",NULL,NULL,NULL}, { 0, "At","Role","Role",0,0,0}, { 0,NULL,NULL,NULL,NULL, NULL,NULL,NULL} }; static TMError ensure_rule_is_loaded(T self,struct rule *rp); static TMError _read_config(T self, const char *filename,Omnivore o); static TMError _init(Omnivore omnivore,void*arg,void **data) { T self; TMError e; TMList lp; int i; TM_NEW(tm_omnivore_get_pool(omnivore),self); *data = NULL; self->topicmap = tm_omnivore_get_topicmap(omnivore); self->omnivore = omnivore; self->current_name = NULL; self->models = NULL; self->rules = NULL; self->ignores = NULL; self->Pbasenames = tm_get_property(tm_omnivore_get_tm(omnivore), SAM_NAME"BaseNames"); self->Psirs = tm_get_property(tm_omnivore_get_tm(omnivore), SAM_NAME"SubjectIndicators"); self->Pasidp = tm_get_property(tm_omnivore_get_tm(omnivore), "http://purl.org/tm/BASE/a-sidp"); assert(self->Pbasenames); assert(self->Psirs); assert(self->Pasidp); /* FIXME: handle allocations/data stuff */ if( ! self->topicmap ) { *data = self; return TM_OK; } else { /* tm_topicmap_start_transaction(self->topicmap,"TEST"); */ } for(i=0; models[i];i++) { self->models = tm_list_push(tm_omnivore_get_pool(self->omnivore),self->models,models[i]); } for(i=0; rules[i].rel;i++) { self->rules = tm_list_push(tm_omnivore_get_pool(self->omnivore),self->rules,&(rules[i])); } for(i=0; ignores[i];i++) { self->ignores = tm_list_push(tm_omnivore_get_pool(self->omnivore),self->ignores,tm_strdup(tm_omnivore_get_pool(self->omnivore),ignores[i])); } if(arg) { if( (e = _read_config(self,(char*)arg,omnivore)) != TM_OK) { /* FIXME: free! */ return e; } } for(lp=self->models;lp;lp=lp->next) { TMModel model; if( (e = tm_lookup_model(tm_omnivore_get_tm(omnivore), (const char*)lp->content,&model)) != TM_OK) { tm_omnivore_set_error(omnivore, "unable to load %s , %s\n", (const char*)lp->content, tm_get_error(tm_omnivore_get_tm(omnivore)) ); TM_RETURN(e); } if( (e=tm_topicmap_require_model(self->topicmap,model)) != TM_OK) { tm_omnivore_set_error(omnivore, "unable to require %s , %s\n", (const char*)lp->content, tm_get_error(tm_omnivore_get_tm(omnivore)) ); TM_RETURN(e); } } for(i=0,lp=self->rules;lp;i++,lp=lp->next) { struct rule *rp = (struct rule*)lp->content; rp->n = i; rp->is_loaded = 0; rp->at_sym = TM_ALLOC(tm_omnivore_get_pool(omnivore),64); rp->active_sym = TM_ALLOC(tm_omnivore_get_pool(omnivore),64); rp->passive_sym = TM_ALLOC(tm_omnivore_get_pool(omnivore),64); /* FIXME: need to free this somewhere! */ sprintf(rp->at_sym,"rule%d-at",rp->n); sprintf(rp->active_sym,"rule%d-active",rp->n); sprintf(rp->passive_sym,"rule%d-passive",rp->n); } *data = self; return TM_OK; } void _delete(void **pself) { Omnivore omnivore; T self = *pself; TMList lp; omnivore = self->omnivore; if(self->current_name) { TM_FREE(tm_omnivore_get_pool(omnivore),self->current_name); } tm_list_delete(tm_omnivore_get_pool(omnivore),&(self->models)); /* if(self->topicmap) { tm_topicmap_end_transaction(self->topicmap); } */ for(lp=self->rules;lp;lp=lp->next) { struct rule *rp = (struct rule*)lp->content; TM_FREE(tm_omnivore_get_pool(omnivore),rp->at_sym); TM_FREE(tm_omnivore_get_pool(omnivore),rp->active_sym); TM_FREE(tm_omnivore_get_pool(omnivore),rp->passive_sym); } tm_list_delete(tm_omnivore_get_pool(omnivore),&(self->rules)); tm_list_delete(tm_omnivore_get_pool(omnivore),&(self->ignores)); TM_FREE(tm_omnivore_get_pool(omnivore),self); } int _handle_line(void *v,const char* line, int isFinal) { T self; TMError e; const char *p; char rel[256]; const char *other; self = (T)v; TMTRACE(TM_PARSE_TRACE,"LINE: _%s_\n" _ line); if(! self->topicmap) return(1); if( tm_is_whitespace_string(line)) return (1); if( tm_is_comment_string(line,'#')) return (1); line = tm_lstrip(line); bzero(rel,sizeof(rel)); TMTRACE(TM_PARSE_TRACE,"not empty or comment\n"); TMTRACE(TM_PARSE_TRACE,"line now: _%s_\n" _ line); p = line; while( *p && (!isspace(*p)) ) p++; if(*p) { strncpy(rel,line, p-line); other = tm_lstrip(p); TMTRACE(TM_PARSE_TRACE,"REL: '%s'\n" _ rel); TMTRACE(TM_PARSE_TRACE,"OTHER: '%s'\n" _ other); if( _handle(self,rel,other) ) return(1); /* else go make new current */ } if(self->current_name) { TM_FREE(tm_omnivore_get_pool(self->omnivore),self->current_name); } self->current_name = tm_strdup(tm_omnivore_get_pool(self->omnivore),line); e = _add_topic(self, self->current_name,"Current"); assert(e == TM_OK); return (1); } struct TMProcModel iso2788procmodel = { "iso2788", /* name */ _init, _delete, NULL, /* root element name (for lookup) */ NULL, /* XML namespace */ NULL, /* XML public ID */ NULL, /* URL to DTD */ /* NULL, -- elements member of struct; unused */ NULL, /* XML ID attribute */ NULL, /* XML Ref attribute */ NULL, /* XML element subtrees to skip */ NULL, /* text elements */ NULL, /* XML start elem */ NULL, /* XML end elem */ _handle_line, /* line handler */ NULL /* no RDF Statement-Handler-Table */ }; int _handle(void *v,const char *rel, const char *other) { T self; TMError e; struct TMList list_type; struct TMList list_roleA; struct TMList list_playerA; struct TMList list_roleB; struct TMList list_playerB; struct TMSubject sbj; struct TMSubject a_sbj; struct TMSubject type_sbj; struct TMSubject roleA_sbj; struct TMSubject playerA_sbj; struct TMSubject roleP_sbj; struct TMSubject playerP_sbj; void *asidp_value; char query[1024]; TMList lp; struct rule *rule = NULL; self = (T)v; TMTRACE(TM_PARSE_TRACE,"enter\n"); for(lp=self->ignores;lp;lp=lp->next) { if( strcmp(rel,(char*)lp->content) == 0 ) { return(1); /* say we handled it to prevent making of new current */ } } TMTRACE(TM_PARSE_TRACE,"1\n"); TMTRACE(TM_PARSE_TRACE,"looking for rule for _%s_\n" _ rel); for(lp=self->rules;lp;lp=lp->next) { struct rule *rp = (struct rule *)lp->content; TMTRACE(TM_PARSE_TRACE," -> _%s_\n" _ rp->rel); if( strcmp(rel,rp->rel) == 0 ) { rule = rp; break; } } TMTRACE(TM_PARSE_TRACE,"2\n"); if( ! rule) { TMTRACE(TM_PARSE_TRACE,"no rule for _%s_\n" _ rel); return (0); /* no rule found, not handled */ } e = _add_topic(self, other,"Other"); assert(e == TM_OK); if( ensure_rule_is_loaded(self,rule) != TM_OK) { assert(0); exit(1); /* FIXME */ } asidp_value = tm_value_new(tm_omnivore_get_pool(self->omnivore),&ASIDP); list_type.next = NULL; list_type.content = rule->at; TM_INIT_SUBJECT_N1(&type_sbj,self->Psirs,&list_type,0); tm_value_call(&ASIDP,asidp_value,"setType",TM_TVAL_SUBJECT,&type_sbj); list_roleA.next = NULL; list_roleA.content = rule->active; list_playerA.next = NULL; list_playerA.content = self->current_name; TM_INIT_SUBJECT_N1(&roleA_sbj,self->Psirs,&list_roleA,0); TM_INIT_SUBJECT_N1(&playerA_sbj,self->Pbasenames,&list_playerA,0); tm_value_call(&ASIDP,asidp_value,"addMember", tm_omnivore_get_pool(self->omnivore), TM_TVAL_SUBJECT,&roleA_sbj,&playerA_sbj); list_roleB.next = NULL; list_roleB.content = (char*)rule->passive; list_playerB.next = NULL; list_playerB.content = (char*)other; TM_INIT_SUBJECT_N1(&roleP_sbj,self->Psirs,&list_roleB,0); TM_INIT_SUBJECT_N1(&playerP_sbj,self->Pbasenames,&list_playerB,0); tm_value_call(&ASIDP,asidp_value,"addMember", tm_omnivore_get_pool(self->omnivore), TM_TVAL_SUBJECT,&roleP_sbj,&playerP_sbj); /* rule->active_sym, rule->passive_sym); */ TM_INIT_SUBJECT_N1(&a_sbj,self->Pasidp,asidp_value,0); if( (e = tm_topicmap_add_topic(self->topicmap,&a_sbj,"A-topic")) != TM_OK) { tm_omnivore_set_error(self->omnivore,"cannot add assertion, %s" , tm_get_error(tm_omnivore_get_tm(self->omnivore))); assert(0); } tm_value_delete(tm_omnivore_get_pool(self->omnivore),&ASIDP,&asidp_value); TMTRACE(TM_PARSE_TRACE,"exit\n"); return(1); } /* FIXME sscanf is not very secure => fix! */ TMError _read_config(T self, const char *filename, Omnivore o) { char buf[1024]; char *p; FILE *file; if( (file = fopen(filename,"r")) == NULL) { tm_omnivore_set_error(o,"unable to open config file %s, %s", filename, strerror(errno)); /* FIXME: portability! */ return TM_ESYS; } while( (p = fgets(buf,sizeof(buf), file)) != NULL) { char b1[1024],b2[1024],b3[1024],b4[1024]; if(tm_is_whitespace_string(p)) continue; if(tm_is_comment_string(p,'#')) continue; p = (char*)tm_lstrip(p); if( strstr(p,"Require") == p) { TMError e; TMModel model; sscanf(p,"Require %s",b1); if( (e = tm_lookup_model(tm_omnivore_get_tm(o), b1,&model)) != TM_OK) { tm_omnivore_set_error(o, "unable to load %s , %s\n", b1, tm_get_error(tm_omnivore_get_tm(o)) ); TM_RETURN(e); } if( (e = tm_topicmap_require_model(self->topicmap,model)) != TM_OK) { tm_omnivore_set_error(o,"unable to require %s, %s\n", b1, tm_get_error(tm_omnivore_get_tm(o)) ); return e; } } else if( strstr(p,"Map") == p) { struct rule *rp; TM_NEW(tm_omnivore_get_pool(self->omnivore),rp); sscanf(p,"Map %s %s %s %s",b1,b2,b3,b4); rp->rel = tm_strdup(tm_omnivore_get_pool(self->omnivore),b1); rp->at = tm_strdup(tm_omnivore_get_pool(self->omnivore),b2); rp->active = tm_strdup(tm_omnivore_get_pool(self->omnivore),b3); rp->passive = tm_strdup(tm_omnivore_get_pool(self->omnivore),b4); rp->at_sym = NULL; rp->active_sym = NULL; rp->passive_sym = NULL; /*FIXME make dynamic flag 'true' here */ self->rules = tm_list_push(tm_omnivore_get_pool(self->omnivore),self->rules,rp); } else if( strstr(p,"Ignore") == p) { sscanf(p,"Ignore %s",b1); self->ignores= tm_list_push(tm_omnivore_get_pool(self->omnivore),self->ignores,tm_strdup(tm_omnivore_get_pool(self->omnivore),b1)); } else { assert(!"unknown command"); } } fclose(file); return TM_OK; } TMError ensure_rule_is_loaded(T self,struct rule *rp) { TMError e; struct TMSubject sbj; struct TMList list; if(rp->is_loaded) return TM_OK; list.next = NULL; list.content = rp->at; TM_INIT_SUBJECT_N1(&sbj,self->Psirs,&list,0); if( (e=tm_topicmap_add_topic(self->topicmap,&sbj, rp->at_sym)) != TM_OK) { tm_omnivore_set_error(self->omnivore, "unable to get topic for %s, %s\n", rp->at, tm_get_error(tm_omnivore_get_tm(self->omnivore)) ); return e; } list.content = rp->active; TM_INIT_SUBJECT_N1(&sbj,self->Psirs,&list,0); if( (e=tm_topicmap_add_topic(self->topicmap,&sbj, rp->active_sym)) != TM_OK) { tm_omnivore_set_error(self->omnivore, "unable to get topic for %s, %s\n", rp->active, tm_get_error(tm_omnivore_get_tm(self->omnivore)) ); return e; } list.content = rp->passive; TM_INIT_SUBJECT_N1(&sbj,self->Psirs,&list,0); if( (e=tm_topicmap_add_topic(self->topicmap,&sbj, rp->passive_sym)) != TM_OK) { tm_omnivore_set_error(self->omnivore, "unable to get topic for %s, %s\n", rp->passive, tm_get_error(tm_omnivore_get_tm(self->omnivore)) ); return e; } rp->is_loaded = 1; return TM_OK; } TMError _add_topic(T self, const char *name,const char *label) { TMError e; struct TMList list; struct TMSubject sbj; list.next = NULL; list.content = (char*)name; TM_INIT_SUBJECT_N1(&sbj,self->Pbasenames,&list,0); #if 0 { char sirbuf[1024]; struct TMList list2; list2.next = NULL; sprintf(sirbuf,"http://itil.dkrz.de/cmdb/items/%s",(char*)other); list2.content = sirbuf; TM_INIT_SUBJECT_N2(&sbj, self->Pbasenames,&list, self->Psirs,&list2); } #endif e = tm_topicmap_add_topic(self->topicmap,&sbj,label); assert(e == TM_OK); return (e); }