コード例 #1
0
ファイル: TypeOf.class.php プロジェクト: xp-forge/match
 /**
  * Invoke match. Returns the handler's result for the first condition to 
  * match the given value. If no condition matched and no default handler
  * was installed, an exception is raised.
  *
  * @param  var $value
  * @return var
  * @throws lang.IllegalArgumentException
  */
 public function __invoke($value)
 {
     if ($this->mapping) {
         $f = $this->mapping;
         $expr = $f($value);
     } else {
         $expr = $value;
     }
     if (null === $expr) {
         $type = null;
     } else {
         $type = gettype($expr);
     }
     if (isset($this->primitive[$type])) {
         return $this->primitive[$type]($value, $this);
     } else {
         foreach ($this->instance as $conditional) {
             if ($conditional->condition->matches($expr)) {
                 $f = $conditional->handle;
                 return $f($value, $this);
             }
         }
     }
     if ($this->otherwise) {
         $f = $this->otherwise;
         return $f($value, $this);
     } else {
         throw new IllegalArgumentException('Unhandled type ' . \xp::typeOf($expr));
     }
 }
コード例 #2
0
ファイル: Transport.class.php プロジェクト: xp-framework/mail
 /**
  * Set a LogCategory for tracing communication
  *
  * @param  util.log.LogCategory $cat pass NULL to stop tracing
  * @return void
  * @throws lang.IllegalArgumentException in case a of a type mismatch
  */
 public function setTrace($cat)
 {
     if (null !== $cat && !$cat instanceof LogCategory) {
         throw new IllegalArgumentException('Expected a LogCategory, have ' . \xp::typeOf($cat));
     }
     $this->cat = $cat;
 }
コード例 #3
0
 /**
  * Send a message
  *
  * @param   peer.mail.Message message the Message object to send
  * @return  bool success
  */
 public function send($message)
 {
     // Sanity check: Is this a message?
     if (!$message instanceof Message) {
         throw new TransportException('Can only send messages (given: ' . xp::typeOf($message) . ')', new IllegalArgumentException('Parameter message is not a Message object'));
     }
     // Sanity check: Do we have at least one recipient?
     $to = '';
     for ($i = 0, $s = sizeof($message->to); $i < $s; $i++) {
         if (!$message->to[$i] instanceof InternetAddress) {
             continue;
         }
         // Ignore!
         $to .= $message->to[$i]->toString($message->getCharset()) . ', ';
     }
     if (empty($to)) {
         throw new TransportException('No recipients defined (recipients[0]: ' . xp::typeOf($message->to[0]), new IllegalArgumentException('Recipient #0 is not an InternetAddress object'));
     }
     // Copy message and unset To / Subject. PHPs mail() function will add them
     // to the mail twice, otherwise
     $tmp = clone $message;
     unset($tmp->to);
     unset($tmp->subject);
     if (FALSE === mail(substr($to, 0, -2), QuotedPrintable::encode($message->getSubject(), $message->getCharset()), strtr($message->getBody(), array("\r\n" => "\n", "\r" => "\n")), rtrim($tmp->getHeaderString(), "\n"), $this->parameters)) {
         throw new TransportException('Could not send mail to ' . xp::stringOf($message->to[0]), new IOException('Call to mail() failed'));
     }
     return TRUE;
 }
コード例 #4
0
 /**
  * Constructor
  *
  * @param   var stream either an io.streams.OutputStream or an io.Stream (BC)
  * @throws  lang.IllegalArgumentException when types are not met
  */
 public function __construct($stream)
 {
     $this->stream = deref($stream);
     if ($this->stream instanceof OutputStream) {
         // Already open
     } else {
         if ($this->stream instanceof Stream) {
             $this->stream->open(STREAM_MODE_WRITE);
         } else {
             throw new IllegalArgumentException('Expected either an io.streams.OutputStream or an io.Stream, have ' . xp::typeOf($this->stream));
         }
     }
     if (self::$GD_USERSTREAMS_BUG) {
         $this->writer = function ($writer, $stream, $handle) {
             ob_start();
             $r = $writer->output($handle);
             if ($r) {
                 $stream->write(ob_get_contents());
             }
             ob_end_clean();
             return $r;
         };
     } else {
         // Use output buffering with a callback method to capture the
         // image(gd|jpeg|png|...) functions' output.
         $this->writer = function ($writer, $stream, $handle) {
             ob_start(function ($data) use($stream) {
                 $stream->write($data);
             });
             $r = $writer->output($handle);
             ob_end_flush();
             return $r;
         };
     }
 }
