From 2fe093422279cb885a95d69d8e25f1ccaaf588cf Mon Sep 17 00:00:00 2001 From: "cst%andrew.cmu.edu" Date: Mon, 17 Jan 2005 21:47:30 +0000 Subject: [PATCH] Bug 271272 Use XML parsing on install.rdf instead of regex Patch by Ted Mielczarek , r=alanjstr git-svn-id: svn://10.0.0.236/trunk@167913 18797224-902f-48f8-a5cc-f745e15eee43 --- .../webtools/update/core/class_rdf_parser.php | 1637 +++++++++++++++++ .../webtools/update/developers/additem.php | 116 +- .../developers/parse_install_manifest.php | 91 + 3 files changed, 1778 insertions(+), 66 deletions(-) create mode 100644 mozilla/webtools/update/core/class_rdf_parser.php create mode 100644 mozilla/webtools/update/developers/parse_install_manifest.php diff --git a/mozilla/webtools/update/core/class_rdf_parser.php b/mozilla/webtools/update/core/class_rdf_parser.php new file mode 100644 index 00000000000..f8ec1e3ff77 --- /dev/null +++ b/mozilla/webtools/update/core/class_rdf_parser.php @@ -0,0 +1,1637 @@ +clear_element($e["parent"]); + $e["state"]=0; + $e["has_property_atributes"]=0; + $e["has_member_attributes"]=0; + $e["subject_type"]=0; + $e["subject"]=''; + $e["predicate"]=''; + $e["ordinal"]=0; + $e["members"]=0; + $e["data"]=''; + $e["xml_lang"]=''; + $e["bag_id"]=''; + $e["statements"]=0; + $e["statement_id"]=''; + + return $e; +} + +function _copy_element($source, &$destination ) +{ + if( $source ) + { + $destination["parent"] = $source; + $destination["state"] = $source["state"]; + $destination["xml_lang"] = $source["xml_lang"]; + } +} + +function _clear_element(&$e) +{ + $e["subject"]=''; + $e["predicate"]=''; + $e["data"]=''; + $e["bag_id"]=''; + $e["statement_id"]=''; + + if(isset($e["parent"])) { + if( $e["parent"] ) + { + if( $e["parent"]["xml_lang"] != $e["xml_lang"] ) + { + $e["xml_lang"]=''; + } + } + else + { + $e["xml_lang"]=''; + } + } else { + $e["xml_lang"]=''; + } + //memset( e, 0, strlen( _rdf_element ) ); + $e["parent"]=Array(); + $e["state"]=0; + $e["has_property_attributes"]=0; + $e["has_member_attributes"]=0; + $e["subject_type"]=0; + $e["subject"]=''; + $e["predicate"]=''; + $e["ordinal"]=0; + $e["members"]=0; + $e["data"]=''; + $e["xml_lang"]=''; + $e["bag_id"]=''; + $e["statements"]=0; + $e["statement_id"]=''; + +} + +function _push_element() +{ + if(!isset($this->rdf_parser["free"])) { + $this->rdf_parser["free"]=Array(); + } + if(count($this->rdf_parser["free"])>0) + { + $e = $this->rdf_parser["free"]; + if(isset($e["parent"])) { + $this->rdf_parser["free"] = $e["parent"]; + } else { + $this->rdf_parser["free"]=$this->_new_element(); + } + } + else + { + $e = $this->_new_element(); + } + if(!isset($this->rdf_parser["top"])) { + $this->rdf_parser["top"]=Array(); + } + $this->_copy_element( $this->rdf_parser["top"], $e ); + $this->rdf_parser["top"] = $e; +} + + +function _pop_element() +{ + $e = $this->rdf_parser["top"]; + $this->rdf_parser["top"] = $e["parent"]; + $this->_clear_element( $e ); + /* + if(isset($this->rdf_parser["free"])) { + $e["parent"] = $this->rdf_parser["free"]; + } else { + $e["parent"]=0; + } + */ + $this->rdf_parser["free"] = $e; +} + +function _delete_elements() +{ +} + + +function _is_rdf_property_attribute_resource($local_name ) +{ + return ( $local_name == RDF_TYPE ); +} + +function _is_rdf_property_attribute_literal($local_name ) +{ + return ( $local_name == RDF_VALUE ); +} + +function _is_rdf_ordinal( $local_name ) +{ + $ordinal = -1; + + //if($local_name{0}=='_') + if( $local_name{0} == '_' ) + { + $ordinal = substr($local_name,1) + 1 ; + } + + return ( $ordinal > 0 ) ? $ordinal : 0; +} + +function _is_rdf_property_attribute( $local_name ) +{ + return $this->_is_rdf_property_attribute_resource( $local_name ) + || $this->_is_rdf_property_attribute_literal( $local_name ); +} + +function _is_rdf_property_element( $local_name ) +{ + return ( $local_name == RDF_TYPE ) + || ( $local_name == RDF_SUBJECT ) + || ( $local_name == RDF_PREDICATE ) + || ( $local_name == RDF_OBJECT ) + || ( $local_name == RDF_VALUE ) + || ( $local_name == RDF_LI ) + || ( $local_name{0} == '_' ); +} + +function _istalnum($val) { + return ereg("[A-Za-z0-9]",$val); +} + +function _istalpha($val) { + return ereg("[A-Za-z]",$val); +} + + +function _is_absolute_uri($uri ) +{ + $result = false; + $uri_p=0; + if( $uri && $this->_istalpha( $uri{$uri_p} ) ) + { + ++$uri_p; + + while( ($uri_p_istalnum( $uri{$uri_p} ) + || ( $uri{$uri_p} == '+' ) + || ( $uri{$uri_p} == '-' ) + || ( $uri{$uri_p} == '.' ) ) ) + { + ++$uri_p; + } + + $result = ( $uri{$uri_p} == ':' ); + } + return $result; +} + + +/* +This function returns an associative array returning any of the various components of the URL that are present. This includes the +$arr=parse_url($url) +scheme - e.g. http +host +port +user +pass +path +query - after the question mark ? +fragment - after the hashmark # +*/ +function _parse_uri($uri,$buffer,$len,&$scheme,&$authority,&$path,&$query,&$fragment ) { + $parsed=parse_url($uri); + if(isset($parsed["scheme"])) { + $scheme=$parsed["scheme"];} else { + $scheme=''; + } + if(isset($parsed["host"])) { + $host=$parsed["host"];} else { + $host=''; + } + if(isset($parsed["host"])) { + $authority=$parsed["host"];} else { + $authority=''; + } + if(isset($parsed["path"])) { + $path=$parsed["path"];} else { + $path=''; + } + if(isset($parsed["query"])) { + $query=$parsed["query"];} else { + $query=''; + } + if(isset($parsed["fragment"])) { + $fragment=$parsed["fragment"];} else { + $fragment=''; + } + +} + + +function _resolve_uri_reference($base_uri,$reference_uri,&$buffer,$length ) +{ + $base_buffer=''; + $reference_buffer=''; + $path_buffer=''; + + $buffer = ''; + + $this->_parse_uri($reference_uri,$reference_buffer,strlen( $reference_buffer ),$reference_scheme,$reference_authority, + $reference_path,$reference_query,$reference_fragment ); + + if( $reference_scheme == '' + && $reference_authority == '' + && $reference_path == '' + && $reference_query == '' ) + { + $buffer=$base_uri; + + if( $reference_fragment != '' ) + { + $buffer.= "#" ; + $buffer.=$reference_fragment; + } + } + else if( $reference_scheme != '' ) + { + $buffer=$reference_uri; + } + else + { + $this->_parse_uri( + $base_uri, + $base_buffer, + strlen( $base_buffer ), + $base_scheme, + $base_authority, + $base_path, + $base_query, + $base_fragment ); + + $result_scheme = $base_scheme; + + if( $reference_authority != '' ) + { + $result_authority = $reference_authority; + } + else + { + $result_authority = $base_authority; + + if( $reference_path != '' + && ( ($reference_path{0} == '/') + || ($reference_path{0} == '\\') ) ) + { + $result_path = $reference_path; + } + else + { + $p = ''; + + $result_path = $path_buffer; + + $path_buffer=''; + + $p = strstr( $base_path, '/' ); + + if( !$p ) + { + $p = strstr( $base_path, '\\' ); + } + + if( $p ) + { + + $path_buffer.=$base_path; + + //while( s <= p ) + //{ + // *d++ = *s++; + //} + + //*d++ = 0; + + } + + if( $reference_path != '' ) + { + $path_buffer.=$reference_path; + } + + { + //remove all occurrences of "./" + //print($path_buffer); + $path_buffer=preg_replace("/\/\.\//","/",$path_buffer); + $path_buffer=preg_replace("/\/([^\/\.])*\/..$/","/",$path_buffer); + while(preg_match("/\.\./",$path_buffer)) { + $path_buffer=preg_replace("/\/([^\/\.]*)\/..\//","/",$path_buffer); + } + $path_buffer=preg_replace("/\.$/","",$path_buffer); + + } + + } + } + + // This replaces the C pointer assignament + + $result_path = $path_buffer; + if( $result_scheme != '' ) + { + $buffer=$result_scheme; + $buffer.=":"; + } + + if( $result_authority != '' ) + { + $buffer.="//"; + $buffer.=$result_authority; + } + + if( $result_path != '' ) + { + + $buffer.=$result_path; + } + + if( $reference_query != '' ) + { + $buffer.="?"; + $buffer.=$reference_query; + } + + if( $reference_fragment != '' ) + { + $buffer.="#"; + $buffer.=$reference_fragment; + } + } +} + + + +function is_valid_id($id ) +{ + $result = false; + $p = $id; + $p_p=0; + + if( $id != '' ) + { + if( $this->_istalpha( $p ) + || $p{0} == '_' + || $p{0} == ':' ) + { + $result = true; + + while( $result != false && ( $p{++$p_p} != 0 ) ) + { + if( ! ( $this->_istalnum( $p{$p_p} ) + || $p{$p_p} == '.' + || $p{$p_p} == '-' + || $p{$p_p} == '_' + || $p{$p_p} == ':' ) ) + { + $result = false; + } + } + } + } + + return $result; +} + +function _resolve_id($id,&$buffer,$length ) +{ + $id_buffer=''; + + if( $this->is_valid_id( $id ) == true ) + { + $id_buffer="#$id"; + } + else + { + $this->report_warning( "bad ID attribute: ".$id_buffer."#_bad_ID_attribute_"); + } + + $this->_resolve_uri_reference( $this->rdf_parser["base_uri"], $id_buffer, $buffer, $length ); +} + +function _split_name($name, &$buffer, $len,&$namespace_uri, &$local_name ) +{ + + static $nul = 0; + $buffer=$name; + + + + + if( strstr( $buffer, NAMESPACE_SEPARATOR_CHAR ) ) + { + $cosas=explode(NAMESPACE_SEPARATOR_CHAR,$buffer); + $namespace_uri = $cosas[0]; + $local_name = $cosas[1]; + } + else + { + if( ( $buffer{ 0 } == 'x' ) + && ( $buffer{ 1 } == 'm' ) + && ( $buffer{ 2 } == 'l' ) + && ( $buffer{ 3 } == ':' ) ) + { + $namespace_uri = XML_NAMESPACE_URI; + $local_name = substr($buffer,4); + } + else + { + $namespace_uri = ''; + $local_name = $buffer; + } + } + + +} + +function _generate_anonymous_uri(&$buf, $len ) +{ + $id=''; + if(!isset($this->rdf_parser["anonymous_id"])) { + $this->rdf_parser["anonymous_id"]=0; + } + $this->rdf_parser["anonymous_id"]++; + + $id="#genid".$this->rdf_parser["anonymous_id"]; + $this->_resolve_uri_reference( $this->rdf_parser["base_uri"], $id, $buf, $len ); + +} + +function _report_statement( $subject_type, $subject, $predicate, $ordinal, $object_type, $object, $xml_lang, $bag_id, $statements, $statement_id ) +{ + $statement_id_type = RDF_SUBJECT_TYPE_URI; + $statement_id_buffer=''; + $predicate_buffer=''; + + if( $this->rdf_parser["statement_handler"] ) + { + $this->rdf_parser["statement_handler"]($this->rdf_parser["user_data"],$subject_type,$subject,$predicate,$ordinal,$object_type,$object,$xml_lang ); + + if( $bag_id ) + { + if( $statements == '' ) + { + $this->_report_statement(RDF_SUBJECT_TYPE_URI, + $bag_id, + RDF_NAMESPACE_URI.RDF_TYPE, + 0, + RDF_OBJECT_TYPE_RESOURCE, + RDF_NAMESPACE_URI.RDF_BAG, + '', + '', + '', + '' ); + } + + if( ! $statement_id ) + { + $statement_id_type = RDF_SUBJECT_TYPE_ANONYMOUS; + $this->_generate_anonymous_uri( + $statement_id_buffer, + strlen( $statement_id_buffer ) ); + $statement_id = $statement_id_buffer; + } + $statements++; + $predicate_buffer="RDF_NAMESPACE_URI_".$statements; + + $this->_report_statement( + RDF_SUBJECT_TYPE_URI, + $bag_id, + $predicate_buffer, + $statements, + RDF_OBJECT_TYPE_RESOURCE, + $statement_id, + '', + '', + '', + '' ); + } + + if( $statement_id ) + { + // rdf:type = rdf:Statement + $this->_report_statement( + $statement_id_type, + $statement_id, + RDF_NAMESPACE_URI.RDF_TYPE, + 0, + RDF_OBJECT_TYPE_RESOURCE, + RDF_NAMESPACE_URI.RDF_STATEMENT, + '', + '', + '', + '' ); + + // rdf:subject + $this->_report_statement( + $statement_id_type, + $statement_id, + RDF_NAMESPACE_URI.RDF_SUBJECT, + 0, + RDF_OBJECT_TYPE_RESOURCE, + $subject, + '', + '', + '', + '' ); + + // rdf:predicate + $this->_report_statement( + $statement_id_type, + $statement_id, + RDF_NAMESPACE_URI.RDF_PREDICATE, + 0, + RDF_OBJECT_TYPE_RESOURCE, + $predicate, + '', + '', + '', + '' ); + + // rdf:object + $this->_report_statement( + $statement_id_type, + $statement_id, + RDF_NAMESPACE_URI.RDF_OBJECT, + 0, + $object_type, + $object, + '', + '', + '', + '' ); + } + } +} + +function _report_start_parse_type_literal() +{ + if( $this->rdf_parser["start_parse_type_literal_handler"] ) + { + $this->rdf_parser["start_parse_type_literal_handler"]( + $this->rdf_parser["user_data"] ); + } +} + +function _report_end_parse_type_literal() +{ + if( $this->rdf_parser["end_parse_type_literal_handler"] ) + { + $this->rdf_parser["end_parse_type_literal_handler"]( + $this->rdf_parser["user_data"] ); + } +} + +function _handle_property_attributes($subject_type, $subject, $attributes, $xml_lang, $bag_id, $statements ) +{ + $i=0; + + $attribute=''; + $predicate=''; + + $attribute_namespace_uri=''; + $attribute_local_name=''; + $attribute_value=''; + + $ordinal=0; + + for( $i = 0; isset($attributes[ $i ]); $i += 2 ) + { + $this->_split_name( + $attributes[ $i ], + $attribute, + strlen( $attribute ), + $attribute_namespace_uri, + $attribute_local_name ); + + $attribute_value = $attributes[ $i + 1 ]; + + $predicate=$attribute_namespace_uri; + $predicate.=$attribute_local_name; + + if( RDF_NAMESPACE_URI == $attribute_namespace_uri ) + { + if( $this->_is_rdf_property_attribute_literal( $attribute_local_name ) ) + { + $this->_report_statement( + $subject_type, + $subject, + $predicate, + 0, + RDF_OBJECT_TYPE_LITERAL, + $attribute_value, + $xml_lang, + $bag_id, + $statements, + '' ); + } + else if( $this->_is_rdf_property_attribute_resource( $attribute_local_name ) ) + { + $this->_report_statement( + $subject_type, + $subject, + $predicate, + 0, + RDF_OBJECT_TYPE_RESOURCE, + $attribute_value, + '', + $bag_id, + $statements, + '' ); + } + else if( ( $ordinal = $this->_is_rdf_ordinal( $attribute_local_name ) ) != 0 ) + { + $this->_report_statement( + $subject_type, + $subject, + $predicate, + $ordinal, + RDF_OBJECT_TYPE_LITERAL, + $attribute_value, + $xml_lang, + $bag_id, + $statements, + '' ); + } + } + else if( XML_NAMESPACE_URI == $attribute_namespace_uri ) + { + //do nothing + } + else if( $attribute_namespace_uri ) + { + // is it required that property attributes be in an explicit namespace? + + $this->_report_statement( + $subject_type, + $subject, + $predicate, + 0, + RDF_OBJECT_TYPE_LITERAL, + $attribute_value, + $xml_lang, + $bag_id, + $statements, + '' ); + } + } +} + +function _report_start_element( $name, $attributes ) +{ + if( isset($this->rdf_parser["start_element_handler"]) ) + { + $this->rdf_parser["start_element_handler"]( + $this->rdf_parser["user_data"], + $name, + $attributes ); + } +} + +function _report_end_element( $name ) +{ + if( isset($this->rdf_parser["end_element_handler"]) ) + { + $this->rdf_parser["end_element_handler"]( + $this->rdf_parser["user_data"], + $name ); + } +} + +function _report_character_data($s,$len ) +{ + if( isset($this->rdf_parser["character_data_handler"]) ) + { + $this->rdf_parser["character_data_handler"]( + $this->rdf_parser["user_data"], + $s, + $len ); + } +} + +function _report_warning( $warning) +{ + + // rdf_parser->top->state = IN_UNKNOWN; + + if( isset($this->rdf_parser["warning_handler"]) ) + { + $this->rdf_parser["warning_handler"] ( + $warning); + } +} + +function _handle_resource_element( $namespace_uri, $local_name, $attributes, $parent ) +{ + $subjects_found = 0; + $aux=$attributes; + $aux2=Array(); + foreach($attributes as $atkey=>$atvalue) { + $aux2[]=$atkey; + $aux2[]=$atvalue; + } + $attributes=$aux2; + $id = ''; + $about = ''; + $about_each = ''; + $about_each_prefix = ''; + + $bag_id = ''; + + $i=0; + + $attribute=''; + + $attribute_namespace_uri=''; + $attribute_local_name=''; + $attribute_value=''; + + $id_buffer=''; + + $type=''; + + $this->rdf_parser["top"]["has_property_attributes"] = false; + $this->rdf_parser["top"]["has_member_attributes"] = false; + + // examine each attribute for the standard RDF "keywords" + for( $i = 0; isset($attributes[$i]); $i += 2 ) + { + $this->_split_name( + $attributes[ $i ], + $attribute, + strlen( $attribute ), + $attribute_namespace_uri, + $attribute_local_name ); + + $attribute_value = $attributes[ $i + 1 ]; + + // if the attribute is not in any namespace + // or the attribute is in the RDF namespace + if( ( $attribute_namespace_uri == '' ) + || ( $attribute_namespace_uri == RDF_NAMESPACE_URI )) + { + if( $attribute_local_name == RDF_ID ) + { + $id = $attribute_value; + ++$subjects_found; + } + else if( $attribute_local_name == RDF_ABOUT ) + { + $about = $attribute_value; + ++$subjects_found; + } + else if( $attribute_local_name == RDF_ABOUT_EACH ) + { + $about_each = $attribute_value; + ++$subjects_found; + } + else if( $attribute_local_name == RDF_ABOUT_EACH_PREFIX ) + { + $about_each_prefix = $attribute_value; + ++$subjects_found; + } + else if( $attribute_local_name == RDF_BAG_ID) + { + $bag_id = $attribute_value; + } + else if( $this->_is_rdf_property_attribute( $attribute_local_name ) ) + { + $this->rdf_parser["top"]["has_property_attributes"] = true; + } + else if( $this->_is_rdf_ordinal( $attribute_local_name ) ) + { + $this->rdf_parser["top"]["has_property_attributes"] = true; + $this->rdf_parser["top"]["has_member_attributes"] = true; + } + else + { + $this->_report_warning( + "unknown or out of context rdf attribute:".$attribute_local_name ); + } + } + else if( $attribute_namespace_uri == XML_NAMESPACE_URI ) + { + if( $attribute_local_name == XML_LANG ) + { + $this->rdf_parser["top"]["xml_lang"] = $attribute_value; + } + } + else if( $attribute_namespace_uri ) + { + $this->rdf_parser["top"]["has_property_attributes"] = true; + } + } + + // if no subjects were found, generate one. + if( $subjects_found == 0 ) + { + $this->_generate_anonymous_uri( $id_buffer, strlen( $id_buffer ) ); + $this->rdf_parser["top"]["subject"]=$id_buffer; + $this->rdf_parser["top"]["subject_type"] = RDF_SUBJECT_TYPE_ANONYMOUS; + } + else if( $subjects_found > 1 ) + { + $this->_report_warning( + "ID, about, aboutEach, and aboutEachPrefix are mutually exclusive" ); + return; + } + else if( $id ) + { + $this->_resolve_id( $id, $id_buffer, strlen( $id_buffer ) ); + $this->rdf_parser["top"]["subject_type"] = RDF_SUBJECT_TYPE_URI; + $this->rdf_parser["top"]["subject"]=$id_buffer; + } + else if( $about ) + { + $this->_resolve_uri_reference( $this->rdf_parser["base_uri"], $about, $id_buffer, strlen( $id_buffer ) ); + $this->rdf_parser["top"]["subject_type"] = RDF_SUBJECT_TYPE_URI; + $this->rdf_parser["top"]["subject"]=$id_buffer; + } + else if( $about_each ) + { + $this->rdf_parser["top"]["subject_type"] = RDF_SUBJECT_TYPE_DISTRIBUTED; + $this->rdf_parser["top"]["subject"]=$about_each; + } + else if( $about_each_prefix ) + { + $this->rdf_parser["top"]["subject_type"] = RDF_SUBJECT_TYPE_PREFIX; + $this->rdf_parser["top"]["subject"]=$about_each_prefix; + } + + // if the subject is empty, assign it the document uri + if( $this->rdf_parser["top"]["subject"] == '' ) + { + $len = 0; + + $this->rdf_parser["top"]["subject"]=$this->rdf_parser["base_uri"]; + + // now remove the trailing '#' + + $len = strlen( $this->rdf_parser["top"]["subject"]); + + if( $len > 0 ) + { + //$rdf_parser["top"]["subject"][" len - 1 "] = 0; + } + } + + if( $bag_id ) + { + $this->_resolve_id( $bag_id, $id_buffer, strlen( $id_buffer ) ); + $this->rdf_parser["top"]["bag_id"]=$id_buffer; + } + + // only report the type for non-rdf:Description elements. + if( ($local_name != RDF_DESCRIPTION ) + || ( $namespace_uri != RDF_NAMESPACE_URI ) ) + { + $type=$namespace_uri; + $type.=$local_name; + + $this->_report_statement( + $this->rdf_parser["top"]["subject_type"], + $this->rdf_parser["top"]["subject"], + RDF_NAMESPACE_URI.RDF_TYPE, + 0, + RDF_OBJECT_TYPE_RESOURCE, + $type, + '', + $this->rdf_parser["top"]["bag_id"], + $this->rdf_parser["top"]["statements"], + '' ); + + } + + // if this element is the child of some property, + // report the appropriate statement. + if( $parent ) + { + $this->_report_statement( + $parent["parent"]["subject_type"], + $parent["parent"]["subject"], + $parent["predicate"], + $parent["ordinal"], + RDF_OBJECT_TYPE_RESOURCE, + $this->rdf_parser["top"]["subject"], + '', + $parent["parent"]["bag_id"], + $parent["parent"]["statements"], + $parent["statement_id"] ); + + } + + if( $this->rdf_parser["top"]["has_property_attributes"] ) + { + $this->_handle_property_attributes( + $this->rdf_parser["top"]["subject_type"], + $this->rdf_parser["top"]["subject"], + $attributes, + $this->rdf_parser["top"]["xml_lang"], + $this->rdf_parser["top"]["bag_id"], + $this->rdf_parser["top"]["statements"] ); + } +} + +function _handle_property_element( &$namespace_uri, &$local_name, &$attributes ) +{ + $buffer=''; + + $i=0; + + $aux=$attributes; + $aux2=Array(); + foreach($attributes as $atkey=>$atvalue) { + $aux2[]=$atkey; + $aux2[]=$atvalue; + } + $attributes=$aux2; + + $attribute_namespace_uri=''; + $attribute_local_name=''; + $attribute_value = ''; + + $resource = ''; + $statement_id = ''; + $bag_id = ''; + $parse_type = ''; + + $this->rdf_parser["top"]["ordinal"] = 0; + + if( $namespace_uri == RDF_NAMESPACE_URI ) + { + if( ($this->rdf_parser["top"]["ordinal"] = ( $this->_is_rdf_ordinal( $local_name ) ) != 0 ) ) + { + if( $this->rdf_parser["top"]["ordinal"] > $this->rdf_parser["top"]["parent"]["members"] ) + { + $this->rdf_parser["top"]["parent"]["members"] = $this->rdf_parser["top"]["ordinal"]; + } + } + else if( ! $this->_is_rdf_property_element( $local_name ) ) + { + $this->_report_warning( + "unknown or out of context rdf property element: ".$local_name ); + return; + } + } + + $buffer=$namespace_uri; + + if( ( $namespace_uri == RDF_NAMESPACE_URI ) + && ( $local_name == RDF_LI ) ) + { + //$ordinal=''; + $this->rdf_parser["top"]["parent"]["members"]++; + $this->rdf_parser["top"]["ordinal"] = $this->rdf_parser["top"]["parent"]["members"]; + + + $this->rdf_parser["top"]["ordinal"]=$this->rdf_parser["top"]["ordinal"]; + //$ordinal{ 0 } = '_' ; + + $buffer.='_'.$this->rdf_parser["top"]["ordinal"]; + } + else + { + $buffer.=$local_name; + } + + $this->rdf_parser["top"]["predicate"]=$buffer; + + $this->rdf_parser["top"]["has_property_attributes"] = false; + $this->rdf_parser["top"]["has_member_attributes"] = false; + + for( $i = 0; isset($attributes[$i]); $i += 2 ) + { + $this->_split_name( + $attributes[$i], + $buffer, + strlen( $buffer ), + $attribute_namespace_uri, + $attribute_local_name ); + + $attribute_value = $attributes[$i + 1]; + + // if the attribute is not in any namespace + // or the attribute is in the RDF namespace + if( ( $attribute_namespace_uri == '' ) + || ( $attribute_namespace_uri == RDF_NAMESPACE_URI ) ) + { + if( ( $attribute_local_name == RDF_ID ) ) + { + $statement_id = $attribute_value; + } + else if( $attribute_local_name == RDF_PARSE_TYPE ) + { + $parse_type = $attribute_value; + } + else if( $attribute_local_name == RDF_RESOURCE ) + { + $resource = $attribute_value; + } + else if( $attribute_local_name == RDF_BAG_ID ) + { + $bag_id = $attribute_value; + } + else if( $this->_is_rdf_property_attribute( $attribute_local_name ) ) + { + $this->rdf_parser["top"]["has_property_attributes"] = true; + } + else + { + $this->_report_warning( + "unknown rdf attribute: ".$attribute_local_name ); + return; + } + } + else if( $attribute_namespace_uri == XML_NAMESPACE_URI ) + { + if( $attribute_local_name == XML_LANG ) + { + $this->rdf_parser["top"]["xml_lang"] = $attribute_value; + } + } + else if( $attribute_namespace_uri ) + { + $this->rdf_parser["top"]["has_property_attributes"] = true; + } + } + + // this isn't allowed by the M&S but I think it should be + if( $statement_id && $resource ) + { + $this->_report_warning( + "rdf:ID and rdf:resource are mutually exclusive" ); + return; + } + + if( $statement_id ) + { + $this->_resolve_id($statement_id, $buffer, strlen( $buffer ) ); + $this->rdf_parser["top"]["statement_id"]=$buffer; + } + + if( $parse_type ) + { + if( $resource ) + { + $this->_report_warning( + "property elements with rdf:parseType do not allow rdf:resource" ); + return; + } + + if( $bag_id ) + { + $this->_report_warning( + "property elements with rdf:parseType do not allow rdf:bagID" ); + return; + } + + if( $this->rdf_parser["top"]["has_property_attributes"] ) + { + $this->_report_warning( + "property elements with rdf:parseType do not allow property attributes"); + return; + } + + if( $attribute_value == RDF_PARSE_TYPE_RESOURCE ) + { + $this->_generate_anonymous_uri( $buffer, strlen( $buffer ) ); + + // since we are sure that this is now a resource property we can report it + $this->_report_statement( + $this->rdf_parser["top"]["parent"]["subject_type"], + $this->rdf_parser["top"]["parent"]["subject"], + $this->rdf_parser["top"]["predicate"], + 0, + RDF_OBJECT_TYPE_RESOURCE, + $buffer, + '', + $this->rdf_parser["top"]["parent"]["bag_id"], + $this->rdf_parser["top"]["parent"]["statements"], + $statement_id ); + + $this->_push_element( ); + + $this->rdf_parser["top"]["state"] = IN_PROPERTY_PARSE_TYPE_RESOURCE; + $this->rdf_parser["top"]["subject_type"] = RDF_SUBJECT_TYPE_ANONYMOUS; + $this->rdf_parser["top"]["subject"]=$buffer; + $this->rdf_parser["top"]["bag_id"]=''; + } + else + { + $this->_report_statement( + $this->rdf_parser["top"]["parent"]["subject_type"], + $this->rdf_parser["top"]["parent"]["subject"], + $this->rdf_parser["top"]["predicate"], + 0, + RDF_OBJECT_TYPE_XML, + '', + '', + $this->rdf_parser["top"]["parent"]["bag_id"], + $this->rdf_parser["top"]["parent"]["statements"], + $statement_id ); + + $this->rdf_parser["top"]["state"] = IN_PROPERTY_PARSE_TYPE_LITERAL; + $this->_report_start_parse_type_literal(); + } + } + else if( $resource || $bag_id || $this->rdf_parser["top"]["has_property_attributes"] ) + { + + + if( $resource != '' ) + { + $subject_type = RDF_SUBJECT_TYPE_URI; + $this->_resolve_uri_reference( $this->rdf_parser["base_uri"], $resource, $buffer, strlen( $buffer ) ); + } + else + { + $subject_type = RDF_SUBJECT_TYPE_ANONYMOUS; + $this->_generate_anonymous_uri( buffer, strlen( $buffer ) ); + } + + $this->rdf_parser["top"]["state"] = IN_PROPERTY_EMPTY_RESOURCE; + + // since we are sure that this is now a resource property we can report it. + $this->_report_statement( + $this->rdf_parser["top"]["parent"]["subject_type"], + $this->rdf_parser["top"]["parent"]["subject"], + $this->rdf_parser["top"]["predicate"], + $this->rdf_parser["top"]["ordinal"], + RDF_OBJECT_TYPE_RESOURCE, + $buffer, + '', + $this->rdf_parser["top"]["parent"]["bag_id"], + $this->rdf_parser["top"]["parent"]["statements"], + '' ); // should we allow IDs? + + if( $bag_id ) + { + $this->_resolve_id( $bag_id, $buffer, strlen( $buffer ) ); + $this->rdf_parser["top"]["bag_id"]=$buffer; + } + + if( $this->rdf_parser["top"]["has_property_attributes"] ) + { + $this->_handle_property_attributes( + $subject_type, + $buffer, + $attributes, + $this->rdf_parser["top"]["xml_lang"], + $this->rdf_parser["top"]["bag_id"], + $this->rdf_parser["top"]["statements"] ); + } + } +} + + +function _start_element_handler($parser, $name, $attributes ) +{ + + + $buffer=''; + + $namespace_uri=''; + $local_name=''; + +/* + if( rdf_parser->top != '' && rdf_parser->top->state != IN_TOP_LEVEL ) + { + ++rdf_parser->anonymous_id; + } +*/ + + $this->_push_element(); + + + $this->_split_name( + $name, + $buffer, + strlen( $buffer ), + $namespace_uri, + $local_name ); + + switch( $this->rdf_parser["top"]["state"] ) + { + case IN_TOP_LEVEL: + if( RDF_NAMESPACE_URI.NAMESPACE_SEPARATOR_STRING.RDF_RDF == $name ) + { + $this->rdf_parser["top"]["state"] = IN_RDF; + } + else + { + $this->_report_start_element( $name, $attributes ); + } + break; + case IN_RDF: + $this->rdf_parser["top"]["state"] = IN_DESCRIPTION; + $this->_handle_resource_element( $namespace_uri, $local_name, $attributes, '' ); + break; + case IN_DESCRIPTION: + case IN_PROPERTY_PARSE_TYPE_RESOURCE: + $this->rdf_parser["top"]["state"] = IN_PROPERTY_UNKNOWN_OBJECT; + $this->_handle_property_element( $namespace_uri, $local_name, $attributes ); + break; + case IN_PROPERTY_UNKNOWN_OBJECT: + /* if we're in a property with an unknown object type and we encounter + an element, the object must be a resource, */ + $this->rdf_parser["top"]["data"]=''; + $this->rdf_parser["top"]["parent"]["state"] = IN_PROPERTY_RESOURCE; + $this->rdf_parser["top"]["state"] = IN_DESCRIPTION; + $this->_handle_resource_element( + $namespace_uri, + $local_name, + $attributes, + $this->rdf_parser["top"]["parent"] ); + break; + case IN_PROPERTY_LITERAL: + $this->_report_warning( "no markup allowed in literals" ); + break; + case IN_PROPERTY_PARSE_TYPE_LITERAL: + $this->rdf_parser["top"]["state"] = IN_XML; + /* fall through */ + case IN_XML: + $this->_report_start_element( $name, $attributes ); + break; + case IN_PROPERTY_RESOURCE: + $this->_report_warning( + "only one element allowed inside a property element" ); + break; + case IN_PROPERTY_EMPTY_RESOURCE: + $this->_report_warning( + "no content allowed in property with rdf:resource, rdf:bagID, or property attributes" ); + break; + case IN_UNKNOWN: + break; + } +} + +/* + this is only called when we're in the IN_PROPERTY_UNKNOWN_OBJECT state. + the only time we won't know what type of object a statement has is + when we encounter property statements without property attributes or + content: + + + + + + notice that the state doesn't switch to IN_PROPERTY_LITERAL when + there is only whitespace between the start and end tags. this isn't + a very useful statement since the object is anonymous and can't + have any statements with it as the subject but it is allowed. +*/ + +function _end_empty_resource_property() +{ + $buffer=''; + + $this->_generate_anonymous_uri($buffer, strlen( $buffer ) ); + + $this->_report_statement( + $this->rdf_parser["top"]["parent"]["subject_type"], + $this->rdf_parser["top"]["parent"]["subject"], + $this->rdf_parser["top"]["predicate"], + $this->rdf_parser["top"]["ordinal"], + RDF_OBJECT_TYPE_RESOURCE, + $buffer, + $this->rdf_parser["top"]["xml_lang"], + $this->rdf_parser["top"]["parent"]["bag_id"], + $this->rdf_parser["top"]["parent"]["statements"], + $this->rdf_parser["top"]["statement_id"] ); +} + +/* + property elements with text only as content set the state to + IN_PROPERTY_LITERAL. as character data is received from expat, + it is saved in a buffer and reported when the end tag is + received. +*/ +function _end_literal_property() +{ + if(!isset($this->rdf_parser["top"]["statement_id"])) { + $this->rdf_parser["top"]["statement_id"]=''; + } + if(!isset($this->rdf_parser["top"]["parent"]["subject_type"])) { + $this->rdf_parser["top"]["parent"]["subject_type"]=''; + } + if(!isset($this->rdf_parser["top"]["parent"]["subject"])) { + $this->rdf_parser["top"]["parent"]["subject"]=''; + } + if(!isset($this->rdf_parser["top"]["parent"]["bag_id"])) { + $this->rdf_parser["top"]["parent"]["bag_id"]=''; + } + if(!isset($this->rdf_parser["top"]["parent"]["statements"])) { + $this->rdf_parser["top"]["parent"]["statements"]=0; + } + if(!isset($this->rdf_parser["top"]["predicate"])) { + $this->rdf_parser["top"]["predicate"]=''; + } + if(!isset($this->rdf_parser["top"]["ordinal"])) { + $this->rdf_parser["top"]["ordinal"]=0; + } + $this->_report_statement( + $this->rdf_parser["top"]["parent"]["subject_type"], + $this->rdf_parser["top"]["parent"]["subject"], + $this->rdf_parser["top"]["predicate"], + $this->rdf_parser["top"]["ordinal"], + RDF_OBJECT_TYPE_LITERAL, + $this->rdf_parser["top"]["data"], + $this->rdf_parser["top"]["xml_lang"], + $this->rdf_parser["top"]["parent"]["bag_id"], + $this->rdf_parser["top"]["parent"]["statements"], + $this->rdf_parser["top"]["statement_id"] ); +} + +function _end_element_handler( $parser, $name ) +{ + + + switch( $this->rdf_parser["top"]["state"] ) + { + case IN_TOP_LEVEL: + /* fall through */ + case IN_XML: + $this->_report_end_element( $name ); + break; + case IN_PROPERTY_UNKNOWN_OBJECT: + $this->_end_empty_resource_property(); + break; + case IN_PROPERTY_LITERAL: + $this->_end_literal_property( ); + break; + case IN_PROPERTY_PARSE_TYPE_RESOURCE: + $this->_pop_element( ); + break; + case IN_PROPERTY_PARSE_TYPE_LITERAL: + $this->_report_end_parse_type_literal(); + break; + case IN_RDF: + case IN_DESCRIPTION: + case IN_PROPERTY_RESOURCE: + case IN_PROPERTY_EMPTY_RESOURCE: + case IN_UNKNOWN: + break; + } + + $this->_pop_element(); +} + +function _character_data_handler( $parser,$s) +{ + $len=strlen($s); + switch( $this->rdf_parser["top"]["state"] ) + { + case IN_PROPERTY_LITERAL: + case IN_PROPERTY_UNKNOWN_OBJECT: + if( isset($this->rdf_parser["top"]["data"]) ) + { + $n = strlen( $this->rdf_parser["top"]["data"] ); + $this->rdf_parser["top"]["data"].= $s; + + } + else + { + $this->rdf_parser["top"]["data"]=$s; + } + + if( $this->rdf_parser["top"]["state"] == IN_PROPERTY_UNKNOWN_OBJECT ) + { + /* look for non-whitespace */ + for( $i = 0; (( $i < $len ) && ( ereg(" |\n|\t",$s{ $i }) )); $i++ ); + $i++; + /* if we found non-whitespace, this is a literal */ + if( $i < $len ) + { + $this->rdf_parser["top"]["state"] = IN_PROPERTY_LITERAL; + } + } + + break; + case IN_TOP_LEVEL: + case IN_PROPERTY_PARSE_TYPE_LITERAL: + case IN_XML: + $this->_report_character_data( + $s, + strlen($s) ); + break; + case IN_RDF: + case IN_DESCRIPTION: + case IN_PROPERTY_RESOURCE: + case IN_PROPERTY_EMPTY_RESOURCE: + case IN_PROPERTY_PARSE_TYPE_RESOURCE: + case IN_UNKNOWN: + break; + } +} + +/* public functions */ + + +function rdf_parser_create( $encoding ) +{ + + $parser = xml_parser_create_ns( $encoding, NAMESPACE_SEPARATOR_CHAR ); + xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,0); + $this->rdf_parser["xml_parser"] = $parser; + + xml_set_object($this->rdf_parser["xml_parser"], $this); + xml_set_element_handler( $this->rdf_parser["xml_parser"], "_start_element_handler", "_end_element_handler" ); + xml_set_character_data_handler( $this->rdf_parser["xml_parser"], "_character_data_handler" ); + + return $this->rdf_parser; +} + +function rdf_parser_free( ) +{ + $z=3; +// xml_parser_free( $this->rdf_parser["xml_parser"] ); + + $this->rdf_parser["base_uri"]=''; + + $this->_delete_elements( $this->rdf_parser ); + + unset( $this->rdf_parser ); +} + +function rdf_set_user_data( &$user_data ) +{ + $this->rdf_parser["user_data"] = &$user_data; +} + +function rdf_get_user_data( ) +{ + return ( $this->rdf_parser["$user_data"] ); +} + +function rdf_set_statement_handler($handler ) +{ + $this->rdf_parser["statement_handler"] = $handler; +} + +function rdf_set_parse_type_literal_handler($start,$end ) +{ + $this->rdf_parser["start_parse_type_literal_handler"] = $start; + $this->rdf_parser["end_parse_type_literal_handler"] = $end; +} + +function rdf_set_element_handler($start,$end) +{ + $this->rdf_parser["_start_element_handler"] = $start; + $this->rdf_parser["_end_element_handler"] = $end; +} + +function rdf_set_character_data_handler( $handler) +{ + $this->rdf_parser["_character_data_handler"] = $handler; +} + +function rdf_set_warning_handler($handler ) +{ + $this->rdf_parser["warning_handler"] = $handler; +} + +function rdf_parse( $s, $len, $is_final ) +{ + return XML_Parse( $this->rdf_parser["xml_parser"], $s, $is_final ); +} + +function rdf_get_xml_parser() +{ + return ( $this->rdf_parser["xml_parser"]); +} + +function rdf_set_base($base ) +{ + + //tcscpy( buffer, base ); + +/* + if( buffer[" tcslen( buffer ) - 1 "] != T( '#' ) ) + { + tcscat( buffer, T( "#" ) ); + } +*/ + + /* check for out of memory */ + $this->rdf_parser["base_uri"]=$base; + + return 0; +} + +function rdf_get_base() +{ + return $this->rdf_parser["base_uri"]; +} + +function rdf_resolve_uri($uri_reference,&$buffer) +{ + _resolve_uri_reference( $this->rdf_parser["base_uri"], $uri_reference, $buffer, strlen($buffer) ); +} + +} + + + + + + + + + +} +?> \ No newline at end of file diff --git a/mozilla/webtools/update/developers/additem.php b/mozilla/webtools/update/developers/additem.php index 67ba6434bfc..44559c13cf6 100755 --- a/mozilla/webtools/update/developers/additem.php +++ b/mozilla/webtools/update/developers/additem.php @@ -10,6 +10,7 @@ $function = $_GET["function"]; (.*?)<\/em:id>/", $buf, $matches); -$manifestdata["id"]=$matches[1]; +if(is_null($manifestdata)) { + echo"Errors were encountered during install.rdf parsing...
\n"; + die("Aborting..."); +} -// em:version -preg_match("/(.*?)<\/em:version>/", $buf, $matches); -$manifestdata["version"]=$matches[1]; - -//em:targetApplication -preg_match_all("/(.*?)<\/em:targetApplication>/s", $buf, $matches); -//echo"
";
-//print_r($buf);
-//print_r($matches);
-//echo"
"; - foreach ($matches[0] as $targetapp ) { - //em:targetApplication --> em:id - preg_match("/(.*?)<\/em:id>/", $targetapp, $matches); - $i = $matches[1]; - $manifestdata["targetapplication"][$i]["id"]=$matches[1]; - - //em:targetApplication --> em:minVersion - preg_match("/(.*?)<\/em:minVersion>/", $targetapp, $matches); - $manifestdata["targetapplication"][$i]["minversion"]=$matches[1]; - - //em:targetApplication --> em:maxVersion - preg_match("/(.*?)<\/em:maxVersion>/", $targetapp, $matches); - $manifestdata["targetapplication"][$i]["maxversion"]=$matches[1]; +// this is a temporary function +// until we support multiple locales for +// name / description +function default_l10n($array) +{ + if($array["en-US"]) { + return $array["en-US"]; + } + else { + foreach($array as $val) { + return $val; + } } -//em:name -preg_match("/(.*?)<\/em:name>/", $buf, $matches); -$manifestdata["name"]=$matches[1]; - -//em:description -preg_match("/(.*?)<\/em:description>/", $buf, $matches); -$manifestdata["description"]=$matches[1]; - -//em:homepageURL -preg_match("/(.*?)<\/em:homepageURL>/", $buf, $matches); -$manifestdata["homepageurl"]=$matches[1]; - + return ""; +} //echo"

