答:
The table User is not included in the query, you should try something like:

```<code>SELECT TutorStudent.id, TutorStudent.tutor_id,  TutorStudent.student_id,  TutorStudent.created
FROM  virlen.tutor_students AS TutorStudent join
virlen.User as user
on user.id = tutorstudent.student_id
 WHERE TutorStudent.tutor_id IS NULL AND User.email LIKE '%ka@mailinator.com%';
</code>```

This assuming that the User table key used in tutor_student.student_id is id and not user_id, in which case you should change your code consequently to be it like: on user.user_id = tutorstudent.student_id

Title: Unknown column 'User.first_name' in 'where clause' cakePHP

Body:
I have tutor_students and users table. tutor_studentscontains id, tutor_id, student_id and created. users contain id, user_id, role_id, email, first_name, last_name. tutor_students table is connected table between tutor and student. so tutor can see their student list and can add new student too.

I succeeded to display student list and add new student to tutor student list. but when i want to search student, there will be an error:

Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column
  'User.email' in 'where clause'

SQL Query: SELECT TutorStudent.id, TutorStudent.tutor_id,
  TutorStudent.student_id, TutorStudent.created FROM
  virlen.tutor_students AS TutorStudent WHERE
  TutorStudent.tutor_id IS NULL AND User.email LIKE
  '%ka@mailinator.com%'

My controller:

public function admin_tutor_add_student($tutor_id = null)
{
    $user_list = '';
    $this->loadModel('TutorStudent');
    $this->set('title_for_layout','User');
    $this->User->bindModel(array(
                    'belongsTo'=>array(
                        'Standard'=>array(
                            'className'=>'Standard'
                        ),
                    )
    ),false);

    $this->User->id     =   $tutor_id;
    /*form post and check conditions*/
    // if ($this->request->is('post') || $this->request->is('put'))
    if(!empty($this->request->data) && isset($this->request->data['User']['status1']))
    {
        // pr($this->request->data);die;
        $action = $this->request->data['User']['pageAction'];
        foreach ($this->request->data['User'] AS $value) {
            if ($value != 0) {
                $ids[] = $value;
            }
        }

        // pr($ids);die;
        if (!empty($this->request->data))
        {
            if (!isset($this->request->params['_Token']['key']) || ($this->request->params['_Token']['key'] != $this->request->params['_Token']['key']))
            {
                $blackHoleCallback = $this->Security->blackHoleCallback;
                $this->$blackHoleCallback();
            }
            foreach($ids as $id)
            {
                if(!empty($id))
                {
                    if($id != 1)
                    {
                        $shift = array();
                        $shift['TutorStudent']['tutor_id'] = $tutor_id;
                        $shift['TutorStudent']['student_id'] = $id;
                        $this->TutorStudent->save($shift);
                        $this->TutorStudent->id = false;
                    }
                }
            }

            $this->Session->setFlash("Tutor has been added successfully", 'admin_flash_good');
            $this->redirect(array('controller'=>'users', 'action'=>'subadmin_tutor',$tutor_id));

        }
    }

    if (!isset($this->params['named']['page']))
    {
        $this->Session->delete('AdminSearch');
    }
    $email = '';
    $first_name = '';
    $role_id = '';
    $status = '';
    if (!empty($this->request->data))
    {
        $this->Session->delete('AdminSearch');
        if (isset($this->request->data['User']['first_name']) && $this->request->data['User']['first_name'] != '')
        {
            $first_name = trim($this->request->data['User']['first_name']);
            $this->Session->write('AdminSearch.first_name', $first_name);
        }
        if (isset($this->request->data['User']['email']) && $this->request->data['User']['email'] != '')
        {
            $email = trim($this->request->data['User']['email']);
            $this->Session->write('AdminSearch.email', $email);
        }

    }

    $filters    =   array('TutorStudent.tutor_id'=>$tutor_id);
    if ($this->Session->check('AdminSearch'))
    {
        $keywords   =   $this->Session->read('AdminSearch');
        foreach($keywords as $key=>$values)
        {
            if($key == 'email')
            {
                $email = $values;
                $filters[] = array('User.'.$key.' LIKE'=>"%".$values."%");
            }
            if($key == 'first_name')
            {
                $first_name = $values;
                $filters[] = array('User.'.$key.' LIKE'=>"%".$values."%");
            }
        }
    }

    $my_tutor_list = $this->TutorStudent->find('all',array('conditions'=>$filters));
    if(!empty($my_tutor_list))
    {
        foreach($my_tutor_list as $key=>$value)
        {
            $user_list[] = $value['TutorStudent']['student_id'];
        }
    }

    $this->paginate = array('User' => array(
        'limit' =>Configure::read('App.PageLimit'),
        'order' => array('User.id' => 'DESC'),
        'conditions'=>array('User.id !='=>$user_list,'User.role_id'=>2),
        )); //role_id 2 means student user

    $student_list = $this->paginate('User');

    // pr($student_list);die;
    $this->loadModel('Standard');
    $standards  =   $this->Standard->getStandardList();
    $this->set(compact('standards'));
    $this->set(compact('student_list','tutor_id','standard_id', 'User', 'email', 'first_name'));
    $this->set('title_for_layout', __('User', true));
}

this is my view file:

<?php echo($this->Form->create('User', array('url'=>array('controller' => 'users', 'action' => 'tutor_add_student'))));?>

Search

                                User Email
                                <?php echo($this->Form->input('User.email', array('placeholder'=>"Tutor Email",'label' => false,'value'=>$email, 'div'=>false,'class'=>'form-control'))); ?>

                                First Name
                                <?php echo($this->Form->input('User.first_name', array('placeholder'=>"First Name",'label' => false,'value'=>$first_name, 'div'=>false,'class'=>'form-control'))); ?>

<?php echo($this->Form->submit('Search', array('div'=>false, 'class'=>'btn btn-primary pull-left')));?>

         <?php echo($this->Form->end());?>

This is my app model for user:

    <?php
/**
 * Country
 *
 * PHP version 5
 *
 * @category Model
 *
 */
// App::uses('AuthComponent', 'Controller/Component');
// App::uses('SessionComponent', 'Controller/Component');
App::uses('AppModel', 'Model');
class User extends AppModel{

    //public $primaryKey = '_id';

    /**
     * Model name
     * @var string
     * @access public
     */
    var $name = 'User';
    /**
     * Behaviors used by the Model
     *
     * @var array
     * @access public
     */

    var $actsAs = array(
       'Multivalidatable'
    );

    var $validationSets = array(
        'login'=>   array(
            'email'=>array(
                'notEmpty' => array(
                    'rule'      => 'notEmpty',
                    'message'   =>  'Email address is required'
                ),
                'R2'=>array(
                    'rule'=>array('maxLength', 50),
                    'message'=>'Email can be maximum 50 characters long.'
                ),
                'email' =>  array(
                    'rule'  =>  'email',
                    'message'   =>  'Please provide a valid email address.'
                ),
            ),
            'password'=>array(
                'R1'=>array(
                    'rule'=>'notEmpty',
                    'message' => 'Password is required.'
                ),
                'R3'=>array(
                    'rule'=>array('minLength', 6),
                    'message'=>'Password must be at least 6 characters long.'
                ),
                'R4'=>array(
                    'rule'=>array('maxLength', 20),
                    'message'=>'Password must be at least 20 characters long.'
                ),
            ),
        ),
        'add'=> array(
            'first_name'=>array(
                'R1'=>array(
                    'rule'=>'notEmpty',
                    'message' => 'First name is required.'
                ),
                'R2'=>array(
                    'rule'=>array('maxLength', 255),
                    'message'=>'First Name can be maximum 255 characters long.'
                ),
                'characters' => array(
                    'rule'     => array('custom', '/^[a-z]*$/i'),
                    'message'  => 'Alphabet characters only'
                )
            ),
            'last_name'=>array(
                'R1'=>array(
                    'rule'=>'notEmpty',
                    'message' => 'Last name is required.'
                ),
                'R2'=>array(
                    'rule'=>array('maxLength',255),
                    'message'=>'Last name can be maximum 255 characters long.'
                ),
                'characters' => array(
                    'rule'     => array('custom', '/^[a-z]*$/i'),
                    'message'  => 'Alphabet characters only'
                )
            ),
            'standard_id'=>array(
                'R1'=>array(
                    'rule'=>'notEmpty',
                    'message' => 'Standard is required.'
                )
            ),
            'role_id'=>array(
                'R1'=>array(
                    'rule'=>'notEmpty',
                    'message' => 'Role is required.'
                )
            ),
            'specilization'=>array(
                'R1' => array(
                    'rule'      => 'notEmpty',
                    'message'   =>  'Specilization is required.'
                ),
                'R2'=>array(
                    'rule'=>array('maxLength', 255),
                    'message'=>'Specilization can be 255 characters long.'
                ),
            ),
            'phone'=>array(
                'R1' => array(
                    'rule'      => 'notEmpty',
                    'message'   =>  'Phone number is required.'
                ),
                'notEmpty' => array(
                    'rule'      => 'numeric',
                    'message'   =>  'Phone number should be numeric'
                ),
                'R2'=>array(
                    'rule'=>array('minLength', 8),
                    'message'=>'Phone number shuold be minimum 8 numbers long'
                ),
                'R3'=>array(
                    'rule'=>array('maxLength', 12),
                    'message'=>'Phone number should be maximum 12 numbers long'
                ),
                /* 'R4'=>array(
                    'rule'=>array('CheckPhoneVailidation'),
                    'message'=>'Phone no should be start with 82 to 87.'
                ),   */
            ),
            'email'=>array(
                'notEmpty' => array(
                    'rule'      => 'notEmpty',
                    'message'   =>  'Email address is required'
                ),
                'R2'=>array(
                    'rule'=>array('maxLength', 50),
                    'message'=>'Email can be maximum 50 characters long.'
                ),
                'isUnique'  =>  array(
                    'rule'  =>  'isUnique',
                    'message'   =>  'Email already exists.'
                ),
                'email' =>  array(
                    'rule'  =>  'email',
                    'message'   =>  'Please provide a valid email address.'
                ),
            ),
            'new_password'=>array(
                'R1'=>array(
                    'rule'=>'notEmpty',
                    'message' => 'Password is required.'
                ),
                'R3'=>array(
                    'rule'=>array('minLength', 6),
                    'message'=>'Password must be at least 6 characters long.'
                ),
                'R4'=>array(
                    'rule'=>array('maxLength', 20),
                    'message'=>'Password must be at least 20 characters long.'
                ),
            ),
            'confirm_password'=>array(
                'identicalFieldValues' => array(
                    'rule' => array('identicalFieldValues', 'new_password'),
                    'message' => 'Password and confirm password mismatch'
                ),
                'R1' => array(
                    'rule' => 'notEmpty',
                    'message' => 'Confirm password is required.'
                )

            ),
            'image' => array(
                'R1' => array(
                    'rule' => array('checkextension'),
                    'message' => 'Please upload only image files'
                )
            ),
        )

    );
}

Body:
The table User is not included in the query, you should try something like:

SELECT TutorStudent.id, TutorStudent.tutor_id,  TutorStudent.student_id,  TutorStudent.created
FROM  virlen.tutor_students AS TutorStudent join
virlen.User as user
on user.id = tutorstudent.student_id
 WHERE TutorStudent.tutor_id IS NULL AND User.email LIKE '%ka@mailinator.com%';

This assuming that the User table key used in tutor_student.student_id is id and not user_id, in which case you should change your code consequently to be it like: on user.user_id = tutorstudent.student_id


来源: stackexchange

问:
update same rows
I have a table like below:
Current

```<code>    Column1 Column2 column3
   -------------------------
    abc       cat1     1
    efg       cat1     3
    hij       cat1     2
    klm       cat2     1
    nop       car2     2
    qrs       cat2     3
</code>```

I want to update column1 where all rows matching cat1 from rows matching cat2 , considering rows will be updated for id which matches column 3 ids

Expected

```<code>Column1 Column2 column3
-------------------------
klm       cat1     1
qrs       cat1     3
nop       cat1     2
klm       cat2     1
nop       car2     2
qrs       cat2     3
</code>```

答:
Please try with below code:</p>

```<code>    DECLARE @Table TABLE
    (Column1 VARCHAR(100),Column2 VARCHAR(100), Column3 INT)

     INSERT INTO @Table VALUES
     ('abc','cat1',1),
     ('efg','cat1',3),
     ('hij','cat1',2),
     ('klm','cat2',1),
     ('nop','cat2',2),
     ('qrs','cat2',3)

    UPDATE
    t
    SET t.Column1 = d.Column1
    FROM @Table t INNER JOIN @Table d
    ON t.Column3 = d.Column3
    WHERE d.Column2 ='cat2'
</code>```

ContentLicense: CC BY-SA 3.0

Title: update same rows

Body:
I have a table like below:
Current

    Column1 Column2 column3
   -------------------------
    abc       cat1     1
    efg       cat1     3
    hij       cat1     2
    klm       cat2     1
    nop       car2     2
    qrs       cat2     3

I want to update column1 where all rows matching cat1 from rows matching cat2 , considering rows will be updated for id which matches column 3 ids

Expected

Column1 Column2 column3
-------------------------
klm       cat1     1
qrs       cat1     3
nop       cat1     2
klm       cat2     1
nop       car2     2
qrs       cat2     3

Body:
Please try with below code:

    DECLARE @Table TABLE
    (Column1 VARCHAR(100),Column2 VARCHAR(100), Column3 INT)

     INSERT INTO @Table VALUES
     ('abc','cat1',1),
     ('efg','cat1',3),
     ('hij','cat1',2),
     ('klm','cat2',1),
     ('nop','cat2',2),
     ('qrs','cat2',3)

    UPDATE
    t
    SET t.Column1 = d.Column1
    FROM @Table t INNER JOIN @Table d
    ON t.Column3 = d.Column3
    WHERE d.Column2 ='cat2'


问:
Xamarin Android FrameLayout displays blank/empty fragment on back where expected to close the app
I am implementing Fragments and hamburger, however when I click the back button I noticed the content_frame (which is filled by fragment) is always empty on the last 'back' pressed (where I expected to close the app instead of showing empty content).

Below is my FirstView.axml

```<code><?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:local="http://schemas.android.com/apk/res-auto"
   android:id="@+id/drawer_layout"
   android:layout_height="match_parent"
   android:layout_width="match_parent">
   <android.support.design.widget.CoordinatorLayout
       android:id="@+id/main_frame"
       android:fitsSystemWindows="true"
       android:layout_width="match_parent"
       android:layout_height="match_parent">
       <FrameLayout
           android:id="@+id/content_frame"
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:layout_centerInParent="true" />
   </android.support.design.widget.CoordinatorLayout>
   <FrameLayout
       android:id="@+id/navigation_frame"
       android:layout_height="match_parent"
       android:layout_width="wrap_content"
       android:layout_gravity="left|start" />
</code>```

Here is the OnBackPressed from my activity

```<code>   public override void OnBackPressed()
   {
       if (DrawerLayout != null && DrawerLayout.IsDrawerOpen(GravityCompat.Start))
           DrawerLayout.CloseDrawers();
       else
           base.OnBackPressed();
   }
</code>```

To navigate between fragment, I use navigate function from my MenuFragment

```<code>private async Task Navigate(int itemId)
   {
       ((FirstView)Activity).DrawerLayout.CloseDrawers();
       // add a small delay to prevent any UI issues
       await Task.Delay(TimeSpan.FromMilliseconds(250));

       switch (itemId)
       {
           case Resource.Id.nav_input:
               ViewModel.ShowInputCommand.Execute();
               break;
           case Resource.Id.nav_registercc:
               ViewModel.ShowRegisterCCCommand.Execute();
               break;
           case Resource.Id.nav_creditcard:
               ViewModel.ShowCreditCardCommand.Execute();
               break;
           case Resource.Id.nav_transaction:
               ViewModel.ShowTransactionCommand.Execute();
               break;
       }
    }
</code>```

Basically, the issue that I am facing is instead of closing the app after content_frame showing the initial fragment, it displays empty/blank fragment (navigation_frame still working). And as you can see, I am following everything from this MvvmCross tutorial.

Any help would be appreciated.

答: I just realize in my initial fragment the header should be [MvxFragment(typeof(FirstViewModel), Resource.Id.content_frame)] instead of [MvxFragment(typeof(FirstViewModel), Resource.Id.content_frame, true)]. It is now working great as expected!

Body:
I am implementing Fragments and hamburger, however when I click the back button I noticed the content_frame (which is filled by fragment) is always empty on the last 'back' pressed (where I expected to close the app instead of showing empty content).

Below is my FirstView.axml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:local="http://schemas.android.com/apk/res-auto"
   android:id="@+id/drawer_layout"
   android:layout_height="match_parent"
   android:layout_width="match_parent">
   <android.support.design.widget.CoordinatorLayout
       android:id="@+id/main_frame"
       android:fitsSystemWindows="true"
       android:layout_width="match_parent"
       android:layout_height="match_parent">
       <FrameLayout
           android:id="@+id/content_frame"
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:layout_centerInParent="true" />
   </android.support.design.widget.CoordinatorLayout>
   <FrameLayout
       android:id="@+id/navigation_frame"
       android:layout_height="match_parent"
       android:layout_width="wrap_content"
       android:layout_gravity="left|start" />

Here is the OnBackPressed from my activity

   public override void OnBackPressed()
   {
       if (DrawerLayout != null && DrawerLayout.IsDrawerOpen(GravityCompat.Start))
           DrawerLayout.CloseDrawers();
       else
           base.OnBackPressed();
   }

To navigate between fragment, I use navigate function from my MenuFragment

private async Task Navigate(int itemId)
   {
       ((FirstView)Activity).DrawerLayout.CloseDrawers();
       // add a small delay to prevent any UI issues
       await Task.Delay(TimeSpan.FromMilliseconds(250));

       switch (itemId)
       {
           case Resource.Id.nav_input:
               ViewModel.ShowInputCommand.Execute();
               break;
           case Resource.Id.nav_registercc:
               ViewModel.ShowRegisterCCCommand.Execute();
               break;
           case Resource.Id.nav_creditcard:
               ViewModel.ShowCreditCardCommand.Execute();
               break;
           case Resource.Id.nav_transaction:
               ViewModel.ShowTransactionCommand.Execute();
               break;
       }
    }

Basically, the issue that I am facing is instead of closing the app after content_frame showing the initial fragment, it displays empty/blank fragment (navigation_frame still working). And as you can see, I am following everything from this MvvmCross tutorial.

Any help would be appreciated.


问:
Bulk query in Elastic search
We have a database of 1 Million records, and we would like to query list of emails using UserID's.

What's the best way to do it in Elastic search. We don't want to loop individual UID and get respective email. If we can get all emails with one bulk search that would be great.

Any ideas are welcome.

答:
You can use Multi Search API for this purpose:

```<code>curl -s -XGET localhost:9200/_msearch/template -d '
{"index" : "logstash-2017.03.20"}
{"inline": {"query": {"match":  {"uid" : "E434C35-B080-403C-ADA9-2FD164CF70" }}}}
{"index" : "logstash-2017.03.20"}
{"inline": {"query": {"match":  {"uid" : "E1D65ED3-F3BE-42E8-AF2F-A4D4F843F7" }}}}
'
</code>```

Note: each search command (pair index and query line) must be separated by a new line a also after last query a new line must be present. It might be safer to write query into a file e.g. requests and then use --data-binary flag:

```<code>curl -s -XGET localhost:9200/_msearch/template --data-binary "@requests"
</code>```

You will obtain an array of responses for each query:

```<code>{
  "responses": [
    {
      "took": 86,
      "timed_out": false,
      "_shards": {
        "total": 3,
        "successful": 3,
        "failed": 0
      },
      "hits": {
        "total": 1,
        "max_score": 13.081283,
        "hits": [
          { ... }
        ]
      }
    },
    {
      "took": 82,
      "timed_out": false,
      "_shards": {
        "total": 3,
        "successful": 3,
        "failed": 0
      },
      "hits": {
        "total": 1,
        "max_score": 13.081283,
        "hits": [
          { ... }
        ]
      }
    }
  ]
}
</code>```

Title: Bulk query in Elastic search

Body:
You can use Multi Search API for this purpose:

curl -s -XGET localhost:9200/_msearch/template -d '
{"index" : "logstash-2017.03.20"}
{"inline": {"query": {"match":  {"uid" : "E434C35-B080-403C-ADA9-2FD164CF70" }}}}
{"index" : "logstash-2017.03.20"}
{"inline": {"query": {"match":  {"uid" : "E1D65ED3-F3BE-42E8-AF2F-A4D4F843F7" }}}}
'

Note: each search command (pair index and query line) must be separated by a new line a also after last query a new line must be present. It might be safer to write query into a file e.g. requests and then use --data-binary flag:

curl -s -XGET localhost:9200/_msearch/template --data-binary "@requests"

You will obtain an array of responses for each query:

{
  "responses": [
    {
      "took": 86,
      "timed_out": false,
      "_shards": {
        "total": 3,
        "successful": 3,
        "failed": 0
      },
      "hits": {
        "total": 1,
        "max_score": 13.081283,
        "hits": [
          { ... }
        ]
      }
    },
    {
      "took": 82,
      "timed_out": false,
      "_shards": {
        "total": 3,
        "successful": 3,
        "failed": 0
      },
      "hits": {
        "total": 1,
        "max_score": 13.081283,
        "hits": [
          { ... }
        ]
      }
    }
  ]
}


问:
log4net: how to customize data to be stored
I have few different web services exposed by my web site. Here is a goals I want to reach:

Store all data in DB in one table;

Each record should have text field with 'service/component' name;

It is necessary to store all income parameters when any method is called;

It is necessary to store all outcome parameters AND error messages if any exception is occurred.