コード例 #5
0
 /**
  * Constructor
  *
  * @param   var $arg either an io.streams.OutputStream, an io.File or an io.Stream (BC)
  * @throws  lang.IllegalArgumentException when types are not met
  */
 public function __construct($arg)
 {
     if ($arg instanceof OutputStream) {
         $this->write($arg);
     } else {
         if ($arg instanceof File) {
             $this->write($arg->out());
         } else {
             if ($arg instanceof Stream) {
                 // BC
                 $this->stream = $arg;
                 $this->writer = function ($writer, $stream, $handle) {
                     ob_start();
                     if ($r = $writer->output($handle)) {
                         $stream->open(STREAM_MODE_WRITE);
                         $stream->write(ob_get_contents());
                         $stream->close();
                     }
                     ob_end_clean();
                     return $r;
                 };
             } else {
                 throw new IllegalArgumentException('Expected either an io.streams.OutputStream or an io.File, have ' . \xp::typeOf($arg));
             }
         }
     }
 }
コード例 #6
0
 /**
  * Checks all entries in an array for correct type
  *
  * @param   string type
  * @param   &array array
  * @throws  lang.IllegalArgumentException
  */
 protected function _assertSubtype($type, $array)
 {
     foreach (array_keys($array) as $key) {
         if ($type != xp::typeOf($array[$key])) {
             throw new IllegalArgumentException('Object (in array) not of expected type ' . $type . ', but ' . xp::typeOf($array[$key]) . ' with value ' . var_export($array[$key], 1));
         }
     }
 }
コード例 #7
0
 /**
  * Creates a string representation of this handler
  *
  * @return  string
  */
 public function toString()
 {
     $s = sprintf("%s@{\n" . "  [name               ] %s\n" . "  [identifier         ] %s\n" . "  [wrapper            ] %s\n", nameof($this), $this->name, $this->identifier, $this->wrapper ? nameof($this->wrapper) : '(null)');
     foreach (array_keys($this->values[HVAL_PERSISTENT]) as $key) {
         $s .= sprintf("  [%-20s] %s\n", $key, \xp::typeOf($this->values[$key]));
     }
     return $s . '}';
 }
コード例 #8
0
ファイル: MultiPart.class.php プロジェクト: xp-framework/mail
 /**
  * Add a Mime Part
  *
  * @param   peer.mail.MimePart part
  * @return  peer.mail.MimePart the part added
  * @throws  lang.IllegalArgumentException if part argument is not a peer.mail.MimePart
  */
 public function addPart($part)
 {
     if (!$part instanceof MimePart) {
         throw new IllegalArgumentException('Parameter part is not a peer.mail.MimePart (given: ' . \xp::typeOf($part) . ')');
     }
     $this->parts[] = $part;
     return $part;
 }
コード例 #9
0
ファイル: KeyOf.class.php プロジェクト: xp-forge/match
 /**
  * Define handler for a given key
  *
  * @param  var $key Either a string or an integer
  * @param  function(?): var $function
  * @return self
  */
 public function when($key, $function)
 {
     if (is_string($key) || is_int($key)) {
         $this->hash[$key] = self::$HANDLE->cast($function);
     } else {
         throw new IllegalArgumentException('Illegal key type ' . \xp::typeOf($key));
     }
     return $this;
 }
コード例 #10
0
 /**
  * Box parameter into soap equivalent
  *
  * @param   lang.Generic object
  * @return  mixed
  * @throws  lang.IllegalArgumentException if type is not supported
  */
 public function box($object)
 {
     foreach ($this->handler as $handler => $t) {
         if (!$object instanceof $handler) {
             continue;
         }
         return call_user_func(array($this, 'box' . $handler), $object);
     }
     throw new IllegalArgumentException('Type ' . xp::typeOf($object) . ' is not supported.');
 }
