text:
<?php

namespace Immutable\Test;

use Carbon\Carbon;
use Immutable\Immutable;
use Immutable\ImmutableElement;
use Immutable\ImmutableInstance;
use PHPUnit\Framework\TestCase;

/**
 * Class ImmutableInstanceTest
 *
 * @package    Envi
 * @subpackage Immutable
 * @author     Suzunone <suzunone.eleven@gmail.com>
 * @copyright  Suzunone 2017
 * @license    BSD 2-Clause License
 * @link       https://github.com/suzunone/ImmutablePHP
 * @see        https://github.com/suzunone/ImmutablePHP
 * @sinse Class available since Release 1.0.0
 * @covers \Immutable\ImmutableInterface
 * @covers \Immutable\ImmutableManager
 */
class ImmutableInstanceTest extends TestCase
{
    /**
     * @covers \Immutable\ImmutableInstance::__construct()
     * @covers \Immutable\ImmutableInstance::__invoke()
     */
    public function test_InvokeClass()
    {
        $ExampleInvokeClass = new \Examples\ExampleInvokeClass();

        /**
         * @var \Examples\ExampleInvokeClass $ExampleInvokeClass2
         */
        $ExampleInvokeClass2 = Immutable::freeze($ExampleInvokeClass);

        $res = $ExampleInvokeClass2();
        $this->assertEquals([], $ExampleInvokeClass->param);
        $this->assertEquals([], $ExampleInvokeClass2->param);
        $this->assertEquals(0, $res);

        $res = $ExampleInvokeClass2(10, false);
        $this->assertEquals([], $ExampleInvokeClass->param);
        $this->assertEquals([], $ExampleInvokeClass2->param);
        $this->assertEquals(10 * 10 * 10, $res);

        /**
         * @var \Examples\ExampleInvokeClass $res2
         */
        $res2 = $ExampleInvokeClass2(10, true);
        $this->assertEquals([], $ExampleInvokeClass->param);
        $this->assertEquals([], $ExampleInvokeClass2->param);
        $this->assertEquals([10, true], $res2->param);
    }

    /**
     * @covers \Immutable\ImmutableInstance::__isset
     */
    public function test_Example1Class_isset()
    {
        $ExampleClass = new \Examples\Example1Class();

        /**
         * @var \Examples\Example1Class $ExampleClass2
         */
        $ExampleClass2 = Immutable::freeze($ExampleClass);

        // isset emptyのテスト
        $this->assertTrue(isset($ExampleClass2->public_property));
        $this->assertEmpty($ExampleClass2->isset_property);
        $this->assertEmpty($ExampleClass->isset_property);

        $this->assertTrue(empty($ExampleClass2->protected_property));
        $this->assertEmpty($ExampleClass2->isset_property);
        $this->assertEmpty($ExampleClass->isset_property);

        $this->assertTrue(empty($ExampleClass2->private_property));
        $this->assertEmpty($ExampleClass2->isset_property);
        $this->assertEmpty($ExampleClass->isset_property);

        $this->assertTrue(empty($ExampleClass2->undefined_property));
        $this->assertEmpty($ExampleClass2->isset_property);
        $this->assertEmpty($ExampleClass->isset_property);

        $this->assertFalse(empty($ExampleClass2->public_property));
        $this->assertEmpty($ExampleClass2->isset_property);
        $this->assertEmpty($ExampleClass->isset_property);

        $this->assertFalse(isset($ExampleClass2->protected_property));
        $this->assertEmpty($ExampleClass2->isset_property);
        $this->assertEmpty($ExampleClass->isset_property);

        $this->assertFalse(isset($ExampleClass2->private_property));
        $this->assertEmpty($ExampleClass2->isset_property);
        $this->assertEmpty($ExampleClass->isset_property);

        $this->assertFalse(isset($ExampleClass2->undefined_property));
        $this->assertEmpty($ExampleClass2->isset_property);
        $this->assertEmpty($ExampleClass->isset_property);
    }

    /**
     * @covers \Immutable\ImmutableInstance::__isset
     */
    public function test_Example2Class_isset()
    {
        $ExampleClass = new \Examples\Example2Class();

        /**
         * @var \Examples\Example1Class $ExampleClass2
         */
        $ExampleClass2 = Immutable::freeze($ExampleClass);

        // isset emptyのテスト
        $this->assertTrue(isset($ExampleClass2->public_property));
        $this->assertEmpty($ExampleClass2->isset_property);
        $this->assertEmpty($ExampleClass->isset_property);

        $this->assertTrue(empty($ExampleClass2->protected_property));
        $this->assertEmpty($ExampleClass2->isset_property);
        $this->assertEmpty($ExampleClass->isset_property);

        $this->assertTrue(empty($ExampleClass2->private_property));
        $this->assertEmpty($ExampleClass2->isset_property);
        $this->assertEmpty($ExampleClass->isset_property);

        $this->assertTrue(empty($ExampleClass2->undefined_property));
        $this->assertEmpty($ExampleClass2->isset_property);
        $this->assertEmpty($ExampleClass->isset_property);

        $this->assertFalse(empty($ExampleClass2->public_property));
        $this->assertEmpty($ExampleClass2->isset_property);
        $this->assertEmpty($ExampleClass->isset_property);

        $this->assertFalse(isset($ExampleClass2->protected_property));
        $this->assertEmpty($ExampleClass2->isset_property);
        $this->assertEmpty($ExampleClass->isset_property);

        $this->assertFalse(isset($ExampleClass2->private_property));
        $this->assertEmpty($ExampleClass2->isset_property);
        $this->assertEmpty($ExampleClass->isset_property);

        $this->assertFalse(isset($ExampleClass2->undefined_property));
        $this->assertEmpty($ExampleClass2->isset_property);
        $this->assertEmpty($ExampleClass->isset_property);

    }

    /**
     * @covers \Immutable\ImmutableInstance::__unset
     */
    public function test_Example1Class_unset()
    {
        $ExampleClass = new \Examples\Example1Class();

        /**
         * @var \Examples\Example1Class $ExampleClass2
         */
        $ExampleClass2 = Immutable::freeze($ExampleClass);

        unset($ExampleClass2->public_property);
        $this->assertEquals($ExampleClass->public_property, $ExampleClass2->public_property);
        $this->assertNull($ExampleClass->get_property);
        $this->assertNull($ExampleClass->set_property);
        $this->assertNull($ExampleClass->call_property);
        $this->assertNull($ExampleClass->unset_property);
        $this->assertNull($ExampleClass2->get_property);
        $this->assertNull($ExampleClass2->set_property);
        $this->assertNull($ExampleClass2->call_property);
        $this->assertNull($ExampleClass2->unset_property);

        unset($ExampleClass2->protected_property);
        $this->assertEquals($ExampleClass->public_property, $ExampleClass2->public_property);
        $this->assertNull($ExampleClass->get_property);
        $this->assertNull($ExampleClass->set_property);
        $this->assertNull($ExampleClass->call_property);
        $this->assertNull($ExampleClass->unset_property);
        $this->assertNull($ExampleClass2->get_property);
        $this->assertNull($ExampleClass2->set_property);
        $this->assertNull($ExampleClass2->call_property);
        $this->assertNull($ExampleClass2->unset_property);

        unset($ExampleClass2->undefined_property);
        $this->assertEquals($ExampleClass->public_property, $ExampleClass2->public_property);
        $this->assertNull($ExampleClass->get_property);
        $this->assertNull($ExampleClass->set_property);
        $this->assertNull($ExampleClass->call_property);
        $this->assertNull($ExampleClass->unset_property);
        $this->assertNull($ExampleClass2->get_property);
        $this->assertNull($ExampleClass2->set_property);
        $this->assertNull($ExampleClass2->call_property);
        $this->assertNull($ExampleClass2->unset_property);

    }

    /**
     * @covers \Immutable\ImmutableInstance::__unset
     * @expectedException \ErrorException
     */
    public function test_Example1Class_unset_error()
    {
        $ExampleClass = new \Examples\Example2Class();

        /**
         * @var \Examples\Example1Class $ExampleClass2
         */
        $ExampleClass2 = Immutable::freeze($ExampleClass);

        unset($ExampleClass2->public_property);
        $this->assertEquals($ExampleClass->public_property, $ExampleClass2->public_property);
        $this->assertNull($ExampleClass->get_property);
        $this->assertNull($ExampleClass->set_property);
        $this->assertNull($ExampleClass->call_property);
        $this->assertNull($ExampleClass->unset_property);
        $this->assertNull($ExampleClass2->get_property);
        $this->assertNull($ExampleClass2->set_property);
        $this->assertNull($ExampleClass2->call_property);
        $this->assertNull($ExampleClass2->unset_property);

        unset($ExampleClass2->undefined_property);

    }

    /**
     * @covers \Immutable\ImmutableInstance::__call
     */
    public function test_Example1Class__call()
    {
        $ExampleClass = new \Examples\Example1Class();

        /**
         * @var \Examples\Example1Class $ExampleClass2
         */
        $ExampleClass2 = Immutable::freeze($ExampleClass);

        $this->assertTrue($ExampleClass2->runPublic());

        $this->assertEquals($ExampleClass->public_property, $ExampleClass2->public_property);
        $this->assertNull($ExampleClass->get_property);
        $this->assertNull($ExampleClass->set_property);
        $this->assertNull($ExampleClass->call_property);
        $this->assertNull($ExampleClass->unset_property);
        $this->assertNull($ExampleClass2->get_property);
        $this->assertNull($ExampleClass2->set_property);
        $this->assertNull($ExampleClass2->call_property);
        $this->assertNull($ExampleClass2->unset_property);

        $this->assertSame($ExampleClass->runPublic(), $ExampleClass2->runPublic());
        $this->assertSame($ExampleClass->runPrivate(), $ExampleClass2->runPrivate());
        $this->assertSame($ExampleClass->runProtected(), $ExampleClass2->runProtected());
        $this->assertSame($ExampleClass->runUndefined(), $ExampleClass2->runUndefined());

    }

    /**
     * @covers \Immutable\ImmutableInstance::__call
     * @expectedException \ErrorException
     */
    public function test_Example1Class__call_error()
    {
        $ExampleClass = new \Examples\Example2Class();

        /**
         * @var \Examples\Example1Class $ExampleClass2
         */
        $ExampleClass2 = Immutable::freeze($ExampleClass);

        $this->assertTrue($ExampleClass2->runPublic());

        $this->assertEquals($ExampleClass->public_property, $ExampleClass2->public_property);
        $this->assertNull($ExampleClass->get_property);
        $this->assertNull($ExampleClass->set_property);
        $this->assertNull($ExampleClass->call_property);
        $this->assertNull($ExampleClass->unset_property);
        $this->assertNull($ExampleClass2->get_property);
        $this->assertNull($ExampleClass2->set_property);
        $this->assertNull($ExampleClass2->call_property);
        $this->assertNull($ExampleClass2->unset_property);

        $ExampleClass2->runUndefined();

    }

    /**
     * @covers \Immutable\ImmutableInstance::__get()
     */
    public function test_Example1Class_get()
    {
        $ExampleClass = new \Examples\Example1Class();

        /**
         * @var \Examples\Example1Class $ExampleClass2
         */
        $ExampleClass2 = Immutable::freeze($ExampleClass);

        $this->assertEquals($ExampleClass->public_property, $ExampleClass2->public_property);
        $this->assertNull($ExampleClass2->get_property);
        $this->assertNull($ExampleClass2->set_property);
        $this->assertNull($ExampleClass2->call_property);
        $this->assertNull($ExampleClass2->unset_property);

        $this->assertEquals($ExampleClass->protected_property, $ExampleClass2->protected_property);
        $this->assertEquals(['protected_property' => 'protected_property'], $ExampleClass->protected_property);
        $this->assertNull($ExampleClass2->get_property);
        $this->assertNull($ExampleClass2->set_property);
        $this->assertNull($ExampleClass2->call_property);
        $this->assertNull($ExampleClass2->unset_property);

        $this->assertEquals($ExampleClass->undefined_property, $ExampleClass2->undefined_property);
        $this->assertNull($ExampleClass2->get_property);
        $this->assertNull($ExampleClass2->set_property);
        $this->assertNull($ExampleClass2->call_property);
        $this->assertNull($ExampleClass2->unset_property);
    }