My original intention was to use log4net. But from these walk-through (http://sadi02.wordpress.com/2008/09/15/how-to-store-log-in-database-using-log4net/, http://logging.apache.org/log4net/release/config-examples.html) I don't see an easy way to add custom data into log table.

Is it feasible to use log4net for such purposes? How can I change logging table schema to store custom data? Should I modify source code of log4net library? Probably would be better to write a custom functionality to store such kind of data?

Thanks.

答:
According to this discussion, the process is pretty straightforward.

The first step is to update the command text in the appender declaration into your config file:

```<code><commandText value="INSERT INTO Log4Net ([Date],[Thread],[Level],[Logger],[Message],[Exception],[MyColumn]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception,@MyColumn)"/>
</code>```

The next step is to and add a new parameter definition for the custom column:

```<code><parameter>
   <parameterName value="@MyColumn "/>
   <dbType value="String" />
   <size value="255" />
   <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%property{MyColumn}" />
   </layout>
</parameter>
</code>```

Finally, you can access the value through the GlobalContext properties of log4net:

```<code>log4net.GlobalContext.Properties["MyColumn"] = "MyValue";
log.Debug("My message");
</code>```

You can do this for as many fields as you need.

ContentLicense: CC BY-SA 2.5

Body:
According to this discussion, the process is pretty straightforward.

The first step is to update the command text in the appender declaration into your config file:

<commandText value="INSERT INTO Log4Net ([Date],[Thread],[Level],[Logger],[Message],[Exception],[MyColumn]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception,@MyColumn)"/>

The next step is to and add a new parameter definition for the custom column:

<parameter>
   <parameterName value="@MyColumn "/>
   <dbType value="String" />
   <size value="255" />
   <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%property{MyColumn}" />
   </layout>
</parameter>

Finally, you can access the value through the GlobalContext properties of log4net:

log4net.GlobalContext.Properties["MyColumn"] = "MyValue";
log.Debug("My message");

You can do this for as many fields as you need.


问:
Using Jackson to dynamically serialize an entity as either its ID or its full representation at runtime
We're developing a RESTful API using Java EE 7 (RESTEasy / Hibernate / Jackson).

We want the API to serialize all child entities using their IDs, by default. We're doing this mostly to maintain consistency with our deserialization strategy, where we insist on receiving an ID.

However, we also want our users to be able to choose to get an expanded view of any of our child entities, either through a custom endpoint or a query parameter (undecided). For example:

```<code>// http://localhost:8080/rest/operator/1
// =====================================
{
    "operatorId": 1,
    "organization": 34,
    "endUser": 23
}

// http://localhost:8080/rest/operator/1?expand=organization
// =====================================
{
    "operatorId": 1,
    "organization": {
        "organizationId": 34,
        "organizationName": "name"
    },
    "endUser": 23
}

// http://localhost:8080/rest/operator/1?expand=enduser
// =====================================
{
    "operatorId": 1,
    "organization": 34,
    "endUser": {
        "endUserId": 23,
        "endUserName": "other name"
    }
}

// http://localhost:8080/rest/operator/1?expand=organization,enduser
// =====================================
{
    "operatorId": 1,
    "organization": {
        "organizationId": 34,
        "organizationName": "name"
    },
    "endUser": {
        "endUserId": 23,
        "endUserName": "other name"
    }
}
</code>```

Is there a way to dynamically change the behavior of Jackson to determine whether a specified AbstractEntity field is serialized in full form or as its ID? How might it be done?

Additional Info

We know of a few ways to serialize our child entities using their IDs, including:

```<code>public class Operator extends AbstractEntity {
    ...
    @JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="organizationId")
    @JsonIdentityReference(alwaysAsId=true)
    public getOrganization() { ... }
    ...
}
</code>```

and

```<code>public class Operator extends AbstractEntity {
    ...
    @JsonSerialize(using=AbstractEntityIdSerializer.class)
    public getOrganization() { ... }
    ...
}
</code>```

where AbstractEntityIdSerializer serializes the entity using its ID.

The problem is that we don't know of a way for the user to override that default behavior and revert to standard Jackson object serialization. Ideally they'd also be able to choose which child properties to serialize in full form.

It would be awesome to dynamically toggle the alwaysAsId argument of @JsonIdentityReference for any property at runtime, if that's possible, or make the equivalent change to ObjectMapper/ObjectWriter.

Update: Working(?) Solution
We haven't had a chance to fully test this yet, but I've been working on a solution that leverages overriding Jackson's AnnotationIntrospector class. It seems to be working as intended.

```<code>public class CustomAnnotationIntrospector extends JacksonAnnotationIntrospector {
    private final Set<String> expandFieldNames_;

    public CustomAnnotationIntrospector(Set<String> expandFieldNames) {
        expandFieldNames_ = expandFieldNames;
    }

    @Override
    public ObjectIdInfo findObjectReferenceInfo(Annotated ann, ObjectIdInfo objectIdInfo) {
        JsonIdentityReference ref = _findAnnotation(ann, JsonIdentityReference.class);
        if (ref != null) {

            for (String expandFieldName : expandFieldNames_) {
                String expandFieldGetterName = "get" + expandFieldName;
                String propertyName = ann.getName();

                boolean fieldNameMatches = expandFieldName.equalsIgnoreCase(propertyName);
                boolean fieldGetterNameMatches = expandFieldGetterName.equalsIgnoreCase(propertyName);

                if (fieldNameMatches || fieldGetterNameMatches) {
                    return objectIdInfo.withAlwaysAsId(false);
                }
            }

            objectIdInfo = objectIdInfo.withAlwaysAsId(ref.alwaysAsId());
        }

        return objectIdInfo;
    }
}
</code>```

At serialization time, we copy our ObjectMapper (so the AnnotationIntrospector runs again) and apply CustomAnnotationIntrospector as follows:

```<code>@Context
private HttpRequest httpRequest_;

@Override
writeTo(...) {
    // Get our application's ObjectMapper.
    ContextResolver<ObjectMapper> objectMapperResolver = provider_.getContextResolver(ObjectMapper.class,
                                                                                MediaType.WILDCARD_TYPE);
    ObjectMapper objectMapper = objectMapperResolver.getContext(Object.class);

    // Get Set of fields to be expanded (pre-parsed).
    Set<String> fieldNames = (Set<String>)httpRequest_.getAttribute("ExpandFields");

    if (!fieldNames.isEmpty()) {
        // Pass expand fields to AnnotationIntrospector.
        AnnotationIntrospector expansionAnnotationIntrospector = new CustomAnnotationIntrospector(fieldNames);

        // Replace ObjectMapper with copy of ObjectMapper and apply custom AnnotationIntrospector.
        objectMapper = objectMapper.copy();
        objectMapper.setAnnotationIntrospector(expansionAnnotationIntrospector);
    }

    ObjectWriter objectWriter = objectMapper.writer();
    objectWriter.writeValue(...);
}
</code>```

Any glaring flaws in this approach? It seems relatively straightforward and is fully dynamic.

答:
If you are looking for a generalized solution that needs to be extended to all of your resources you may try following approach. I tried below solution using Jersey and Jackson. It should also work with RestEasy.

Basically, you need to write a custom jackson provider which set a special serializer for an expand field. Also, you need to pass the expand fields to the serializer so that you can decide how to do the serialization for expand fields.

```<code>@Singleton
public class ExpandFieldJacksonProvider extends JacksonJaxbJsonProvider {

@Inject
private Provider<ContainerRequestContext> provider;

@Override
protected JsonEndpointConfig _configForWriting(final ObjectMapper mapper, final Annotation[] annotations, final Class<?> defaultView) {
    final AnnotationIntrospector customIntrospector = mapper.getSerializationConfig().getAnnotationIntrospector();
    // Set the custom (user) introspector to be the primary one.
    final ObjectMapper filteringMapper = mapper.setAnnotationIntrospector(AnnotationIntrospector.pair(customIntrospector, new JacksonAnnotationIntrospector() {
        @Override
        public Object findSerializer(Annotated a) {
            // All expand fields should be annotated with '@ExpandField'.
            ExpandField expField = a.getAnnotation(ExpandField.class);
            if (expField != null) {
                // Use a custom serializer for expand field
                return new ExpandSerializer(expField.fieldName(), expField.idProperty());
            }
            return super.findSerializer(a);
        }
    }));

    return super._configForWriting(filteringMapper, annotations, defaultView);
}

@Override
public void writeTo(final Object value, final Class<?> type, final Type genericType, final Annotation[] annotations, final MediaType mediaType, final MultivaluedMap<String, Object> httpHeaders,
        final OutputStream entityStream) throws IOException {

    // Set the expand fields to java's ThreadLocal so that it can be accessed in 'ExpandSerializer' class.
    ExpandFieldThreadLocal.set(provider.get().getUriInfo().getQueryParameters().get("expand"));
    super.writeTo(value, type, genericType, annotations, mediaType, httpHeaders, entityStream);
    // Once the serialization is done, clear ThreadLocal
    ExpandFieldThreadLocal.remove();
}
</code>```

ExpandField.java

```<code>@Retention(RUNTIME)
public @interface ExpandField {
    // name of expand field
    String fieldName();
    // name of Id property in expand field. For eg: oraganisationId
    String idProperty();
}
</code>```

ExpandFieldThreadLocal.java

```<code>public class ExpandFieldThreadLocal {

    private static final ThreadLocal<List<String>> _threadLocal = new ThreadLocal<>();

    public static List<String> get() {
        return _threadLocal.get();
    }

    public static void set(List<String> expandFields) {
        _threadLocal.set(expandFields);
    }

    public static void remove() {
        _threadLocal.remove();
    }

}
</code>```

ExpandFieldSerializer.java

```<code>    public static class ExpandSerializer extends JsonSerializer<Object> {
    private String fieldName;
    private String idProperty;

    public ExpandSerializer(String fieldName,String idProperty) {
        this.fieldName = fieldName;
        this.idProperty = idProperty;
    }

    @Override
    public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
        // Get expand fields in current request which is set in custom jackson provider.
        List<String> expandFields = ExpandFieldThreadLocal.get();
        if (expandFields == null || !expandFields.contains(fieldName)) {
            try {
                // If 'expand' is not present in query param OR if the 'expand' field does not contain this field, write only id.
                serializers.defaultSerializeValue(value.getClass().getMethod("get"+StringUtils.capitalize(idProperty)).invoke(value),gen);
            } catch (Exception e) {
                //Handle Exception here
            }
        } else {
            serializers.defaultSerializeValue(value, gen);
        }

    }

}
</code>```

Operator.java

```<code>public class Operator extends AbstractEntity {
...
@ExpandField(fieldName = "organization",idProperty="organizationId")
private organization;
...
}
</code>```

The final step is to register the new ExpandFieldJacksonProvider. In Jersey, we register it through an instance of javax.ws.rs.core.Application as shown below. I hope there is something similar in RestEasy. By default, most of the JAX-RS libraries tend to load default JacksonJaxbJsonProvider through auto-discovery. You have to make sure auto-discovery is disabled for Jackson and new ExpandFieldJacksonProvider is registered.

```<code>public class JaxRsApplication extends Application{

    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> clazzes=new HashSet<>();
        clazzes.add(ExpandFieldJacksonProvider.class);
        return clazzes;
    }

}
</code>```

Body:
We're developing a RESTful API using Java EE 7 (RESTEasy / Hibernate / Jackson).

We want the API to serialize all child entities using their IDs, by default. We're doing this mostly to maintain consistency with our deserialization strategy, where we insist on receiving an ID.

However, we also want our users to be able to choose to get an expanded view of any of our child entities, either through a custom endpoint or a query parameter (undecided). For example:

// http://localhost:8080/rest/operator/1
// =====================================
{
    "operatorId": 1,
    "organization": 34,
    "endUser": 23
}

// http://localhost:8080/rest/operator/1?expand=organization
// =====================================
{
    "operatorId": 1,
    "organization": {
        "organizationId": 34,
        "organizationName": "name"
    },
    "endUser": 23
}

// http://localhost:8080/rest/operator/1?expand=enduser
// =====================================
{
    "operatorId": 1,
    "organization": 34,
    "endUser": {
        "endUserId": 23,
        "endUserName": "other name"
    }
}

// http://localhost:8080/rest/operator/1?expand=organization,enduser
// =====================================
{
    "operatorId": 1,
    "organization": {
        "organizationId": 34,
        "organizationName": "name"
    },
    "endUser": {
        "endUserId": 23,
        "endUserName": "other name"
    }
}

Is there a way to dynamically change the behavior of Jackson to determine whether a specified AbstractEntity field is serialized in full form or as its ID? How might it be done?

Additional Info

We know of a few ways to serialize our child entities using their IDs, including:

public class Operator extends AbstractEntity {
    ...
    @JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="organizationId")
    @JsonIdentityReference(alwaysAsId=true)
    public getOrganization() { ... }
    ...
}