コード例 #11
0
 /**
  * Box parameter into soap equivalent
  *
  * @param   lang.Generic object
  * @return  mixed
  * @throws  lang.IllegalArgumentException if type is not supported
  */
 public function box($object)
 {
     foreach ($this->handler as $class => $handler) {
         if (!$object instanceof $class) {
             continue;
         }
         return call_user_func([$this, $handler], $object);
     }
     throw new \lang\IllegalArgumentException('Type ' . \xp::typeOf($object) . ' is not supported.');
 }
コード例 #12
0
 /**
  * Initializes the attribute with default values, depending on $type
  *
  */
 public function initialize()
 {
     // determine type from value if type is not set
     if (isset($this->_value)) {
         if (!isset($this->_type)) {
             $this->_type = xp::typeOf($this->_value);
         }
         if ($this->_type === 'integer') {
             $this->_type = 'int';
         }
         if (in_array($this->_type, array('float', 'double'))) {
             $this->_type = 'real';
         }
         if ($this->_type === 'bool') {
             $this->_type = 'boolean';
         }
         $value = $this->_value;
     } else {
         $value = NULL;
     }
     // set type if defined
     if (isset($this->_type)) {
         switch ($this->_type) {
             case 'int':
                 $this->set('value', new DiaInt($value));
                 break;
             case 'real':
                 $this->set('value', new DiaReal($value));
                 break;
             case 'string':
                 $this->set('value', new DiaString($value));
                 break;
             case 'boolean':
                 $this->set('value', new DiaBoolean($value));
                 break;
             case 'enum':
                 $this->set('value', new DiaEnum($value));
                 break;
             case 'point':
                 $this->set('value', new DiaPoint($value));
                 break;
             case 'rectangle':
                 $this->set('value', new DiaRectangle($value));
                 break;
             case 'font':
                 $this->set('value', new DiaFont($value));
                 break;
             case 'color':
                 $this->set('value', new DiaColor($value));
                 break;
             default:
                 throw new IllegalArgumentException('Unkown type "' . $this->_type . '"');
         }
     }
 }
コード例 #13
0
 /**
  * Constructor
  *
  * @param   var stream either an io.streams.OutputStream or an io.Stream (BC)
  * @throws  lang.IllegalArgumentException when types are not met
  */
 public function __construct($stream)
 {
     $this->stream = deref($stream);
     if ($this->stream instanceof OutputStream) {
         // Already open
     } else {
         if ($this->stream instanceof Stream) {
             $this->stream->open(STREAM_MODE_WRITE);
         } else {
             throw new IllegalArgumentException('Expected either an io.streams.OutputStream or an io.Stream, have ' . xp::typeOf($this->stream));
         }
     }
 }
コード例 #14
0
ファイル: TextWriter.class.php プロジェクト: johannes85/core
 /**
  * Constructor. Creates a new TextWriter on an underlying output
  * stream with a given charset.
  *
  * @param   io.streams.OutputStream|io.Channel $arg The target
  * @param   string $charset the charset the stream is encoded in.
  * @throws  lang.IllegalArgumentException
  */
 public function __construct($arg, $charset = \xp::ENCODING)
 {
     if ($arg instanceof OutputStream) {
         parent::__construct($arg);
     } else {
         if ($arg instanceof Channel) {
             parent::__construct($arg->out());
         } else {
             throw new IllegalArgumentException('Given argument is neither an input stream, a channel nor a string: ' . \xp::typeOf($arg));
         }
     }
     $this->charset = $charset;
 }
コード例 #15
0
 /**
  * Substract a TimeSpan
  *
  * @param   util.TimeSpan... args
  * @return  util.TimeSpan
  * @throws  lang.IllegalStateException if the result would be a negative timespan
  */
 public function substract()
 {
     foreach (func_get_args() as $span) {
         if (!$span instanceof self) {
             throw new IllegalArgumentException('Given argument is not a TimeSpan: ' . xp::typeOf($span));
         }
         if ($span->_seconds > $this->_seconds) {
             throw new IllegalStateException('Cannot subtract ' . $span->toString() . ' from ' . $this->toString());
         }
         $this->_seconds -= $span->_seconds;
     }
     return $this;
 }
