<?php
/**
* Accepts XML data and generates {@link stickleback_Descriptor} objects
* * @package stickleback
*
* Copyright (c) 2007 Yahoo! Inc. All rights reserved.
* The copyrights embodied in the content of this file are licensed under the BSD
* open source license
*
* @subpackage plugin
* @author Matt Zandstra <hide@address.com>
* @version CVS: $Id: PluginXml.php,v 1.21 2009-04-03 23:44:02 zandstra Exp $
*/
/**
* requires
*/
//require_once("stickleback/PluginRegistry.php");
require_once("stickleback/Exception.php");
require_once("stickleback/Logger.php");
require_once("stickleback/PluginDescriptor.php");
require_once("stickleback/ExtensionPointDescriptor.php");
require_once("stickleback/plugins/sbplug/Null.php");
//require_once("stickleback/FSPluginObserver.php");
/**
* Reads a plugin on the filesystem and constructs descriptor objects
*
* @package stickleback
* @subpackage plugin
* @author Matt Zandstra <hide@address.com>
* @version CVS: $Id: PluginXml.php,v 1.21 2009-04-03 23:44:02 zandstra Exp $
*/
class stickleback_PluginXml {
function __construct() {
}
function readFile( $xmlfile ) {
//print "loading $xmlfile\n";
if ( ! file_exists( $xmlfile ) ) {
return ( array() );
}
$this->ensure( $xml = simplexml_load_file( $xmlfile ), "unable to parse XML file: '$xmlfile'" );
return $this->handleXML( $xml );
}
function readString( $str ) {
$this->ensure( $xml = simplexml_load_string( $str ), "unable to parse XML string" );
return $this->handleXML( $xml );
}
private function handleXML( SimpleXmlElement $xml ) {
$nsurl = 'http://developer.yahoo.com/xmlns/stickleback/sbconfig';
$atts = $this->getAtts( $xml );
$this->ensure( isset( $atts['name'] ), '\'name\' is a required attribute of \'pluginset\'' );
$pset_name = $atts['name'];
$default_found = false;
$names = array();
$types = array();
foreach ( $xml->children( $nsurl ) as $key => $plugin_el ) {
if ( $key != "plugin" ) { continue; }
$atts = $this->getAtts( $plugin_el );
$plugin_name = isset($atts['name'])?$atts['name']:$pset_name;
$plugin_status = isset($atts['status'])?$atts['status']:null;
$type = isset($atts['type'])?$atts['type']:"sbplug_Null";
L::debug("default found for '$plugin_name'");
if ( $plugin_name == $pset_name ) {
$default_found = true;
}
L::debug("checking plugin '$plugin_name'");
$this->ensure( (! isset( $names[$plugin_name]) ), "duplicate plugin '$plugin_name' found" );
$names[$plugin_name]=1;
$offers = array();
$honors = array();
$wild_honors = array();
$depends = array();
$params = array();
$param_parent = null;
foreach ( $plugin_el->children() as $child_key => $child_el ) {
$atts = $this->getAtts( $child_el );
if ( $child_key == 'offers' ) {
$wcard = false;
$this->ensure( isset( $atts['epoint'] ), "'epoint' attribute is required for 'offers' element" );
$epoint = (string)$atts['epoint'];
if ( isset( $offers[$epoint] ) ) {
throw new Exception("duplicate extension point: $epoint");
}
if ( isset( $atts['acceptwildcards'] ) ) {
$wcardable = (string)$atts['acceptwildcards'];
if ( $wcardable == "yes" ) {
$wcard=true;
}
}
$wcgroups = array();
if ( isset( $atts['wcgroup'] ) ) {
$ep_alias = (string)$atts['wcgroup'];
$wcgroups=explode(',', $ep_alias );
}
$offers[$epoint] = array( $wcard, $wcgroups );
}
if ( $child_key == 'honors' ) {
$this->ensure( isset($atts['plugin']), "'plugin' attribute is required for 'honors' element" );
$this->ensure( isset($atts['epoint']), "'epoint' attribute is required for 'honors' element" );
$honors_plugin=(string)$atts['plugin'];
$honors_epoint=(string)$atts['epoint'];
$honors_alias = $honors_epoint;
if ( isset( $atts['wcgroup'] ) ) {
$honors_alias=(string)$atts['wcgroup'];
}
if ( $honors_plugin=='*' ) {
$wild_honors[] = "{$honors_alias}.{$honors_epoint}";
} else {
$honors[] = "{$honors_plugin}.{$honors_epoint}";
}
}
if ( $child_key == 'depends' ) {
$this->ensure( isset($atts['plugin']), "'plugin' attribute is required for 'depends' element" );
$depends[] = (string)$atts['plugin'];
}
if ( $child_key == 'inherit' ) {
$this->ensure( isset($atts['axis']), "'axis' attribute is required for 'inherit' element" );
$this->ensure( isset($atts['plugin']), "'plugin' attribute is required for 'inherit' element" );
if ( (string)$atts['axis'] == 'param' ) {
$param_parent = (string)$atts['plugin'];
}
}
if ( $child_key == 'param' ) {
$this->ensure( isset($atts['name']), "'name' attribute is required for 'param' element" );
$this->ensure( isset($atts['value']), "'value' attribute is required for 'param' element" );
if( substr( $atts['name'], -2 ) === "[]" ) {
$atts['name'] = substr( $atts['name'], 0, -2 );
if ( !isset ( $params[$atts['name']] ) ) {
$params[$atts['name']] = array();
}
}
if ( isset ( $params[$atts['name']] ) ) {
$storedval = $params[$atts['name']];
if ( is_array( $storedval ) ) {
$params[$atts['name']][] = $atts['value'];
} else {
$params[$atts['name']] = array( $storedval, $atts['value'] );
}
} else {
$params[$atts['name']] = $atts['value'];
}
}
}
$ret = new stickleback_PluginDescriptor( $plugin_name, $type, $honors, $params, $wild_honors );
if ( ! is_null( $plugin_status ) ) {
$ret->setFallback();
}
if ( ! is_null( $param_parent ) ) {
$ret->setParamParentName( $param_parent );
}
$ret->setDepends( $depends );
foreach ( $offers as $epoint => $offers_info ) {
$extdesc = new stickleback_ExtensionPointDescriptor( $ret, $epoint, $offers_info[1] ); // automatically added
/*
if ( $plugin_name=="testplugin" && $offers_info[0] ) {
print_r( $extdesc );
}
*/
$extdesc->setAcceptsWildcards( $offers_info[0] );
}
$descriptors[] = $ret;
}
$this->ensure( $default_found, "No default plug-in found for pluginset: $pset_name" );
return $descriptors;
}
private function getAtts( SimpleXmlElement $el ) {
$atts = array();
foreach ( $el->attributes() as $attkey => $attval ) {
L::debug("setting '$attkey' to '$attval'");
$atts[$attkey] = (string)$attval;
}
return $atts;
}
private function ensure( $bool, $msg ) {
if ( ! $bool ) { throw new stickleback_Exception( $msg ); }
}
}
?>