and

public class Operator extends AbstractEntity {
    ...
    @JsonSerialize(using=AbstractEntityIdSerializer.class)
    public getOrganization() { ... }
    ...
}

where AbstractEntityIdSerializer serializes the entity using its ID.

The problem is that we don't know of a way for the user to override that default behavior and revert to standard Jackson object serialization. Ideally they'd also be able to choose which child properties to serialize in full form.

It would be awesome to dynamically toggle the alwaysAsId argument of @JsonIdentityReference for any property at runtime, if that's possible, or make the equivalent change to ObjectMapper/ObjectWriter.

Update: Working(?) Solution
We haven't had a chance to fully test this yet, but I've been working on a solution that leverages overriding Jackson's AnnotationIntrospector class. It seems to be working as intended.

public class CustomAnnotationIntrospector extends JacksonAnnotationIntrospector {
    private final Set<String> expandFieldNames_;

    public CustomAnnotationIntrospector(Set<String> expandFieldNames) {
        expandFieldNames_ = expandFieldNames;
    }

    @Override
    public ObjectIdInfo findObjectReferenceInfo(Annotated ann, ObjectIdInfo objectIdInfo) {
        JsonIdentityReference ref = _findAnnotation(ann, JsonIdentityReference.class);
        if (ref != null) {

            for (String expandFieldName : expandFieldNames_) {
                String expandFieldGetterName = "get" + expandFieldName;
                String propertyName = ann.getName();

                boolean fieldNameMatches = expandFieldName.equalsIgnoreCase(propertyName);
                boolean fieldGetterNameMatches = expandFieldGetterName.equalsIgnoreCase(propertyName);

                if (fieldNameMatches || fieldGetterNameMatches) {
                    return objectIdInfo.withAlwaysAsId(false);
                }
            }

            objectIdInfo = objectIdInfo.withAlwaysAsId(ref.alwaysAsId());
        }

        return objectIdInfo;
    }
}

At serialization time, we copy our ObjectMapper (so the AnnotationIntrospector runs again) and apply CustomAnnotationIntrospector as follows:

@Context
private HttpRequest httpRequest_;

@Override
writeTo(...) {
    // Get our application's ObjectMapper.
    ContextResolver<ObjectMapper> objectMapperResolver = provider_.getContextResolver(ObjectMapper.class,
                                                                                MediaType.WILDCARD_TYPE);
    ObjectMapper objectMapper = objectMapperResolver.getContext(Object.class);

    // Get Set of fields to be expanded (pre-parsed).
    Set<String> fieldNames = (Set<String>)httpRequest_.getAttribute("ExpandFields");

    if (!fieldNames.isEmpty()) {
        // Pass expand fields to AnnotationIntrospector.
        AnnotationIntrospector expansionAnnotationIntrospector = new CustomAnnotationIntrospector(fieldNames);

        // Replace ObjectMapper with copy of ObjectMapper and apply custom AnnotationIntrospector.
        objectMapper = objectMapper.copy();
        objectMapper.setAnnotationIntrospector(expansionAnnotationIntrospector);
    }

    ObjectWriter objectWriter = objectMapper.writer();
    objectWriter.writeValue(...);
}

Any glaring flaws in this approach? It seems relatively straightforward and is fully dynamic.

Body:
If you are looking for a generalized solution that needs to be extended to all of your resources you may try following approach. I tried below solution using Jersey and Jackson. It should also work with RestEasy.

Basically, you need to write a custom jackson provider which set a special serializer for an expand field. Also, you need to pass the expand fields to the serializer so that you can decide how to do the serialization for expand fields.

@Singleton
public class ExpandFieldJacksonProvider extends JacksonJaxbJsonProvider {

@Inject
private Provider<ContainerRequestContext> provider;

@Override
protected JsonEndpointConfig _configForWriting(final ObjectMapper mapper, final Annotation[] annotations, final Class<?> defaultView) {
    final AnnotationIntrospector customIntrospector = mapper.getSerializationConfig().getAnnotationIntrospector();
    // Set the custom (user) introspector to be the primary one.
    final ObjectMapper filteringMapper = mapper.setAnnotationIntrospector(AnnotationIntrospector.pair(customIntrospector, new JacksonAnnotationIntrospector() {
        @Override
        public Object findSerializer(Annotated a) {
            // All expand fields should be annotated with '@ExpandField'.
            ExpandField expField = a.getAnnotation(ExpandField.class);
            if (expField != null) {
                // Use a custom serializer for expand field
                return new ExpandSerializer(expField.fieldName(), expField.idProperty());
            }
            return super.findSerializer(a);
        }
    }));

    return super._configForWriting(filteringMapper, annotations, defaultView);
}

@Override
public void writeTo(final Object value, final Class<?> type, final Type genericType, final Annotation[] annotations, final MediaType mediaType, final MultivaluedMap<String, Object> httpHeaders,
        final OutputStream entityStream) throws IOException {

    // Set the expand fields to java's ThreadLocal so that it can be accessed in 'ExpandSerializer' class.
    ExpandFieldThreadLocal.set(provider.get().getUriInfo().getQueryParameters().get("expand"));
    super.writeTo(value, type, genericType, annotations, mediaType, httpHeaders, entityStream);
    // Once the serialization is done, clear ThreadLocal
    ExpandFieldThreadLocal.remove();
}

ExpandField.java

@Retention(RUNTIME)
public @interface ExpandField {
    // name of expand field
    String fieldName();
    // name of Id property in expand field. For eg: oraganisationId
    String idProperty();
}

ExpandFieldThreadLocal.java

public class ExpandFieldThreadLocal {

    private static final ThreadLocal<List<String>> _threadLocal = new ThreadLocal<>();

    public static List<String> get() {
        return _threadLocal.get();
    }

    public static void set(List<String> expandFields) {
        _threadLocal.set(expandFields);
    }

    public static void remove() {
        _threadLocal.remove();
    }

}

ExpandFieldSerializer.java

    public static class ExpandSerializer extends JsonSerializer<Object> {
    private String fieldName;
    private String idProperty;

    public ExpandSerializer(String fieldName,String idProperty) {
        this.fieldName = fieldName;
        this.idProperty = idProperty;
    }

    @Override
    public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
        // Get expand fields in current request which is set in custom jackson provider.
        List<String> expandFields = ExpandFieldThreadLocal.get();
        if (expandFields == null || !expandFields.contains(fieldName)) {
            try {
                // If 'expand' is not present in query param OR if the 'expand' field does not contain this field, write only id.
                serializers.defaultSerializeValue(value.getClass().getMethod("get"+StringUtils.capitalize(idProperty)).invoke(value),gen);
            } catch (Exception e) {
                //Handle Exception here
            }
        } else {
            serializers.defaultSerializeValue(value, gen);
        }

    }

}

Operator.java

public class Operator extends AbstractEntity {
...
@ExpandField(fieldName = "organization",idProperty="organizationId")
private organization;
...
}

The final step is to register the new ExpandFieldJacksonProvider. In Jersey, we register it through an instance of javax.ws.rs.core.Application as shown below. I hope there is something similar in RestEasy. By default, most of the JAX-RS libraries tend to load default JacksonJaxbJsonProvider through auto-discovery. You have to make sure auto-discovery is disabled for Jackson and new ExpandFieldJacksonProvider is registered.

public class JaxRsApplication extends Application{

    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> clazzes=new HashSet<>();
        clazzes.add(ExpandFieldJacksonProvider.class);
        return clazzes;
    }

}


问:
Anagram with JavaScript
```<code>const myAnagram = (arr1, arr2) => {
  let str1 = arr1;
  let str2 = arr2;
  let temp1 = [];
  let temp2 = [];
  let flag = 0;

  if (str1.length !== str2.length) return "Not Anagram statement A";

  for (var i = 0; i < str1.length - 1; i++) {
    temp1[i] = str1[i];
  }

  for (var j = 0; j < str2.length - 1; j++) {
    temp2[i] = str2[i];
  }

  temp1.sort();
  temp2.sort();

  for (var k = 0; k < str1.length - 1; k++) {
    if (temp1[j] !== temp2[j]) return "Not Anagram statement C";
    return "Anagram! statement D";
  }
}
</code>```

答:
The problem you have is with the identifiers you have used in loops.
Have a look at the corrected code.

```<code>function myAnagram(arr1, arr2) {

    var str1 = arr1;
    var str2 = arr2;
    var temp1 = [];
    var temp2 = [];
    var flag = 0;
    if (str1.length !== str2.length) {
        return "Not Anagram statement A";
    } else {
        for (var i = 0; i < str1.length; i++) {
            temp1[i] = str1[i];
        }

        for (var j = 0; j < str2.length; j++) {
            temp2[j] = str2[j];
        }
        temp1.sort();
        temp2.sort();
        for (var k = 0; k < str1.length; k++) {
            if (temp1[k] !== temp2[k]) {
                return "Not Anagram statement C";
            } else {
                return "Anagram! statement D";
            }
        }
    }
}
</code>```

Hope it helps !!
    PS: You can optimize this code to a great extend.

ContentLicense: CC BY-SA 4.0

Title: Anagram with JavaScript

Body:
The problem you have is with the identifiers you have used in loops.
Have a look at the corrected code.