コード例 #16
0
 /**
  * Invokes the underlying method represented by this Method object, 
  * on the specified object with the specified parameters.
  *
  * Example:
  * <code>
  *   $method= XPClass::forName('lang.Object')->getMethod('toString');
  *
  *   var_dump($method->invoke(new Object()));
  * </code>
  *
  * Example (passing arguments)
  * <code>
  *   $method= XPClass::forName('lang.types.String')->getMethod('concat');
  *
  *   var_dump($method->invoke(new String('Hello'), array('World')));
  * </code>
  *
  * Example (static invokation):
  * <code>
  *   $method= XPClass::forName('util.log.Logger')->getMethod('getInstance');
  *
  *   var_dump($method->invoke(NULL));
  * </code>
  *
  * @param   lang.Object obj
  * @param   var[] args default array()
  * @return  var
  * @throws  lang.IllegalArgumentException in case the passed object is not an instance of the declaring class
  * @throws  lang.IllegalAccessException in case the method is not public or if it is abstract
  * @throws  lang.reflect.TargetInvocationException for any exception raised from the invoked method
  */
 public function invoke($obj, $args = array())
 {
     if (NULL !== $obj && !$obj instanceof $this->_class) {
         throw new IllegalArgumentException(sprintf('Passed argument is not a %s class (%s)', xp::nameOf($this->_class), xp::typeOf($obj)));
     }
     // Check modifiers. If caller is an instance of this class, allow
     // protected method invocation (which the PHP reflection API does
     // not).
     $m = $this->_reflect->getModifiers();
     if ($m & MODIFIER_ABSTRACT) {
         throw new IllegalAccessException(sprintf('Cannot invoke abstract %s::%s', $this->_class, $this->_reflect->getName()));
     }
     $public = $m & MODIFIER_PUBLIC;
     if (!$public && !$this->accessible) {
         $t = debug_backtrace(0);
         $decl = $this->_reflect->getDeclaringClass()->getName();
         if ($m & MODIFIER_PROTECTED) {
             $allow = $t[1]['class'] === $decl || is_subclass_of($t[1]['class'], $decl);
         } else {
             $allow = $t[1]['class'] === $decl && self::$SETACCESSIBLE_AVAILABLE;
         }
         if (!$allow) {
             throw new IllegalAccessException(sprintf('Cannot invoke %s %s::%s from scope %s', Modifiers::stringOf($this->getModifiers()), $this->_class, $this->_reflect->getName(), $t[1]['class']));
         }
     }
     // For non-public methods: Use setAccessible() / invokeArgs() combination
     // if possible, resort to __call() workaround.
     try {
         if ($public) {
             return $this->_reflect->invokeArgs($obj, (array) $args);
         }
         if (self::$SETACCESSIBLE_AVAILABLE) {
             $this->_reflect->setAccessible(TRUE);
             return $this->_reflect->invokeArgs($obj, (array) $args);
         } else {
             if ($m & MODIFIER_STATIC) {
                 return call_user_func(array($this->_class, '__callStatic'), "" . $this->_reflect->getName(), $args);
             } else {
                 return $obj->__call("" . $this->_reflect->getName(), $args);
             }
         }
     } catch (SystemExit $e) {
         throw $e;
     } catch (Throwable $e) {
         throw new TargetInvocationException($this->_class . '::' . $this->_reflect->getName(), $e);
     } catch (Exception $e) {
         throw new TargetInvocationException($this->_class . '::' . $this->_reflect->getName(), new XPException($e->getMessage()));
     }
 }
コード例 #17
0
ファイル: Filters.class.php プロジェクト: xp-framework/core
 public function __construct(array $list = [], $accept = null)
 {
     $this->list = $list;
     if (null === $accept) {
         $this->accept = function ($list, $e) {
             throw new IllegalStateException('No accepting closure set');
         };
     } else {
         if ($accept instanceof \Closure) {
             $this->accept = $accept;
         } else {
             throw new IllegalArgumentException('Expecting either a closure or null, ' . \xp::typeOf($accept) . ' given');
         }
     }
 }
