Changeset 676 for trunk/zoo-project/zoo-kernel
- Timestamp:
- Jun 19, 2015, 3:58:00 PM (10 years ago)
- Location:
- trunk/zoo-project/zoo-kernel
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/zoo-project/zoo-kernel/main.cfg
r673 r676 8 8 dataPath = /tmp/ 9 9 cacheDir = /tmp/ 10 11 10 12 11 [identification] -
trunk/zoo-project/zoo-kernel/main_conf_read.l
r621 r676 36 36 attname [a-zA-Z0-9_\-:]+ 37 37 38 attvalue1 [%\*,;@a-zA-Z0-9_\-.:" "\"\'/\\\(\)\+\x41-\xff ]+38 attvalue1 [%\*,;@a-zA-Z0-9_\-.:" "\"\'/\\\(\)\+\x41-\xff?&=]+ 39 39 40 40 whitesp [ ] -
trunk/zoo-project/zoo-kernel/response_print.c
r673 r676 639 639 * Generate a wps:Process node for a servie and add it to a given node. 640 640 * 641 * @param reg the profiles registry 641 642 * @param m the conf maps containing the main.cfg settings 642 643 * @param registry the profile registry if any … … 645 646 * @return the generated wps:ProcessOfferings xmlNodePtr 646 647 */ 647 void printGetCapabilitiesForProcess( maps* m,xmlNodePtr nc,service* serv){648 void printGetCapabilitiesForProcess(registry *reg, maps* m,xmlNodePtr nc,service* serv){ 648 649 xmlNsPtr ns,ns_ows,ns_xml,ns_xlink; 649 650 xmlNodePtr n=NULL,nc1,nc2; … … 702 703 } 703 704 705 /** 706 * Attach attributes to a ProcessDescription or a ProcessOffering node. 707 * 708 * @param n the XML node to attach the attributes to 709 * @param ns the XML namespace to create the attributes 710 * @param content the servive main content created from the zcfg file 711 * @param vid the version identifier (0 for 1.0.0 and 1 for 2.0.0) 712 */ 704 713 void attachAttributes(xmlNodePtr n,xmlNsPtr ns,map* content,int vid){ 705 xmlNodePtr nc1;706 714 int limit=(vid==1?7:3); 707 715 for(int i=1;i<limit;i+=2){ … … 711 719 char *val=(char*)malloc((strlen(tmp1->value)+5)*sizeof(char)); 712 720 sprintf(val,"%s.0.0",tmp1->value); 713 xmlNewNsProp(n c1,ns,BAD_CAST capabilities[vid][i],BAD_CAST val);721 xmlNewNsProp(n,ns,BAD_CAST capabilities[vid][i],BAD_CAST val); 714 722 free(val); 715 723 } 716 724 else 717 xmlNewNsProp(n c1,ns,BAD_CAST capabilities[vid][i],BAD_CAST tmp1->value);725 xmlNewNsProp(n,ns,BAD_CAST capabilities[vid][i],BAD_CAST tmp1->value); 718 726 } 719 727 else 720 xmlNewNsProp(nc1,ns,BAD_CAST capabilities[vid][i],BAD_CAST capabilities[vid][i+1]); 728 xmlNewNsProp(n,ns,BAD_CAST capabilities[vid][i],BAD_CAST capabilities[vid][i+1]); 729 } 730 } 731 732 /** 733 * Add the ows:Metadata nodes relative to the profile registry 734 * 735 * @param n the XML node to add the ows:Metadata 736 * @param ns_ows the ows XML namespace 737 * @param ns_xlink the ows xlink namespace 738 * @param reg the profile registry 739 * @param main_conf the map containing the main configuration content 740 * @param serv the service 741 */ 742 void addInheritedMetadata(xmlNodePtr n,xmlNsPtr ns_ows,xmlNsPtr ns_xlink,registry* reg,maps* main_conf,service* serv){ 743 int vid=1; 744 map* tmp1=getMap(serv->content,"extend"); 745 if(tmp1==NULL) 746 tmp1=getMap(serv->content,"concept"); 747 if(tmp1!=NULL){ 748 map* level=getMap(serv->content,"level"); 749 if(level!=NULL){ 750 xmlNodePtr nc1 = xmlNewNode(ns_ows, BAD_CAST "Metadata"); 751 char* ckey=level->value; 752 if(strncasecmp(level->value,"profile",7)==0) 753 ckey="generic"; 754 if(strncasecmp(level->value,"generic",7)==0) 755 ckey="concept"; 756 service* inherited=getServiceFromRegistry(reg,ckey,tmp1->value); 757 if(inherited!=NULL){ 758 addInheritedMetadata(n,ns_ows,ns_xlink,reg,main_conf,inherited); 759 } 760 char cschema[71]; 761 sprintf(cschema,"%s%s",schemas[vid][7],ckey); 762 map* regUrl=getMapFromMaps(main_conf,"main","registryUrl"); 763 map* regExt=getMapFromMaps(main_conf,"main","registryExt"); 764 char* registryUrl=(char*)malloc((strlen(regUrl->value)+strlen(ckey)+ 765 (regExt!=NULL?strlen(regExt->value)+1:0)+ 766 strlen(tmp1->value)+2)*sizeof(char)); 767 if(regExt!=NULL) 768 sprintf(registryUrl,"%s%s/%s.%s",regUrl->value,ckey,tmp1->value,regExt->value); 769 else 770 sprintf(registryUrl,"%s%s/%s",regUrl->value,ckey,tmp1->value); 771 xmlNewNsProp(nc1,ns_xlink,BAD_CAST "role",BAD_CAST cschema); 772 xmlNewNsProp(nc1,ns_xlink,BAD_CAST "href",BAD_CAST registryUrl); 773 free(registryUrl); 774 xmlAddChild(n,nc1); 775 } 721 776 } 722 777 } … … 725 780 * Generate a ProcessDescription node for a servie and add it to a given node. 726 781 * 782 * @param reg the profile registry 727 783 * @param m the conf maps containing the main.cfg settings 728 784 * @param nc the XML node to add the Process node … … 730 786 * @return the generated wps:ProcessOfferings xmlNodePtr 731 787 */ 732 void printDescribeProcessForProcess( maps* m,xmlNodePtr nc,service* serv){788 void printDescribeProcessForProcess(registry *reg, maps* m,xmlNodePtr nc,service* serv){ 733 789 xmlNsPtr ns,ns_ows,ns_xlink; 734 790 xmlNodePtr n,nc1,nc2; … … 752 808 else{ 753 809 nc2 = xmlNewNode(ns, BAD_CAST "ProcessOffering"); 810 // In case mode was defined in the ZCFG file then restrict the 811 // jobControlOptions value to this value. The dismiss is always 812 // supported whatever you can set in the ZCFG file. 813 // cf. http://docs.opengeospatial.org/is/14-065/14-065.html#47 (Table 30) 814 map* mode=getMap(serv->content,"mode"); 815 if(mode!=NULL){ 816 if( strncasecmp(mode->value,"sync",strlen(mode->value))==0 || 817 strncasecmp(mode->value,"async",strlen(mode->value))==0 ){ 818 char toReplace[22]; 819 sprintf(toReplace,"%s-execute dismiss",mode->value); 820 addToMap(serv->content,capabilities[vid][3],toReplace); 821 } 822 } 754 823 attachAttributes(nc2,NULL,serv->content,vid); 755 nc = xmlNewNode(ns, BAD_CAST "Process"); 756 } 757 /* 758 const char *tmp4[3]; 759 tmp4[0]="processVersion"; 760 tmp4[1]="storeSupported"; 761 tmp4[2]="statusSupported"; 762 int j=0; 763 for(j=0;j<3;j++){ 764 tmp1=getMap(serv->content,tmp4[j]); 765 if(tmp1!=NULL){ 766 if(j==0) 767 xmlNewNsProp(nc,ns,BAD_CAST "processVersion",BAD_CAST tmp1->value); 768 else 769 xmlNewProp(nc,BAD_CAST tmp4[j],BAD_CAST tmp1->value); 770 } 771 else{ 772 if(j>0) 773 xmlNewProp(nc,BAD_CAST tmp4[j],BAD_CAST "true"); 774 else 775 xmlNewNsProp(nc,ns,BAD_CAST "processVersion",BAD_CAST "1"); 776 } 777 } 778 */ 824 map* level=getMap(serv->content,"level"); 825 if(level!=NULL && strcasecmp(level->value,"generic")==0) 826 nc = xmlNewNode(ns, BAD_CAST "GenericProcess"); 827 else 828 nc = xmlNewNode(ns, BAD_CAST "Process"); 829 } 779 830 780 831 tmp1=getMapFromMaps(m,"lenv","level"); … … 782 833 printDescription(nc,ns_ows,serv->name,serv->content,vid); 783 834 784 tmp1=serv->metadata; 785 while(tmp1!=NULL){ 786 nc1 = xmlNewNode(ns_ows, BAD_CAST "Metadata"); 787 xmlNewNsProp(nc1,ns_xlink,BAD_CAST tmp1->name,BAD_CAST tmp1->value); 788 xmlAddChild(nc,nc1); 789 tmp1=tmp1->next; 790 } 791 792 tmp1=getMap(serv->content,"Profile"); 793 if(tmp1!=NULL && vid==0){ 794 nc1 = xmlNewNode(ns, BAD_CAST "Profile"); 795 xmlAddChild(nc1,xmlNewText(BAD_CAST tmp1->value)); 796 xmlAddChild(nc,nc1); 835 if(vid==0){ 836 tmp1=serv->metadata; 837 while(tmp1!=NULL){ 838 nc1 = xmlNewNode(ns_ows, BAD_CAST "Metadata"); 839 xmlNewNsProp(nc1,ns_xlink,BAD_CAST tmp1->name,BAD_CAST tmp1->value); 840 xmlAddChild(nc,nc1); 841 tmp1=tmp1->next; 842 } 843 tmp1=getMap(serv->content,"Profile"); 844 if(tmp1!=NULL && vid==0){ 845 nc1 = xmlNewNode(ns, BAD_CAST "Profile"); 846 xmlAddChild(nc1,xmlNewText(BAD_CAST tmp1->value)); 847 xmlAddChild(nc,nc1); 848 } 849 }else{ 850 addInheritedMetadata(nc,ns_ows,ns_xlink,reg,m,serv); 797 851 } 798 852 … … 835 889 * @param type the name ("Input" or "Output") of the XML node to create 836 890 * @param ns_ows the ows XML namespace 891 * @param ns_ows the ows XML namespace 837 892 * @param nc1 the XML node to use to add the created tree 893 * @param vid the WPS version id (0 for 1.0.0, 1 for 2.0.0) 838 894 */ 839 895 void printFullDescription(int in,elements *elem,const char* type,xmlNsPtr ns,xmlNsPtr ns_ows,xmlNodePtr nc1,int vid){ … … 841 897 if(vid==1) 842 898 ns1=ns; 843 const char *orderedFields[13];844 orderedFields[0]="mimeType";845 orderedFields[1]="encoding";846 orderedFields[2]="schema";847 orderedFields[3]="dataType";848 orderedFields[4]="uom";849 orderedFields[5]="CRS";850 orderedFields[6]="value";851 orderedFields[7]="AllowedValues";852 orderedFields[8]="range";853 orderedFields[9]="rangeMin";854 orderedFields[10]="rangeMax";855 orderedFields[11]="rangeClosure";856 orderedFields[12]="rangeSpace";857 899 858 900 xmlNodePtr nc2,nc3,nc4,nc5,nc6,nc7,nc8,nc9; … … 864 906 int isAnyValue=1; 865 907 nc2 = xmlNewNode(NULL, BAD_CAST type); 866 if(str ncmp(type,"Input",5)==0){908 if(strstr(type,"Input")!=NULL){ 867 909 tmp1=getMap(e->content,"minOccurs"); 868 910 if(tmp1!=NULL){ … … 885 927 printDescription(nc2,ns_ows,e->name,e->content,vid); 886 928 887 /** 888 * Build the (Literal/Complex/BoundingBox)Data node 889 */ 890 if(strncmp(type,"Output",6)==0){ 891 if(strncasecmp(e->format,"LITERALDATA",strlen(e->format))==0) 892 nc3 = xmlNewNode(ns1, BAD_CAST "LiteralOutput"); 893 else if(strncasecmp(e->format,"COMPLEXDATA",strlen(e->format))==0) 894 nc3 = xmlNewNode(ns1, BAD_CAST "ComplexOutput"); 895 else if(strncasecmp(e->format,"BOUNDINGBOXDATA",strlen(e->format))==0) 896 nc3 = xmlNewNode(ns1, BAD_CAST "BoundingBoxOutput"); 897 else 898 nc3 = xmlNewNode(ns1, BAD_CAST e->format); 899 }else{ 900 if(strncasecmp(e->format,"LITERALDATA",strlen(e->format))==0 || 901 strncasecmp(e->format,"LITERALOUTPUT",strlen(e->format))==0){ 902 nc3 = xmlNewNode(ns1, BAD_CAST "LiteralData"); 903 } 904 else if(strncasecmp(e->format,"COMPLEXDATA",strlen(e->format))==0) 905 nc3 = xmlNewNode(ns1, BAD_CAST "ComplexData"); 906 else if(strncasecmp(e->format,"BOUNDINGBOXDATA",strlen(e->format))==0) 907 nc3 = xmlNewNode(ns1, BAD_CAST "BoundingBoxData"); 908 else 909 nc3 = xmlNewNode(ns1, BAD_CAST e->format); 910 } 911 912 iotype* _tmp0=NULL; 913 iotype* _tmp=e->defaults; 914 int datatype=0; 915 bool hasUOM=false; 916 bool hasUOM1=false; 917 if(_tmp!=NULL){ 918 if(strcmp(e->format,"LiteralOutput")==0 || 919 strcmp(e->format,"LiteralData")==0){ 920 datatype=1; 921 if(vid==1){ 922 nc4 = xmlNewNode(ns1, BAD_CAST "Format"); 923 xmlNewProp(nc4,BAD_CAST "mimeType",BAD_CAST "text/plain"); 924 xmlNewProp(nc4,BAD_CAST "default",BAD_CAST "true"); 925 xmlAddChild(nc3,nc4); 926 nc5 = xmlNewNode(NULL, BAD_CAST "LiteralDataDomain"); 927 xmlNewProp(nc5,BAD_CAST "default",BAD_CAST "true"); 928 } 929 else{ 930 nc4 = xmlNewNode(NULL, BAD_CAST "UOMs"); 931 nc5 = xmlNewNode(NULL, BAD_CAST "Default"); 932 } 933 } 934 else if(strcmp(e->format,"BoundingBoxOutput")==0 || 935 strcmp(e->format,"BoundingBoxData")==0){ 936 datatype=2; 937 nc5 = xmlNewNode(NULL, BAD_CAST "Default"); 938 } 939 else{ 940 if(vid==0) 941 nc4 = xmlNewNode(NULL, BAD_CAST "Default"); 942 nc5 = xmlNewNode(ns1, BAD_CAST "Format"); 943 if(vid==1){ 944 xmlNewProp(nc5,BAD_CAST "default",BAD_CAST "true"); 945 int oI=0; 946 for(oI=0;oI<3;oI++) 947 if((tmp1=getMap(_tmp->content,orderedFields[oI]))!=NULL){ 948 xmlNewProp(nc5,BAD_CAST orderedFields[oI],BAD_CAST tmp1->value); 949 } 950 } 951 } 952 953 tmp1=_tmp->content; 954 955 if(vid==0) 956 if((tmp1=getMap(_tmp->content,"DataType"))!=NULL){ 957 nc8 = xmlNewNode(ns_ows, BAD_CAST "DataType"); 958 xmlAddChild(nc8,xmlNewText(BAD_CAST tmp1->value)); 959 char tmp[1024]; 960 sprintf(tmp,"http://www.w3.org/TR/xmlschema-2/#%s",tmp1->value); 961 xmlNewNsProp(nc8,ns_ows,BAD_CAST "reference",BAD_CAST tmp); 962 if(vid==0) 963 xmlAddChild(nc3,nc8); 964 else 965 xmlAddChild(nc5,nc8); 929 if(e->format!=NULL){ 930 const char orderedFields[13][14]={ 931 "mimeType", 932 "encoding", 933 "schema", 934 "dataType", 935 "uom", 936 "CRS", 937 "AllowedValues", 938 "range", 939 "rangeMin", 940 "rangeMax", 941 "rangeClosure", 942 "rangeSpace" 943 }; 944 945 //Build the (Literal/Complex/BoundingBox)Data node 946 if(strncmp(type,"Output",6)==0){ 947 if(strncasecmp(e->format,"LITERALDATA",strlen(e->format))==0) 948 nc3 = xmlNewNode(ns1, BAD_CAST "LiteralOutput"); 949 else if(strncasecmp(e->format,"COMPLEXDATA",strlen(e->format))==0) 950 nc3 = xmlNewNode(ns1, BAD_CAST "ComplexOutput"); 951 else if(strncasecmp(e->format,"BOUNDINGBOXDATA",strlen(e->format))==0) 952 nc3 = xmlNewNode(ns1, BAD_CAST "BoundingBoxOutput"); 953 else 954 nc3 = xmlNewNode(ns1, BAD_CAST e->format); 955 }else{ 956 if(strncasecmp(e->format,"LITERALDATA",strlen(e->format))==0 || 957 strncasecmp(e->format,"LITERALOUTPUT",strlen(e->format))==0){ 958 nc3 = xmlNewNode(ns1, BAD_CAST "LiteralData"); 959 } 960 else if(strncasecmp(e->format,"COMPLEXDATA",strlen(e->format))==0) 961 nc3 = xmlNewNode(ns1, BAD_CAST "ComplexData"); 962 else if(strncasecmp(e->format,"BOUNDINGBOXDATA",strlen(e->format))==0) 963 nc3 = xmlNewNode(ns1, BAD_CAST "BoundingBoxData"); 964 else 965 nc3 = xmlNewNode(ns1, BAD_CAST e->format); 966 } 967 968 iotype* _tmp0=NULL; 969 iotype* _tmp=e->defaults; 970 int datatype=0; 971 bool hasUOM=false; 972 bool hasUOM1=false; 973 if(_tmp!=NULL){ 974 if(strcmp(e->format,"LiteralOutput")==0 || 975 strcmp(e->format,"LiteralData")==0){ 966 976 datatype=1; 967 } 968 969 bool isInput=false; 970 if(strncmp(type,"Input",5)==0 || strncmp(type,"wps:Input",9)==0){ 971 isInput=true; 972 if((tmp1=getMap(_tmp->content,"AllowedValues"))!=NULL){ 973 nc6 = xmlNewNode(ns_ows, BAD_CAST "AllowedValues"); 974 char *token,*saveptr1; 975 token=strtok_r(tmp1->value,",",&saveptr1); 976 while(token!=NULL){ 977 nc7 = xmlNewNode(ns_ows, BAD_CAST "Value"); 978 char *tmps=strdup(token); 979 tmps[strlen(tmps)]=0; 980 xmlAddChild(nc7,xmlNewText(BAD_CAST tmps)); 981 free(tmps); 982 xmlAddChild(nc6,nc7); 983 token=strtok_r(NULL,",",&saveptr1); 984 } 985 if(getMap(_tmp->content,"range")!=NULL || 986 getMap(_tmp->content,"rangeMin")!=NULL || 987 getMap(_tmp->content,"rangeMax")!=NULL || 988 getMap(_tmp->content,"rangeClosure")!=NULL ) 989 goto doRange; 990 if(vid==0) 991 xmlAddChild(nc3,nc6); 992 else 993 xmlAddChild(nc5,nc6); 994 isAnyValue=-1; 995 } 996 997 tmp1=getMap(_tmp->content,"range"); 998 if(tmp1==NULL) 999 tmp1=getMap(_tmp->content,"rangeMin"); 1000 if(tmp1==NULL) 1001 tmp1=getMap(_tmp->content,"rangeMax"); 1002 1003 if(tmp1!=NULL && isAnyValue==1){ 1004 nc6 = xmlNewNode(ns_ows, BAD_CAST "AllowedValues"); 1005 doRange: 1006 1007 /** 1008 * Range: Table 46 OGC Web Services Common Standard 1009 */ 1010 nc8 = xmlNewNode(ns_ows, BAD_CAST "Range"); 1011 1012 map* tmp0=getMap(tmp1,"range"); 1013 if(tmp0!=NULL){ 1014 char* pToken; 1015 char* orig=zStrdup(tmp0->value); 1016 /** 1017 * RangeClosure: Table 47 OGC Web Services Common Standard 1018 */ 1019 const char *tmp="closed"; 1020 if(orig[0]=='[' && orig[strlen(orig)-1]=='[') 1021 tmp="closed-open"; 1022 else 1023 if(orig[0]==']' && orig[strlen(orig)-1]==']') 1024 tmp="open-closed"; 1025 else 1026 if(orig[0]==']' && orig[strlen(orig)-1]=='[') 1027 tmp="open"; 1028 xmlNewNsProp(nc8,ns_ows,BAD_CAST "rangeClosure",BAD_CAST tmp); 1029 pToken=strtok(orig,","); 1030 int nci0=0; 1031 while(pToken!=NULL){ 1032 char *tmpStr=(char*) malloc((strlen(pToken))*sizeof(char)); 1033 if(nci0==0){ 1034 nc7 = xmlNewNode(ns_ows, BAD_CAST "MinimumValue"); 1035 strncpy( tmpStr, pToken+1, strlen(pToken)-1 ); 1036 tmpStr[strlen(pToken)-1] = '\0'; 1037 }else{ 1038 nc7 = xmlNewNode(ns_ows, BAD_CAST "MaximumValue"); 1039 const char* bkt; 1040 if ( ( bkt = strchr(pToken, '[') ) != NULL || ( bkt = strchr(pToken, ']') ) != NULL ){ 1041 strncpy( tmpStr, pToken, bkt - pToken ); 1042 tmpStr[bkt - pToken] = '\0'; 1043 } 1044 } 1045 xmlAddChild(nc7,xmlNewText(BAD_CAST tmpStr)); 1046 free(tmpStr); 1047 xmlAddChild(nc8,nc7); 1048 nci0++; 1049 pToken = strtok(NULL,","); 1050 } 1051 if(getMap(tmp1,"rangeSpacing")==NULL){ 1052 nc7 = xmlNewNode(ns_ows, BAD_CAST "Spacing"); 1053 xmlAddChild(nc7,xmlNewText(BAD_CAST "1")); 1054 xmlAddChild(nc8,nc7); 1055 } 1056 free(orig); 1057 }else{ 1058 1059 tmp0=getMap(tmp1,"rangeMin"); 1060 if(tmp0!=NULL){ 1061 nc7 = xmlNewNode(ns_ows, BAD_CAST "MinimumValue"); 1062 xmlAddChild(nc7,xmlNewText(BAD_CAST tmp0->value)); 1063 xmlAddChild(nc8,nc7); 1064 }else{ 1065 nc7 = xmlNewNode(ns_ows, BAD_CAST "MinimumValue"); 1066 xmlAddChild(nc8,nc7); 1067 } 1068 tmp0=getMap(tmp1,"rangeMax"); 1069 if(tmp0!=NULL){ 1070 nc7 = xmlNewNode(ns_ows, BAD_CAST "MaximumValue"); 1071 xmlAddChild(nc7,xmlNewText(BAD_CAST tmp0->value)); 1072 xmlAddChild(nc8,nc7); 1073 }else{ 1074 nc7 = xmlNewNode(ns_ows, BAD_CAST "MaximumValue"); 1075 xmlAddChild(nc8,nc7); 1076 } 1077 tmp0=getMap(tmp1,"rangeSpacing"); 1078 if(tmp0!=NULL){ 1079 nc7 = xmlNewNode(ns_ows, BAD_CAST "Spacing"); 1080 xmlAddChild(nc7,xmlNewText(BAD_CAST tmp0->value)); 1081 xmlAddChild(nc8,nc7); 1082 } 1083 tmp0=getMap(tmp1,"rangeClosure"); 1084 if(tmp0!=NULL){ 1085 const char *tmp="closed"; 1086 if(strcasecmp(tmp0->value,"co")==0) 1087 tmp="closed-open"; 1088 else 1089 if(strcasecmp(tmp0->value,"oc")==0) 1090 tmp="open-closed"; 1091 else 1092 if(strcasecmp(tmp0->value,"o")==0) 1093 tmp="open"; 1094 xmlNewNsProp(nc8,ns_ows,BAD_CAST "rangeClosure",BAD_CAST tmp); 1095 }else 1096 xmlNewNsProp(nc8,ns_ows,BAD_CAST "rangeClosure",BAD_CAST "closed"); 1097 } 1098 if(_tmp0==NULL){ 1099 xmlAddChild(nc6,nc8); 1100 _tmp0=e->supported; 1101 if(_tmp0!=NULL && 1102 (getMap(_tmp0->content,"range")!=NULL || 1103 getMap(_tmp0->content,"rangeMin")!=NULL || 1104 getMap(_tmp0->content,"rangeMax")!=NULL || 1105 getMap(_tmp0->content,"rangeClosure")!=NULL )){ 1106 tmp1=_tmp0->content; 1107 goto doRange; 1108 } 1109 }else{ 1110 _tmp0=_tmp0->next; 1111 if(_tmp0!=NULL){ 1112 xmlAddChild(nc6,nc8); 1113 if(getMap(_tmp0->content,"range")!=NULL || 1114 getMap(_tmp0->content,"rangeMin")!=NULL || 1115 getMap(_tmp0->content,"rangeMax")!=NULL || 1116 getMap(_tmp0->content,"rangeClosure")!=NULL ){ 1117 tmp1=_tmp0->content; 1118 goto doRange; 1119 } 1120 } 1121 } 1122 xmlAddChild(nc6,nc8); 1123 if(vid==0) 1124 xmlAddChild(nc3,nc6); 1125 else 1126 xmlAddChild(nc5,nc6); 1127 isAnyValue=-1; 1128 } 1129 1130 } 1131 1132 int oI=0; 1133 /*if(vid==0)*/ { 1134 for(oI=0;oI<13;oI++) 1135 if((tmp1=getMap(_tmp->content,orderedFields[oI]))!=NULL){ 1136 #ifdef DEBUG 1137 printf("DATATYPE DEFAULT ? %s\n",tmp1->name); 1138 #endif 1139 if(strcmp(tmp1->name,"asReference")!=0 && 1140 strncasecmp(tmp1->name,"DataType",8)!=0 && 1141 strcasecmp(tmp1->name,"extension")!=0 && 1142 strcasecmp(tmp1->name,"value")!=0 && 1143 strcasecmp(tmp1->name,"AllowedValues")!=0 && 1144 strncasecmp(tmp1->name,"range",5)!=0){ 1145 if(datatype!=1){ 1146 char *tmp2=zCapitalize1(tmp1->name); 1147 nc9 = xmlNewNode(NULL, BAD_CAST tmp2); 1148 free(tmp2); 1149 } 1150 else{ 1151 char *tmp2=zCapitalize(tmp1->name); 1152 nc9 = xmlNewNode(ns_ows, BAD_CAST tmp2); 1153 free(tmp2); 1154 } 1155 xmlAddChild(nc9,xmlNewText(BAD_CAST tmp1->value)); 1156 if(vid==0 || oI>=3){ 1157 if(vid==0 || oI!=4) 1158 xmlAddChild(nc5,nc9); 1159 if(oI==4 && vid==1){ 1160 xmlNewProp(nc9,BAD_CAST "default",BAD_CAST "true"); 1161 } 1162 } 1163 else 1164 xmlFree(nc9); 1165 if(strcasecmp(tmp1->name,"uom")==0) 1166 hasUOM1=true; 1167 hasUOM=true; 1168 }else 1169 tmp1=tmp1->next; 1170 } 1171 } 1172 1173 if(datatype!=2){ 1174 if(hasUOM==true){ 1175 if(vid==0){ 1176 xmlAddChild(nc4,nc5); 977 if(vid==1){ 978 nc4 = xmlNewNode(ns1, BAD_CAST "Format"); 979 xmlNewProp(nc4,BAD_CAST "mimeType",BAD_CAST "text/plain"); 980 xmlNewProp(nc4,BAD_CAST "default",BAD_CAST "true"); 1177 981 xmlAddChild(nc3,nc4); 982 nc5 = xmlNewNode(NULL, BAD_CAST "LiteralDataDomain"); 983 xmlNewProp(nc5,BAD_CAST "default",BAD_CAST "true"); 1178 984 } 1179 985 else{ 1180 xmlAddChild(nc3,nc5); 986 nc4 = xmlNewNode(NULL, BAD_CAST "UOMs"); 987 nc5 = xmlNewNode(NULL, BAD_CAST "Default"); 1181 988 } 1182 }else{ 1183 if(hasUOM1==false && vid==0){ 1184 xmlFreeNode(nc5); 1185 if(datatype==1) 1186 xmlFreeNode(nc4); 1187 } 1188 else 1189 xmlAddChild(nc3,nc5); 1190 } 1191 }else{ 1192 xmlAddChild(nc3,nc5); 1193 } 1194 1195 if(datatype!=1 && default1<0){ 1196 xmlFreeNode(nc5); 1197 if(datatype!=2) 1198 xmlFreeNode(nc4); 1199 } 1200 1201 1202 if((isInput || vid==1) && datatype==1 && 1203 getMap(_tmp->content,"AllowedValues")==NULL && 1204 getMap(_tmp->content,"range")==NULL && 1205 getMap(_tmp->content,"rangeMin")==NULL && 1206 getMap(_tmp->content,"rangeMax")==NULL && 1207 getMap(_tmp->content,"rangeClosure")==NULL ){ 1208 tmp1=getMap(_tmp->content,"dataType"); 1209 // We were tempted to define default value for boolean as {true,false} 1210 if(tmp1!=NULL && strcasecmp(tmp1->value,"boolean")==0){ 1211 nc6 = xmlNewNode(ns_ows, BAD_CAST "AllowedValues"); 1212 nc7 = xmlNewNode(ns_ows, BAD_CAST "Value"); 1213 xmlAddChild(nc7,xmlNewText(BAD_CAST "true")); 1214 xmlAddChild(nc6,nc7); 1215 nc7 = xmlNewNode(ns_ows, BAD_CAST "Value"); 1216 xmlAddChild(nc7,xmlNewText(BAD_CAST "false")); 1217 xmlAddChild(nc6,nc7); 989 } 990 else if(strcmp(e->format,"BoundingBoxOutput")==0 || 991 strcmp(e->format,"BoundingBoxData")==0){ 992 datatype=2; 993 nc5 = xmlNewNode(NULL, BAD_CAST "Default"); 994 } 995 else{ 1218 996 if(vid==0) 1219 xmlAddChild(nc3,nc6); 1220 else 1221 xmlAddChild(nc5,nc6); 1222 } 1223 else 1224 if(vid==0) 1225 xmlAddChild(nc3,xmlNewNode(ns_ows, BAD_CAST "AnyValue")); 1226 else 1227 xmlAddChild(nc5,xmlNewNode(ns_ows, BAD_CAST "AnyValue")); 1228 } 1229 1230 if(vid==1){ 1231 if((tmp1=getMap(_tmp->content,"DataType"))!=NULL){ 1232 nc8 = xmlNewNode(ns_ows, BAD_CAST "DataType"); 1233 xmlAddChild(nc8,xmlNewText(BAD_CAST tmp1->value)); 1234 char tmp[1024]; 1235 sprintf(tmp,"http://www.w3.org/TR/xmlschema-2/#%s",tmp1->value); 1236 xmlNewNsProp(nc8,ns_ows,BAD_CAST "reference",BAD_CAST tmp); 1237 if(vid==0) 1238 xmlAddChild(nc3,nc8); 1239 else 1240 xmlAddChild(nc5,nc8); 1241 datatype=1; 1242 } 1243 if(hasUOM==true){ 1244 tmp1=getMap(_tmp->content,"uom"); 1245 if(tmp1!=NULL){ 1246 char *tmp2=zCapitalize(tmp1->name); 1247 nc9 = xmlNewNode(ns_ows, BAD_CAST tmp2); 1248 free(tmp2); 1249 //xmlNewProp(nc9, BAD_CAST "default", BAD_CAST "true"); 1250 xmlAddChild(nc9,xmlNewText(BAD_CAST tmp1->value)); 1251 xmlAddChild(nc5,nc9); 1252 /*struct iotype * _ltmp=e->supported; 1253 while(_ltmp!=NULL){ 1254 tmp1=getMap(_ltmp->content,"uom"); 1255 if(tmp1!=NULL){ 1256 char *tmp2=zCapitalize(tmp1->name); 1257 nc9 = xmlNewNode(ns_ows, BAD_CAST tmp2); 1258 free(tmp2); 1259 xmlAddChild(nc9,xmlNewText(BAD_CAST tmp1->value)); 1260 xmlAddChild(nc5,nc9); 1261 } 1262 _ltmp=_ltmp->next; 1263 }*/ 1264 1265 } 1266 } 1267 if(e->defaults!=NULL && (tmp1=getMap(e->defaults->content,"value"))!=NULL){ 1268 nc7 = xmlNewNode(ns_ows, BAD_CAST "DefaultValue"); 1269 xmlAddChild(nc7,xmlNewText(BAD_CAST tmp1->value)); 1270 xmlAddChild(nc5,nc7); 1271 } 1272 } 1273 1274 map* metadata=e->metadata; 1275 xmlNodePtr n=NULL; 1276 int xlinkId=zooXmlAddNs(n,"http://www.w3.org/1999/xlink","xlink"); 1277 xmlNsPtr ns_xlink=usedNs[xlinkId]; 1278 1279 while(metadata!=NULL){ 1280 nc6=xmlNewNode(ns_ows, BAD_CAST "Metadata"); 1281 xmlNewNsProp(nc6,ns_xlink,BAD_CAST metadata->name,BAD_CAST metadata->value); 1282 xmlAddChild(nc2,nc6); 1283 metadata=metadata->next; 1284 } 1285 1286 } 1287 1288 _tmp=e->supported; 1289 if(_tmp==NULL && datatype!=1) 1290 _tmp=e->defaults; 1291 1292 int hasSupported=-1; 1293 1294 while(_tmp!=NULL){ 1295 if(hasSupported<0){ 1296 if(datatype==0){ 1297 if(vid==0) 1298 nc4 = xmlNewNode(NULL, BAD_CAST "Supported"); 997 nc4 = xmlNewNode(NULL, BAD_CAST "Default"); 1299 998 nc5 = xmlNewNode(ns1, BAD_CAST "Format"); 1300 999 if(vid==1){ 1000 xmlNewProp(nc5,BAD_CAST "default",BAD_CAST "true"); 1301 1001 int oI=0; 1302 1002 for(oI=0;oI<3;oI++) … … 1306 1006 } 1307 1007 } 1308 else 1309 if(vid==0) 1310 nc5 = xmlNewNode(NULL, BAD_CAST "Supported"); 1311 hasSupported=0; 1312 }else 1313 if(datatype==0){ 1314 nc5 = xmlNewNode(ns1, BAD_CAST "Format"); 1315 if(vid==1){ 1316 int oI=0; 1317 for(oI=0;oI<3;oI++) 1318 if((tmp1=getMap(_tmp->content,orderedFields[oI]))!=NULL){ 1319 xmlNewProp(nc5,BAD_CAST orderedFields[oI],BAD_CAST tmp1->value); 1008 1009 tmp1=_tmp->content; 1010 1011 if(vid==0) 1012 if((tmp1=getMap(_tmp->content,"DataType"))!=NULL){ 1013 nc8 = xmlNewNode(ns_ows, BAD_CAST "DataType"); 1014 xmlAddChild(nc8,xmlNewText(BAD_CAST tmp1->value)); 1015 char tmp[1024]; 1016 sprintf(tmp,"http://www.w3.org/TR/xmlschema-2/#%s",tmp1->value); 1017 xmlNewNsProp(nc8,ns_ows,BAD_CAST "reference",BAD_CAST tmp); 1018 if(vid==0) 1019 xmlAddChild(nc3,nc8); 1020 else 1021 xmlAddChild(nc5,nc8); 1022 datatype=1; 1023 } 1024 1025 bool isInput=false; 1026 if(strncmp(type,"Input",5)==0 || strncmp(type,"wps:Input",9)==0){ 1027 isInput=true; 1028 if((tmp1=getMap(_tmp->content,"AllowedValues"))!=NULL){ 1029 nc6 = xmlNewNode(ns_ows, BAD_CAST "AllowedValues"); 1030 char *token,*saveptr1; 1031 token=strtok_r(tmp1->value,",",&saveptr1); 1032 while(token!=NULL){ 1033 nc7 = xmlNewNode(ns_ows, BAD_CAST "Value"); 1034 char *tmps=strdup(token); 1035 tmps[strlen(tmps)]=0; 1036 xmlAddChild(nc7,xmlNewText(BAD_CAST tmps)); 1037 free(tmps); 1038 xmlAddChild(nc6,nc7); 1039 token=strtok_r(NULL,",",&saveptr1); 1040 } 1041 if(getMap(_tmp->content,"range")!=NULL || 1042 getMap(_tmp->content,"rangeMin")!=NULL || 1043 getMap(_tmp->content,"rangeMax")!=NULL || 1044 getMap(_tmp->content,"rangeClosure")!=NULL ) 1045 goto doRange; 1046 if(vid==0) 1047 xmlAddChild(nc3,nc6); 1048 else 1049 xmlAddChild(nc5,nc6); 1050 isAnyValue=-1; 1051 } 1052 1053 tmp1=getMap(_tmp->content,"range"); 1054 if(tmp1==NULL) 1055 tmp1=getMap(_tmp->content,"rangeMin"); 1056 if(tmp1==NULL) 1057 tmp1=getMap(_tmp->content,"rangeMax"); 1058 1059 if(tmp1!=NULL && isAnyValue==1){ 1060 nc6 = xmlNewNode(ns_ows, BAD_CAST "AllowedValues"); 1061 doRange: 1062 1063 /** 1064 * Range: Table 46 OGC Web Services Common Standard 1065 */ 1066 nc8 = xmlNewNode(ns_ows, BAD_CAST "Range"); 1067 1068 map* tmp0=getMap(tmp1,"range"); 1069 if(tmp0!=NULL){ 1070 char* pToken; 1071 char* orig=zStrdup(tmp0->value); 1072 /** 1073 * RangeClosure: Table 47 OGC Web Services Common Standard 1074 */ 1075 const char *tmp="closed"; 1076 if(orig[0]=='[' && orig[strlen(orig)-1]=='[') 1077 tmp="closed-open"; 1078 else 1079 if(orig[0]==']' && orig[strlen(orig)-1]==']') 1080 tmp="open-closed"; 1081 else 1082 if(orig[0]==']' && orig[strlen(orig)-1]=='[') 1083 tmp="open"; 1084 xmlNewNsProp(nc8,ns_ows,BAD_CAST "rangeClosure",BAD_CAST tmp); 1085 pToken=strtok(orig,","); 1086 int nci0=0; 1087 while(pToken!=NULL){ 1088 char *tmpStr=(char*) malloc((strlen(pToken))*sizeof(char)); 1089 if(nci0==0){ 1090 nc7 = xmlNewNode(ns_ows, BAD_CAST "MinimumValue"); 1091 strncpy( tmpStr, pToken+1, strlen(pToken)-1 ); 1092 tmpStr[strlen(pToken)-1] = '\0'; 1093 }else{ 1094 nc7 = xmlNewNode(ns_ows, BAD_CAST "MaximumValue"); 1095 const char* bkt; 1096 if ( ( bkt = strchr(pToken, '[') ) != NULL || ( bkt = strchr(pToken, ']') ) != NULL ){ 1097 strncpy( tmpStr, pToken, bkt - pToken ); 1098 tmpStr[bkt - pToken] = '\0'; 1099 } 1100 } 1101 xmlAddChild(nc7,xmlNewText(BAD_CAST tmpStr)); 1102 free(tmpStr); 1103 xmlAddChild(nc8,nc7); 1104 nci0++; 1105 pToken = strtok(NULL,","); 1106 } 1107 if(getMap(tmp1,"rangeSpacing")==NULL){ 1108 nc7 = xmlNewNode(ns_ows, BAD_CAST "Spacing"); 1109 xmlAddChild(nc7,xmlNewText(BAD_CAST "1")); 1110 xmlAddChild(nc8,nc7); 1320 1111 } 1321 } 1322 } 1323 tmp1=_tmp->content; 1324 int oI=0; 1325 for(oI=0;oI<6;oI++) 1326 if((tmp1=getMap(_tmp->content,orderedFields[oI]))!=NULL){ 1327 #ifdef DEBUG 1328 printf("DATATYPE SUPPORTED ? %s\n",tmp1->name); 1329 #endif 1330 if(strcmp(tmp1->name,"asReference")!=0 && 1331 strcmp(tmp1->name,"value")!=0 && 1332 strcmp(tmp1->name,"DataType")!=0 && 1333 strcasecmp(tmp1->name,"extension")!=0){ 1334 if(datatype!=1){ 1335 char *tmp2=zCapitalize1(tmp1->name); 1336 nc6 = xmlNewNode(NULL, BAD_CAST tmp2); 1337 free(tmp2); 1112 free(orig); 1113 }else{ 1114 1115 tmp0=getMap(tmp1,"rangeMin"); 1116 if(tmp0!=NULL){ 1117 nc7 = xmlNewNode(ns_ows, BAD_CAST "MinimumValue"); 1118 xmlAddChild(nc7,xmlNewText(BAD_CAST tmp0->value)); 1119 xmlAddChild(nc8,nc7); 1120 }else{ 1121 nc7 = xmlNewNode(ns_ows, BAD_CAST "MinimumValue"); 1122 xmlAddChild(nc8,nc7); 1123 } 1124 tmp0=getMap(tmp1,"rangeMax"); 1125 if(tmp0!=NULL){ 1126 nc7 = xmlNewNode(ns_ows, BAD_CAST "MaximumValue"); 1127 xmlAddChild(nc7,xmlNewText(BAD_CAST tmp0->value)); 1128 xmlAddChild(nc8,nc7); 1129 }else{ 1130 nc7 = xmlNewNode(ns_ows, BAD_CAST "MaximumValue"); 1131 xmlAddChild(nc8,nc7); 1132 } 1133 tmp0=getMap(tmp1,"rangeSpacing"); 1134 if(tmp0!=NULL){ 1135 nc7 = xmlNewNode(ns_ows, BAD_CAST "Spacing"); 1136 xmlAddChild(nc7,xmlNewText(BAD_CAST tmp0->value)); 1137 xmlAddChild(nc8,nc7); 1138 } 1139 tmp0=getMap(tmp1,"rangeClosure"); 1140 if(tmp0!=NULL){ 1141 const char *tmp="closed"; 1142 if(strcasecmp(tmp0->value,"co")==0) 1143 tmp="closed-open"; 1144 else 1145 if(strcasecmp(tmp0->value,"oc")==0) 1146 tmp="open-closed"; 1147 else 1148 if(strcasecmp(tmp0->value,"o")==0) 1149 tmp="open"; 1150 xmlNewNsProp(nc8,ns_ows,BAD_CAST "rangeClosure",BAD_CAST tmp); 1151 }else 1152 xmlNewNsProp(nc8,ns_ows,BAD_CAST "rangeClosure",BAD_CAST "closed"); 1338 1153 } 1339 else{ 1340 char *tmp2=zCapitalize(tmp1->name); 1341 nc6 = xmlNewNode(ns_ows, BAD_CAST tmp2); 1342 free(tmp2); 1343 } 1344 if(datatype==2){ 1345 char *tmpv,*tmps; 1346 tmps=strtok_r(tmp1->value,",",&tmpv); 1347 while(tmps){ 1348 xmlAddChild(nc6,xmlNewText(BAD_CAST tmps)); 1349 tmps=strtok_r(NULL,",",&tmpv); 1350 if(tmps){ 1351 char *tmp2=zCapitalize1(tmp1->name); 1352 nc6 = xmlNewNode(NULL, BAD_CAST tmp2); 1353 free(tmp2); 1154 if(_tmp0==NULL){ 1155 xmlAddChild(nc6,nc8); 1156 _tmp0=e->supported; 1157 if(_tmp0!=NULL && 1158 (getMap(_tmp0->content,"range")!=NULL || 1159 getMap(_tmp0->content,"rangeMin")!=NULL || 1160 getMap(_tmp0->content,"rangeMax")!=NULL || 1161 getMap(_tmp0->content,"rangeClosure")!=NULL )){ 1162 tmp1=_tmp0->content; 1163 goto doRange; 1164 } 1165 }else{ 1166 _tmp0=_tmp0->next; 1167 if(_tmp0!=NULL){ 1168 xmlAddChild(nc6,nc8); 1169 if(getMap(_tmp0->content,"range")!=NULL || 1170 getMap(_tmp0->content,"rangeMin")!=NULL || 1171 getMap(_tmp0->content,"rangeMax")!=NULL || 1172 getMap(_tmp0->content,"rangeClosure")!=NULL ){ 1173 tmp1=_tmp0->content; 1174 goto doRange; 1354 1175 } 1355 1176 } 1356 1177 } 1178 xmlAddChild(nc6,nc8); 1179 if(vid==0) 1180 xmlAddChild(nc3,nc6); 1181 else 1182 xmlAddChild(nc5,nc6); 1183 isAnyValue=-1; 1184 } 1185 1186 } 1187 1188 int oI=0; 1189 /*if(vid==0)*/ { 1190 for(oI=0;oI<13;oI++) 1191 if((tmp1=getMap(_tmp->content,orderedFields[oI]))!=NULL){ 1192 #ifdef DEBUG 1193 printf("DATATYPE DEFAULT ? %s\n",tmp1->name); 1194 #endif 1195 if(strcmp(tmp1->name,"asReference")!=0 && 1196 strncasecmp(tmp1->name,"DataType",8)!=0 && 1197 strcasecmp(tmp1->name,"extension")!=0 && 1198 strcasecmp(tmp1->name,"value")!=0 && 1199 strcasecmp(tmp1->name,"AllowedValues")!=0 && 1200 strncasecmp(tmp1->name,"range",5)!=0){ 1201 if(datatype!=1){ 1202 char *tmp2=zCapitalize1(tmp1->name); 1203 nc9 = xmlNewNode(NULL, BAD_CAST tmp2); 1204 free(tmp2); 1205 } 1206 else{ 1207 char *tmp2=zCapitalize(tmp1->name); 1208 nc9 = xmlNewNode(ns_ows, BAD_CAST tmp2); 1209 free(tmp2); 1210 } 1211 xmlAddChild(nc9,xmlNewText(BAD_CAST tmp1->value)); 1212 if(vid==0 || oI>=3){ 1213 if(vid==0 || oI!=4) 1214 xmlAddChild(nc5,nc9); 1215 if(oI==4 && vid==1){ 1216 xmlNewProp(nc9,BAD_CAST "default",BAD_CAST "true"); 1217 } 1218 } 1219 else 1220 xmlFree(nc9); 1221 if(strcasecmp(tmp1->name,"uom")==0) 1222 hasUOM1=true; 1223 hasUOM=true; 1224 }else 1225 tmp1=tmp1->next; 1226 } 1227 } 1228 1229 if(datatype!=2){ 1230 if(hasUOM==true){ 1231 if(vid==0){ 1232 xmlAddChild(nc4,nc5); 1233 xmlAddChild(nc3,nc4); 1234 } 1357 1235 else{ 1358 xmlAddChild(nc 6,xmlNewText(BAD_CAST tmp1->value));1236 xmlAddChild(nc3,nc5); 1359 1237 } 1360 if(vid==0 || oI>=3){ 1361 if(vid==0 || oI!=4) 1362 xmlAddChild(nc5,nc6); 1238 }else{ 1239 if(hasUOM1==false && vid==0){ 1240 xmlFreeNode(nc5); 1241 if(datatype==1) 1242 xmlFreeNode(nc4); 1243 } 1244 else 1245 xmlAddChild(nc3,nc5); 1246 } 1247 }else{ 1248 xmlAddChild(nc3,nc5); 1249 } 1250 1251 if(datatype!=1 && default1<0){ 1252 xmlFreeNode(nc5); 1253 if(datatype!=2) 1254 xmlFreeNode(nc4); 1255 } 1256 1257 1258 if((isInput || vid==1) && datatype==1 && 1259 getMap(_tmp->content,"AllowedValues")==NULL && 1260 getMap(_tmp->content,"range")==NULL && 1261 getMap(_tmp->content,"rangeMin")==NULL && 1262 getMap(_tmp->content,"rangeMax")==NULL && 1263 getMap(_tmp->content,"rangeClosure")==NULL ){ 1264 tmp1=getMap(_tmp->content,"dataType"); 1265 // We were tempted to define default value for boolean as {true,false} 1266 if(tmp1!=NULL && strcasecmp(tmp1->value,"boolean")==0){ 1267 nc6 = xmlNewNode(ns_ows, BAD_CAST "AllowedValues"); 1268 nc7 = xmlNewNode(ns_ows, BAD_CAST "Value"); 1269 xmlAddChild(nc7,xmlNewText(BAD_CAST "true")); 1270 xmlAddChild(nc6,nc7); 1271 nc7 = xmlNewNode(ns_ows, BAD_CAST "Value"); 1272 xmlAddChild(nc7,xmlNewText(BAD_CAST "false")); 1273 xmlAddChild(nc6,nc7); 1274 if(vid==0) 1275 xmlAddChild(nc3,nc6); 1276 else 1277 xmlAddChild(nc5,nc6); 1278 } 1279 else 1280 if(vid==0) 1281 xmlAddChild(nc3,xmlNewNode(ns_ows, BAD_CAST "AnyValue")); 1282 else 1283 xmlAddChild(nc5,xmlNewNode(ns_ows, BAD_CAST "AnyValue")); 1284 } 1285 1286 if(vid==1){ 1287 if((tmp1=getMap(_tmp->content,"DataType"))!=NULL){ 1288 nc8 = xmlNewNode(ns_ows, BAD_CAST "DataType"); 1289 xmlAddChild(nc8,xmlNewText(BAD_CAST tmp1->value)); 1290 char tmp[1024]; 1291 sprintf(tmp,"http://www.w3.org/TR/xmlschema-2/#%s",tmp1->value); 1292 xmlNewNsProp(nc8,ns_ows,BAD_CAST "reference",BAD_CAST tmp); 1293 if(vid==0) 1294 xmlAddChild(nc3,nc8); 1295 else 1296 xmlAddChild(nc5,nc8); 1297 datatype=1; 1298 } 1299 if(hasUOM==true){ 1300 tmp1=getMap(_tmp->content,"uom"); 1301 if(tmp1!=NULL){ 1302 char *tmp2=zCapitalize(tmp1->name); 1303 nc9 = xmlNewNode(ns_ows, BAD_CAST tmp2); 1304 free(tmp2); 1305 //xmlNewProp(nc9, BAD_CAST "default", BAD_CAST "true"); 1306 xmlAddChild(nc9,xmlNewText(BAD_CAST tmp1->value)); 1307 xmlAddChild(nc5,nc9); 1308 /*struct iotype * _ltmp=e->supported; 1309 while(_ltmp!=NULL){ 1310 tmp1=getMap(_ltmp->content,"uom"); 1311 if(tmp1!=NULL){ 1312 char *tmp2=zCapitalize(tmp1->name); 1313 nc9 = xmlNewNode(ns_ows, BAD_CAST tmp2); 1314 free(tmp2); 1315 xmlAddChild(nc9,xmlNewText(BAD_CAST tmp1->value)); 1316 xmlAddChild(nc5,nc9); 1317 } 1318 _ltmp=_ltmp->next; 1319 }*/ 1320 1321 } 1322 } 1323 if(e->defaults!=NULL && (tmp1=getMap(e->defaults->content,"value"))!=NULL){ 1324 nc7 = xmlNewNode(ns_ows, BAD_CAST "DefaultValue"); 1325 xmlAddChild(nc7,xmlNewText(BAD_CAST tmp1->value)); 1326 xmlAddChild(nc5,nc7); 1327 } 1328 } 1329 1330 map* metadata=e->metadata; 1331 xmlNodePtr n=NULL; 1332 int xlinkId=zooXmlAddNs(n,"http://www.w3.org/1999/xlink","xlink"); 1333 xmlNsPtr ns_xlink=usedNs[xlinkId]; 1334 1335 while(metadata!=NULL){ 1336 nc6=xmlNewNode(ns_ows, BAD_CAST "Metadata"); 1337 xmlNewNsProp(nc6,ns_xlink,BAD_CAST metadata->name,BAD_CAST metadata->value); 1338 xmlAddChild(nc2,nc6); 1339 metadata=metadata->next; 1340 } 1341 1342 } 1343 1344 _tmp=e->supported; 1345 if(_tmp==NULL && datatype!=1) 1346 _tmp=e->defaults; 1347 1348 int hasSupported=-1; 1349 1350 while(_tmp!=NULL){ 1351 if(hasSupported<0){ 1352 if(datatype==0){ 1353 if(vid==0) 1354 nc4 = xmlNewNode(NULL, BAD_CAST "Supported"); 1355 nc5 = xmlNewNode(ns1, BAD_CAST "Format"); 1356 if(vid==1){ 1357 int oI=0; 1358 for(oI=0;oI<3;oI++) 1359 if((tmp1=getMap(_tmp->content,orderedFields[oI]))!=NULL){ 1360 xmlNewProp(nc5,BAD_CAST orderedFields[oI],BAD_CAST tmp1->value); 1361 } 1362 } 1363 } 1364 else 1365 if(vid==0) 1366 nc5 = xmlNewNode(NULL, BAD_CAST "Supported"); 1367 hasSupported=0; 1368 }else 1369 if(datatype==0){ 1370 nc5 = xmlNewNode(ns1, BAD_CAST "Format"); 1371 if(vid==1){ 1372 int oI=0; 1373 for(oI=0;oI<3;oI++) 1374 if((tmp1=getMap(_tmp->content,orderedFields[oI]))!=NULL){ 1375 xmlNewProp(nc5,BAD_CAST orderedFields[oI],BAD_CAST tmp1->value); 1376 } 1377 } 1378 } 1379 tmp1=_tmp->content; 1380 int oI=0; 1381 for(oI=0;oI<6;oI++) 1382 if((tmp1=getMap(_tmp->content,orderedFields[oI]))!=NULL){ 1383 #ifdef DEBUG 1384 printf("DATATYPE SUPPORTED ? %s\n",tmp1->name); 1385 #endif 1386 if(strcmp(tmp1->name,"asReference")!=0 && 1387 strcmp(tmp1->name,"value")!=0 && 1388 strcmp(tmp1->name,"DataType")!=0 && 1389 strcasecmp(tmp1->name,"extension")!=0){ 1390 if(datatype!=1){ 1391 char *tmp2=zCapitalize1(tmp1->name); 1392 nc6 = xmlNewNode(NULL, BAD_CAST tmp2); 1393 free(tmp2); 1394 } 1395 else{ 1396 char *tmp2=zCapitalize(tmp1->name); 1397 nc6 = xmlNewNode(ns_ows, BAD_CAST tmp2); 1398 free(tmp2); 1399 } 1400 if(datatype==2){ 1401 char *tmpv,*tmps; 1402 tmps=strtok_r(tmp1->value,",",&tmpv); 1403 while(tmps){ 1404 xmlAddChild(nc6,xmlNewText(BAD_CAST tmps)); 1405 tmps=strtok_r(NULL,",",&tmpv); 1406 if(tmps){ 1407 char *tmp2=zCapitalize1(tmp1->name); 1408 nc6 = xmlNewNode(NULL, BAD_CAST tmp2); 1409 free(tmp2); 1410 } 1411 } 1412 } 1413 else{ 1414 xmlAddChild(nc6,xmlNewText(BAD_CAST tmp1->value)); 1415 } 1416 if(vid==0 || oI>=3){ 1417 if(vid==0 || oI!=4) 1418 xmlAddChild(nc5,nc6); 1419 else 1420 xmlFree(nc6); 1421 } 1363 1422 else 1364 1423 xmlFree(nc6); 1365 1424 } 1366 else 1367 xmlFree(nc6); 1425 tmp1=tmp1->next; 1368 1426 } 1369 tmp1=tmp1->next; 1370 } 1371 if(hasSupported<=0){ 1372 if(datatype==0){ 1373 if(vid==0){ 1374 xmlAddChild(nc4,nc5); 1375 xmlAddChild(nc3,nc4); 1427 if(hasSupported<=0){ 1428 if(datatype==0){ 1429 if(vid==0){ 1430 xmlAddChild(nc4,nc5); 1431 xmlAddChild(nc3,nc4); 1432 } 1433 else{ 1434 xmlAddChild(nc3,nc5); 1435 } 1436 1437 }else{ 1438 if(datatype!=1) 1439 xmlAddChild(nc3,nc5); 1376 1440 } 1377 else{ 1378 xmlAddChild(nc3,nc5); 1441 hasSupported=1; 1442 } 1443 else 1444 if(datatype==0){ 1445 if(vid==0){ 1446 xmlAddChild(nc4,nc5); 1447 xmlAddChild(nc3,nc4); 1448 } 1449 else{ 1450 xmlAddChild(nc3,nc5); 1451 } 1379 1452 } 1380 1381 }else{ 1382 if(datatype!=1) 1383 xmlAddChild(nc3,nc5); 1384 } 1385 hasSupported=1; 1386 } 1387 else 1388 if(datatype==0){ 1389 if(vid==0){ 1390 xmlAddChild(nc4,nc5); 1391 xmlAddChild(nc3,nc4); 1392 } 1393 else{ 1394 xmlAddChild(nc3,nc5); 1395 } 1396 } 1397 else 1398 if(datatype!=1) 1399 xmlAddChild(nc3,nc5); 1400 1401 _tmp=_tmp->next; 1402 } 1403 1404 if(hasSupported==0){ 1405 if(datatype==0 && vid!=0) 1406 xmlFreeNode(nc4); 1407 xmlFreeNode(nc5); 1408 } 1409 1410 _tmp=e->defaults; 1411 if(datatype==1 && hasUOM1==true){ 1412 if(vid==0){ 1413 xmlAddChild(nc4,nc5); 1414 xmlAddChild(nc3,nc4); 1415 } 1416 else{ 1417 xmlAddChild(nc3,nc5); 1418 } 1419 } 1420 1421 if(vid==0 && _tmp!=NULL && (tmp1=getMap(_tmp->content,"value"))!=NULL){ 1422 nc7 = xmlNewNode(NULL, BAD_CAST "DefaultValue"); 1423 xmlAddChild(nc7,xmlNewText(BAD_CAST tmp1->value)); 1424 xmlAddChild(nc3,nc7); 1425 } 1453 else 1454 if(datatype!=1) 1455 xmlAddChild(nc3,nc5); 1456 1457 _tmp=_tmp->next; 1458 } 1459 1460 if(hasSupported==0){ 1461 if(datatype==0 && vid!=0) 1462 xmlFreeNode(nc4); 1463 xmlFreeNode(nc5); 1464 } 1465 1466 _tmp=e->defaults; 1467 if(datatype==1 && hasUOM1==true){ 1468 if(vid==0){ 1469 xmlAddChild(nc4,nc5); 1470 xmlAddChild(nc3,nc4); 1471 } 1472 else{ 1473 xmlAddChild(nc3,nc5); 1474 } 1475 } 1476 1477 if(vid==0 && _tmp!=NULL && (tmp1=getMap(_tmp->content,"value"))!=NULL){ 1478 nc7 = xmlNewNode(NULL, BAD_CAST "DefaultValue"); 1479 xmlAddChild(nc7,xmlNewText(BAD_CAST tmp1->value)); 1480 xmlAddChild(nc3,nc7); 1481 } 1426 1482 1427 xmlAddChild(nc2,nc3); 1483 xmlAddChild(nc2,nc3); 1484 } 1428 1485 1429 1486 xmlAddChild(nc1,nc2); -
trunk/zoo-project/zoo-kernel/response_print.h
r654 r676 143 143 * Definitions of schemas depending on the WPS version 144 144 */ 145 static const char* schemas[2][ 7]={145 static const char* schemas[2][8]={ 146 146 {"1.0.0","http://www.opengis.net/ows/1.1","http://www.opengis.net/wps/1.0.0","http://schemas.opengis.net/wps/1.0.0","%s %s/wps%s_response.xsd","http://schemas.opengis.net/ows/1.1.0/owsExceptionReport.xsd","1.1.0"}, 147 {"2.0.0","http://www.opengis.net/ows/2.0","http://www.opengis.net/wps/2.0","http://schemas.opengis.net/wps/2.0"," %s %s/wps%s.xsd","http://schemas.opengis.net/ows/2.0/owsExceptionReport.xsd","2.0.2"},147 {"2.0.0","http://www.opengis.net/ows/2.0","http://www.opengis.net/wps/2.0","http://schemas.opengis.net/wps/2.0","http://www.opengis.net/wps/2.0 http://schemas.opengis.net/wps/2.0/wps.xsd","http://schemas.opengis.net/ows/2.0/owsExceptionReport.xsd","2.0.2","http://www.opengis.net/spec/wps/2.0/def/process-profile/"}, 148 148 }; 149 149 /** … … 208 208 xmlNodePtr printWPSHeader(xmlDocPtr,maps*,const char*,const char*,const char*,int); 209 209 xmlNodePtr printGetCapabilitiesHeader(xmlDocPtr,maps*,const char*); 210 void printGetCapabilitiesForProcess( maps*,xmlNodePtr,service*);211 void printDescribeProcessForProcess( maps*,xmlNodePtr,service*);210 void printGetCapabilitiesForProcess(registry*,maps*,xmlNodePtr,service*); 211 void printDescribeProcessForProcess(registry*,maps*,xmlNodePtr,service*); 212 212 void printFullDescription(int,elements*,const char*,xmlNsPtr,xmlNsPtr,xmlNodePtr,int); 213 213 void printDocument(maps*,xmlDocPtr,int); -
trunk/zoo-project/zoo-kernel/server_internal.c
r657 r676 966 966 sprintf(fileName,"%s/%s",r_inputs->value,dp->d_name); 967 967 if(unlink(fileName)!=0){ 968 errorException (conf, _("The job cannot be removed, a file cannot be removed"), 968 errorException (conf, 969 _("The job cannot be removed, a file cannot be removed"), 969 970 "NoApplicableCode", NULL); 970 971 return; … … 983 984 return; 984 985 } 986 987 extern int getServiceFromFile (maps *, const char *, service **); 988 989 /** 990 * Parse the service file using getServiceFromFile or use getServiceFromYAML 991 * if YAML support was activated. 992 * 993 * @param conf the conf maps containing the main.cfg settings 994 * @param file the file name to parse 995 * @param service the service to update witht the file content 996 * @param name the service name 997 * @return true if the file can be parsed or false 998 * @see getServiceFromFile, getServiceFromYAML 999 */ 1000 int readServiceFile (maps * conf, char *file, service ** service, char *name){ 1001 int t = getServiceFromFile (conf, file, service); 1002 #ifdef YAML 1003 if (t < 0){ 1004 t = getServiceFromYAML (conf, file, service, name); 1005 } 1006 #endif 1007 return t; 1008 } 1009 1010 /** 1011 * Create the profile registry. 1012 * 1013 * The profile registry is optional (created only if the registry key is 1014 * available in the [main] section of the main.cfg file) and can be used to 1015 * store the profiles hierarchy. The registry is a directory which should 1016 * contain the following sub-directories: 1017 * * concept: direcotry containing .html files describing concept 1018 * * generic: directory containing .zcfg files for wps:GenericProcess 1019 * * implementation: directory containing .zcfg files for wps:Process 1020 * 1021 * @param m the conf maps containing the main.cfg settings 1022 * @param r the registry to update 1023 * @param reg_dir the resgitry 1024 * @return 0 if the resgitry is null or was correctly updated, -1 on failure 1025 */ 1026 int createRegistry (maps* m,registry ** r, char *reg_dir) 1027 { 1028 char registryKeys[3][15]={ 1029 "concept", 1030 "generic", 1031 "implementation" 1032 }; 1033 int scount = 0,i=0; 1034 if (reg_dir == NULL) 1035 return 0; 1036 for(i=0;i<3;i++){ 1037 char * tmpName = 1038 (char *) malloc ((strlen (reg_dir) + strlen (registryKeys[i]) + 2) * 1039 sizeof (char)); 1040 sprintf (tmpName, "%s/%s", reg_dir, registryKeys[i]); 1041 1042 DIR *dirp1 = opendir (tmpName); 1043 struct dirent *dp1; 1044 while ((dp1 = readdir (dirp1)) != NULL){ 1045 char* extn = strstr(dp1->d_name, ".zcfg"); 1046 if(dp1->d_name[0] != '.' && extn != NULL && strlen(extn) == 5) 1047 { 1048 int t; 1049 char *tmps1= 1050 (char *) malloc ((strlen (tmpName) + strlen (dp1->d_name) + 2) * 1051 sizeof (char)); 1052 sprintf (tmps1, "%s/%s", tmpName, dp1->d_name); 1053 char *tmpsn = zStrdup (dp1->d_name); 1054 tmpsn[strlen (tmpsn) - 5] = 0; 1055 service* s1 = (service *) malloc (SERVICE_SIZE); 1056 if (s1 == NULL) 1057 { 1058 setMapInMaps(m,"lenv","message",_("Unable to allocate memory.")); 1059 setMapInMaps(m,"lenv","type","InternalError"); 1060 return -2; 1061 } 1062 t = readServiceFile (m, tmps1, &s1, tmpsn); 1063 free (tmpsn); 1064 if (t < 0) 1065 { 1066 map *tmp00 = getMapFromMaps (m, "lenv", "message"); 1067 char tmp01[1024]; 1068 if (tmp00 != NULL) 1069 sprintf (tmp01, _("Unable to parse the ZCFG file: %s (%s)"), 1070 dp1->d_name, tmp00->value); 1071 else 1072 sprintf (tmp01, _("Unable to parse the ZCFG file: %s."), 1073 dp1->d_name); 1074 setMapInMaps(m,"lenv","message",tmp01); 1075 setMapInMaps(m,"lenv","type","InternalError"); 1076 return -1; 1077 } 1078 if(strncasecmp(registryKeys[i],"implementation",14)==0){ 1079 inheritance(*r,&s1); 1080 } 1081 addServiceToRegistry(r,registryKeys[i],s1); 1082 freeService (&s1); 1083 free (s1); 1084 scount++; 1085 } 1086 } 1087 (void) closedir (dirp1); 1088 } 1089 return 0; 1090 } -
trunk/zoo-project/zoo-kernel/server_internal.h
r654 r676 58 58 59 59 char* getLastErrorMessage(); 60 60 int readServiceFile (maps *, char *, service **, char *); 61 int createRegistry (maps*,registry **,char *); 62 61 63 #ifdef __cplusplus 62 64 } -
trunk/zoo-project/zoo-kernel/service.c
r652 r676 1262 1262 void inheritMap(map** out,map* in){ 1263 1263 map* content=in; 1264 while(content!=NULL && *out!=NULL){ 1264 if((*out)==NULL){ 1265 addMapToMap(out,in); 1266 return; 1267 } 1268 while(content!=NULL){ 1265 1269 map* cmap=getMap(*out,content->name); 1266 1270 if(cmap==NULL) -
trunk/zoo-project/zoo-kernel/service_conf.y
r640 r676 814 814 #endif 815 815 if(wait_outputs && current_element!=NULL && current_element->name!=NULL){ 816 if(current_content!=NULL){ 817 addMapToMap(¤t_element->content,current_content); 818 } 816 819 if(my_service->outputs==NULL){ 817 820 #ifdef DEBUG_SERVICE_CONF -
trunk/zoo-project/zoo-kernel/zoo_service_loader.c
r673 r676 141 141 #endif 142 142 143 extern int getServiceFromFile (maps *, const char *, service **);144 145 /**146 * Parse the service file using getServiceFromFile or use getServiceFromYAML147 * if YAML support was activated.148 *149 * @param conf the conf maps containing the main.cfg settings150 * @param file the file name to parse151 * @param service the service to update witht the file content152 * @param name the service name153 * @return true if the file can be parsed or false154 * @see getServiceFromFile, getServiceFromYAML155 */156 int157 readServiceFile (maps * conf, char *file, service ** service, char *name)158 {159 int t = getServiceFromFile (conf, file, service);160 #ifdef YAML161 if (t < 0)162 {163 t = getServiceFromYAML (conf, file, service, name);164 }165 #endif166 return t;167 }168 143 169 144 /** … … 185 160 } 186 161 187 188 /**189 * Create the profile registry.190 *191 * The profile registry is optional (created only if the registry key is192 * available in the [main] section of the main.cfg file) and can be used to193 * store the profiles hierarchy. The registry is a directory which should194 * contain the following sub-directories:195 * * concept: direcotry containing .html files describing concept196 * * generic: directory containing .zcfg files for wps:GenericProcess197 * * implementation: directory containing .zcfg files for wps:Process198 *199 * @param m the conf maps containing the main.cfg settings200 * @param r the registry to update201 * @param reg_dir the resgitry202 * @param saved_stdout the saved stdout identifier203 * @return 0 if the resgitry is null or was correctly updated, -1 on failure204 */205 int206 createRegistry (maps* m,registry ** r, char *reg_dir, int saved_stdout)207 {208 char registryKeys[3][15]={209 "concept",210 "generic",211 "implementation"212 };213 int scount = 0,i=0;214 if (reg_dir == NULL)215 return 0;216 for(i=0;i<3;i++){217 char * tmpName =218 (char *) malloc ((strlen (reg_dir) + strlen (registryKeys[i]) + 2) *219 sizeof (char));220 sprintf (tmpName, "%s/%s", reg_dir, registryKeys[i]);221 222 DIR *dirp1 = opendir (tmpName);223 struct dirent *dp1;224 while ((dp1 = readdir (dirp1)) != NULL){225 char* extn = strstr(dp1->d_name, ".zcfg");226 if(dp1->d_name[0] != '.' && extn != NULL && strlen(extn) == 5)227 {228 int t;229 char *tmps1=230 (char *) malloc ((strlen (tmpName) + strlen (dp1->d_name) + 2) *231 sizeof (char));232 sprintf (tmps1, "%s/%s", tmpName, dp1->d_name);233 char *tmpsn = zStrdup (dp1->d_name);234 tmpsn[strlen (tmpsn) - 5] = 0;235 service* s1 = (service *) malloc (SERVICE_SIZE);236 if (s1 == NULL)237 {238 dup2 (saved_stdout, fileno (stdout));239 errorException (m, _("Unable to allocate memory."),240 "InternalError", NULL);241 return -1;242 }243 t = readServiceFile (m, tmps1, &s1, tmpsn);244 free (tmpsn);245 if (t < 0)246 {247 map *tmp00 = getMapFromMaps (m, "lenv", "message");248 char tmp01[1024];249 if (tmp00 != NULL)250 sprintf (tmp01, _("Unable to parse the ZCFG file: %s (%s)"),251 dp1->d_name, tmp00->value);252 else253 sprintf (tmp01, _("Unable to parse the ZCFG file: %s."),254 dp1->d_name);255 dup2 (saved_stdout, fileno (stdout));256 errorException (m, tmp01, "InternalError", NULL);257 return -1;258 }259 #ifdef DEBUG260 dumpService (s1);261 fflush (stdout);262 fflush (stderr);263 #endif264 if(strncasecmp(registryKeys[i],"implementation",14)==0){265 inheritance(*r,&s1);266 }267 addServiceToRegistry(r,registryKeys[i],s1);268 freeService (&s1);269 free (s1);270 scount++;271 }272 }273 (void) closedir (dirp1);274 }275 return 0;276 }277 278 162 /** 279 163 * Recursivelly parse zcfg starting from the ZOO-Kernel cwd. … … 288 172 * @param level the current level (number of sub-directories to reach the 289 173 * current path) 174 * @param func a pointer to a function having 4 parameters 175 * (registry*, maps*, xmlNodePtr and service*). 290 176 * @see inheritance, readServiceFile 291 177 */ 292 178 int 293 recursReaddirF ( maps * m, registry *r, xmlNodePtr n, char *conf_dir, char *prefix,294 int saved_stdout, int level, void (func) (maps *, xmlNodePtr, 295 service *))179 recursReaddirF ( maps * m, registry *r, xmlNodePtr n, char *conf_dir, 180 char *prefix, int saved_stdout, int level, 181 void (func) (registry *, maps *, xmlNodePtr, service *) ) 296 182 { 297 183 struct dirent *dp; … … 400 286 #endif 401 287 inheritance(r,&s1); 402 func ( m, n, s1);288 func (r, m, n, s1); 403 289 freeService (&s1); 404 290 free (s1); … … 1251 1137 int saved_stdout = dup (fileno (stdout)); 1252 1138 dup2 (fileno (stderr), fileno (stdout)); 1253 createRegistry (m,&zooRegistry,reg->value,saved_stdout); 1139 if(createRegistry (m,&zooRegistry,reg->value)<0){ 1140 map *message=getMapFromMaps(m,"lenv","message"); 1141 map *type=getMapFromMaps(m,"lenv","type"); 1142 dup2 (saved_stdout, fileno (stdout)); 1143 errorException (m, message->value, 1144 type->value, NULL); 1145 return 0; 1146 } 1254 1147 dup2 (saved_stdout, fileno (stdout)); 1148 close(saved_stdout); 1255 1149 } 1256 1150 … … 1433 1327 #endif 1434 1328 inheritance(zooRegistry,&s1); 1435 printDescribeProcessForProcess ( m, n, s1);1329 printDescribeProcessForProcess (zooRegistry,m, n, s1); 1436 1330 freeService (&s1); 1437 1331 free (s1); … … 1511 1405 #endif 1512 1406 inheritance(zooRegistry,&s1); 1513 printDescribeProcessForProcess ( m, n, s1);1407 printDescribeProcessForProcess (zooRegistry,m, n, s1); 1514 1408 freeService (&s1); 1515 1409 free (s1); … … 2177 2071 fclose (stdin); 2178 2072 #endif 2179 2073 fprintf(stderr,"DEBUG START %s %d \n",__FILE__,__LINE__); 2180 2074 #ifdef RELY_ON_DB 2181 2075 init_sql(m);
Note: See TracChangeset
for help on using the changeset viewer.