    /**
     * @covers \Immutable\ImmutableInstance::__get()
     * @expectedException \ErrorException
     */
    public function test_Example2Class_get()
    {
        $ExampleClass = new \Examples\Example2Class();

        /**
         * @var \Examples\Example1Class $ExampleClass2
         */
        $ExampleClass2 = Immutable::freeze($ExampleClass);

        $this->assertEquals($ExampleClass->public_property, $ExampleClass2->public_property);
        $this->assertNull($ExampleClass2->get_property);
        $this->assertNull($ExampleClass2->set_property);
        $this->assertNull($ExampleClass2->call_property);
        $this->assertNull($ExampleClass2->unset_property);

        $res = $ExampleClass2->undefined_property;
    }

    /**
     * @covers \Immutable\ImmutableInstance::__set()
     */
    public function test_Example1Class_set()
    {
        $ExampleClass = new \Examples\Example1Class();

        /**
         * @var \Examples\Example1Class $ExampleClass2
         */
        $ExampleClass2 = Immutable::freeze($ExampleClass);

        $ExampleClass2->public_property = 123456789;

        $this->assertEquals($ExampleClass->public_property, $ExampleClass2->public_property);
        $this->assertNull($ExampleClass2->get_property);
        $this->assertNull($ExampleClass2->set_property);
        $this->assertNull($ExampleClass2->call_property);
        $this->assertNull($ExampleClass2->unset_property);

        $ExampleClass2->protected_property = 1234567;
        $this->assertNull($ExampleClass2->get_property);
        $this->assertNull($ExampleClass2->set_property);
        $this->assertNull($ExampleClass2->call_property);
        $this->assertNull($ExampleClass2->unset_property);

        $ExampleClass2->undefined_property = 1234567;
        $this->assertNull($ExampleClass2->get_property);
        $this->assertNull($ExampleClass2->set_property);
        $this->assertNull($ExampleClass2->call_property);
        $this->assertNull($ExampleClass2->unset_property);
    }

    /**
     * @covers \Immutable\ImmutableInstance::__set()
     */
    public function test_Example2Class_set()
    {
        $ExampleClass = new \Examples\Example2Class();

        /**
         * @var \Examples\Example1Class $ExampleClass2
         */
        $ExampleClass2 = Immutable::freeze($ExampleClass);
        $ExampleClass2->public_property = 123456789;

        $this->assertEquals($ExampleClass->public_property, $ExampleClass2->public_property);
        $this->assertNull($ExampleClass2->get_property);
        $this->assertNull($ExampleClass2->set_property);
        $this->assertNull($ExampleClass2->call_property);
        $this->assertNull($ExampleClass2->unset_property);

    }

    /**
     * @covers \Immutable\ImmutableInstance::__set()
     * @expectedException \ErrorException
     */
    public function test_Example2Class_set_error()
    {
        $ExampleClass = new \Examples\Example2Class();

        /**
         * @var \Examples\Example1Class $ExampleClass2
         */
        $ExampleClass2 = Immutable::freeze($ExampleClass);
        $ExampleClass2->undefined_property = 123456789;

    }

    /**
     * @covers \Immutable\ImmutableInstance
     */
    public function test_Example1Class__debugInfo()
    {
        $ExampleClass = new \Examples\Example1Class();

        /**
         * @var \Examples\Example1Class $ExampleClass2
         */
        $ExampleClass2 = Immutable::freeze($ExampleClass);

        ob_start();
        var_dump($ExampleClass2);
        $contents = ob_get_contents();
        ob_end_clean();

        $this->assertRegExp('/mutable_instance/', $contents);
        $this->assertRegExp('/protected/', $contents);
        $this->assertRegExp('/Example1Class/', $contents);
    }

    /**
     * @covers \Immutable\ImmutableInstance::__set_state()
     */
    public function test_Example1Class__set_state()
    {
        $ExampleClass = new \Examples\Example1Class();

        /**
         * @var \Examples\Example1Class $ExampleClass2
         */
        $ExampleClass2 = Immutable::freeze($ExampleClass);

        //ob_start();
        $export1 = var_export($ExampleClass, true);
        $export2 = var_export($ExampleClass2, true);

        /**
         * @var \Examples\Example1Class $ExampleClass_1
         */
        eval('$ExampleClass_1 = ' . $export1 . ';');

        /**
         * @var \Examples\Example1Class $ExampleClass2_1
         */
        eval('$ExampleClass2_1 = ' . $export2 . ';');

        $this->assertEquals($ExampleClass->public_property, $ExampleClass2->public_property);
        $this->assertEquals($ExampleClass->public_property, $ExampleClass2->public_property);
        $this->assertEquals($ExampleClass->public_property, $ExampleClass_1->public_property);
        $this->assertEquals($ExampleClass->public_property, $ExampleClass2_1->public_property);

    }

    /**
     * @covers \Immutable\ImmutableInstance::__toString()
     */
    public function test_Example1Class_toString()
    {
        $ExampleClass = new \Examples\Example1Class();

        /**
         * @var \Examples\Example1Class $ExampleClass2
         */
        $ExampleClass2 = Immutable::freeze($ExampleClass);

        $this->assertEquals((string)$ExampleClass, (string)$ExampleClass2);

        $this->assertEquals($ExampleClass->public_property, $ExampleClass2->public_property);
        $this->assertNull($ExampleClass2->get_property);
        $this->assertNull($ExampleClass2->set_property);
        $this->assertNull($ExampleClass2->call_property);
        $this->assertNull($ExampleClass2->unset_property);
    }

    /**
     * @covers \Immutable\ImmutableInstance::__sleep()
     * @expectedException \ErrorException
     */
    public function test_Example1Class_sleep()
    {
        $ExampleClass = new \Examples\Example1Class();

        /**
         * @var \Examples\Example1Class $ExampleClass2
         */
        $ExampleClass2 = Immutable::freeze($ExampleClass);

        serialize($ExampleClass2);

    }

    /**
     * @covers \Immutable\ImmutableInstance
     * @covers \Immutable\Immutable::freezeRecursive()
     * @covers \Immutable\ImmutableElement::freezeRecursive()
     */
    public function test_Carbon()
    {
        $Carbon = new Carbon();

        /**
         * @var Carbon $Carbon2
         */
        $Carbon2 = Immutable::freezeRecursive($Carbon);
        $this->assertInstanceOf(ImmutableInstance::class, $Carbon2);

        // 生成されたオブジェクトは基本的に同じ
        $this->assertEquals($Carbon->format('Y-m-d H:i:s'), $Carbon2->format('Y-m-d H:i:s'));

        // Immutable化すると、元のオブジェクトとは関係なくなる
        $Carbon->nextWeekday();
        $this->assertNotEquals($Carbon2->format('Y-m-d H:i:s'), $Carbon->format('Y-m-d H:i:s'));

        /**
         * @var Carbon $Carbon3
         */
        $Carbon3 = $Carbon2->nextWeekday();

        // メソッドチェーンできるMethodの場合は、新しいオブジェクトが生成される
        $this->assertNotEquals($Carbon2->format('Y-m-d H:i:s'), $Carbon3->format('Y-m-d H:i:s'));
        $this->assertEquals($Carbon->format('Y-m-d H:i:s'), $Carbon3->format('Y-m-d H:i:s'));
        $Carbon->nextWeekday();
        $this->assertNotEquals($Carbon->format('Y-m-d H:i:s'), $Carbon3->format('Y-m-d H:i:s'));

    }

}


text:
layout: post
title: "Editores de código online para programar"
category: genbeta
---

Hace poco se planteaba esta pregunta desde la sección [Genbeta
Respuestas](http://www.genbeta.com/respuestas/algun-buen-editor-de-codigo-en-
la-nube-para-programacion). Y es que en este caso los propios lectores de
Genbeta, **con vuestras respuestas, además de ayudar a otro usuario, habéis
dejado unos buenos enlaces **que paso a recopilar.

La pregunta era curiosa: **_¿Algún buen editor de código en la nube para
programación?_ **En un principio no me parecía muy clara. ¿Sólo queremos
editar un trozo de código? ¿Querrías compilarlo? ¿Lo que realmente quieres es
un sitio donde guardar tus proyectos en la nube?
La pregunta era abierta, y seguramente por ello, **vuestras respuestas han
sido diversas y enriquecedoras**:

## Editores de lenguajes compilados

Unas de las primeras respuestas en llegar han dado luz verde dos servicios web
que **no sólo te permiten editar código, sino que también lo compilan y lo
ejecutan**. No esperes poder compilar varias librerías, simplemente prueba un
código, o aprende viendo los códigos que otras personas comparten.

Hace un tiempo compartíamos con vosotros en Genbeta el editor/compilador
online [Ideone](http://www.genbeta.com/herramientas/ideone-tu-compilador-
online) y esta ha sido una de vuestras sugerencias. Podemos trabajar con **más
de 40 lenguajes**, y desde la última vez que le dimos un vistazo, ahora
podemos editar con el código resaltado _(syntax highlighting)_. Podemos
utilizar diferentes compiladores para un mismo lenguaje y **ver ejemplos muy
variopintos**.

![Ideone: Un editor online de código que además compila y ejecuta más de 40
lenguajes](http://img.genbeta.com/2011/03/editores-online-compilados-
ideone.jpg)

Parecido a Ideone, pero más limitado encontramos entre vuestras respuestas
**Codepad**. Con 13 lenguajes en los que programar y probar nuestras
aplicaciones, se aparece como una buena herramienta para elaborar de forma
colaborativa una aplicación, ya que **nos facilita un enlace para nuestro
código que podremos compartir**.

## Editores de HTML - CSS online

Existen muchas páginas que normalmente te enseñan a programar en HTML/CSS que
**nos dejan probar _nuestras chapuzas_ en un pequeño editor**. Pero en
vuestras respuestas hemos encontrado dos opciones muy similares que nos
dejarán probar nuestro código sin mayores problemas.

El primero de ellos se llama HtmlEdit y los fundamentos son sencillos. Divide
la pantalla del navegador de forma horizontal por la mitad y en la parte
superior escribimos el código, mientras que en la de abajo, **en tiempo real,
vemos cómo va quedando nuestra página web**.