コード例 #18
0
 /**
  * Processes a method invocation on a proxy instance and returns
  * the result.
  *
  * @param  lang.reflect.Proxy $proxy
  * @param  string $method the method name
  * @param  var... $args an array of arguments
  * @return var
  * @throws util.DeferredInitializationException
  */
 public function invoke($proxy, $method, $args)
 {
     if (null === $this->_instance) {
         try {
             $this->_instance = $this->initialize();
         } catch (Throwable $e) {
             $this->_instance = null;
             throw new DeferredInitializationException($method, $e);
         }
         if (!is_object($this->_instance)) {
             throw new DeferredInitializationException($method, new ClassCastException('Initializer returned ' . \xp::typeOf($this->_instance)));
         }
     }
     return $this->_instance->{$method}(...$args);
 }
 /**
  * Processes a method invocation on a proxy instance and returns
  * the result.
  *
  * @param   lang.reflect.Proxy proxy
  * @param   string method the method name
  * @param   var* args an array of arguments
  * @return  var
  * @throws  util.DeferredInitializationException
  */
 public function invoke($proxy, $method, $args)
 {
     if (NULL === $this->_instance) {
         try {
             $this->_instance = $this->initialize();
         } catch (Throwable $e) {
             $this->_instance = NULL;
             throw new DeferredInitializationException($method, $e);
         }
         if (!$this->_instance instanceof Generic) {
             throw new DeferredInitializationException($method, XPClass::forName('lang.ClassCastException')->newInstance('Initializer returned ' . xp::typeOf($this->_instance)));
         }
     }
     return call_user_func_array(array($this->_instance, $method), $args);
 }
コード例 #20
0
 /**
  * Factory method
  *
  * @param  var arg either an InputStream, File, or IOElement
  * @return self
  * @throws lang.IllegalArgumentException
  */
 public static function of($arg)
 {
     if ($arg instanceof InputStream) {
         return new self($arg);
     } else {
         if ($arg instanceof File) {
             return create(new self($arg->getInputStream()))->withMediaType(MimeType::getByFileName($arg->getFileName()))->withContentLength($arg->getSize())->withLastModified(new Date($arg->lastModified()));
         } else {
             if ($arg instanceof IOElement) {
                 return create(new self($arg->getInputStream()))->withMediaType(MimeType::getByFileName($arg->getURI()))->withContentLength($arg->getSize())->withLastModified($arg->lastModified());
             } else {
                 throw new IllegalArgumentException('Expected either an InputStream, File, or IOElement, have ' . xp::typeOf($arg));
             }
         }
     }
 }
コード例 #21
0
 /**
  * Return XML representation of DiaComposite
  *
  * @return  &xml.Node
  */
 public function getNode()
 {
     $node = parent::getNode();
     // TODO: the value should always be 'boolean'!
     if (isset($this->value)) {
         if (xp::typeOf($this->value) === 'boolean') {
             $node->setAttribute('val', $this->value ? 'true' : 'false');
         } else {
             $node->setAttribute('val', $this->value === 'true' ? 'true' : 'false');
         }
     } else {
         $node->setAttribute('val', 'false');
         // default
     }
     return $node;
 }
コード例 #22
0
 /**
  * Constructor. Accepts  the following types as argument:
  * <ul>
  *   <li>A string containing the XML</li>
  *   <li>A DomDocument object (as returned by domxml_open_mem, e.g.)</li>
  *   <li>An xml.Tree object</li>
  * </ul>
  *
  * @param   var arg
  * @throws  lang.IllegalArgumentException
  * @throws  xml.XMLFormatException in case the argument is a string and not valid XML
  */
 public function __construct($arg)
 {
     if ($arg instanceof DOMDocument) {
         $this->context = new DOMXPath($arg);
     } else {
         if ($arg instanceof Tree) {
             $this->context = new DOMXPath($this->loadXML($arg->getDeclaration() . $arg->getSource(INDENT_NONE)));
         } else {
             if (is_string($arg)) {
                 $this->context = new DOMXPath($this->loadXML($arg));
             } else {
                 throw new IllegalArgumentException('Unsupported parameter type ' . xp::typeOf($arg));
             }
         }
     }
 }