function myAnagram(arr1, arr2) {

    var str1 = arr1;
    var str2 = arr2;
    var temp1 = [];
    var temp2 = [];
    var flag = 0;
    if (str1.length !== str2.length) {
        return "Not Anagram statement A";
    } else {
        for (var i = 0; i < str1.length; i++) {
            temp1[i] = str1[i];
        }

        for (var j = 0; j < str2.length; j++) {
            temp2[j] = str2[j];
        }
        temp1.sort();
        temp2.sort();
        for (var k = 0; k < str1.length; k++) {
            if (temp1[k] !== temp2[k]) {
                return "Not Anagram statement C";
            } else {
                return "Anagram! statement D";
            }
        }
    }
}

Hope it helps !!
    PS: You can optimize this code to a great extend.


问:
Returning HTML or JSON based on header type Nodejs
My nodeJS Api needs to return HTML or Json based on the header. If the header is:

```<code>Accept = application/json
</code>```

The Api needs to return Json else my Api needs to return a HTML file.

this is the code I use on my routes:

```<code>var app = express();
app.use('/auth', require('./routes/Authenticate'));
</code>```

In the Authenticate file I catch /login, and do the login stuff. if it succeeds I redirect to /users. In the /users I check for the Accept with an if statement:

```<code>router.get('/users', function(req,res){
    if(req.get('Accept') === 'application/json'){
       res.json({ success: true, user: req.user });
    } else {
        res.render("account/profile") //redirect to the file
    }
});
</code>```

This works(from this solution) but is there a better way? Because there are like 20 endpoints and the application is growing and this will be a mess for every endpoint.

答:
You can wrap router.get function with a custom function</p>

```<code>router.wrappedGet = function (path, callback) {
    router.get(path, function (req, res) {
        if (req.get('Content-Type') === 'application/json') {
            res.render = res.json;
        }
        callback(req, res);
    })
};
</code>```

Body:
My nodeJS Api needs to return HTML or Json based on the header. If the header is:

Accept = application/json

The Api needs to return Json else my Api needs to return a HTML file.

this is the code I use on my routes:

var app = express();
app.use('/auth', require('./routes/Authenticate'));

In the Authenticate file I catch /login, and do the login stuff. if it succeeds I redirect to /users. In the /users I check for the Accept with an if statement:

router.get('/users', function(req,res){
    if(req.get('Accept') === 'application/json'){
       res.json({ success: true, user: req.user });
    } else {
        res.render("account/profile") //redirect to the file
    }
});

This works(from this solution) but is there a better way? Because there are like 20 endpoints and the application is growing and this will be a mess for every endpoint.

Body:
You can wrap router.get function with a custom function

router.wrappedGet = function (path, callback) {
    router.get(path, function (req, res) {
        if (req.get('Content-Type') === 'application/json') {
            res.render = res.json;
        }
        callback(req, res);
    })
};


问:
How to calculate scale based on viewport width and kept aspect ratio, with pure CSS?
I have this container with a fixed 16:9 aspect ratio.
In this container I have another container with full width and 7.81% height based on the width. What I would like to achieve is to scale the contents in this container based on the viewport width but with kept aspect ratio.
The base size is 1280px. So if the windows is 640px, the scale would be 0.5.
Calc however, doesn't return a float value. So scale is not working properly with calc. Is there another way to achieve this?

I know this is possible with JavaScript, but I would like to avoid this.

JsFiddle: https://jsfiddle.net/qdc05hqm/

```<code><style>
.outer-container {
  width: 100vw;
  height: 56.25vw;
  max-height: 100vh;
  max-width: 177.78vh;
  background: #cc00cc;
  position:relative;
}

.inner-container {
  background: #333;
  position: absolute;
  bottom: 0;
  width: 100%;
  height: 7.81vw;
}

.content {
  color: #FFF;
  transform: scale(calc(1280px / 100vw)); <--- Does not work.
}
</style>

<div class="outer-container">
  <div class="inner-container">
    <div class="content">
      This text and other stuff should be scaled based on the viewport width
    </div>
  </div>
</div>
</code>```

答:
Use

.content{
       font-size:calc(10px + 0.3vw)
 }

Hope this will help you.

Body:
I have this container with a fixed 16:9 aspect ratio.
In this container I have another container with full width and 7.81% height based on the width. What I would like to achieve is to scale the contents in this container based on the viewport width but with kept aspect ratio.
The base size is 1280px. So if the windows is 640px, the scale would be 0.5.
Calc however, doesn't return a float value. So scale is not working properly with calc. Is there another way to achieve this?

I know this is possible with JavaScript, but I would like to avoid this.

JsFiddle: https://jsfiddle.net/qdc05hqm/

      This text and other stuff should be scaled based on the viewport width


问:
Struct for JSON Response
I'm trying to workout how the type-struct should be for this JSON response.
from CryptoWatch https://api.cryptowat.ch/markets/kraken/btcusd/ohlc?periods=60

```<code>{
  "result": {
    "60": [
      [
        1490733900,
        1027.001,
        1027.001,
        1027,
        1027,
        0.024999999
      ],
      [
        1490733960,
        1027,
        1027,
        1027,
        1027,
        12.61904
      ],
      [
        1490778360,
        1037.749,
        1037.749,
        1037.749,
        1037.749,
        0.0052474597
      ]
    ]
  },
  "allowance": {
    "cost": 1234,
    "remaining": 456677
  }
}
</code>```

I've tried the JSON-TO-GoLang-Struct service.

type AutoGenerated struct {
    Result struct {
        Num60 []struct {
        Num0 int json:"0"
        Num1 float64 json:"1"
        Num2 float64 json:"2"
        Num3 int json:"3"
        Num4 int json:"4"
        Num5 float64 json:"5"
        } json:"60"
} json:"result"
        Allowance struct {
            Cost int json:"cost"
            Remaining int json:"remaining"
        } json:"allowance"
}

code-formatting seems broken :/

It seems to get stuck on array-to-struct error when i tried to decode it.

I don't want to use the map+interface method for this struct.

答:
Here you go. You can put the result as map[string][][]float64 also. But this is more readable I think.

```<code>type Result [][]float64

type Response struct {
    Result    map[string]Result `json:"result"`
    Allowance struct {
        Cost      int `json:"cost"`
        Remaining int `json:"remaining"`
    } `json:"allowance"`
}
</code>```

Title: Struct for JSON Response

Body:
I'm trying to workout how the type-struct should be for this JSON response.
from CryptoWatch https://api.cryptowat.ch/markets/kraken/btcusd/ohlc?periods=60

{
  "result": {
    "60": [
      [
        1490733900,
        1027.001,
        1027.001,
        1027,
        1027,
        0.024999999
      ],
      [
        1490733960,
        1027,
        1027,
        1027,
        1027,
        12.61904
      ],
      [
        1490778360,
        1037.749,
        1037.749,
        1037.749,
        1037.749,
        0.0052474597
      ]
    ]
  },
  "allowance": {
    "cost": 1234,
    "remaining": 456677
  }
}

I've tried the JSON-TO-GoLang-Struct service.

type AutoGenerated struct {
    Result struct {
        Num60 []struct {
        Num0 int json:"0"
        Num1 float64 json:"1"
        Num2 float64 json:"2"
        Num3 int json:"3"
        Num4 int json:"4"
        Num5 float64 json:"5"
        } json:"60"
} json:"result"
        Allowance struct {
            Cost int json:"cost"
            Remaining int json:"remaining"
        } json:"allowance"
}

code-formatting seems broken :/

It seems to get stuck on array-to-struct error when i tried to decode it.

I don't want to use the map+interface method for this struct.

Body:
Here you go. You can put the result as map[string][][]float64 also. But this is more readable I think.

type Result [][]float64

type Response struct {
    Result    map[string]Result `json:"result"`
    Allowance struct {
        Cost      int `json:"cost"`
        Remaining int `json:"remaining"`
    } `json:"allowance"`
}


问:
When to return vector iterator instead of vector?
Let's say we have a function 1 :

```<code>vector<T>::iterator GetSomething()
{
 vector<T> vec;

 // Update vec with something...

 return vec.begin();
}
</code>```

And another function 2:

```<code>vector<T> GetSomething()
{
 vector<T> vec;

 // Update vec with something...

 return vec;
}
</code>```

In what situations would we prefer function 1 ?
Also, what would be the lifetime of that vector object ?
How would we know if the iterator is pointing to empty vector ? Probably need to pass pair of iterators to determine begin / end.

答:
A vector iterator is only valid for the vector it comes from so returning an iterator to a local vector is no use.

Only return a vector iterator when you passed the vector it belongs to in as a parameter reference:

```<code>std::vector<int>::iterator find(std::vector<int>& v, int i)
{
    // do findie stuff
    return std::find(std::begin(v), std::end(v), i);
}
</code>```

You would never want to do this:

```<code>vector<T>::iterator GetSomething()
{
    vector<T> vec;

    // Update vec with something...

    return vec.begin(); // this iterator will be bad when it arrives
}
</code>```

Once the vector is destroyed at the end of the function its iterators are invalidated.

Body:
Let's say we have a function 1 :

vector<T>::iterator GetSomething()
{
 vector<T> vec;

 // Update vec with something...

 return vec.begin();
}

And another function 2:

vector<T> GetSomething()
{
 vector<T> vec;

 // Update vec with something...

 return vec;
}

In what situations would we prefer function 1 ?
Also, what would be the lifetime of that vector object ?
How would we know if the iterator is pointing to empty vector ? Probably need to pass pair of iterators to determine begin / end.

Body:
A vector iterator is only valid for the vector it comes from so returning an iterator to a local vector is no use.

Only return a vector iterator when you passed the vector it belongs to in as a parameter reference:

std::vector<int>::iterator find(std::vector<int>& v, int i)
{
    // do findie stuff
    return std::find(std::begin(v), std::end(v), i);
}

You would never want to do this:

vector<T>::iterator GetSomething()
{
    vector<T> vec;

    // Update vec with something...

    return vec.begin(); // this iterator will be bad when it arrives
}

Once the vector is destroyed at the end of the function its iterators are invalidated.


问:
tomcat deploy module war to sub url path
I have a multi-module maven project whose structure looks like this:

```<code>app                // parent/root project folder
 |- src
 |- target
      |- app.war   // common features
 |- app-payment    // child/module folder
        |- src
        |- target
             |- app-payment.war  // shop/pay features
</code>```

How can I map the two war files to urls like below?

```<code>requests for
   localhost:8080/app/payment   --goto-->   $CATALINA_HOME/webapps/app-payment.war (or any other locations, doesn't matter)
other requests for
   localhost:8080/app           --goto-->   $CATALINA_HOME/webapps/app.war
</code>```

The web.xml -> <servlet-mapping> both are <url-pattern>/</url-pattern>.

I'm using tomcat 8.5 and want to keep default settings if possible (e.g., do not add <Context> in server.xml, leave autoDeploy=true). So probably the approaches provided in A word on Contexts at
https://tomcat.apache.org/tomcat-8.5-doc/deployer-howto.html would not work (have tried anyway and no).

In case this turns out to be an XY problem...Is it the right way to use/modify tomcat to achieve such url pattern? Or should I change the project settings (or design)? It's a spring-mvc project and the whole spring-*.xml thing is like a myth...

catalina.2017-03-29.log:

```
29-Mar-2017 17:28:49.472 INFO [main] org.apache.catalina.core.StandardService.startInternal Starting service Catalina
29-Mar-2017 17:28:49.472 INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet Engine: Apache Tomcat/8.5.5
29-Mar-2017 17:28:49.494 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployWAR Deploying web application archive C:\Program_Files\tomcat-8.5.5\webapps\payment.war
29-Mar-2017 17:28:49.505 WARNING [localhost-startStop-1] org.apache.catalina.startup.SetContextPropertiesRule.begin [SetContextPropertiesRule]{Context} Setting property 'antiJARLocking' to 'true' did not find a matching property.
29-Mar-2017 17:28:51.071 INFO [localhost-startStop-1] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
29-Mar-2017 17:28:52.480 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployWAR Deployment of web application archive C:\Program_Files\tomcat-8.5.5\webapps\payment.war has finished in 2,985 ms
29-Mar-2017 17:28:52.482 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory C:\Program_Files\tomcat-8.5.5\webapps\docs
29-Mar-2017 17:28:52.494 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory C:\Program_Files\tomcat-8.5.5\webapps\docs has finished in 12 ms
29-Mar-2017 17:28:52.494 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory C:\Program_Files\tomcat-8.5.5\webapps\examples
```

答:
Try changing context.xml of your war file

```<code> <Context antiJARLocking="true" path="/app/payment"/>
</code>```

By default, it would be

```<code> <Context antiJARLocking="true" path="/app-payment"/>
</code>```

Body:
I have a multi-module maven project whose structure looks like this:

app                // parent/root project folder
 |- src
 |- target
      |- app.war   // common features
 |- app-payment    // child/module folder
        |- src
        |- target
             |- app-payment.war  // shop/pay features

How can I map the two war files to urls like below?