![HtmlEdit: Un sencillo editor online de Html y
Css](http://img.genbeta.com/2011/03/editores-online-html-css.jpg)

Dentro de la web TreeWeb nos dan un pequeño editor similar al descrito
anteriormente. **Escribimos nuestro código en la parte superior y en la
inferior podemos ver cómo va quedando**. Además nos proporciona un enlace
permanente para poder compartir nuestro código. Para mi gusto, el editor tiene
pocos caracteres de anchura.

## Para completar: Ace y CodeRun

Como vemos, las respuestas principalmente han ido en dos variantes,
dependiendo del tipo de lenguaje en el que queramos programar. Pero,
posiblemente, la respuesta más acertada haya sido la que proponía el editor
**Ace. Un editor de código online escrito con JavaScript**.

La propuesta es sencilla, y es que simplemente **es un editor, que se ha
creado como base para el editor Cloud9 **donde se pueden desarrollar proyectos
más importantes, guardando tu código y creando tu aplicación directamente
desde tu navegador. Es un servicio de pago, pero gratuito si desarrollas un
proyecto de código abierto.

Por último CodeRun, un editor sorprendente. Cuando abres la página te
encuentras con **una interfaz que ya parece un editor de código de
escritorio**. Un navegador de nuestros ficheros, consola de errores, y
pestañas. Son sorprendentes las tecnologías que puedes utilizar enfocadas a la
programación web: **C#, JavaScript y PHP**.

![CodeRun: Un completo editor y compilador de proyectos
online](http://img.genbeta.com/2011/03/editores-online-cabecera-coderun.jpg)

Pero no sólo podemos crear nuestro proyecto, sino que también **podemos
probarlo, evitándonos el paso de instalar un servidor en nuestro ordenador **y
configurarlo (o subir los ficheros a un servidor externo). Se pueden
desarrollar aplicaciones con Silverlight, jQuery, Ajax o ASP.

## Mis conclusiones

Después de muchos años _tirando_ líneas de código uno aprende que hay pequeños
detalles que resultan imprescindibles. Y pocos de ellos los ofrecen la mayoría
de los editores explicados anteriormente. **Hasta un editor como **(el también
comentado) **Notepad++ nos facilita muchas herramientas que nos ahorra mucho
tiempo**.

**Una ventaja que tenemos es que nos compilan o interpretan nuestro código**. Eso es realmente una ayuda, pues no necesitamos instalar ningún compilador o servidor en nuestro ordenador; pero si llevamos a producción nuestro proyecto ¿realmente sabremos aplicarlo y optimizarlo?

**Utilizar una interfaz completa y eficaz unido a un buen servidor SVN para guardar versiones de nuestro código **ha dado y sigue dando buenos resultados. Pero después de llevar ya unos años enseñando los principios de la programación, **páginas como Ideone o HtmlEdit facilitan la labor docente**.

Lenguajes "compilados" | [Ideone](http://ideone.com/) |
[CodePad](http://codepad.org/)
HTML - CSS - JavaScript | [HtmlEdit](http://htmledit.squarefree.com/) |
[TreeWeb](http://www.treeweb.es/WebCode)
Otros | [Ace](http://ajaxorg.github.com/ace/build/editor.html) |
[CodeRun](http://www.coderun.com/ide/)

Artículo extraído de [Genbeta](http://www.genbeta.com).

redpajama_set_name: RedPajamaGithub


text:
package org.collectionspace.chain.csp.webui.nuispec;

import java.util.Iterator;

import org.apache.commons.lang.StringUtils;
import org.collectionspace.chain.csp.config.ConfigException;
import org.collectionspace.chain.csp.schema.Field;
import org.collectionspace.chain.csp.schema.FieldParent;
import org.collectionspace.chain.csp.schema.FieldSet;
import org.collectionspace.chain.csp.schema.Group;
import org.collectionspace.chain.csp.schema.Instance;
import org.collectionspace.chain.csp.schema.Record;
import org.collectionspace.chain.csp.schema.Repeat;
import org.collectionspace.chain.csp.schema.Schemas;
import org.collectionspace.chain.csp.schema.Spec;
import org.collectionspace.chain.csp.schema.UISpecRunContext;
import org.collectionspace.chain.csp.webui.main.Request;
import org.collectionspace.chain.csp.webui.main.WebMethod;
import org.collectionspace.chain.csp.webui.main.WebUI;
import org.collectionspace.csp.api.persistence.Storage;
import org.collectionspace.csp.api.ui.UIException;
import org.collectionspace.csp.api.ui.UIRequest;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class UISchema extends SchemaStructure implements WebMethod {
	private static final Logger log = LoggerFactory.getLogger(UISchema.class);
	protected CacheTermList ctl;
	protected Record record;
	protected Storage storage;
	private Schemas schema;

	public UISchema(Record r, String sview) {
		super(r, sview);
		this.record = r;
	}
	public UISchema(Spec spec, String sview, String stype) {
		super(spec, sview, stype);
	}
	public UISchema(Spec spec, Schemas s) {
		super(spec,"screen");
		this.schema = s;
		this.spec = spec;
		this.record = null;
	}

	@Override
	public void configure(WebUI ui, Spec spec) {
		// TODO Auto-generated method stub
	}

	@Override
	public void run(Object in, String[] tail) throws UIException {
		Request q = (Request) in;
		JSONObject out;
		if(this.record != null){
			if(this.spectype.equals("search")){
				out = uisearchschema(q.getStorage(),this.record);
			}
			else{
				out = uirecordschema(q.getStorage(),this.record);
			}
		}
		else{
			out = uiotherschema(q.getStorage(),StringUtils.join(tail,"/"));
		}
		UIRequest uir = q.getUIRequest();
		uir.sendJSONResponse(out);
		int cacheMaxAgeSeconds = spec.getAdminData().getUiSpecSchemaCacheAge();
		if(cacheMaxAgeSeconds > 0) {
			uir.setCacheMaxAgeSeconds(cacheMaxAgeSeconds);
		}
	}

	protected void actualValidatedField(JSONObject out, FieldSet fs, UISpecRunContext context) throws JSONException{
		String datatype = ((Field)fs).getDataType();
		if(datatype.equals("")){datatype="string";}
		JSONObject validator = new JSONObject();
		actualSchemaObject(datatype, null, null, null, validator);
		out.put(getSelector(fs,context),validator);
	}

	protected void actualExternalURLField(JSONObject out, FieldSet fs, UISpecRunContext context) throws JSONException{
		String datatype = "string";
		JSONObject urlfield = new JSONObject();
		actualSchemaObject(datatype, null, null, null, urlfield);
		out.put(getSelector(fs,context),urlfield);
	}

        protected void actualDeURNedField(JSONObject out, FieldSet fs, UISpecRunContext context) throws JSONException{
		String datatype = "string";
		JSONObject deurnedfield = new JSONObject();
		actualSchemaObject(datatype, null, null, null, deurnedfield);
		out.put(getSelector(fs,context),deurnedfield);
	}

	protected void actualSubRecordField(JSONObject out, FieldSet fs, UISpecRunContext context, Record subr, Boolean repeated, JSONObject parent) throws JSONException{

		if(fs instanceof Group){
			Group gp = (Group)fs;
			if(!gp.isGrouped()){
				makeASubRecord(subr, out,  repeated,  context, parent);
				return;
			}
		}

		JSONObject insidebit = new JSONObject();
		makeASubRecord(subr, insidebit,  repeated,  context, parent);

		JSONObject chooser = new JSONObject();
		actualSchemaObject("object", null, insidebit, null, chooser);
		out.put(getSelector(fs,context),chooser);
	}
	protected void actualChooserField(JSONObject out, FieldSet fs, UISpecRunContext context, Boolean useContainer) throws JSONException{
		JSONObject chooser = new JSONObject();
		actualSchemaObject("string", null, null, null, chooser);
		out.put(getSelector(fs,context),chooser);
	}

	protected void actualDateField(JSONObject out, FieldSet fs, UISpecRunContext context) throws JSONException{
		String type = "date";
		JSONObject datefield = new JSONObject();
		actualSchemaObject(type, null, null, null, datefield);
		out.put(getSelector(fs,context),datefield);
	}

	/**
	 * Overwrite with output you need for this thing you are doing
	 * @param out
	 * @param context
	 * @param f
	 * @throws JSONException
	 */
	protected void actualAuthorities(JSONObject out, FieldSet fs, UISpecRunContext context)
			throws JSONException {
		if("enum".equals(fs.getUIType())){
			out.put(getSelector(fs,context),actualFieldEntry(fs,context));
		}
		else{
			out.put(getSelector(fs,context),actualAutocomplete(fs,context));
		}
	}

	/**
	 *
	 * @param f
	 * @param context
	 * @return
	 * @throws JSONException
	 */
	protected JSONObject actualAutocomplete(FieldSet fs,UISpecRunContext context) throws JSONException {
		JSONObject out = new JSONObject();
		actualSchemaObject("string", null, null, null, out);
		return out;
	}

	/**
	 * Do the same in UISchema with refactored and not refactored fields
	 * @param out
	 * @param affix
	 * @param f
	 * @throws JSONException
	 */
	protected void actualFieldNotRefactored(JSONObject out,FieldSet fs, UISpecRunContext context) throws JSONException{
		actualFieldRefactored(out, fs, context);
	}
	protected void 	actualGroupEntry(FieldSet fs, JSONObject out, UISpecRunContext context, JSONObject contents) throws JSONException{
		if(contents.has("type")){
			out.put("type", contents.get("type"));// array|object|string
		}
		if (contents.has("default")) {
			out.put("default", contents.get("default"));
		}
		if (contents.has("properties")) {
			out.put("properties", contents.get("properties"));
		}
		if (contents.has("items")) {
			out.put("items", contents.get("items"));
		}
	}

	/**
	 * Overwrite with output you need for this thing you are doing
	 * @param f
	 * @param context
	 * @return
	 * @throws JSONException
	 */
	protected Object actualOptionField(Field f,UISpecRunContext context) throws JSONException {
		String type = "string";
		String defaultval = f.getOptionDefault();
		if( (this.spectype.equals("search") && !f.getSearchType().equals(""))){
			defaultval = "";
		}
		JSONObject out = new JSONObject();
		actualSchemaObject(type, defaultval, null, null, out);
		return out;
	}

	/**
	 * specific UISchema realization of this item
	 */
	protected void actualSelfRendererField(JSONObject out, FieldSet fs, UISpecRunContext context) throws JSONException{
		Object temp = actualFieldEntry(fs,context);
		if(temp instanceof JSONObject){
			JSONObject tempo = (JSONObject)temp;

			Iterator rit=tempo.keys();
			while(rit.hasNext()) {
				String key=(String)rit.next();
				out.put(key, tempo.get(key));
			}

		}
		else{
			out.put(getSelector(fs,context),actualFieldEntry(fs,context));
		}
	}
	/**
	 * Overwrite with output you need for this thing you are doing
	 * @param out
	 * @param context
	 * @param f
	 * @throws JSONException
	 */
	protected void actualFieldExpanderEntry(JSONObject out, UISpecRunContext context,
			Field f) throws JSONException {
		out.put(getSelector(f,context), actualOptionField(f,context));
	}

	/**
	 * Overwrite with output you need for this thing you are doing
	 * @param out
	 * @param fs
	 * @param context
	 * @throws JSONException
	 */
	protected void actualField(JSONObject out, FieldSet fs, UISpecRunContext context) throws JSONException{
		out.put(getSelector(fs,context),actualFieldEntry(fs,context));
	}

	protected Object displayAsplain(Field f,UISpecRunContext context) throws JSONException {
		JSONObject output = new JSONObject();
		actualSchemaObject("string", null, null, null, output);
		return output;
	}

	protected Object displayAsplainlist(Field f) throws JSONException {
		JSONObject output = new JSONObject();
		actualSchemaObject("object", new JSONObject(), null, null, output);
		return output;
	}

	protected void makeAStructureDate(FieldSet fs, JSONObject out,
			JSONObject subexpander, JSONObject options, Record subitems,
			UISpecRunContext sub, UISpecRunContext mainContext) throws JSONException {
		// We map structured-date range searches onto a range search on the scalar date fields.
		// We continue to refer to the structured date field so that the search builder can
		// do the right thing, but here in the search schema, we act as though the structured
		// date is really a scalar date, so the UI code will build the right UI
		// Note that at this point, the fs is actually a synthetic copy of the original
		// with the id changed to append "Start" or "End"
		if( (this.spectype.equals("search") && fs.getSearchType().equals("range"))){
			actualDateField(out, fs, mainContext);
		} else {
			makeAOtherGroup(fs,out,subexpander, options, subitems, sub);
		}
	}

	protected void makeAOtherGroup(FieldSet fs, JSONObject out,
			JSONObject subexpander, JSONObject options, Record subitems,
			UISpecRunContext sub) throws JSONException {
		JSONObject protoTree = new JSONObject();
		for(FieldSet fs2 : subitems.getAllFieldTopLevel("")) {
			whatIsThisFieldSet(protoTree, fs2, sub);
		}
		JSONObject output = new JSONObject();
		actualSchemaObject("boolean", true, null, null, output);
		protoTree.put("_primary",output);

		actualSchemaObject("object", null, protoTree, null, out);
	}

	/**
	 * return the affix for this selector
	 * @param fs
	 * @return
	 */
	protected String getSelectorAffix(FieldSet fs){
		return fs.getSelectorAffix();
	}
	/**
	 * UISchema specific idea of a repeatable item
	 * @param out
	 * @param r
	 * @param context
	 * @throws JSONException
	 */
	private void UISchemaRepeatItem(JSONObject out, Repeat r, UISpecRunContext context)
			throws JSONException {
		JSONObject items = new JSONObject();
		JSONObject structuredate = new JSONObject();

		String selector = getSelector(r,context);
		JSONObject preProtoTree = new JSONObject();

		if(isARepeatingSubRecord(r)){
			makeASubRecordEntry(preProtoTree, r, context, out);
			preProtoTree = preProtoTree.getJSONObject(selector).getJSONObject("properties");
		}
		else{
			Integer numChild = r.getChildren("").length;
			for(FieldSet child :r.getChildren("")) {
				whatIsThisFieldSet(preProtoTree, child, context);
				if(isAStructureDate(child)){
					Boolean truerepeat = isATrueRepeat(r);
					//should we use structured dates in line rather than nested

					if(!truerepeat){
						structuredate = preProtoTree.getJSONObject(getSelector(child,context)).getJSONObject("properties");
						preProtoTree.remove(getSelector(child,context));
						Iterator rit=structuredate.keys();
						while(rit.hasNext()) {
							String key=(String)rit.next();
							preProtoTree.put(key, structuredate.get(key));
						}
					}
					else if(numChild != 1 && preProtoTree.has("properties")){

						structuredate.put("properties",preProtoTree.getJSONObject("properties"));
						if(preProtoTree.has("type")){
							structuredate.put("type",preProtoTree.getString("type"));
							preProtoTree.remove("type");
						}
						else{
							structuredate.put("type","object");
						}
						preProtoTree.remove("properties");
						preProtoTree.put(getSelector(child,context), structuredate);
					}
				}
			}
		}
		//actualRepeatNonSiblingEntry(out, r, context, preProtoTree);//XXX ??? do I need this?
		if(preProtoTree.has("properties")){
			preProtoTree = preProtoTree.getJSONObject("properties");
		}
		if (r.hasPrimary()) {
			JSONObject output = new JSONObject();
			actualSchemaObject("boolean", true, null, null, output);
			preProtoTree.put("_primary", output);
		}
		actualSchemaObject("object", null, preProtoTree, null, items);
		JSONObject output = new JSONObject();
		actualSchemaObject("array", null, null, items, output);
		out.put(selector, output);
	}

	protected void makeARepeatSiblingEntry(JSONObject out, Repeat r, UISpecRunContext context) throws JSONException {
		UISchemaRepeatItem(out, r, context);
	}
	protected void makeARepeatNonSiblingEntry(JSONObject out, Repeat r, UISpecRunContext context) throws JSONException{
		makeARepeatSiblingEntry(out, r, context);
	}
	protected void makeASelfRenderer(FieldSet fs, UISpecRunContext context,
			JSONObject out, JSONObject subexpander, JSONObject options,
			Record subitems, UISpecRunContext sub) throws JSONException {
		for(FieldSet fs2 : subitems.getAllFieldTopLevel("")) {
			whatIsThisFieldSet(out, fs2, context);
		}
	}

	protected Object actualENUMField(Field f,UISpecRunContext context) throws JSONException {
		String type = "string";
		String defaultval = f.getEnumDefault();
		if( (this.spectype.equals("search") && !f.getSearchType().equals(""))){
			defaultval = "";
		}
		JSONObject output = new JSONObject();
		actualSchemaObject(type, defaultval, null, null, output);
		return output;
	}

	protected Object actualBooleanField(Field f,UISpecRunContext context) throws JSONException {
		String type = "boolean";
		String defaultval = f.getDefault();
		Boolean defval = false;
		if("1".equals(defaultval) || "yes".equals(defaultval.toLowerCase()) || "true".equals(defaultval.toLowerCase())){
			defval = true;
		}
		if( (this.spectype.equals("search") && !f.getSearchType().equals(""))){
			defval = null;
		}
		JSONObject output = new JSONObject();
		actualSchemaObject(type, defval, null, null, output);
		return output;
	}
	/**
	 * Selector is just the ID in the UISchema
	 * @param fs
	 * @param context
	 * @return
	 */
	protected String getSelector(FieldSet fs, UISpecRunContext context) {
		return fs.getID();
	}

	/**
	 * Abstraction for creating the UISchema structure for items
	 * @param r
	 * @param context
	 * @return
	 * @throws JSONException
	 */
	private JSONObject actualSchemaFields(Record r,UISpecRunContext context) throws JSONException {
		JSONObject out = generateDataEntrySection(context, r, this.spectype);
		JSONObject output = new JSONObject();
		actualSchemaObject("object", null, out, null, output);
		return output;
	}
	/**
	 * Generate the UISpec Relations bit
	 * @return
	 * @throws JSONException
	 */
	private JSONObject actualSchemaRelations() throws JSONException {
		JSONObject output = new JSONObject();
		actualSchemaObject("object", new JSONObject(), null, null, output);
		return output;
	}
	/**
	 * Generate the UISchema Termsused section
	 * @param affix
	 * @return
	 * @throws JSONException
	 */
	private JSONObject actualSchemaTermsUsed(UISpecRunContext affix) throws JSONException {
		JSONObject output = new JSONObject();
		actualSchemaObject("array", new JSONArray(), null, null, output);
		return output;
	}

	/**
	 * Nuts and bolts of the UISchema obj structure
	 * @param type
	 * @param defaultobj
	 * @param properties
	 * @param items
	 * @return
	 * @return
	 * @throws JSONException
	 */
	private void actualSchemaObject(String type, Object defaultobj,
			JSONObject properties, JSONObject items, JSONObject out) throws JSONException {
		out.put("type", type);// array|object|string
		if (defaultobj != null) {
			out.put("default", defaultobj);
		}
		if (properties != null) {
			out.put("properties", properties);
		}
		if (items != null) {
			out.put("items", items);
		}
	}
	/**
	 * Create all the other weird schemas that the UI wants
	 * @param storage
	 * @param params
	 * @return
	 * @throws UIException
	 */
	private JSONObject uiotherschema(Storage storage, String params) throws UIException {
		JSONObject out = new JSONObject();
		String sectionname = "";
		String sectionid = params.toLowerCase();
		if(schema !=null){
			sectionid = schema.getID();
			sectionname = schema.getWebURL();
		}
		try {
			if (sectionid.toLowerCase().equals("recordlist")) {
				JSONObject schema = new JSONObject();
				JSONArray recrds = new JSONArray();
				for(Record rc : this.spec.getAllRecords()){
					if(rc.isShowType("authority")){
						if(rc.isInRecordList()){
							for(Instance ins : rc.getAllInstances()){
								recrds.put(ins.getWebURL());
							}
						}
					}
					else if(rc.isShowType("record")||rc.isShowType("procedure")){
						if(rc.isInRecordList()){
							recrds.put(rc.getWebURL());
						}
					}
				}
				schema.put("type", "array");
				schema.put("default", recrds);
				out.put(sectionname, schema);
			}
			else if(sectionid.toLowerCase().equals("namespaces")){
				JSONObject namespaces = new JSONObject();
				JSONObject namespacesProps = new JSONObject();

				for (Record rc : this.spec.getAllRecords()) {
					if (rc.isInRecordList()) {
						if (rc.isShowType("authority")) {
							JSONObject authInfoProps = new JSONObject();
							int cardinal = 0;
							for(Instance ins : rc.getAllInstances()){
								JSONObject instanceInfo = new JSONObject();
								JSONObject instanceProps = new JSONObject();
								JSONObject nptAllowed = new JSONObject();
								nptAllowed.put("type", "boolean");
								nptAllowed.put("default", ins.getNPTAllowed());
								instanceProps.put("nptAllowed", nptAllowed);
								// Preserve the order of the namespaces
								JSONObject orderProp = new JSONObject();
								orderProp.put("type", "integer");
								orderProp.put("default", cardinal);
								instanceProps.put("order", orderProp);
								instanceInfo.put("type", "object");
								instanceInfo.put("properties", instanceProps);
								authInfoProps.put(ins.getWebURL(), instanceInfo);
								cardinal++;
							}
							JSONObject authorityInfo = new JSONObject();
							authorityInfo.put("type", "object");
							authorityInfo.put("properties", authInfoProps);
							namespacesProps.put(rc.getWebURL(), authorityInfo);
						}
					}
				}
				namespaces.put("type", "object");
				namespaces.put("properties", namespacesProps);
				out.put("namespaces", namespaces);
				/**
				 *
{
    "namespaces": {
        "type": "object",
        "properties": {
            "person": {
                "type": "object"
                "properties": {
                    "person" : {
                        "type": "object"
                        "properties": {
                            "nptAllowed": {
                                "type": "boolean",
                                "default": true
                            }
                        }
                    },
                    "persontest" : {
                        "type": "object"
                        "properties": {
                            "nptAllowed": {
                                "type": "boolean",
                                "default": true
                            }
                        }
                    }
                }
            },
            "organization": {
                "type": "object"
                "properties": {
                    "organization" : {
                        "type": "object"
                        "properties": {
                            "nptAllowed": {
                                "type": "boolean",
                                "default": true
                            }
                        }
                    },
                    "organizationtest" : {
                        "type": "object"
                        "properties": {
                            "nptAllowed": {
                                "type": "boolean",
                                "default": true
                            }
                        }
                    }
                }
            },
            ...
        }
    }
}
				 */
			}
			else if(sectionid.toLowerCase().equals("recordtypes")){

				JSONObject procedures_schema = new JSONObject();
				JSONObject authorities_schema = new JSONObject();
				JSONObject admin_schema = new JSONObject();
				JSONObject cataloging_schema = new JSONObject();
				JSONObject searchAll_schema = new JSONObject();

				JSONArray procedures_records = new JSONArray();
				JSONArray authorities_records = new JSONArray();
				JSONArray admin_records = new JSONArray();
				JSONArray cataloging_records = new JSONArray();
				JSONArray searchAll_records = new JSONArray();
				/**
				 * { "procedures": { "type": "array", "default": ["loanout",
				 * "movement", ...] }, "vocabularies": { "type": "array",
				 * "default": ["person", "organization", ...] }, "cataloging": {
				 * "type": "array", "default": ["cataloging"] } }
				 */
				for (Record rc : this.spec.getAllRecords()) {
					if (rc.isInRecordList()) {
						if (rc.isShowType("procedure")) {
							procedures_records.put(rc.getWebURL());
						} else if (rc.isShowType("authority")) {
							for(Instance ins : rc.getAllInstances()){
								authorities_records.put(ins.getWebURL());
							}
						} else if (rc.isShowType("record")) {
							// FIXME Assumes that "records" are either
							// procedures, authorities, or cataloging.
							// Should instead have a type "cataloging"
							cataloging_records.put(rc.getWebURL());
						} else if (rc.isShowType("searchall")) {
								searchAll_records.put(rc.getWebURL());
						} else if(rc.isShowType("authorizationdata") || rc.isShowType("userdata")){
							admin_records.put(rc.getWebURL());
						}
					}
				}

				procedures_schema.put("type", "array");
				procedures_schema.put("default", procedures_records);
				authorities_schema.put("type", "array");
				authorities_schema.put("default", authorities_records);
				admin_schema.put("type", "array");
				admin_schema.put("default", admin_records);
				cataloging_schema.put("type", "array");
				cataloging_schema.put("default", cataloging_records);
				searchAll_schema.put("type", "array");
				searchAll_schema.put("default", searchAll_records);

				JSONObject record_types = new JSONObject();
				JSONObject types_list = new JSONObject();

				types_list.put("procedures", procedures_schema);
				types_list.put("vocabularies", authorities_schema);
				types_list.put("cataloging", cataloging_schema);
				types_list.put("all", searchAll_schema);
				types_list.put("administration", admin_schema);
				record_types.put("type","object");
				record_types.put("properties",types_list);

				out.put("recordtypes", record_types);

			}
		} catch (JSONException e) {
			throw new UIException("Cannot generate UISpec due to JSONException", e);
		}
		return out;
	}
	/**
	 * Create the search uischemas
	 * @param storage
	 * @param record
	 * @return
	 * @throws UIException
	 */
	private JSONObject uisearchschema(Storage storage, Record record) throws UIException {
		UISpecRunContext context = new UISpecRunContext();
		this.storage = storage;
		this.record = record;
		this.tenantname = this.record.getSpec().getAdminData().getTenantName();

		try {
			JSONObject out = new JSONObject();

			JSONObject fields = actualSchemaFields(record, context);
			JSONObject prop = fields.getJSONObject("properties");
			fields.put("properties", prop);
			out.put(record.getWebURL(), fields);
			return out;
		} catch (JSONException e) {
			throw new UIException("Cannot generate UISpec due to JSONException", e);
		}
	}

	/**
	 * Create the generic UI record schemas
	 * @param storage
	 * @param record
	 * @return
	 * @throws UIException
	 */
	private JSONObject uirecordschema(Storage storage,Record record) throws UIException {
		UISpecRunContext context = new UISpecRunContext();
		this.storage = storage;
		this.record = record;
		this.tenantname = this.record.getSpec().getAdminData().getTenantName();
		try {
			JSONObject out = new JSONObject();
			JSONObject details = new JSONObject();
			JSONObject properties = new JSONObject();

			if (record.hasTermsUsed()) {
				properties.put("termsUsed", actualSchemaTermsUsed(context));
			}
			if (record.hasRefObjUsed()) {
				properties.put("relations", actualSchemaRelations());
			}
			JSONObject fields = actualSchemaFields(record, context);
			JSONObject prop = fields.getJSONObject("properties");

			if(record.hasHierarchyUsed("screen")){
				JSONObject temp = actualSchemaFields(record.getSpec().getRecord("hierarchy"),context);
				JSONObject prop2 = temp.getJSONObject("properties");

				Iterator rit=prop2.keys();
				while(rit.hasNext()) {
					String key=(String)rit.next();
					Object value = prop2.get(key);
					prop.put(key,value);
				}
			}
			fields.put("properties", prop);
			properties.put("fields", fields);

			JSONObject output = new JSONObject();
			actualSchemaObject("string", null, null, null, output);
			properties.put("csid", output);
			actualSchemaObject("object", null, properties, null, details);

			out.put(record.getWebURL(), details);
			/*
			 * { "cataloging": { "type": "object", "properties": {
			 */

			return out;
		} catch (JSONException e) {
			throw new UIException("Cannot generate UISpec due to JSONException", e);
		}
	}
}


text:
import React, { PropTypes } from 'react';
import * as styles from '../global/styles';

const InfoHomePage = (props) => {
  return (
    <div style={styles.results.infoHomePageContainer}>
      <a
        style={styles.results.infoHomePageLink}
        href={props.homePage}
        target="_blank">
        {props.homePage}
      </a>
    </div>
  );
}

InfoHomePage.propTypes = {
  homePage: PropTypes.string
};

export default InfoHomePage;


text:
var localStream, room;

DEMO.init_demo = function (my_name) {

  localStream = Erizo.Stream({audio: true, video: false, data: true, attributes: {name: my_name}});
  DEMO.chat_stream = localStream;

  DEMO.create_token("user", "presenter", function (response) {
    var token = response;
    console.log(token);
    room = Erizo.Room({token: token});

    localStream.addEventListener("access-accepted", function () {
      var subscribeToStreams = function (streams) {
        for (var index in streams) {
          var stream = streams[index];
          if (localStream.getID() !== stream.getID()) {
            room.subscribe(stream);
          }
        }
      };

      room.addEventListener("room-connected", function (roomEvent) {
        DEMO.connect_to_chat();
        console.log('vopy a pub');
        room.publish(localStream);
        subscribeToStreams(roomEvent.streams);
      });

      room.addEventListener("stream-subscribed", function(streamEvent) {
        var stream = streamEvent.stream;

        add_div_to_grid("test" + stream.getID(), stream.getAttributes().name)
        stream.play("test" + stream.getID());

        stream.addEventListener("stream-data", DEMO.chat_message_received);
        DEMO.add_chat_participant(stream.getAttributes().name);

      });

      room.addEventListener("stream-added", function (streamEvent) {
        var streams = [];
        streams.push(streamEvent.stream);
        subscribeToStreams(streams);
      });

      room.addEventListener("stream-removed", function (streamEvent) {
        // Remove stream from DOM
        var stream = streamEvent.stream;
        if (stream.elementID !== undefined) {
          remove_div_from_grid(stream.elementID, "video_grid");
        }
      });

      room.connect();

      add_div_to_grid("localVideo", my_name + ' (自己)');
      localStream.play("localVideo");

    });
    localStream.init();
  });
};

var add_div_to_grid = function(divId, name) {

    $('#video_grid').css('border', 'none');

    var grid = document.getElementById('video_grid');
    var newDiv = document.createElement('div');
    newDiv.setAttribute("id", divId + '_container');
    newDiv.className = newDiv.className + " grid_element_border";

    var newDiv2 = document.createElement('div');
    newDiv2.setAttribute("id", divId);
    newDiv2.className = newDiv2.className + " grid_element";
    newDiv.appendChild(newDiv2);

    newDiv2.setAttribute("style", "background-image: url(/images/audio_user.gif); background-position: center; background-repeat: no-repeat; background-color: white; background-size: contain;");

    var p = document.createElement('h5');
    p.innerHTML = name;
    p.setAttribute("style", "position: absolute; padding-left: 10px");
    newDiv.appendChild(p);

    grid.appendChild(newDiv);
    resizeGrid('video_grid');
}

var remove_div_from_grid = function(divId) {

    var grid = document.getElementById('video_grid');
    grid.removeChild(document.getElementById(divId + '_container'));
    resizeGrid('video_grid');
}

var resizeGrid = function() {

    var grid = document.getElementById('video_grid');
    var nChilds = grid.childElementCount;

    var c = Math.floor((nChilds-1)/3);
    var r = (nChilds-1) % 3;

    if (nChilds === 1) {
        grid.childNodes[1].setAttribute("style", "width: 100%; height: 100%;");
    } else {

        var height = 100/(c+1);

        for(var i = 1; i <= nChilds; i++) {

            var row = Math.floor((i-1) / 3);
            var width = 100/3;

            if (r === 0) {  // las dos últimas filas tienen dos vídeos

                if (row > c - 2) {
                    width = 50;
                }
                grid.childNodes[i].setAttribute("style", "width: " + width + "%; height: " + height + "%;");

            } else if (r === 1) {  // la última fila tiene un vídeo
                if (row === c) {
                    width = 50;
                }
                grid.childNodes[i].setAttribute("style", "width: " + width + "%; height: " + height + "%;");

            } else {
                grid.childNodes[i].setAttribute("style", "width: " + width + "%; height: " + height + "%;");
            }
        }
    }
}


text:
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="../assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Warren Liu (Posts about coding)</title><link>https://wudong.graceliu.uk/</link><description></description><atom:link href="https://wudong.graceliu.uk/categories/coding.xml" rel="self" type="application/rss+xml"></atom:link><language>en</language><copyright>Contents © 2017 Warren Liu </copyright><lastBuildDate>Mon, 17 Jul 2017 07:12:10 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>Coding Questions</title><link>https://wudong.graceliu.uk/posts/notes/coding-questions/</link><dc:creator>Warren Liu</dc:creator><description>

Table of Contents

Some Coding Questions

Some Coding Questions

String rotation:

  Use substring() only to determine if a string is a rotation
of the other.

Return k-th to last element (last k element) of a singlely linked list

Delete middle node in a singely linke list, given only access to
that node.

Partition a linked list around a value x, so that the node that
has value smaller than x comes before the those larger than x.

</description><category>algorithm</category><category>coding</category><guid>https://wudong.graceliu.uk/posts/notes/coding-questions/</guid><pubDate>Fri, 14 Jul 2017 15:28:48 GMT</pubDate></item></channel></rss>


text:
/*	$NetBSD: portset.c,v 1.1.1.2.4.1 2014/12/24 00:05:17 riz Exp $	*/

/*
 * Copyright (C) 2008  Internet Systems Consortium, Inc. ("ISC")
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/* Id: portset.c,v 1.4 2008/06/24 23:24:35 marka Exp  */

/*! \file */

#include <config.h>

#include <isc/mem.h>
#include <isc/portset.h>
#include <isc/string.h>
#include <isc/types.h>
#include <isc/util.h>

#define ISC_PORTSET_BUFSIZE (65536 / (sizeof(isc_uint32_t) * 8))

/*%
 * Internal representation of portset.  It's an array of 32-bit integers, each
 * bit corresponding to a single port in the ascending order.  For example,
 * the second most significant bit of buf[0] corresponds to port 1.
 */
struct isc_portset {
	unsigned int nports;	/*%< number of ports in the set */
	isc_uint32_t buf[ISC_PORTSET_BUFSIZE];
};

static inline isc_boolean_t
portset_isset(isc_portset_t *portset, in_port_t port) {
	return (ISC_TF((portset->buf[port >> 5] & (1 << (port & 31))) != 0));
}

static inline void
portset_add(isc_portset_t *portset, in_port_t port) {
	if (!portset_isset(portset, port)) {
		portset->nports++;
		portset->buf[port >> 5] |= (1 << (port & 31));
	}
}

static inline void
portset_remove(isc_portset_t *portset, in_port_t port) {
	if (portset_isset(portset, port)) {
		portset->nports--;
		portset->buf[port >> 5] &= ~(1 << (port & 31));
	}
}

isc_result_t
isc_portset_create(isc_mem_t *mctx, isc_portset_t **portsetp) {
	isc_portset_t *portset;

	REQUIRE(portsetp != NULL && *portsetp == NULL);

	portset = isc_mem_get(mctx, sizeof(*portset));
	if (portset == NULL)
		return (ISC_R_NOMEMORY);

	/* Make the set 'empty' by default */
	memset(portset, 0, sizeof(*portset));
	*portsetp = portset;

	return (ISC_R_SUCCESS);
}

void
isc_portset_destroy(isc_mem_t *mctx, isc_portset_t **portsetp) {
	isc_portset_t *portset;

	REQUIRE(portsetp != NULL);
	portset = *portsetp;

	isc_mem_put(mctx, portset, sizeof(*portset));
}

isc_boolean_t
isc_portset_isset(isc_portset_t *portset, in_port_t port) {
	REQUIRE(portset != NULL);

	return (portset_isset(portset, port));
}

unsigned int
isc_portset_nports(isc_portset_t *portset) {
	REQUIRE(portset != NULL);

	return (portset->nports);
}

void
isc_portset_add(isc_portset_t *portset, in_port_t port) {
	REQUIRE(portset != NULL);

	portset_add(portset, port);
}

void
isc_portset_remove(isc_portset_t *portset, in_port_t port) {
	portset_remove(portset, port);
}

void
isc_portset_addrange(isc_portset_t *portset, in_port_t port_lo,
		     in_port_t port_hi)
{
	in_port_t p;

	REQUIRE(portset != NULL);
	REQUIRE(port_lo <= port_hi);

	p = port_lo;
	do {
		portset_add(portset, p);
	} while (p++ < port_hi);
}

void
isc_portset_removerange(isc_portset_t *portset, in_port_t port_lo,
			in_port_t port_hi)
{
	in_port_t p;

	REQUIRE(portset != NULL);
	REQUIRE(port_lo <= port_hi);

	p = port_lo;
	do {
		portset_remove(portset, p);
	} while (p++ < port_hi);
}


text:
package main

import (
	"encoding/json"
	"log"
	"net/http"

	"github.com/jf-marino/simple.go.server/controllers"
	"github.com/jf-marino/simple.go.server/routes"
	"github.com/jf-marino/simple.go.server/storage"
)

func main() {
	log.Println("Starting server...")
	storage.Initialize()

	log.Println("Server initialized...")
	log.Println("Moving on to setting up routes...")
	people := new(routes.PeopleHandler)
	root := new(routes.RootHandler)

	http.Handle("/", root)
	http.Handle("/people", people)
	http.HandleFunc("/events", createEvent)
	http.HandleFunc("/events/all", selectEvents)

	log.Println("Finished setup...")
	http.ListenAndServe(":8080", nil)
	log.Println("Listening...")
}

func createEvent(w http.ResponseWriter, r *http.Request) {
	controllers.CreateEvent("SomeEventName")
	json.NewEncoder(w).Encode(nil)
}

func selectEvents(w http.ResponseWriter, r *http.Request) {
	events := controllers.GetEvents()
	json.NewEncoder(w).Encode(events)
}


text:
package com.asksunny.jdbc.wrapper;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.sql.SQLException;
import java.sql.SQLXML;

import javax.xml.transform.Result;
import javax.xml.transform.Source;

public class SqlXmlObject implements SQLXML {

	public SqlXmlObject() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public void free() throws SQLException {
		// TODO Auto-generated method stub

	}

	@Override
	public InputStream getBinaryStream() throws SQLException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public OutputStream setBinaryStream() throws SQLException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Reader getCharacterStream() throws SQLException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Writer setCharacterStream() throws SQLException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String getString() throws SQLException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void setString(String value) throws SQLException {
		// TODO Auto-generated method stub

	}

	@Override
	public <T extends Source> T getSource(Class<T> sourceClass)
			throws SQLException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public <T extends Result> T setResult(Class<T> resultClass)
			throws SQLException {
		// TODO Auto-generated method stub
		return null;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

}


text:
class Admin::DocumentsController < ApplicationController
  layout "admin"

  # List documents
  def index
    @documents = Document.where({})

    respond_to do |format|
      format.html
      format.xml  { render :xml => @documents }
    end
  end

  # Show a doc
  def show
    @document = Document.find(params[:id])

    respond_to do |format|
      format.html
      format.xml  { render :xml => @document }
    end
  end

  # New doc form
  def new
    @document = Document.new

    respond_to do |format|
      format.html
      format.xml  { render :xml => @document }
    end
  end

  # Edit doc form
  def edit
    @document = Document.find(params[:id])
  end

  # Create a doc
  def create
    @document = Document.new(params[:document])

    respond_to do |format|
      if @document.save
        format.html { redirect_to(edit_document_path(@document), :notice => 'Document was successfully created.') }
        format.xml  { render :xml => @document, :status => :created, :location => @document }
      else
        flash.now[:error] = "Could not create."
        format.html { render :action => "new" }
        format.xml  { render :xml => @document.errors, :status => :unprocessable_entity }
      end
    end
  end

  # Update a doc
  def update
    @document = Document.find(params[:id])

    respond_to do |format|
      if @document.update_attributes(params[:document])
        format.html { redirect_to(edit_document_path(@document), :notice => 'Document was successfully updated.') }
        format.xml  { head :ok }
      else
        flash.now[:error] = "Could not update."
        format.html { render :action => "edit" }
        format.xml  { render :xml => @document.errors, :status => :unprocessable_entity }
      end
    end
  end

  # Delete a doc
  def destroy
    @document = Document.find(params[:id])
    @document.destroy

    respond_to do |format|
      format.html { redirect_to(documents_url) }
      format.xml  { head :ok }
    end
  end
end


text:
<?php
// autogenerated file 30.09.2013 15:20
// $Id: $
// $Log: $
//
//
require_once 'AbstractResponseType.php';

/**
 * Response to AddMemberMessageRTQ request.
 *
 * @link http://developer.ebay.com/DevZone/XML/docs/Reference/eBay/types/AddMemberMessageRTQResponseType.html
 *
 */
class AddMemberMessageRTQResponseType extends AbstractResponseType
{

	/**
	 * @return
	 */
	function __construct()
	{
		parent::__construct('AddMemberMessageRTQResponseType', 'urn:ebay:apis:eBLBaseComponents');
		if (!isset(self::$_elements[__CLASS__])) {
			self::$_elements[__CLASS__] = array_merge(self::$_elements[get_parent_class()], array());
		}
	}
}
?>


text:
<?php

namespace Smath\ProductoBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;

class SmathProductoBundle extends Bundle
{
}


text:
package net.fehmicansaglam.tepkin.protocol.command

import akka.util.ByteString
import net.fehmicansaglam.bson.BsonDocument
import net.fehmicansaglam.tepkin.protocol.message.Message

/**
 * A MongoDB Command.
 *
 * Basically, it is a query that is performed on any db.\$cmd collection.
 */
trait Command extends Message {

  override val responseTo: Int = 0

  override val opCode: Int = 2004

  def databaseName: String

  def command: BsonDocument

  override def encodeBody: ByteString = {
    val flags: Int = 0

    ByteString.newBuilder
      .putInt(flags)
      .putBytes((databaseName + ".$cmd").getBytes("utf-8"))
      .putByte(0)
      .putInt(0) // numberToSkip
      .putInt(1) // numberToReturn
      .append(command.encode)
      .result()
  }
}

/**
 * A command that targets the admin database only (administrative commands).
 */
trait AdminCommand extends Command {
  override def databaseName: String = "admin"
}


text:
namespace PTL
{
template <typename FuncT, typename... ArgTypes>
#if __cpp_lib_is_invocable >= 201703
using ResultOf_t = std::invoke_result_t<FuncT, ArgTypes...>;
#else
using ResultOf_t = typename std::result_of<FuncT(ArgTypes...)>::type;
#endif
}  // namespace PTL

// compatible OS and compiler
#if defined(PTL_UNIX) &&                                                                 \
    (defined(__GNUC__) || defined(__clang__) || defined(_INTEL_COMPILER))
#    if !defined(PTL_SIGNAL_AVAILABLE)
#        define PTL_SIGNAL_AVAILABLE
#    endif
#    if !defined(PTL_DEMANGLE_AVAILABLE)
#        define PTL_DEMANGLE_AVAILABLE
#    endif
#endif

#if !defined(PTL_PSIGINFO_AVAILABLE)
#    if _XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L
#        define PTL_PSIGINFO_AVAILABLE 1
#    else
#        define PTL_PSIGINFO_AVAILABLE 0
#    endif
#endif

//----------------------------------------------------------------------------//

namespace PTL
{
inline std::string
Demangle(const char* _str)
{
#if defined(PTL_DEMANGLE_AVAILABLE)
    // demangling a string when delimiting
    int   _status = 0;
    char* _ret    = ::abi::__cxa_demangle(_str, nullptr, nullptr, &_status);
    if(_ret && _status == 0)
        return std::string(const_cast<const char*>(_ret));
    return _str;
#else
    return _str;
#endif
}

//----------------------------------------------------------------------------//

inline std::string
Demangle(const std::string& _str)
{
    return Demangle(_str.c_str());
}

//----------------------------------------------------------------------------//

template <typename Tp>
inline std::string
Demangle()
{
    return Demangle(typeid(Tp).name());
}
}  // namespace PTL

//----------------------------------------------------------------------------//
//
//      ONLY IF SIGNAL_AVAILABLE
//
//----------------------------------------------------------------------------//
//
#if defined(PTL_SIGNAL_AVAILABLE)
//
//  these are not in the original POSIX.1-1990 standard so we are defining
//  them in case the OS hasn't
//  POSIX-1.2001
#    ifndef SIGTRAP
#        define SIGTRAP 5
#    endif
//  not specified in POSIX.1-2001, but nevertheless appears on most other
//  UNIX systems, where its default action is typically to terminate the
//  process with a core dump.
#    ifndef SIGEMT
#        define SIGEMT 7
#    endif
//  POSIX-1.2001
#    ifndef SIGURG
#        define SIGURG 16
#    endif
//  POSIX-1.2001
#    ifndef SIGXCPU
#        define SIGXCPU 24
#    endif
//  POSIX-1.2001
#    ifndef SIGXFSZ
#        define SIGXFSZ 25
#    endif
//  POSIX-1.2001
#    ifndef SIGVTALRM
#        define SIGVTALRM 26
#    endif
//  POSIX-1.2001
#    ifndef SIGPROF
#        define SIGPROF 27
#    endif
//  POSIX-1.2001
#    ifndef SIGINFO
#        define SIGINFO 29
#    endif

//----------------------------------------------------------------------------//

#    include <algorithm>
#    include <array>
#    include <cstdio>
#    include <cstdlib>
#    include <functional>
#    include <iomanip>
#    include <iostream>
#    include <map>
#    include <regex>
#    include <set>
#    include <sstream>
#    include <string>
#    include <tuple>
#    include <vector>

// PTL header
#    include "Threading.hh"

//----------------------------------------------------------------------------//

namespace PTL
{
class Backtrace
{
public:
    using sigaction_t   = struct sigaction;
    using exit_action_t = std::function<void(int)>;
    using frame_func_t  = std::function<std::string(const char*)>;
    using signal_set_t  = std::set<int>;

public:
    struct actions
    {
        using id_entry_t = std::tuple<std::string, int, std::string>;
        using id_list_t  = std::vector<id_entry_t>;

        std::map<int, bool>        is_active    = {};
        std::map<int, sigaction_t> current      = {};
        std::map<int, sigaction_t> previous     = {};
        std::vector<exit_action_t> exit_actions = {};
        const id_list_t            identifiers  = {
            id_entry_t("SIGHUP", SIGHUP, "terminal line hangup"),
            id_entry_t("SIGINT", SIGINT, "interrupt program"),
            id_entry_t("SIGQUIT", SIGQUIT, "quit program"),
            id_entry_t("SIGILL", SIGILL, "illegal instruction"),
            id_entry_t("SIGTRAP", SIGTRAP, "trace trap"),
            id_entry_t("SIGABRT", SIGABRT, "abort program (formerly SIGIOT)"),
            id_entry_t("SIGEMT", SIGEMT, "emulate instruction executed"),
            id_entry_t("SIGFPE", SIGFPE, "floating-point exception"),
            id_entry_t("SIGKILL", SIGKILL, "kill program"),
            id_entry_t("SIGBUS", SIGBUS, "bus error"),
            id_entry_t("SIGSEGV", SIGSEGV, "segmentation violation"),
            id_entry_t("SIGSYS", SIGSYS, "non-existent system call invoked"),
            id_entry_t("SIGPIPE", SIGPIPE, "write on a pipe with no reader"),
            id_entry_t("SIGALRM", SIGALRM, "real-time timer expired"),
            id_entry_t("SIGTERM", SIGTERM, "software termination signal"),
            id_entry_t("SIGURG", SIGURG, "urgent condition present on socket"),
            id_entry_t("SIGSTOP", SIGSTOP, "stop (cannot be caught or ignored)"),
            id_entry_t("SIGTSTP", SIGTSTP, "stop signal generated from keyboard"),
            id_entry_t("SIGCONT", SIGCONT, "continue after stop"),
            id_entry_t("SIGCHLD", SIGCHLD, "child status has changed"),
            id_entry_t("SIGTTIN", SIGTTIN,
                       "background read attempted from control terminal"),
            id_entry_t("SIGTTOU", SIGTTOU,
                       "background write attempted to control terminal"),
            id_entry_t("SIGIO ", SIGIO, "I/O is possible on a descriptor"),
            id_entry_t("SIGXCPU", SIGXCPU, "cpu time limit exceeded"),
            id_entry_t("SIGXFSZ", SIGXFSZ, "file size limit exceeded"),
            id_entry_t("SIGVTALRM", SIGVTALRM, "virtual time alarm"),
            id_entry_t("SIGPROF", SIGPROF, "profiling timer alarm"),
            id_entry_t("SIGWINCH", SIGWINCH, "Window size change"),
            id_entry_t("SIGINFO", SIGINFO, "status request from keyboard"),
            id_entry_t("SIGUSR1", SIGUSR1, "User defined signal 1"),
            id_entry_t("SIGUSR2", SIGUSR2, "User defined signal 2")
        };
    };

public:
    // a functor called for each frame in the backtrace
    static frame_func_t& FrameFunctor();
    // default set of signals
    static signal_set_t& DefaultSignals();
    // the signal handler
    static void Handler(int sig, siginfo_t* sinfo, void* context);
    // information message about the signal, performs exit-actions
    // and prints back-trace
    static void Message(int sig, siginfo_t* sinfo, std::ostream&);
    // calls user-provided functions after signal is caught but before abort
    static void ExitAction(int sig);
    // enable signals via a string (which is tokenized)
    static int Enable(const std::string&);
    // enable signals via set of integers, anything less than zero is ignored
    static int Enable(const signal_set_t& _signals = DefaultSignals());
    // disable signals
    static int Disable(signal_set_t _signals = {});
    // gets the numeric value for a signal name
    static int GetSignal(const std::string&);
    // provides a description of the signal
    static std::string Description(int sig);

    // adds an exit action
    template <typename FuncT>
    static void AddExitAction(FuncT&& func);

    // gets a backtrace of "Depth" frames. The offset parameter is used
    // to ignore initial frames (such as this function). A callback
    // can be provided to inspect and/or tweak the frame string
    template <size_t Depth, size_t Offset = 0, typename FuncT = frame_func_t>
    static std::array<ResultOf_t<FuncT, const char*>, Depth> GetMangled(
        FuncT&& func = FrameFunctor());

    // gets a demangled backtrace of "Depth" frames. The offset parameter is
    // used to ignore initial frames (such as this function). A callback
    // can be provided to inspect and/or tweak the frame string
    template <size_t Depth, size_t Offset = 0, typename FuncT = frame_func_t>
    static std::array<ResultOf_t<FuncT, const char*>, Depth> GetDemangled(
        FuncT&& func = FrameFunctor());

private:
    static actions& GetData()
    {
        static auto _instance = actions{};
        return _instance;
    }
};

//----------------------------------------------------------------------------//

// a functor called for each frame in the backtrace
inline Backtrace::frame_func_t&
Backtrace::FrameFunctor()
{
    static frame_func_t _instance = [](const char* inp) { return std::string(inp); };
    return _instance;
}

//----------------------------------------------------------------------------//

// default set of signals
inline Backtrace::signal_set_t&
Backtrace::DefaultSignals()
{
    static signal_set_t _instance = {
        SIGQUIT, SIGILL, SIGABRT, SIGKILL, SIGBUS, SIGSEGV
    };
    return _instance;
}

//----------------------------------------------------------------------------//

template <typename FuncT>
inline void
Backtrace::AddExitAction(FuncT&& func)
{
    GetData().exit_actions.emplace_back(std::forward<FuncT>(func));
}

//----------------------------------------------------------------------------//

inline void
Backtrace::ExitAction(int sig)
{
    for(auto& itr : GetData().exit_actions)
        itr(sig);
}

//----------------------------------------------------------------------------//

template <size_t Depth, size_t Offset, typename FuncT>
inline std::array<ResultOf_t<FuncT, const char*>, Depth>
Backtrace::GetMangled(FuncT&& func)
{
    static_assert((Depth - Offset) >= 1, "Error Depth - Offset should be >= 1");

    using type = ResultOf_t<FuncT, const char*>;
    // destination
    std::array<type, Depth> btrace;
    btrace.fill((std::is_pointer<type>::value) ? nullptr : type{});

    // plus one for this stack-frame
    std::array<void*, Depth + Offset> buffer;
    // size of returned buffer
    auto sz = backtrace(buffer.data(), Depth + Offset);
    // size of relevant data
    auto n = sz - Offset;

    // skip ahead (Offset + 1) stack frames
    char** bsym = backtrace_symbols(buffer.data() + Offset, n);

    // report errors
    if(bsym == nullptr)
        perror("backtrace_symbols");
    else
    {
        for(decltype(n) i = 0; i < n; ++i)
            btrace[i] = func(bsym[i]);
        free(bsym);
    }
    return btrace;
}

//----------------------------------------------------------------------------//

template <size_t Depth, size_t Offset, typename FuncT>
inline std::array<ResultOf_t<FuncT, const char*>, Depth>
Backtrace::GetDemangled(FuncT&& func)
{
    auto demangle_bt = [&](const char* cstr) {
        auto _trim = [](std::string& _sub, size_t& _len) {
            size_t _pos = 0;
            while((_pos = _sub.find_first_of(' ')) == 0)
            {
                _sub = _sub.erase(_pos, 1);
                --_len;
            }
            while((_pos = _sub.find_last_of(' ')) == _sub.length() - 1)
            {
                _sub = _sub.substr(0, _sub.length() - 1);
                --_len;
            }
            return _sub;
        };

        auto str = Demangle(std::string(cstr));
        auto beg = str.find("(");
        if(beg == std::string::npos)
        {
            beg = str.find("_Z");
            if(beg != std::string::npos)
                beg -= 1;
        }
        auto end = str.find("+", beg);
        if(beg != std::string::npos && end != std::string::npos)
        {
            auto len = end - (beg + 1);
            auto sub = str.substr(beg + 1, len);
            auto dem = Demangle(_trim(sub, len));
            str      = str.replace(beg + 1, len, dem);
        }
        else if(beg != std::string::npos)
        {
            auto len = str.length() - (beg + 1);
            auto sub = str.substr(beg + 1, len);
            auto dem = Demangle(_trim(sub, len));
            str      = str.replace(beg + 1, len, dem);
        }
        else if(end != std::string::npos)
        {
            auto len = end;
            auto sub = str.substr(beg, len);
            auto dem = Demangle(_trim(sub, len));
            str      = str.replace(beg, len, dem);
        }
        return func(str.c_str());
    };
    return GetMangled<Depth, Offset>(demangle_bt);
}

//----------------------------------------------------------------------------//

inline void
Backtrace::Message(int sig, siginfo_t* sinfo, std::ostream& os)
{
    // try to avoid as many dynamic allocations as possible here to avoid
    // overflowing the signal stack

    // ignore future signals of this type
    signal(sig, SIG_IGN);

    os << "\n### CAUGHT SIGNAL: " << sig << " ### ";
    if(sinfo)
        os << "address: " << sinfo->si_addr << ", ";
    os << Description(sig) << ". ";

    if(sig == SIGSEGV)
    {
        if(sinfo)
        {
            switch(sinfo->si_code)
            {
                case SEGV_MAPERR: os << "Address not mapped to object."; break;
                case SEGV_ACCERR: os << "Invalid permissions for mapped object."; break;
                default:
                    os << "Unknown segmentation fault error: " << sinfo->si_code << ".";
                    break;
            }
        }
        else
        {
            os << "Segmentation fault (unknown).";
        }
    }
    else if(sig == SIGFPE)
    {
        if(sinfo)
        {
            switch(sinfo->si_code)
            {
                case FE_DIVBYZERO: os << "Floating point divide by zero."; break;
                case FE_OVERFLOW: os << "Floating point overflow."; break;
                case FE_UNDERFLOW: os << "Floating point underflow."; break;
                case FE_INEXACT: os << "Floating point inexact result."; break;
                case FE_INVALID: os << "Floating point invalid operation."; break;
                default:
                    os << "Unknown floating point exception error: " << sinfo->si_code
                       << ".";
                    break;
            }
        }
        else
        {
            os << "Unknown floating point exception";
            if(sinfo)
                os << ": " << sinfo->si_code;
            os << ". ";
        }
    }

    os << '\n';

    auto bt = GetMangled<256, 3>([](const char* _s) { return _s; });
    char prefix[64];
    snprintf(prefix, 64, "[PID=%i, TID=%i]", (int) getpid(),
             (int) Threading::GetThreadId());
    size_t sz = 0;
    for(auto& itr : bt)
    {
        if(!itr)
            break;
        if(strlen(itr) == 0)
            break;
        ++sz;
    }
    os << "\nBacktrace:\n";
    auto _w = std::log10(sz) + 1;
    for(size_t i = 0; i < sz; ++i)
    {
        os << prefix << "[" << std::setw(_w) << std::right << i << '/' << std::setw(_w)
           << std::right << sz << "]> " << std::left << bt.at(i) << '\n';
    }
    os << std::flush;

    // exit action could cause more signals to be raise so make sure this is done
    // after the message has been printed
    try
    {
        ExitAction(sig);
    } catch(std::exception& e)
    {
        std::cerr << "ExitAction(" << sig << ") threw an exception" << std::endl;
        std::cerr << e.what() << std::endl;
    }
}

//----------------------------------------------------------------------------//

inline void
Backtrace::Handler(int sig, siginfo_t* sinfo, void*)
{
    Message(sig, sinfo, std::cerr);

    char msg[1024];
    snprintf(msg, 1024, "%s", "\n");

    if(sinfo && PTL_PSIGINFO_AVAILABLE > 0)
    {
#    if PTL_PSIGINFO_AVAILABLE > 0
        psiginfo(sinfo, msg);
        fflush(stdout);
        fflush(stderr);
#    endif
    }
    else
    {
        std::cerr << msg << std::flush;
    }

    // ignore any termination signals
    for(auto itr : { SIGKILL, SIGTERM, SIGABRT })
        signal(itr, SIG_IGN);
    abort();
}

//----------------------------------------------------------------------------//

inline int
Backtrace::Enable(const signal_set_t& _signals)
{
    static bool _first = true;
    if(_first)
    {
        std::string       _msg = "!!! Backtrace is activated !!!";
        std::stringstream _filler;
        std::stringstream _spacer;
        _filler.fill('#');
        _filler << std::setw(_msg.length()) << "";
        _spacer << std::setw(10) << "";
        std::cout << "\n\n"
                  << _spacer.str() << _filler.str() << "\n"
                  << _spacer.str() << _msg << "\n"
                  << _spacer.str() << _filler.str() << "\n\n"
                  << std::flush;
    }
    _first  = false;
    int cnt = 0;
    for(const auto& itr : _signals)
    {
        if(itr < 0)
            continue;
        if(GetData().is_active[itr])
            continue;
        ++cnt;
        sigfillset(&(GetData().current[itr].sa_mask));
        sigdelset(&(GetData().current[itr].sa_mask), itr);
        GetData().current[itr].sa_sigaction = &Handler;
        GetData().current[itr].sa_flags     = SA_SIGINFO;
        sigaction(itr, &(GetData().current[itr]), &(GetData().previous[itr]));
    }
    return cnt;
}

//----------------------------------------------------------------------------//

inline int
Backtrace::Enable(const std::string& _signals)
{
    if(_signals.empty())
        return 0;

    auto _add_signal = [](std::string sig, signal_set_t& _targ) {
        if(!sig.empty())
        {
            for(auto& itr : sig)
                itr = toupper(itr);
            _targ.insert(Backtrace::GetSignal(sig));
        }
    };

    const std::regex wsp_re("[ ,;:\t\n]+");
    auto             _maxid  = GetData().identifiers.size();
    auto             _result = std::vector<std::string>(_maxid, "");
    std::copy(std::sregex_token_iterator(_signals.begin(), _signals.end(), wsp_re, -1),
              std::sregex_token_iterator(), _result.begin());
    signal_set_t _sigset{};
    for(auto& itr : _result)
        _add_signal(itr, _sigset);
    return Enable(_sigset);
}

//----------------------------------------------------------------------------//

inline int
Backtrace::Disable(signal_set_t _signals)
{
    if(_signals.empty())
    {
        for(auto& itr : GetData().is_active)
            _signals.insert(itr.first);
    }

    int cnt = 0;
    for(const auto& itr : _signals)
    {
        if(itr < 0)
            continue;
        if(!GetData().is_active[itr])
            continue;
        ++cnt;
        sigaction(itr, &(GetData().previous[itr]), nullptr);
        GetData().current.erase(itr);
        GetData().is_active[itr] = false;
    }
    return cnt;
}

//----------------------------------------------------------------------------//

inline int
Backtrace::GetSignal(const std::string& sid)
{
    for(auto&& itr : GetData().identifiers)
    {
        if(std::get<0>(itr) == sid)
            return std::get<1>(itr);
    }
    return -1;
}

//----------------------------------------------------------------------------//

inline std::string
Backtrace::Description(int sig)
{
    for(auto&& itr : GetData().identifiers)
    {
        if(std::get<1>(itr) == sig)
        {
            std::stringstream ss;
            ss << " signal = " << std::setw(8) << std::get<0>(itr)
               << ", value = " << std::setw(4) << std::get<1>(itr)
               << ", description = " << std::get<2>(itr);
            return ss.str();
        }
    }
    std::stringstream ss;
    ss << " signal = " << std::setw(8) << "unknown"
       << ", value = " << std::setw(4) << sig;
    return ss.str();
}

//----------------------------------------------------------------------------//

}  // namespace PTL

#else

#    include <array>
#    include <functional>
#    include <map>
#    include <set>
#    include <string>
#    include <tuple>
#    include <vector>

namespace PTL
{
// dummy implementation
class Backtrace
{
public:
    struct fake_siginfo
    {};
    struct fake_sigaction
    {};

    using siginfo_t     = fake_siginfo;
    using sigaction_t   = fake_sigaction;
    using exit_action_t = std::function<void(int)>;
    using frame_func_t  = std::function<std::string(const char*)>;
    using signal_set_t  = std::set<int>;

public:
    struct actions
    {
        using id_entry_t = std::tuple<std::string, int, std::string>;
        using id_list_t  = std::vector<id_entry_t>;

        std::map<int, bool>        is_active    = {};
        std::map<int, sigaction_t> current      = {};
        std::map<int, sigaction_t> previous     = {};
        std::vector<exit_action_t> exit_actions = {};
        const id_list_t            identifiers  = {};
    };

public:
    static void        Handler(int, siginfo_t*, void*) {}
    static void        Message(int, siginfo_t*, std::ostream&) {}
    static void        ExitAction(int) {}
    static int         Enable(const std::string&) { return 0; }
    static int         Enable(const signal_set_t& = DefaultSignals()) { return 0; }
    static int         Disable(signal_set_t = {}) { return 0; }
    static int         GetSignal(const std::string&) { return -1; }
    static std::string Description(int) { return std::string{}; }

    template <typename FuncT>
    static void AddExitAction(FuncT&&)
    {}

    template <size_t Depth, size_t Offset = 0, typename FuncT = frame_func_t>
    static std::array<ResultOf_t<FuncT, const char*>, Depth> GetMangled(
        FuncT&& func = FrameFunctor())
    {
        using type = ResultOf_t<FuncT, const char*>;
        auto ret   = std::array<type, Depth>{};
        ret.fill(func(""));
        return ret;
    }

    template <size_t Depth, size_t Offset = 0, typename FuncT = frame_func_t>
    static std::array<ResultOf_t<FuncT, const char*>, Depth> GetDemangled(
        FuncT&& func = FrameFunctor())
    {
        using type = ResultOf_t<FuncT, const char*>;
        auto ret   = std::array<type, Depth>{};
        ret.fill(func(""));
        return ret;
    }

    // a functor called for each frame in the backtrace
    static frame_func_t& FrameFunctor()
    {
        static frame_func_t _instance = [](const char* _s) { return std::string(_s); };
        return _instance;
    }

    // default set of signals
    static signal_set_t& DefaultSignals()
    {
        static signal_set_t _instance = {};
        return _instance;
    }

    static actions& GetData()
    {
        static auto _instance = actions{};
        return _instance;
    }
};

//----------------------------------------------------------------------------//

}  // namespace PTL

#endif  // SIGNAL_AVAILABLE
#endif  // Backtrace_hh


text:
'use strict';

var Spider = require('../').Spider;
new Spider(['http://www.apple.com/cn/macbook/']).then(function (data) {
    console.info(data);
    console.info('test end');
});


text:
// Compiled by ClojureScript 1.9.293 {}
goog.provide('sablono.util');
goog.require('cljs.core');
goog.require('goog.Uri');
goog.require('clojure.set');
goog.require('clojure.string');
sablono.util._STAR_base_url_STAR_ = null;

/**
 * @interface
 */
sablono.util.ToString = function(){};

/**
 * Convert a value into a string.
 */
sablono.util.to_str = (function sablono$util$to_str(x){
if((!((x == null))) && (!((x.sablono$util$ToString$to_str$arity$1 == null)))){
return x.sablono$util$ToString$to_str$arity$1(x);
} else {
var x__20948__auto__ = (((x == null))?null:x);
var m__20949__auto__ = (sablono.util.to_str[goog.typeOf(x__20948__auto__)]);
if(!((m__20949__auto__ == null))){
return m__20949__auto__.call(null,x);
} else {
var m__20949__auto____$1 = (sablono.util.to_str["_"]);
if(!((m__20949__auto____$1 == null))){
return m__20949__auto____$1.call(null,x);
} else {
throw cljs.core.missing_protocol.call(null,"ToString.to-str",x);
}
}
}
});

/**
 * @interface
 */
sablono.util.ToURI = function(){};

/**
 * Convert a value into a URI.
 */
sablono.util.to_uri = (function sablono$util$to_uri(x){
if((!((x == null))) && (!((x.sablono$util$ToURI$to_uri$arity$1 == null)))){
return x.sablono$util$ToURI$to_uri$arity$1(x);
} else {
var x__20948__auto__ = (((x == null))?null:x);
var m__20949__auto__ = (sablono.util.to_uri[goog.typeOf(x__20948__auto__)]);
if(!((m__20949__auto__ == null))){
return m__20949__auto__.call(null,x);
} else {
var m__20949__auto____$1 = (sablono.util.to_uri["_"]);
if(!((m__20949__auto____$1 == null))){
return m__20949__auto____$1.call(null,x);
} else {
throw cljs.core.missing_protocol.call(null,"ToURI.to-uri",x);
}
}
}
});

/**
 * Converts its arguments into a string using to-str.
 */
sablono.util.as_str = (function sablono$util$as_str(var_args){
var args__21400__auto__ = [];
var len__21393__auto___25443 = arguments.length;
var i__21394__auto___25444 = (0);
while(true){
if((i__21394__auto___25444 < len__21393__auto___25443)){
args__21400__auto__.push((arguments[i__21394__auto___25444]));

var G__25445 = (i__21394__auto___25444 + (1));
i__21394__auto___25444 = G__25445;
continue;
} else {
}
break;
}

var argseq__21401__auto__ = ((((0) < args__21400__auto__.length))?(new cljs.core.IndexedSeq(args__21400__auto__.slice((0)),(0),null)):null);
return sablono.util.as_str.cljs$core$IFn$_invoke$arity$variadic(argseq__21401__auto__);
});

sablono.util.as_str.cljs$core$IFn$_invoke$arity$variadic = (function (xs){
return cljs.core.apply.call(null,cljs.core.str,cljs.core.map.call(null,sablono.util.to_str,xs));
});

sablono.util.as_str.cljs$lang$maxFixedArity = (0);

sablono.util.as_str.cljs$lang$applyTo = (function (seq25442){
return sablono.util.as_str.cljs$core$IFn$_invoke$arity$variadic(cljs.core.seq.call(null,seq25442));
});

/**
 * Returns camel case version of the key, e.g. :http-equiv becomes :httpEquiv.
 */
sablono.util.camel_case = (function sablono$util$camel_case(k){
if(((k instanceof cljs.core.Keyword)) || (typeof k === 'string') || ((k instanceof cljs.core.Symbol))){
var vec__25449 = clojure.string.split.call(null,cljs.core.name.call(null,k),/-/);
var seq__25450 = cljs.core.seq.call(null,vec__25449);
var first__25451 = cljs.core.first.call(null,seq__25450);
var seq__25450__$1 = cljs.core.next.call(null,seq__25450);
var first_word = first__25451;
var words = seq__25450__$1;
if((cljs.core.empty_QMARK_.call(null,words)) || (cljs.core._EQ_.call(null,"aria",first_word)) || (cljs.core._EQ_.call(null,"data",first_word))){
return k;
} else {
return cljs.core.keyword.call(null,clojure.string.join.call(null,cljs.core.conj.call(null,cljs.core.map.call(null,clojure.string.capitalize,words),first_word)));
}
} else {
return k;
}
});
/**
 * Recursively transforms all map keys into camel case.
 */
sablono.util.camel_case_keys = (function sablono$util$camel_case_keys(m){
if(cljs.core.map_QMARK_.call(null,m)){
var ks = cljs.core.keys.call(null,m);
var kmap = cljs.core.zipmap.call(null,ks,cljs.core.map.call(null,sablono.util.camel_case,ks));
var G__25453 = clojure.set.rename_keys.call(null,m,kmap);
if(cljs.core.map_QMARK_.call(null,new cljs.core.Keyword(null,"style","style",-496642736).cljs$core$IFn$_invoke$arity$1(m))){
return cljs.core.update_in.call(null,G__25453,new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"style","style",-496642736)], null),sablono.util.camel_case_keys);
} else {
return G__25453;
}
} else {
return m;
}
});
/**
 * Return true if `x` is an HTML element. True when `x` is a vector
 *   and the first element is a keyword, e.g. `[:div]` or `[:div [:span "x"]`.
 */
sablono.util.element_QMARK_ = (function sablono$util$element_QMARK_(x){
return (cljs.core.vector_QMARK_.call(null,x)) && ((cljs.core.first.call(null,x) instanceof cljs.core.Keyword));
});
/**
 * Converts all HTML attributes to their DOM equivalents.
 */
sablono.util.html_to_dom_attrs = (function sablono$util$html_to_dom_attrs(attrs){
return clojure.set.rename_keys.call(null,sablono.util.camel_case_keys.call(null,attrs),new cljs.core.PersistentArrayMap(null, 2, [new cljs.core.Keyword(null,"class","class",-2030961996),new cljs.core.Keyword(null,"className","className",-1983287057),new cljs.core.Keyword(null,"for","for",-1323786319),new cljs.core.Keyword(null,"htmlFor","htmlFor",-1050291720)], null));
});
/**
 * Join the `classes` with a whitespace.
 */
sablono.util.join_classes = (function sablono$util$join_classes(classes){
return clojure.string.join.call(null," ",cljs.core.remove.call(null,cljs.core.nil_QMARK_,cljs.core.flatten.call(null,cljs.core.map.call(null,(function (p1__25454_SHARP_){
if(typeof p1__25454_SHARP_ === 'string'){
return p1__25454_SHARP_;
} else {
return cljs.core.seq.call(null,p1__25454_SHARP_);

}
}),classes))));
});
/**
 * Return the symbol of a fn that build a React element.
 */
sablono.util.react_fn = (function sablono$util$react_fn(type){
if(cljs.core.contains_QMARK_.call(null,new cljs.core.PersistentHashSet(null, new cljs.core.PersistentArrayMap(null, 3, [new cljs.core.Keyword(null,"textarea","textarea",-650375824),null,new cljs.core.Keyword(null,"input","input",556931961),null,new cljs.core.Keyword(null,"select","select",1147833503),null], null), null),cljs.core.keyword.call(null,type))){
return new cljs.core.Symbol("sablono.interpreter","create-element","sablono.interpreter/create-element",748785555,null);
} else {
return new cljs.core.Symbol("js","React.createElement","js/React.createElement",1766367641,null);
}
});
cljs.core.Keyword.prototype.sablono$util$ToString$ = cljs.core.PROTOCOL_SENTINEL;

cljs.core.Keyword.prototype.sablono$util$ToString$to_str$arity$1 = (function (x){
var x__$1 = this;
return cljs.core.name.call(null,x__$1);
});

goog.Uri.prototype.sablono$util$ToString$ = cljs.core.PROTOCOL_SENTINEL;

goog.Uri.prototype.sablono$util$ToString$to_str$arity$1 = (function (x){
var x__$1 = this;
if(cljs.core.truth_((function (){var or__20285__auto__ = x__$1.hasDomain();
if(cljs.core.truth_(or__20285__auto__)){
return or__20285__auto__;
} else {
return ((x__$1.getPath() == null)) || (cljs.core.not.call(null,cljs.core.re_matches.call(null,/^\/.*/,x__$1.getPath())));
}
})())){
return [cljs.core.str(x__$1)].join('');
} else {
var base = [cljs.core.str(sablono.util._STAR_base_url_STAR_)].join('');
if(cljs.core.truth_(cljs.core.re_matches.call(null,/.*\/$/,base))){
return [cljs.core.str(cljs.core.subs.call(null,base,(0),(cljs.core.count.call(null,base) - (1)))),cljs.core.str(x__$1)].join('');
} else {
return [cljs.core.str(base),cljs.core.str(x__$1)].join('');
}
}
});

(sablono.util.ToString["null"] = true);

(sablono.util.to_str["null"] = (function (_){
return "";
}));

(sablono.util.ToString["number"] = true);

(sablono.util.to_str["number"] = (function (x){
return [cljs.core.str(x)].join('');
}));

(sablono.util.ToString["_"] = true);

(sablono.util.to_str["_"] = (function (x){
return [cljs.core.str(x)].join('');
}));
goog.Uri.prototype.sablono$util$ToURI$ = cljs.core.PROTOCOL_SENTINEL;

goog.Uri.prototype.sablono$util$ToURI$to_uri$arity$1 = (function (x){
var x__$1 = this;
return x__$1;
});

(sablono.util.ToURI["_"] = true);

(sablono.util.to_uri["_"] = (function (x){
return (new goog.Uri([cljs.core.str(x)].join('')));
}));

//# sourceMappingURL=util.js.map?rel=1483335399031


text:
package org.jolokia.converter.json;

import java.lang.reflect.InvocationTargetException;
import java.util.Stack;

import javax.management.AttributeNotFoundException;

import org.jolokia.converter.object.StringToObjectConverter;

/**
 * Extractor for extracting enums. Enums are represented by the canonical name (Enum.name()).
 *
 * @author roland
 * @since 18.02.13
 */
public class EnumExtractor implements Extractor {

    /** {@inheritDoc} */
    public Class getType() {
        return Enum.class;
    }

    /** {@inheritDoc} */
    public Object extractObject(ObjectToJsonConverter pConverter, Object pValue, Stack<String> pExtraArgs, boolean jsonify) throws AttributeNotFoundException {
        if (!jsonify) {
            return pValue;
        }
        Enum en = (Enum) pValue;
        return en.name();
    }

    /** {@inheritDoc} */
    public Object setObjectValue(StringToObjectConverter pConverter, Object pInner, String pAttribute, Object pValue) throws IllegalAccessException, InvocationTargetException {
        throw new IllegalArgumentException("An enum itself is immutable an cannot change its value");
    }

    /** {@inheritDoc} */
    public boolean canSetValue() {
        return false;
    }
}


text:
<?xml version="1.0"?>
<ruleset name="Aurora">
	<description>The coding standard for Anodyne's Aurora forum system.</description>

	<file>app</file>
	<file>resources</file>

	<exclude-pattern>*/app/CodeSniffer/*</exclude-pattern>
	<exclude-pattern>*/tests/*</exclude-pattern>
	<exclude-pattern>*/vendor/*</exclude-pattern>
	<exclude-pattern>*/resources/assets/js/mixins/Collection.js</exclude-pattern>

	<arg value="np"/>

	<rule ref="PSR2">
		<exclude name="Generic.WhiteSpace.DisallowTabIndent"/>
	</rule>
	<rule ref="app/CodeSniffer/Standards/Anodyne"/>
	<rule ref="Generic.WhiteSpace.DisallowSpaceIndent"/>
	<rule ref="Generic.WhiteSpace.ScopeIndent">
		<properties>
			<property name="indent" value="4"/>
			<property name="tabIndent" value="true"/>
		</properties>
	</rule>
</ruleset>