コード例 #23
0
 /**
  * Update method
  *
  * @param   util.Observable obs
  * @param   var arg default NULL
  */
 public function update($obs, $arg = null)
 {
     if (!$obs instanceof DBConnection) {
         throw new \lang\IllegalArgumentException('Argument 1 must be instanceof "rdbms.DBConnection", "' . \xp::typeOf($obs) . '" given.');
     }
     if (!$arg instanceof DBEvent) {
         return;
     }
     // Store reference for later reuse
     if (null === $this->cat) {
         $this->setTrace(Logger::getInstance()->getCategory($this->name));
     }
     if (null === $this->dsn) {
         $this->dsn = $obs->getDSN()->withoutPassword();
     }
     $method = $arg->getName();
     switch ($method) {
         case 'query':
         case 'open':
             $this->lastq = $this->typeOf($arg->getArgument());
             // Fallthrough intentional
         // Fallthrough intentional
         case 'connect':
             if ('connect' == $method) {
                 $this->lastq = $method;
             }
             $this->timer = new Timer();
             $this->timer->start();
             // Count some well-known SQL keywords
             $this->countFor($this->lastq);
             break;
         case 'connected':
         case 'queryend':
             // Protect against illegal order of events (should not occur)
             if (!$this->timer) {
                 return;
             }
             $this->timer->stop();
             $this->addElapsedTimeTo($method, $this->timer->elapsedTime());
             if ($this->lastq) {
                 $this->addElapsedTimeTo($this->lastq, $this->timer->elapsedTime());
                 $this->lastq = null;
             }
             $this->timer = null;
             break;
     }
 }
コード例 #24
0
ファイル: Bytes.class.php プロジェクト: johannes85/core
 /**
  * Constructor
  *
  * @param   var initial default NULL
  * @throws  lang.IllegalArgumentException in case argument is of incorrect type.
  */
 public function __construct($initial = null)
 {
     if (null === $initial) {
         // Intentionally empty
     } else {
         if (is_array($initial)) {
             $this->buffer = implode('', array_map([$this, 'asByte'], $initial));
         } else {
             if (is_string($initial)) {
                 $this->buffer = $initial;
             } else {
                 throw new \lang\IllegalArgumentException('Expected either Byte[], char[], int[] or string but was ' . \xp::typeOf($initial));
             }
         }
     }
     $this->size = strlen($this->buffer);
 }
コード例 #25
0
ファイル: TimeZone.class.php プロジェクト: xp-framework/core
 /**
  * Creates a new timezone from a given name.
  *
  * @param   string timezone name or NULL to use default timezone
  * @throws  lang.IllegalArgumentException if timezone is unknown
  */
 public function __construct($tz)
 {
     if (null === $tz) {
         $this->tz = timezone_open(date_default_timezone_get());
     } else {
         if (is_string($tz)) {
             try {
                 $this->tz = new \DateTimeZone($tz);
             } catch (\Throwable $e) {
                 throw new IllegalArgumentException('Invalid timezone identifier given: ' . $e->getMessage());
             }
         } else {
             if ($tz instanceof \DateTimeZone) {
                 $this->tz = $tz;
             } else {
                 throw new IllegalArgumentException('Expecting NULL, a string or a DateTimeZone instance, have ' . \xp::typeOf($tz));
             }
         }
     }
 }
コード例 #26
0
 /**
  * Constructor
  *
  * @param   var stream either an io.streams.InputStream or an io.Stream (BC)
  * @throws  lang.IllegalArgumentException when types are not met
  */
 public function __construct($stream)
 {
     $this->stream = deref($stream);
     if ($this->stream instanceof InputStream) {
         if ($this instanceof img·io·UriReader && !self::$GD_USERSTREAMS_BUG) {
             $this->reader = function ($reader, $stream) {
                 return $reader->readImageFromUri(Streams::readableUri($stream));
             };
         } else {
             $this->reader = function ($reader, $stream) {
                 $bytes = '';
                 while ($stream->available() > 0) {
                     $bytes .= $stream->read();
                 }
                 $stream->close();
                 return $reader->readImageFromString($bytes);
             };
         }
     } else {
         if ($this->stream instanceof Stream) {
             if ($this instanceof img·io·UriReader && !self::$GD_USERSTREAMS_BUG) {
                 $this->reader = function ($reader, $stream) {
                     $stream->open(STREAM_MODE_READ);
                     return $reader->readImageFromUri($stream->getURI());
                 };
             } else {
                 $this->reader = function ($reader, $stream) {
                     $stream->open(STREAM_MODE_READ);
                     $bytes = '';
                     do {
                         $bytes .= $stream->read();
                     } while (!$stream->eof());
                     $stream->close();
                     return $reader->readImageFromString($bytes);
                 };
             }
         } else {
             throw new IllegalArgumentException('Expected either an io.streams.InputStream or an io.Stream, have ' . xp::typeOf($this->stream));
         }
     }
 }