Adding Extension... Checking file...

\n"; //echo"
"; print_r($manifestdata); echo"
\n"; //Populate Form Variables from manifestdata. -$id = $manifestdata[id]; -$name = $manifestdata[name]; -$version = $manifestdata[version]; -$homepage = $manifestdata[homepageurl]; -$description = $manifestdata[description]; +$id = $manifestdata["id"]; +$version = $manifestdata["version"]; +$homepage = $manifestdata["homepageURL"]; +// $names, $descriptions are arrays keyed by locale +$names = $manifestdata["name"]; +$descriptions = $manifestdata["description"]; +//TODO: support multiple locale names/descriptions +// right now we just use en-US or the first one +$name = default_l10n($names); +$description = default_l10n($descriptions); //Check GUID for validity/existance, if it exists, check the logged in author for permission $sql = "SELECT ID, GUID from `main` WHERE `GUID` = '".escape_string($manifestdata[id])."' LIMIT 1"; @@ -179,37 +165,36 @@ if ($_POST["legacy"]=="TRUE") { } //Verify MinAppVer and MaxAppVer per app for validity, if they're invalid, reject the file. -if ($_POST["legacy"]=="TRUE" AND !$manifestdata[targetapplication]) {$manifestdata[targetapplication]=array(); } -foreach ($manifestdata[targetapplication] as $key=>$val) { -//echo"$key -- $val[minversion] $val[maxversion]
\n"; - +if ($_POST["legacy"]=="TRUE" AND !$manifestdata["targetApplication"]) {$manifestdata["targetApplication"]=array(); } +foreach ($manifestdata["targetApplication"] as $key=>$val) { +$esckey = escape_string($key); $i=0; - $sql = "SELECT `AppName`, `major`, `minor`, `release`, `SubVer` FROM `applications` WHERE `GUID`='$key' ORDER BY `major` DESC, `minor` DESC, `release` DESC, `SubVer` DESC"; + $sql = "SELECT `AppName`, `major`, `minor`, `release`, `SubVer` FROM `applications` WHERE `GUID`='$esckey' ORDER BY `major` DESC, `minor` DESC, `release` DESC, `SubVer` DESC"; $sql_result = mysql_query($sql, $connection) or trigger_error("MySQL Error ".mysql_errno().": ".mysql_error()."", E_USER_NOTICE); while ($row = mysql_fetch_array($sql_result)) { $i++; $appname = $row["AppName"]; $subver = $row["SubVer"]; - $release = "$row[major].$row[minor]"; - if ($row["release"]) {$release = "$release.$row[release]";} + $release = $row["major"] . "." . $row["minor"]; + if ($row["release"]) {$release = "$release." . $row["release"];} if ($subver !=="final") {$release="$release$subver";} - if ($release == $val[minversion]) { $versioncheck[$key][minversion_valid] = "true"; } - if ($release == $val[maxversion]) { $versioncheck[$key][maxversion_valid] = "true"; } + if ($release == $val["minVersion"]) { $versioncheck[$key]["minVersion_valid"] = "true"; } + if ($release == $val["maxVersion"]) { $versioncheck[$key]["maxVersion_valid"] = "true"; } } - if (!$versioncheck[$key][minversion_valid]) { - $versioncheck[$key][minversion_valid]="false"; - echo"Error! The MinAppVer for $appname of $val[minversion] in install.rdf is invalid.
\n"; - $versioncheck[errors]="true"; + if (!$versioncheck[$key]["minVersion_valid"]) { + $versioncheck[$key]["minVersion_valid"]="false"; + echo"Error! The MinAppVer for $appname of " . $val["minVersion"] . " in install.rdf is invalid.
\n"; + $versioncheck["errors"]="true"; } - if (!$versioncheck[$key][maxversion_valid]) { - $versioncheck[$key][maxversion_valid]="false"; - echo"Error! The MaxAppVer for $appname of $val[maxversion] in install.rdf is invalid.
\n"; - $versioncheck[errors]="true"; + if (!$versioncheck[$key]["maxVersion_valid"]) { + $versioncheck[$key]["maxVersion_valid"]="false"; + echo"Error! The MaxAppVer for $appname of ". $val["maxVersion"] . " in install.rdf is invalid.
\n"; + $versioncheck["errors"]="true"; } } -if ($versioncheck[errors]=="true") { +if ($versioncheck["errors"]=="true") { echo"Errors were encountered during install.rdf checking...
\n"; die("Aborting..."); } else { @@ -310,7 +295,6 @@ if (!$categories) {$categories = array(); } "> Name* " SIZE=45 MAXLENGTH=100> - Target Application(s):$appname "; -if (($mode=="new" or $mode=="update") and (strtolower($appname) !="mozilla" or $manifestdata["targetapplication"]["$mozguid"])) { +if (($mode=="new" or $mode=="update") and (strtolower($appname) !="mozilla" or $manifestdata["targetApplication"]["$mozguid"])) { //Based on Extension Manifest (New Mode) if ($minappver and $maxappver) { echo"$minappver - $maxappver\n"; diff --git a/mozilla/webtools/update/developers/parse_install_manifest.php b/mozilla/webtools/update/developers/parse_install_manifest.php new file mode 100644 index 00000000000..f805e35bdb7 --- /dev/null +++ b/mozilla/webtools/update/developers/parse_install_manifest.php @@ -0,0 +1,91 @@ +1, "version"=>1, "creator"=>1, "homepageURL"=>1, "updateURL"=>1); +// ignoring File +$multiprops = array("contributor"=>1, "targetApplication"=>1, "requires"=>1); +// these properties are localizable +$l10nprops = array("name"=>1, "description"=>1); + +function parse_install_manifest( $manifestdata ) { + +$data = array(); + +$rdf=new Rdf_parser(); +$rdf->rdf_parser_create( NULL ); +$rdf->rdf_set_user_data( $data ); +$rdf->rdf_set_statement_handler( "mf_statement_handler" ); +$rdf->rdf_set_base(""); + +if ( ! $rdf->rdf_parse( $manifestdata, strlen($manifestdata), true ) ) { + return null; +} + +// now set the targetApplication data for real +$tarray = array(); +if(is_array($data["manifest"]["targetApplication"])) { + foreach($data["manifest"]["targetApplication"] as $ta) { + $id = $data[$ta][EM_NS . "id"]; + $minVer = $data[$ta][EM_NS . "minVersion"]; + $maxVer = $data[$ta][EM_NS . "maxVersion"]; + $tarray[$id]["minVersion"] = $minVer; + $tarray[$id]["maxVersion"] = $maxVer; + } +} +$data["manifest"]["targetApplication"] = $tarray; +$rdf->rdf_parser_free(); + +return $data["manifest"]; +} + +function mf_statement_handler( + &$data, + $subject_type, + $subject, + $predicate, + $ordinal, + $object_type, + $object, + $xml_lang ) +{ + global $singleprops, $multiprops, $l10nprops; + + // look for props on the install manifest itself + if($subject == MF_RES) { + // we're only really interested in EM props + $l = strlen(EM_NS); + if(strncmp($predicate,EM_NS,$l) == 0) { + $prop = substr($predicate,$l,strlen($predicate)-$l); + + if($singleprops[$prop]) { + $data["manifest"][$prop] = $object; + } + elseif($multiprops[$prop]) { + $data["manifest"][$prop][] = $object; + } + elseif($l10nprops[$prop]) { + // handling these separately + // so we can handle multiple languages + if($xml_lang) { + $lang = $xml_lang; + } + else { + // default to en-US + $lang = "en-US"; + } + $data["manifest"][$prop][$lang] = $object; + } + } + } + else { + // just save it, probably a targetApplication or something + // shouldn't ever have multiple targets, doesn't matter + $data[$subject][$predicate] = $object; + } +} + +?>