requests for
   localhost:8080/app/payment   --goto-->   $CATALINA_HOME/webapps/app-payment.war (or any other locations, doesn't matter)
other requests for
   localhost:8080/app           --goto-->   $CATALINA_HOME/webapps/app.war

The web.xml -> <servlet-mapping> both are <url-pattern>/</url-pattern>.

I'm using tomcat 8.5 and want to keep default settings if possible (e.g., do not add <Context> in server.xml, leave autoDeploy=true). So probably the approaches provided in A word on Contexts at
https://tomcat.apache.org/tomcat-8.5-doc/deployer-howto.html would not work (have tried anyway and no).

In case this turns out to be an XY problem...Is it the right way to use/modify tomcat to achieve such url pattern? Or should I change the project settings (or design)? It's a spring-mvc project and the whole spring-*.xml thing is like a myth...

catalina.2017-03-29.log:

29-Mar-2017 17:28:49.472 INFO [main] org.apache.catalina.core.StandardService.startInternal Starting service Catalina
29-Mar-2017 17:28:49.472 INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet Engine: Apache Tomcat/8.5.5
29-Mar-2017 17:28:49.494 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployWAR Deploying web application archive C:\Program_Files\tomcat-8.5.5\webapps\payment.war
29-Mar-2017 17:28:49.505 WARNING [localhost-startStop-1] org.apache.catalina.startup.SetContextPropertiesRule.begin [SetContextPropertiesRule]{Context} Setting property 'antiJARLocking' to 'true' did not find a matching property.
29-Mar-2017 17:28:51.071 INFO [localhost-startStop-1] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
29-Mar-2017 17:28:52.480 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployWAR Deployment of web application archive C:\Program_Files\tomcat-8.5.5\webapps\payment.war has finished in 2,985 ms
29-Mar-2017 17:28:52.482 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory C:\Program_Files\tomcat-8.5.5\webapps\docs
29-Mar-2017 17:28:52.494 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory C:\Program_Files\tomcat-8.5.5\webapps\docs has finished in 12 ms
29-Mar-2017 17:28:52.494 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory C:\Program_Files\tomcat-8.5.5\webapps\examples

Body:
Try changing context.xml of your war file

 <Context antiJARLocking="true" path="/app/payment"/>

By default, it would be

 <Context antiJARLocking="true" path="/app-payment"/>


问:
Reindex and fill out array depending on another array
I'm trying to create a tables with information from two arrays. Here are the two arrays:

First array, for table headers

```<code>Array
(
    [0] => Color
    [1] => Length
    [2] => Waist
)
</code>```

Second array, the one that needs modification

```<code>Array
(
    [0] => Array
        [0] => green [1] => Color

    [1] => Array
        [0] => 23 [1] => Length
)
Array
(
    [0] =>
)
Array
(
    [0] => Array
        [0] => 23 [1] => Length

    [1] => Array
        [0] => 24 [1] => Waist
)
</code>```

Array needs to look like this:

```<code>Array
(
    [0] => Array
        [0] => green [1] => Color

    [1] => Array
        [0] => 23 [1] => Length

    [2] => Array
        [0] => [1] => Waist

Array
(
    [0] => Array
        [0] => [1] => Color

    [1] => Array
        [0] => [1] => Length

    [2] => Array
        [0] => [1] => Waist

Array
(
    [0] => Array
        [0] => [1] => Color

    [1] => Array
        [0] => 23 [1] => Length

    [2] => Array
        [0] => 24 [1] => Waist
</code>```

So the point is that the keys in the first level needs to match the keys in the array that makes the table headers, where [1] one the second level has the same value as the table header. Any ideas?

After some feedback, an alternative acceptable output array structure would be:

```<code>array(
    array(
        'Color' => 'green',
        'Length' => 23,
        'Waist' => null
    ),
    array(
        'Color' => null,
        'Length' => null,
        'Waist' => null
    ),
    array(
        'Color' => null,
        'Length' => 23,
        'Waist' => 24
    )
)
</code>```

答:
You have a complex array structure for an easy set of data.  Could your final array work better like this?

```<code>$data = array(
    array(
        'Color' => 'green',
        'Length' => 23,
        'Waist' => NULL
    ),
    array(
        'Color' => NULL,
        'Length' => NULL,
        'Waist' => NULL
    ),
    array(
        'Color' => NULL,
        'Length' => 23,
        'Waist' => 24
    )
);
</code>```

If you're dead set on your structure, though, this should work:

```<code>function format_my_array($keys, $malformed) {
    foreach ($malformed as $key => $fragments) {
        $temp = array(
            'Color' => NULL,
            'Length' => NULL,
            'Waist' => NULL
        );
        foreach ($fragments as $fragment) {
            if (isset($fragment[1])) {
                switch($fragment[1]) {
                    case 'Length':
                        $temp['Length'] = $fragment[1];
                        break;
                    case 'Waist':
                        $temp['Waist'] = $fragment[1];
                        break;
                    default:
                        $temp['Color'] = $fragment[1];
                        break;
                }
            }
        }
        $malformed[$key] = array(
            array($temp['Color'], 'Color'),
            array($temp['Length'], 'Length'),
            array($temp['Waist'], 'Waist')
        );
    }
    return $malformed;
}
</code>```

Body:
I'm trying to create a tables with information from two arrays. Here are the two arrays:

First array, for table headers

Array
(
    [0] => Color
    [1] => Length
    [2] => Waist
)

Second array, the one that needs modification

Array
(
    [0] => Array
        [0] => green [1] => Color

    [1] => Array
        [0] => 23 [1] => Length
)
Array
(
    [0] =>
)
Array
(
    [0] => Array
        [0] => 23 [1] => Length

    [1] => Array
        [0] => 24 [1] => Waist
)

Array needs to look like this:

Array
(
    [0] => Array
        [0] => green [1] => Color

    [1] => Array
        [0] => 23 [1] => Length

    [2] => Array
        [0] => [1] => Waist

Array
(
    [0] => Array
        [0] => [1] => Color

    [1] => Array
        [0] => [1] => Length

    [2] => Array
        [0] => [1] => Waist

Array
(
    [0] => Array
        [0] => [1] => Color

    [1] => Array
        [0] => 23 [1] => Length

    [2] => Array
        [0] => 24 [1] => Waist

So the point is that the keys in the first level needs to match the keys in the array that makes the table headers, where [1] one the second level has the same value as the table header. Any ideas?

After some feedback, an alternative acceptable output array structure would be:

array(
    array(
        'Color' => 'green',
        'Length' => 23,
        'Waist' => null
    ),
    array(
        'Color' => null,
        'Length' => null,
        'Waist' => null
    ),
    array(
        'Color' => null,
        'Length' => 23,
        'Waist' => 24
    )
)

Body:
You have a complex array structure for an easy set of data.  Could your final array work better like this?

$data = array(
    array(
        'Color' => 'green',
        'Length' => 23,
        'Waist' => NULL
    ),
    array(
        'Color' => NULL,
        'Length' => NULL,
        'Waist' => NULL
    ),
    array(
        'Color' => NULL,
        'Length' => 23,
        'Waist' => 24
    )
);

If you're dead set on your structure, though, this should work:

function format_my_array($keys, $malformed) {
    foreach ($malformed as $key => $fragments) {
        $temp = array(
            'Color' => NULL,
            'Length' => NULL,
            'Waist' => NULL
        );
        foreach ($fragments as $fragment) {
            if (isset($fragment[1])) {
                switch($fragment[1]) {
                    case 'Length':
                        $temp['Length'] = $fragment[1];
                        break;
                    case 'Waist':
                        $temp['Waist'] = $fragment[1];
                        break;
                    default:
                        $temp['Color'] = $fragment[1];
                        break;
                }
            }
        }
        $malformed[$key] = array(
            array($temp['Color'], 'Color'),
            array($temp['Length'], 'Length'),
            array($temp['Waist'], 'Waist')
        );
    }
    return $malformed;
}


问:
Grails 3.2.8 not able to get springSecurityService.currentUser in controller
I'm unable to get springSecurityService.currentUser from a controller in Grails 3.2.8.

Please note that Grails 3.2.8 made some performance improvements not in previous versions that seem to be breaking Spring Security Core. As per Grails 3.2.8 dependency injection in domain classes, I set grails.gorm.autowire = true, which fixed that incompatibility.

Steps to reproduce:

Create a new Grails 3.2.8 web app with Spring Security 3.1.1 using Roles and Groups.

In application.yml, set grails.gorm.autowire = true

In Bootstrap:

```<code>def init = { servletContext ->
    User user = new User(username: 'foo', password:'foo').save(flush: true)
    Role role = new Role(authority: 'SomeRole').save(flush: true)
    RoleGroup roleGroup = new RoleGroup(name: 'SomeRole').save(flush: true)
    RoleGroupRole.create(roleGroup, role)
    UserRoleGroup.create(user, roleGroup)
}
</code>```

Create a controller TestController:

```<code>@Secured(['SomeRole'])
class TestController {
    def springSecurityService

    def index() {
        println "springSecurityService==null? ${(springSecurityService==null).toString()}"
        println "SecurityContextHolder.context==null? ${(SecurityContextHolder.context==null).toString()}"
        println "SecurityContextHolder.context?.authentication==null? ${(SecurityContextHolder.context?.authentication==null).toString()}"
        println "springSecurityService.principal==null? ${(springSecurityService.principal==null).toString()}"
        println "springSecurityService.currentUser==null? ${(springSecurityService.currentUser==null).toString()}"

        render "1" //Render something so we don't get an exception.
    }
}
</code>```

Start up the server and go to /test. The output is:

```<code>springSecurityService==null? false
SecurityContextHolder.context==null? false
SecurityContextHolder.context?.authentication==null? true
springSecurityService.principal==null? true
springSecurityService.currentUser==null? true`
</code>```

Is there a good workaround?

答:
If SecurityContextHolder.context is not null (it should never be null) but
SecurityContextHolder.context?.authentication is null, then this is probably not a Grails or a plugin issue - you're not authenticated. So there's no principal to get the cached user id from (i.e. springSecurityService.principal is null as your output shows) and there's no way to retrieve the current User instance.

Body:
I'm unable to get springSecurityService.currentUser from a controller in Grails 3.2.8.

Please note that Grails 3.2.8 made some performance improvements not in previous versions that seem to be breaking Spring Security Core. As per Grails 3.2.8 dependency injection in domain classes, I set grails.gorm.autowire = true, which fixed that incompatibility.

Steps to reproduce:

Create a new Grails 3.2.8 web app with Spring Security 3.1.1 using Roles and Groups.

In application.yml, set grails.gorm.autowire = true

In Bootstrap:

def init = { servletContext ->
    User user = new User(username: 'foo', password:'foo').save(flush: true)
    Role role = new Role(authority: 'SomeRole').save(flush: true)
    RoleGroup roleGroup = new RoleGroup(name: 'SomeRole').save(flush: true)
    RoleGroupRole.create(roleGroup, role)
    UserRoleGroup.create(user, roleGroup)
}

Create a controller TestController:

@Secured(['SomeRole'])
class TestController {
    def springSecurityService

    def index() {
        println "springSecurityService==null? ${(springSecurityService==null).toString()}"
        println "SecurityContextHolder.context==null? ${(SecurityContextHolder.context==null).toString()}"
        println "SecurityContextHolder.context?.authentication==null? ${(SecurityContextHolder.context?.authentication==null).toString()}"
        println "springSecurityService.principal==null? ${(springSecurityService.principal==null).toString()}"
        println "springSecurityService.currentUser==null? ${(springSecurityService.currentUser==null).toString()}"

        render "1" //Render something so we don't get an exception.
    }
}

Start up the server and go to /test. The output is:

springSecurityService==null? false
SecurityContextHolder.context==null? false
SecurityContextHolder.context?.authentication==null? true
springSecurityService.principal==null? true
springSecurityService.currentUser==null? true`

Is there a good workaround?


问:
Read and Split(Parse) data in java
I am trying to split some simple data from a .txt file. I have found some useful structures on the internet but it was not enough to split the data the way I wanted. I get a string like this:

```<code>{X:0.8940594 Y:0.6853521 Z:1.470214}
</code>```

And I want to transform it to like this;

```<code>0.8940594
0.6853521
1.470214
</code>```

And then put them in a matrix in order X=[], Y=[], Z=[]; (the data is the coordinate of an object)

Here is my code:

```<code>BufferedReader in = null; {
        try {
            in = new BufferedReader(new FileReader("file.txt"));
            String read = null;
            while ((read = in.readLine()) != null) {
                String[] splited = read.split("\\s+");
                for (String part : splited) {
                    System.out.println(part);
                }
            }
        } catch (IOException e) {
            System.out.println("There was a problem: " + e);
            e.printStackTrace();
        } finally {
            try {
                in.close();
            } catch (Exception e) {
            }
        }
    }
</code>```

What do I need to add to my code to get the data the way I want?

Right now with this code I receive data like this:

```<code>{X:0.8940594
Y:0.6853521
Z:1.470214}
</code>```

答:
You can try using a regex similar to the following to match and capture the three numbers contained in each tuple:

```<code>{\s*X:(.*?)\s+Y:(.*?)\s+Z:(.*?)\s*}
</code>```

Each quantity contained in parenthesis is a capture group, and is available after a match has taken place.

```<code>int size = 100;  // replace with actual size of your vectors/matrix
double[] A = new double[size];
double[] B = new double[size];
double[] C = new double[size];
String input = "{X:0.8940594 Y:0.6853521 Z:1.470214}";
String regex = "\\{\\s*X:(.*?)\\s+Y:(.*?)\\s+Z:(.*?)\\s*\\}";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(input);
int counter = 0;
while (m.find()) {
    A[counter] = Double.parseDouble(m.group(1));
    B[counter] = Double.parseDouble(m.group(2));
    C[counter] = Double.parseDouble(m.group(3));
    ++counter;
}
</code>```

Title: Read and Split(Parse) data in java

Body:
I am trying to split some simple data from a .txt file. I have found some useful structures on the internet but it was not enough to split the data the way I wanted. I get a string like this:

{X:0.8940594 Y:0.6853521 Z:1.470214}

And I want to transform it to like this;

0.8940594
0.6853521
1.470214

And then put them in a matrix in order X=[], Y=[], Z=[]; (the data is the coordinate of an object)

Here is my code:

BufferedReader in = null; {
        try {
            in = new BufferedReader(new FileReader("file.txt"));
            String read = null;
            while ((read = in.readLine()) != null) {
                String[] splited = read.split("\\s+");
                for (String part : splited) {
                    System.out.println(part);
                }
            }
        } catch (IOException e) {
            System.out.println("There was a problem: " + e);
            e.printStackTrace();
        } finally {
            try {
                in.close();
            } catch (Exception e) {
            }
        }
    }

What do I need to add to my code to get the data the way I want?

Right now with this code I receive data like this:

{X:0.8940594
Y:0.6853521
Z:1.470214}

Body:
You can try using a regex similar to the following to match and capture the three numbers contained in each tuple:

{\s*X:(.*?)\s+Y:(.*?)\s+Z:(.*?)\s*}

Each quantity contained in parenthesis is a capture group, and is available after a match has taken place.

int size = 100;  // replace with actual size of your vectors/matrix
double[] A = new double[size];
double[] B = new double[size];
double[] C = new double[size];
String input = "{X:0.8940594 Y:0.6853521 Z:1.470214}";
String regex = "\\{\\s*X:(.*?)\\s+Y:(.*?)\\s+Z:(.*?)\\s*\\}";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(input);
int counter = 0;
while (m.find()) {
    A[counter] = Double.parseDouble(m.group(1));
    B[counter] = Double.parseDouble(m.group(2));
    C[counter] = Double.parseDouble(m.group(3));
    ++counter;
}


问:
Unity multithreading producer consumer
I created a situation where a producer class adds strings to a queue in a controller class. The controller class notifies the worker class that there is work and executes the work, in this case appending strings to a file. I'm not able to get this work. The file is created but nothing is appending. I created this situation in java where I succeeded. I will put this code at the end. Just to clearify I need solve this in C#.

With using the debugger I came to the conclusion that the thread doesn't wake up after going into wait. I could be wrong however.

As a note: I do not want to use coroutines

Producer method:

```<code>void Start () {
    for (int i = 0; i < 100; i++)
    {
        Ccontroller.Instance.AddWork("no: " + i);
    }
}
</code>```

Controller class
For locking I tried Monitor.enter/exit and current solution. I changed the implementation abit for easyness. This implementation uses the worker static queue. The static queue was needed for the thread.

```<code>public class Ccontroller : Singleton<Ccontroller>
{
public Queue<string> workLoad = new Queue<string>();
public Worker worker;

public Object lockGetWork = new Object();

public void AddWork(string toProcess)
{
    Worker.workload.Enqueue(toProcess);

    lock (lockGetWork)
    {
        Monitor.PulseAll(lockGetWork);
    }
}

public string GetWork()
{
    string process;

    process = workLoad.Dequeue();

    return process;
}
}
</code>```

Worker class:
public class Worker : MonoBehaviour {

```<code>static string path = @"d:\test.txt";
Thread t;

public static Queue<string> workload = new Queue<string>();

private void Awake()
{
    t = new Thread(Work);
}

// Use this for initialization
void Start()
{
    //create file
    if (!File.Exists(path))
    {
        using (StreamWriter sw = File.CreateText(path)) { }
    }
    t.Start();
}

static void Work()
{

while (true)
{
    if (workload.Peek() != null)
        {
            using (StreamWriter sw = File.AppendText(path))
            {
                sw.WriteLine(workload.Dequeue());
            }
        }
        else
        {
            Monitor.Wait(Ccontroller.Instance.lockGetWork);
        }
    }
}
}
</code>```

Code in Java code and desired situation:
Method in producer class:

```<code>public void StartWork(){
    for(int i=0; i<200; i++){

        controller.AddWork("work order: "+i);
    }
}
</code>```

The controller:

```<code>public class WorkController {

private Queue<String> workload = new ArrayDeque<String>();
private AtomicInteger LockAdd = new AtomicInteger();
private AtomicInteger LockRemove = new AtomicInteger();

public void AddWork(String work){
        workload.add(work);
        synchronized(LockAdd){
            LockAdd.notify();
        }
}

public String RemoveWork(){
    String work;
    synchronized(LockRemove){
        work= workload.remove();
    }
    return work;
}
}
</code>```

The worker:

```<code>public class Worker {

public WorkController controller;

Thread work = new Thread(){
    public void run(){
        while(true){
            try{
                System.out.println(controller.RemoveWork());
            }catch(NoSuchElementException ex){
                 System.out.println("no work");
                try {
                    wait();
                } catch (InterruptedException ex1) {
                    Logger.getLogger(Worker.class.getName()).log(Level.SEVERE, null, ex1);
                }
            }
        }
    }
};

void StartWorker(){
    work.start();
}

}
</code>```

答: What solved the problem: It seems that in Unity and/or c# you to do Monitor.wait within a Lock statement of the same object.</p>

Title: Unity multithreading producer consumer

Body:
I created a situation where a producer class adds strings to a queue in a controller class. The controller class notifies the worker class that there is work and executes the work, in this case appending strings to a file. I'm not able to get this work. The file is created but nothing is appending. I created this situation in java where I succeeded. I will put this code at the end. Just to clearify I need solve this in C#.

With using the debugger I came to the conclusion that the thread doesn't wake up after going into wait. I could be wrong however.

As a note: I do not want to use coroutines

Producer method:

void Start () {
    for (int i = 0; i < 100; i++)
    {
        Ccontroller.Instance.AddWork("no: " + i);
    }
}

Controller class
For locking I tried Monitor.enter/exit and current solution. I changed the implementation abit for easyness. This implementation uses the worker static queue. The static queue was needed for the thread.

public class Ccontroller : Singleton<Ccontroller>
{
public Queue<string> workLoad = new Queue<string>();
public Worker worker;

public Object lockGetWork = new Object();

public void AddWork(string toProcess)
{
    Worker.workload.Enqueue(toProcess);

    lock (lockGetWork)
    {
        Monitor.PulseAll(lockGetWork);
    }
}

public string GetWork()
{
    string process;

    process = workLoad.Dequeue();

    return process;
}
}

Worker class:
public class Worker : MonoBehaviour {

static string path = @"d:\test.txt";
Thread t;

public static Queue<string> workload = new Queue<string>();

private void Awake()
{
    t = new Thread(Work);
}

// Use this for initialization
void Start()
{
    //create file
    if (!File.Exists(path))
    {
        using (StreamWriter sw = File.CreateText(path)) { }
    }
    t.Start();
}

static void Work()
{

while (true)
{
    if (workload.Peek() != null)
        {
            using (StreamWriter sw = File.AppendText(path))
            {
                sw.WriteLine(workload.Dequeue());
            }
        }
        else
        {
            Monitor.Wait(Ccontroller.Instance.lockGetWork);
        }
    }
}
}

Code in Java code and desired situation:
Method in producer class:

public void StartWork(){
    for(int i=0; i<200; i++){

        controller.AddWork("work order: "+i);
    }
}

The controller:

public class WorkController {

private Queue<String> workload = new ArrayDeque<String>();
private AtomicInteger LockAdd = new AtomicInteger();
private AtomicInteger LockRemove = new AtomicInteger();

public void AddWork(String work){
        workload.add(work);
        synchronized(LockAdd){
            LockAdd.notify();
        }
}

public String RemoveWork(){
    String work;
    synchronized(LockRemove){
        work= workload.remove();
    }
    return work;
}
}

The worker:

public class Worker {

public WorkController controller;

Thread work = new Thread(){
    public void run(){
        while(true){
            try{
                System.out.println(controller.RemoveWork());
            }catch(NoSuchElementException ex){
                 System.out.println("no work");
                try {
                    wait();
                } catch (InterruptedException ex1) {
                    Logger.getLogger(Worker.class.getName()).log(Level.SEVERE, null, ex1);
                }
            }
        }
    }
};

void StartWorker(){
    work.start();
}

}


问:
numpy.where with like operator
I would like to use np.where, but need to match a string using a wildcard. Is this possible, or is there another function that is best to be used in this scenario?

```<code>df['PRODUCT'] = np.where(df['TYPE'] == '2b', 'Pencil',
                np.where(df['TYPE'] like 'I5%', 'Ruler', 0))
</code>```

I tried using the in operator, however this did not work.

```<code>df['PRODUCT'] = np.where(df['TYPE'] == '2b', 'Pencil',
                np.where('I5' in df['TYPE'], 'Ruler', 0))
</code>```

答:
You need contains:

```<code>df['PRODUCT'] = np.where(df['TYPE'] == '2b', 'Pencil',
                np.where(df['TYPE'].str.contains('I5'), 'Ruler', 0))
</code>```

Sample:

```<code>df = pd.DataFrame({'TYPE':['2b','2c','I5','I5 a', 'a I5']})
print (df)
   TYPE
0    2b
1    2c
2    I5
3  I5 a
4  a I5

df['PRODUCT'] = np.where(df['TYPE'] == '2b', 'Pencil',
                np.where(df['TYPE'].str.contains('I5'), 'Ruler', 0))

print (df)
   TYPE PRODUCT
0    2b  Pencil
1    2c       0
2    I5   Ruler
3  I5 a   Ruler
4  a I5   Ruler
</code>```

If need check only starts of string add ^:

```<code>df['PRODUCT'] = np.where(df['TYPE'] == '2b', 'Pencil',
                np.where(df['TYPE'].str.contains('^I5'), 'Ruler', 0))

print (df)
   TYPE PRODUCT
0    2b  Pencil
1    2c       0
2    I5   Ruler
3  I5 a   Ruler
4  a I5       0
</code>```

Title: numpy.where with like operator

Body:
I would like to use np.where, but need to match a string using a wildcard. Is this possible, or is there another function that is best to be used in this scenario?

df['PRODUCT'] = np.where(df['TYPE'] == '2b', 'Pencil',
                np.where(df['TYPE'] like 'I5%', 'Ruler', 0))

I tried using the in operator, however this did not work.

df['PRODUCT'] = np.where(df['TYPE'] == '2b', 'Pencil',
                np.where('I5' in df['TYPE'], 'Ruler', 0))

Body:
You need contains:

df['PRODUCT'] = np.where(df['TYPE'] == '2b', 'Pencil',
                np.where(df['TYPE'].str.contains('I5'), 'Ruler', 0))

Sample:

df = pd.DataFrame({'TYPE':['2b','2c','I5','I5 a', 'a I5']})
print (df)
   TYPE
0    2b
1    2c
2    I5
3  I5 a
4  a I5

df['PRODUCT'] = np.where(df['TYPE'] == '2b', 'Pencil',
                np.where(df['TYPE'].str.contains('I5'), 'Ruler', 0))

print (df)
   TYPE PRODUCT
0    2b  Pencil
1    2c       0
2    I5   Ruler
3  I5 a   Ruler
4  a I5   Ruler

If need check only starts of string add ^:

df['PRODUCT'] = np.where(df['TYPE'] == '2b', 'Pencil',
                np.where(df['TYPE'].str.contains('^I5'), 'Ruler', 0))

print (df)
   TYPE PRODUCT
0    2b  Pencil
1    2c       0
2    I5   Ruler
3  I5 a   Ruler
4  a I5       0


问:
JUnit vs TestNG
At work we are currently still using JUnit 3 to run our tests. We have been considering switching over to JUnit 4 for new tests being written but I have been keeping an eye on TestNG for a while now. What experiences have you all had with either JUnit 4 or TestNG, and which seems to work better for very large numbers of tests? Having flexibility in writing tests is also important to us since our functional tests cover a wide aspect and need to be written in a variety of ways to get results.

Old tests will not be re-written as they do their job just fine. What I would like to see in new tests though is flexibility in the way the test can be written, natural assertions, grouping, and easily distributed test executions.

答:
Also one more advantage of TestNG is supporting of parallel testing. In our era of multicores it's important, i think.

I also used both frameworks. But i using hamcrest for assertations. Hamcrest allows you easily write your own assert method. So instead of

```<code>assertEquals(operation.getStatus(), Operation.Status.Active);
</code>```

You can write

```<code>assertThat(operation, isActive());
</code>```

That gives you opportunity to use higher level of abstraction in your tests. And this makes your tests more robust.

Title: JUnit vs TestNG

LastEditorDisplayName: Sam Merrell

Body:
Also one more advantage of TestNG is supporting of parallel testing. In our era of multicores it's important, i think.

I also used both frameworks. But i using hamcrest for assertations. Hamcrest allows you easily write your own assert method. So instead of

assertEquals(operation.getStatus(), Operation.Status.Active);

You can write

assertThat(operation, isActive());

That gives you opportunity to use higher level of abstraction in your tests. And this makes your tests more robust.

OwnerDisplayName: dotsid


问:
How to determine DICOM / DICOMDIR images relationship?
The DICOM images have "Slice location" parameter recorded in addition to the "Slice Thickness".

Question: "Slice location" in where? I understand it's in the body depth - but it must be in images as well, right?

I think a series must or may have a corresponding series in which we can find a reference of the "Slice Location".

If I am right, How to find that those images?  And then how to establish the point of the slice in the corresponding images?

As well, if you know a well written refference guide to dicom image structure, please share.

Thanks a lot.

答:
The standard specifies that the unit for Slice Location is millimeters. Usually there is a special scout image that is refferenced by slices with an overlay that looks like a grid, that shows where each slice is mapped.

And a suggestion: don't expect it to work "in theory", without trying on real samples. DICOM is rather a collection of all standards that existed at the time it was created. Also, many modalities use their own private tags for additional info. If you need to process the output of a certain modality then you are lucky, you just have to find its DICOM Conformance Statement. If it's for a viewer.. then good luck :)

EDIT: Also, CT series usually have one image with LOCALIZER in the Image Type tag that refferences the rest of images in the series that are slices (or is reffered by them).


问:
Allow Only Numbers and a Dot in the following Format with Regex javascript/jquery
I have an input field which should get filled by the user with only numbers and a singel dot/comma and only in the following format.
This should occure .on("input") meaning as the user types it should secure the right input format.

A wrong char should be replaced with a blank.

Format Example:
 1.000
1.281
 21212.000
 21212.810
Nothing like this:
1.02.12
or
1919,201,00
 Only a dot between the two Number blocks.

This is what i have so far:

    Regex 1:

```<code>$("body").on("input", "#testId", function(){
     this.value = this.value.replace(/[^0-9]/g,'');
});
</code>```

Regex 2:

```<code>$("body").on("input", "#testId", function(){
     this.value = this.value.replace(/[0-9]+\.+[0-9]{1,3}/g,'');
});
</code>```

Regex 3:

```<code>$("body").on("input", "#testId", function(){
     this.value = this.value.replace(/[0-9]+\.+[0-9]{1,3}/g,'');
});
</code>```

I think i am doing something wrong with the replace() method.
Unfortunately none of them work as i want to. Any help is appreciated.

Here is the FIDDLE

Should Work in IE11

答:
try this one,

```<code>^[0-9]*(\.|,)?[0-9]*$
</code>```

this take below cases:

1111,
.0000
123,12
12.12
12345

but if you want only

111,11
11.11
12345

so please use this

```<code>^[0-9]+(\.|,)?[0-9]+$
</code>```

to force use dot/comma please use this

```<code>^[0-9]+(\.|,)[0-9]+$
</code>```

add this code

```<code>$("#testId").keyup(function(){

   var vals = $("#testId").val();

   if(/^[0-9]*(\.|,)?[0-9]*$/g.test(vals))
    $("#testId").val(vals);
     else
    vals = vals.replace(/.$/,"");

    $("#testId").val(vals);
  });
</code>```

and change input type to

type="text"

Body:
I have an input field which should get filled by the user with only numbers and a singel dot/comma and only in the following format.
This should occure .on("input") meaning as the user types it should secure the right input format.

A wrong char should be replaced with a blank.

Format Example:
 1.000
1.281
 21212.000
 21212.810
Nothing like this:
1.02.12
or
1919,201,00
 Only a dot between the two Number blocks.

This is what i have so far:

    Regex 1:

$("body").on("input", "#testId", function(){
     this.value = this.value.replace(/[^0-9]/g,'');
});

Regex 2:

$("body").on("input", "#testId", function(){
     this.value = this.value.replace(/[0-9]+\.+[0-9]{1,3}/g,'');
});

Regex 3:

$("body").on("input", "#testId", function(){
     this.value = this.value.replace(/[0-9]+\.+[0-9]{1,3}/g,'');
});

I think i am doing something wrong with the replace() method.
Unfortunately none of them work as i want to. Any help is appreciated.

Here is the FIDDLE

Should Work in IE11

Body:
try this one,

^[0-9]*(\.|,)?[0-9]*$

this take below cases:

1111,
.0000
123,12
12.12
12345

but if you want only

111,11
11.11
12345

so please use this

^[0-9]+(\.|,)?[0-9]+$

to force use dot/comma please use this

^[0-9]+(\.|,)[0-9]+$

add this code

$("#testId").keyup(function(){

   var vals = $("#testId").val();

   if(/^[0-9]*(\.|,)?[0-9]*$/g.test(vals))
    $("#testId").val(vals);
     else
    vals = vals.replace(/.$/,"");

    $("#testId").val(vals);
  });

and change input type to

type="text"