コード例 #27
0
ファイル: Method.class.php プロジェクト: johannes85/core
 /**
  * Invokes the underlying method represented by this Method object, 
  * on the specified object with the specified parameters.
  *
  * Example:
  * ```php
  * $method= XPClass::forName('lang.Object')->getMethod('toString');
  * $str= $method->invoke(new Object());
  * ```
  *
  * Example (passing arguments)
  * ```php
  * $method= XPClass::forName('lang.types.String')->getMethod('concat');
  * $str= $method->invoke(new String('Hello'), ['World']);
  * ```
  *
  * Example (static invokation):
  * ```php
  * $method= XPClass::forName('util.log.Logger')->getMethod('getInstance');
  * $log= $method->invoke(null);
  * ```
  *
  * @param   lang.Object $obj
  * @param   var[] $args default []
  * @return  var
  * @throws  lang.IllegalArgumentException in case the passed object is not an instance of the declaring class
  * @throws  lang.IllegalAccessException in case the method is not public or if it is abstract
  * @throws  lang.reflect.TargetInvocationException for any exception raised from the invoked method
  */
 public function invoke($obj, $args = [])
 {
     if (null !== $obj && !$obj instanceof $this->_class) {
         throw new IllegalArgumentException(sprintf('Passed argument is not a %s class (%s)', XPClass::nameOf($this->_class), \xp::typeOf($obj)));
     }
     // Check modifiers. If caller is an instance of this class, allow
     // protected method invocation (which the PHP reflection API does
     // not).
     $m = $this->_reflect->getModifiers();
     if ($m & MODIFIER_ABSTRACT) {
         throw new IllegalAccessException(sprintf('Cannot invoke abstract %s::%s', XPClass::nameOf($this->_class), $this->_reflect->getName()));
     }
     $public = $m & MODIFIER_PUBLIC;
     if (!$public && !$this->accessible) {
         $t = debug_backtrace(0, 2);
         $decl = $this->_reflect->getDeclaringClass()->getName();
         if ($m & MODIFIER_PROTECTED) {
             $allow = $t[1]['class'] === $decl || is_subclass_of($t[1]['class'], $decl);
         } else {
             $allow = $t[1]['class'] === $decl;
         }
         if (!$allow) {
             throw new IllegalAccessException(sprintf('Cannot invoke %s %s::%s from scope %s', Modifiers::stringOf($this->getModifiers()), XPClass::nameOf($this->_class), $this->_reflect->getName(), $t[1]['class']));
         }
     }
     try {
         if (!$public) {
             $this->_reflect->setAccessible(true);
         }
         return $this->_reflect->invokeArgs($obj, (array) $args);
     } catch (\lang\SystemExit $e) {
         throw $e;
     } catch (\lang\Throwable $e) {
         throw new TargetInvocationException(XPClass::nameOf($this->_class) . '::' . $this->_reflect->getName(), $e);
     } catch (\Exception $e) {
         throw new TargetInvocationException(XPClass::nameOf($this->_class) . '::' . $this->_reflect->getName(), new \lang\XPException($e->getMessage()));
     } catch (\Throwable $e) {
         throw new TargetInvocationException(XPClass::nameOf($this->_class) . '::' . $this->_reflect->getName(), new \lang\Error($e->getMessage()));
     }
 }
コード例 #28
0
 /**
  * Constructor
  *
  * @param   var $arg either an io.streams.InputStream, an io.File or an io.Stream (BC)
  * @throws  lang.IllegalArgumentException when types are not met
  */
 public function __construct($arg)
 {
     if ($arg instanceof InputStream) {
         $this->read($arg);
     } else {
         if ($arg instanceof File) {
             $this->read($arg->in());
         } else {
             if ($arg instanceof Stream) {
                 // BC
                 $this->stream = $arg;
                 $this->reader = function ($reader, $stream) {
                     $stream->open(STREAM_MODE_READ);
                     $bytes = $stream->read($stream->size());
                     $stream->close();
                     return $reader->readImageFromString($bytes);
                 };
             } else {
                 throw new IllegalArgumentException('Expected either an io.streams.InputStream or an io.File, have ' . \xp::typeOf($this->stream));
             }
         }
     }
 }
コード例 #29
0
 /**
  * Recursivly serialize data to the given node.
  *
  * Scalar values are natively supported by the protocol, so we just encode
  * them as the spec tells us. As arrays and structs / hashes are the same
  * in PHP, and structs are the more powerful construct, we're always encoding 
  * arrays as structs.
  * 
  * XP objects are encoded as structs, having their FQDN stored in the member
  * __xp_class.
  *
  * @param   xml.Node node
  * @param   var data
  * @throws  lang.IllegalArgumentException in case the data could not be serialized.
  */
 protected function _marshall($data)
 {
     $value = new Node('value');
     // Handle objects:
     // - util.Date objects are serialized as dateTime.iso8601
     // - lang.types.Bytes object are serialized as base64
     // - Provide a standard-way to serialize Object-derived classes
     if ($data instanceof Date) {
         $value->addChild(new Node('dateTime.iso8601', $data->toString('Ymd\\TH:i:s')));
         return $value;
     } else {
         if ($data instanceof Bytes || $data instanceof \lang\types\Bytes) {
             $value->addChild(new Node('base64', base64_encode($data)));
             return $value;
         } else {
             if ($data instanceof \lang\Generic) {
                 $n = $value->addChild(new Node('struct'));
                 $n->addChild(Node::fromArray(['name' => '__xp_class', 'value' => ['string' => nameof($data)]], 'member'));
                 foreach ($data->getClass()->getFields() as $field) {
                     if ($field->getModifiers() & MODIFIER_STATIC) {
                         continue;
                     }
                     $member = $n->addChild(new Node('member'));
                     $member->addChild(new Node('name', $field->getName()));
                     $member->addChild($this->_marshall($field->setAccessible(true)->get($data)));
                 }
                 return $value;
             }
         }
     }
     switch (\xp::typeOf($data)) {
         case 'integer':
             $value->addChild(new Node('int', $data));
             break;
         case 'boolean':
             $value->addChild(new Node('boolean', (string) (int) $data));
             break;
         case 'double':
         case 'float':
             $value->addChild(new Node('double', $data));
             break;
         case 'array':
             if ($this->_isVector($data)) {
                 $n = $value->addChild(new Node('array'))->addChild(new Node('data'));
                 for ($i = 0, $s = sizeof($data); $i < $s; $i++) {
                     $n->addChild($this->_marshall($data[$i]));
                 }
             } else {
                 $n = $value->addChild(new Node('struct'));
                 foreach ($data as $name => $v) {
                     $member = $n->addChild(new Node('member'));
                     $member->addChild(new Node('name', $name));
                     $member->addChild($this->_marshall($v));
                 }
             }
             break;
         case 'string':
             $value->addChild(new Node('string', $data));
             break;
         case 'NULL':
             $value->addChild(new Node('nil'));
             break;
         default:
             throw new \lang\IllegalArgumentException('Cannot serialize data of type "' . \xp::typeOf($data) . '"');
     }
     return $value;
 }
コード例 #30
0
 /**
  * Invokes a given function with the given arguments.
  *
  * @param   var $func
  * @param   var[] $args
  * @return  var
  * @throws  lang.IllegalArgumentException in case the passed function is not an instance of this type
  * @throws  lang.reflect.TargetInvocationException for any exception raised from the invoked function
  */
 public function invoke($func, $args = [])
 {
     $closure = $this->verified($func, function ($m) use($func) {
         throw new IllegalArgumentException(sprintf('Passed argument is not of a %s type (%s): %s', $this->getName(), \xp::typeOf($func), $m));
     });
     try {
         return call_user_func_array($closure, $args);
     } catch (SystemExit $e) {
         throw $e;
     } catch (Throwable $e) {
         throw new \lang\reflect\TargetInvocationException($this->getName(), $e);
     }
 }