问:
How to get jQuery to wait until an animation is finished?
I need to wait (prevent) until this animation (flip card) is finished, if you hover again while animation is running it triggers again and restart the animation.

1) I want leave finish the currently animation even you hover again or you hover out.

This is what I have tried so far:

```<code>if(!$(this).find(".card").is(':animated')){
    $(this).find(".card").toggleClass('flipped')
}
</code>```

And this:

```<code>$(":animated").promise().done(function() {
    $(this).find(".card").toggleClass('flipped')
});
</code>```

2) If you re-hover flipped card (blue part) and you leave the cursor inside dont flip it again to the red part while cursor is inside. I tried this canceling setTimeout with clearTimeout but still doesnt work:

```<code>$(document).ready(function () {
    var funct = 0
    $(".container").hover(function () {
        clearTimeout(funct);
        $(this).find(".card").addClass('flipped')
    }, function () {
        var val = $(this).find(".card")
        var funct = setTimeout(function () {
            val.removeClass('flipped')
        }, 2000)
    })
 })
</code>```

Note: I use setTimeOut function because I need reverse flip card 2 seconds after you hover out and I want keep it.

Here is the working snippet code:

$(document).ready(function () {
    $(".container").hover(function(){
        $(this).find(".card").toggleClass('flipped')

    }, function(){
        var val = $(this).find(".card")
        setTimeout(function(){
            val.toggleClass('flipped')
        }, 2000)
    })
})```
<pre class="snippet-code-css lang-css prettyprint-override"><code>.container {
  width: 200px;
  height: 260px;
  position: relative;
  margin: 0 auto 40px;
  -webkit-perspective: 800px;
  -moz-perspective: 800px;
  -o-perspective: 800px;
  perspective: 800px;
  display: inline-block;
}

#main {
  border: 1px solid black;
}

button {
  width: 30%;
  height: 10%;
  margin-top: 100px;
  cursor: default;
}

.card {
  width: 100%;
  height: 100%;
  position: absolute;
  -webkit-transition: -webkit-transform 1s;
  -moz-transition: -moz-transform 1s;
  -o-transition: -o-transform 1s;
  transition: transform 1s;
  -webkit-transform-style: preserve-3d;
  -moz-transform-style: preserve-3d;
  -o-transform-style: preserve-3d;
  transform-style: preserve-3d;
  -webkit-transform-origin: right center;
  -moz-transform-origin: right center;
  -o-transform-origin: right center;
  transform-origin: right center;
}

.card.flipped {
  -webkit-transform: translateX( -100%) rotateY( -180deg);
  -moz-transform: translateX( -100%) rotateY( -180deg);
  -o-transform: translateX( -100%) rotateY( -180deg);
  transform: translateX( -100%) rotateY( -180deg);
}

.card div {
  height: 100%;
  width: 100%;
  color: white;
  text-align: center;
  font-weight: bold;
  position: absolute;
  -webkit-backface-visibility: hidden;
  -moz-backface-visibility: hidden;
  -o-backface-visibility: hidden;
  backface-visibility: hidden;
  cursor: pointer;
}

.card .front {
  background: red;
  display: flex;
  justify-content: center;
  align-items: center;
}
/*
.card .front p {
  margin-top: 100px;
}
*/
.card .back p {
  margin: auto;
}

.card .back {
  background: blue;
  -webkit-transform: rotateY( 180deg);
  -moz-transform: rotateY( 180deg);
  -o-transform: rotateY( 180deg);
  transform: rotateY( 180deg);
  display: flex;
  justify-content: center;
  align-items: center;
}</code>```

Test

MyBack

```

答:
Run a conditional check first to determine if the trigger class flipped has already been added to the element in question.

This will imply that the animation is still running or currently active (if the class flipped is already present).

```<code>if (!$(this).find(".card").hasClass('flipped')) {
      $(this).find(".card").toggleClass('flipped')
    }
</code>```

$(document).ready(function() {
  $(".container").hover(function() {
    if (!$(this).find(".card").hasClass('flipped')) {
      $(this).find(".card").toggleClass('flipped')
    }

  }, function() {
    var val = $(this).find(".card")
    setTimeout(function() {
      val.removeClass('flipped')
    }, 1000);
  });
});```
<pre class="snippet-code-css lang-css prettyprint-override"><code>.container {
  width: 200px;
  height: 260px;
  position: relative;
  margin: 0 auto 40px;
  -webkit-perspective: 800px;
  -moz-perspective: 800px;
  -o-perspective: 800px;
  perspective: 800px;
  display: inline-block;
}

#main {
  border: 1px solid black;
}

button {
  width: 30%;
  height: 10%;
  margin-top: 100px;
  cursor: default;
}

.card {
  width: 100%;
  height: 100%;
  position: absolute;
  -webkit-transition: -webkit-transform 1s;
  -moz-transition: -moz-transform 1s;
  -o-transition: -o-transform 1s;
  transition: transform 1s;
  -webkit-transform-style: preserve-3d;
  -moz-transform-style: preserve-3d;
  -o-transform-style: preserve-3d;
  transform-style: preserve-3d;
  -webkit-transform-origin: right center;
  -moz-transform-origin: right center;
  -o-transform-origin: right center;
  transform-origin: right center;
}

.card.flipped {
  -webkit-transform: translateX( -100%) rotateY( -180deg);
  -moz-transform: translateX( -100%) rotateY( -180deg);
  -o-transform: translateX( -100%) rotateY( -180deg);
  transform: translateX( -100%) rotateY( -180deg);
}

.card div {
  height: 100%;
  width: 100%;
  color: white;
  text-align: center;
  font-weight: bold;
  position: absolute;
  -webkit-backface-visibility: hidden;
  -moz-backface-visibility: hidden;
  -o-backface-visibility: hidden;
  backface-visibility: hidden;
  cursor: pointer;
}

.card .front {
  background: red;
  display: flex;
  justify-content: center;
  align-items: center;
}

/*
.card .front p {
  margin-top: 100px;
}
*/

.card .back p {
  margin: auto;
}

.card .back {
  background: blue;
  -webkit-transform: rotateY( 180deg);
  -moz-transform: rotateY( 180deg);
  -o-transform: rotateY( 180deg);
  transform: rotateY( 180deg);
  display: flex;
  justify-content: center;
  align-items: center;
}</code>```

Test

MyBack

```
</div>
</div>
</p>
<p>Then replace the <code>.toggleClass()</code> method with the <code>.removeClass()</code> method in your <code>setTimeout()</code> function for better "fool-proofing" and more reliable application during intended events - so that this class is never unintentionally added when it should simply be removed.</p>
<h3>Edit</h3>
<p>To address the issue you've pointed out in the comments, see what the embedded code snippet below demonstrates.<br>
Essentially, a <em>class is added as a flag to check against</em> during specific events at specific times.</p>
<p><div class="snippet" data-lang="js" data-hide="true" data-console="true" data-babel="false">
<div class="snippet-code snippet-currently-hidden">
<pre class="snippet-code-js lang-js prettyprint-override"><code>$(document).ready(function() {

  $('.container').hover(function() {
    if (!$(this).find('.card').hasClass('flipped')) {
      $(this).find('.card').toggleClass('flipped')
    }
    $(this).find('.card').addClass('hovered'); /* add class - this will be our flag we'll check against */

  }, function() {
    var val = $(this).find('.card');
    $(this).find('.card').removeClass('hovered'); /* remove class - if we refrain from hovering over again, the condition block below will return true and run the code within */
    setTimeout(function() {
      if(!val.hasClass('hovered')) {
        val.removeClass('flipped')
      }
    }, 1000);
  });

});</code>```

.container {
  width: 200px;
  height: 260px;
  position: relative;
  margin: 0 auto 40px;
  -webkit-perspective: 800px;
  -moz-perspective: 800px;
  -o-perspective: 800px;
  perspective: 800px;
  display: inline-block;
}

#main {
  border: 1px solid black;
}

button {
  width: 30%;
  height: 10%;
  margin-top: 100px;
  cursor: default;
}

.card {
  width: 100%;
  height: 100%;
  position: absolute;
  -webkit-transition: -webkit-transform 1s;
  -moz-transition: -moz-transform 1s;
  -o-transition: -o-transform 1s;
  transition: transform 1s;
  -webkit-transform-style: preserve-3d;
  -moz-transform-style: preserve-3d;
  -o-transform-style: preserve-3d;
  transform-style: preserve-3d;
  -webkit-transform-origin: right center;
  -moz-transform-origin: right center;
  -o-transform-origin: right center;
  transform-origin: right center;
}

.card.flipped {
  -webkit-transform: translateX( -100%) rotateY( -180deg);
  -moz-transform: translateX( -100%) rotateY( -180deg);
  -o-transform: translateX( -100%) rotateY( -180deg);
  transform: translateX( -100%) rotateY( -180deg);
}

.card div {
  height: 100%;
  width: 100%;
  color: white;
  text-align: center;
  font-weight: bold;
  position: absolute;
  -webkit-backface-visibility: hidden;
  -moz-backface-visibility: hidden;
  -o-backface-visibility: hidden;
  backface-visibility: hidden;
  cursor: pointer;
}

.card .front {
  background: red;
  display: flex;
  justify-content: center;
  align-items: center;
}

/*
.card .front p {
  margin-top: 100px;
}
*/

.card .back p {
  margin: auto;
}

.card .back {
  background: blue;
  -webkit-transform: rotateY( 180deg);
  -moz-transform: rotateY( 180deg);
  -o-transform: rotateY( 180deg);
  transform: rotateY( 180deg);
  display: flex;
  justify-content: center;
  align-items: center;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container-fluid">
  <div id="main"><br>
    <section class="container">
      <div class="card">
        <div class="front">
          <p>Test</p>
        </div>
        <div class="back">
          <p>MyBack</p>
        </div>
      </div>
    </section>
  </div>
</div></code>```

Body:
I need to wait (prevent) until this animation (flip card) is finished, if you hover again while animation is running it triggers again and restart the animation.

1) I want leave finish the currently animation even you hover again or you hover out.

This is what I have tried so far:

if(!$(this).find(".card").is(':animated')){
    $(this).find(".card").toggleClass('flipped')
}

And this:

$(":animated").promise().done(function() {
    $(this).find(".card").toggleClass('flipped')
});

2) If you re-hover flipped card (blue part) and you leave the cursor inside dont flip it again to the red part while cursor is inside. I tried this canceling setTimeout with clearTimeout but still doesnt work:

$(document).ready(function () {
    var funct = 0
    $(".container").hover(function () {
        clearTimeout(funct);
        $(this).find(".card").addClass('flipped')
    }, function () {
        var val = $(this).find(".card")
        var funct = setTimeout(function () {
            val.removeClass('flipped')
        }, 2000)
    })
 })

Note: I use setTimeOut function because I need reverse flip card 2 seconds after you hover out and I want keep it.

Here is the working snippet code:

$(document).ready(function () {
    $(".container").hover(function(){
        $(this).find(".card").toggleClass('flipped')

    }, function(){
        var val = $(this).find(".card")
        setTimeout(function(){
            val.toggleClass('flipped')
        }, 2000)
    })
})

.container {
  width: 200px;
  height: 260px;
  position: relative;
  margin: 0 auto 40px;
  -webkit-perspective: 800px;
  -moz-perspective: 800px;
  -o-perspective: 800px;
  perspective: 800px;
  display: inline-block;
}

#main {
  border: 1px solid black;
}

button {
  width: 30%;
  height: 10%;
  margin-top: 100px;
  cursor: default;
}

.card {
  width: 100%;
  height: 100%;
  position: absolute;
  -webkit-transition: -webkit-transform 1s;
  -moz-transition: -moz-transform 1s;
  -o-transition: -o-transform 1s;
  transition: transform 1s;
  -webkit-transform-style: preserve-3d;
  -moz-transform-style: preserve-3d;
  -o-transform-style: preserve-3d;
  transform-style: preserve-3d;
  -webkit-transform-origin: right center;
  -moz-transform-origin: right center;
  -o-transform-origin: right center;
  transform-origin: right center;
}

.card.flipped {
  -webkit-transform: translateX( -100%) rotateY( -180deg);
  -moz-transform: translateX( -100%) rotateY( -180deg);
  -o-transform: translateX( -100%) rotateY( -180deg);
  transform: translateX( -100%) rotateY( -180deg);
}

.card div {
  height: 100%;
  width: 100%;
  color: white;
  text-align: center;
  font-weight: bold;
  position: absolute;
  -webkit-backface-visibility: hidden;
  -moz-backface-visibility: hidden;
  -o-backface-visibility: hidden;
  backface-visibility: hidden;
  cursor: pointer;
}

.card .front {
  background: red;
  display: flex;
  justify-content: center;
  align-items: center;
}
/*
.card .front p {
  margin-top: 100px;
}
*/
.card .back p {
  margin: auto;
}

.card .back {
  background: blue;
  -webkit-transform: rotateY( 180deg);
  -moz-transform: rotateY( 180deg);
  -o-transform: rotateY( 180deg);
  transform: rotateY( 180deg);
  display: flex;
  justify-content: center;
  align-items: center;
}

Test

MyBack

Body:
Run a conditional check first to determine if the trigger class flipped has already been added to the element in question.

This will imply that the animation is still running or currently active (if the class flipped is already present).

if (!$(this).find(".card").hasClass('flipped')) {
      $(this).find(".card").toggleClass('flipped')
    }

$(document).ready(function() {
  $(".container").hover(function() {
    if (!$(this).find(".card").hasClass('flipped')) {
      $(this).find(".card").toggleClass('flipped')
    }

  }, function() {
    var val = $(this).find(".card")
    setTimeout(function() {
      val.removeClass('flipped')
    }, 1000);
  });
});

.container {
  width: 200px;
  height: 260px;
  position: relative;
  margin: 0 auto 40px;
  -webkit-perspective: 800px;
  -moz-perspective: 800px;
  -o-perspective: 800px;
  perspective: 800px;
  display: inline-block;
}

#main {
  border: 1px solid black;
}

button {
  width: 30%;
  height: 10%;
  margin-top: 100px;
  cursor: default;
}

.card {
  width: 100%;
  height: 100%;
  position: absolute;
  -webkit-transition: -webkit-transform 1s;
  -moz-transition: -moz-transform 1s;
  -o-transition: -o-transform 1s;
  transition: transform 1s;
  -webkit-transform-style: preserve-3d;
  -moz-transform-style: preserve-3d;
  -o-transform-style: preserve-3d;
  transform-style: preserve-3d;
  -webkit-transform-origin: right center;
  -moz-transform-origin: right center;
  -o-transform-origin: right center;
  transform-origin: right center;
}

.card.flipped {
  -webkit-transform: translateX( -100%) rotateY( -180deg);
  -moz-transform: translateX( -100%) rotateY( -180deg);
  -o-transform: translateX( -100%) rotateY( -180deg);
  transform: translateX( -100%) rotateY( -180deg);
}

.card div {
  height: 100%;
  width: 100%;
  color: white;
  text-align: center;
  font-weight: bold;
  position: absolute;
  -webkit-backface-visibility: hidden;
  -moz-backface-visibility: hidden;
  -o-backface-visibility: hidden;
  backface-visibility: hidden;
  cursor: pointer;
}

.card .front {
  background: red;
  display: flex;
  justify-content: center;
  align-items: center;
}

/*
.card .front p {
  margin-top: 100px;
}
*/

.card .back p {
  margin: auto;
}

.card .back {
  background: blue;
  -webkit-transform: rotateY( 180deg);
  -moz-transform: rotateY( 180deg);
  -o-transform: rotateY( 180deg);
  transform: rotateY( 180deg);
  display: flex;
  justify-content: center;
  align-items: center;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container-fluid">
  <div id="main"><br>
    <section class="container">
      <div class="card">
        <div class="front">
          <p>Test</p>
        </div>
        <div class="back">
          <p>MyBack</p>
        </div>
      </div>
    </section>
  </div>
</div>

Then replace the .toggleClass() method with the .removeClass() method in your setTimeout() function for better "fool-proofing" and more reliable application during intended events - so that this class is never unintentionally added when it should simply be removed.

Edit

To address the issue you've pointed out in the comments, see what the embedded code snippet below demonstrates.

Essentially, a class is added as a flag to check against during specific events at specific times.

$(document).ready(function() {

  $('.container').hover(function() {
    if (!$(this).find('.card').hasClass('flipped')) {
      $(this).find('.card').toggleClass('flipped')
    }
    $(this).find('.card').addClass('hovered'); /* add class - this will be our flag we'll check against */

  }, function() {
    var val = $(this).find('.card');
    $(this).find('.card').removeClass('hovered'); /* remove class - if we refrain from hovering over again, the condition block below will return true and run the code within */
    setTimeout(function() {
      if(!val.hasClass('hovered')) {
        val.removeClass('flipped')
      }
    }, 1000);
  });

});

.container {
  width: 200px;
  height: 260px;
  position: relative;
  margin: 0 auto 40px;
  -webkit-perspective: 800px;
  -moz-perspective: 800px;
  -o-perspective: 800px;
  perspective: 800px;
  display: inline-block;
}

#main {
  border: 1px solid black;
}

button {
  width: 30%;
  height: 10%;
  margin-top: 100px;
  cursor: default;
}

.card {
  width: 100%;
  height: 100%;
  position: absolute;
  -webkit-transition: -webkit-transform 1s;
  -moz-transition: -moz-transform 1s;
  -o-transition: -o-transform 1s;
  transition: transform 1s;
  -webkit-transform-style: preserve-3d;
  -moz-transform-style: preserve-3d;
  -o-transform-style: preserve-3d;
  transform-style: preserve-3d;
  -webkit-transform-origin: right center;
  -moz-transform-origin: right center;
  -o-transform-origin: right center;
  transform-origin: right center;
}

.card.flipped {
  -webkit-transform: translateX( -100%) rotateY( -180deg);
  -moz-transform: translateX( -100%) rotateY( -180deg);
  -o-transform: translateX( -100%) rotateY( -180deg);
  transform: translateX( -100%) rotateY( -180deg);
}

.card div {
  height: 100%;
  width: 100%;
  color: white;
  text-align: center;
  font-weight: bold;
  position: absolute;
  -webkit-backface-visibility: hidden;
  -moz-backface-visibility: hidden;
  -o-backface-visibility: hidden;
  backface-visibility: hidden;
  cursor: pointer;
}

.card .front {
  background: red;
  display: flex;
  justify-content: center;
  align-items: center;
}

/*
.card .front p {
  margin-top: 100px;
}
*/

.card .back p {
  margin: auto;
}

.card .back {
  background: blue;
  -webkit-transform: rotateY( 180deg);
  -moz-transform: rotateY( 180deg);
  -o-transform: rotateY( 180deg);
  transform: rotateY( 180deg);
  display: flex;
  justify-content: center;
  align-items: center;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container-fluid">
  <div id="main"><br>
    <section class="container">
      <div class="card">
        <div class="front">
          <p>Test</p>
        </div>
        <div class="back">
          <p>MyBack</p>
        </div>
      </div>
    </section>
  </div>
</div>


来源: stackexchange

问:
Does Realm executeTransactionAsync close the instance
The title says it all.  I've done some searching but haven't found anything concrete.

Do I need to call realm.close after doing realm.executeTransactionAsync or does the async transaction handle that?

Thank you

EDIT:  Per EpidPandaForce, executeTransactionAsync closes the background realm instance when complete.

But what is the proper way to close the realm instance if executeTransactionAsync is called from the UI thread?  In the transactions onSuccess/onFailure?

答:
You seem like you're looking for the following scenario.</p>

```<code>public void doWrite(MyObject obj) {
    Realm realm = Realm.getDefaultInstance();
    realm.executeTransactionAsync(new Realm.Transaction() {
        @Override
        public void execute(Realm bgRealm) {
            bgRealm.insert(obj); // assuming obj is unmanaged
        }
    }, new Realm.Transaction.OnSuccess() {
        @Override
        public void onSuccess() {
            realm.close();
        }
    }, new Realm.Transaction.OnError() {
        @Override
        public void onError(Throwable error) {
            realm.close();
        }
    });
}
</code>```

ContentLicense: CC BY-SA 3.0

Body:
You seem like you're looking for the following scenario.

public void doWrite(MyObject obj) {
    Realm realm = Realm.getDefaultInstance();
    realm.executeTransactionAsync(new Realm.Transaction() {
        @Override
        public void execute(Realm bgRealm) {
            bgRealm.insert(obj); // assuming obj is unmanaged
        }
    }, new Realm.Transaction.OnSuccess() {
        @Override
        public void onSuccess() {
            realm.close();
        }
    }, new Realm.Transaction.OnError() {
        @Override
        public void onError(Throwable error) {
            realm.close();
        }
    });
}


问:
Calling Java webdynpro from JSP or Java Servlet
Is it possible to call SAP Java web dynpro application from JSP or Java Servlet  in another system ? If possible please advise how.

-Vipin.

答: This has been achieved by using iframe tag and application url of web dynpro application as src.</p>


问:
Gap between table header and first cell
I have a grouped table view with multiple sections, there is a gap between the header and the first cell which I don't understand. It's not the section header/footer and when I use the debug view hierarchy it looks like the y origin of the cell frame is causing the problem:

(UITableViewWrapperView highlighted)

The red and blue views are headers and footers, I coloured them so I could rule them out as being the problem.

If I get a printout of the first cell the frame has properties: frame = (0 35; 320 86)

So it looks like the y coordinate of 35 is causing the gap between the cell and the header. If I manually set the y coordinate of the cell to 0 in cellForRowAt it doesn't seem to do anything. I already have automaticallyAdjustScrollViewInsets to false.

A point in the right direction would be much appreciated.

答:
Same issue happens to me now.

I just worked around to solve this. Please check this. It may work for you.

tableView.tableHeaderView = myView

I used auto layout and constraints in the header view. After I set it to my tableHeaderView, I got header view frame as (0 35 0 0).

I got the height of my header view using systemLayoutSizeFitting.height and I know the width as 414 and resetted the header view frame to (0 0 414 200) and then I set the header view to my tableHeaderView again.

let height = myView.systemLayoutSizeFitting(UILayoutFittingCompressedSize).height //height = 200

myView.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: height)

tableView.tableHeaderView = myView

Now it is working for me.

Title: Gap between table header and first cell


问:
Anyway to run docker rules with custom venv python environment or add cacert via variable?
I'm using the docker rules to push images in the bazel build. The docker repository uses a custom cacert. To be able to upload images to it, I had to create a custom cacerts.txt file with one additional cacerts that is installed via module ca_certs_locater with function get() in a venv python2 environment. This is to override the default cacerts.txt that is provided with httplib2 which the docker rules use.

My question is there anyway to have the docker rules run under a custom .venv environment? Or would it be better to provide an additional variable for custom cacert.

Currently, I activate the venv before I run any bazel rules. This seems messy. What would be the recommended way to get the cacert to be picked up by the docker rules?

答:
Suggestion from the rules_docker team:

rules_docker supports overriding its imports, so if you define a customized version of the httplib2 repo (with your certs), we should pick it up:
https://github.com/bazelbuild/rules_docker/blob/master/container/container.bzl#L62-L77


问:
How to show image from other domain by htaccess in wordpress
I am new to WordPress and I have uploaded my files into two domains, a main domain and a sub domain. In my sub domain I want to show my main domain images by htaccess. I have used below codes but couldnot get any success.

```<code><IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /

RewriteRule ^(files/profile_image/.*)$ http://example.com/$1 [R=301,NC,L]

RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^(.*)$ http://dev.example.com/$1 [R=301,L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?%{QUERY_STRING} [NE,L]

RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
</code>```

I have used above code but couldn't get any success. Can I get any help?

答:
I do this all the time with my localhost sites to grab the images from the online production site. In your sub domain .htaccess file use the following.</p>

```<code><IfModule mod_rewrite.c>
# Attempt to load files from production if
# they're not in our dev version
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule wp-content/uploads/(.*) \
http://example.com/wp-content/uploads/$1 [NC,L]
</IfModule>
</code>```

Body:
I am new to WordPress and I have uploaded my files into two domains, a main domain and a sub domain. In my sub domain I want to show my main domain images by htaccess. I have used below codes but couldnot get any success.

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /

RewriteRule ^(files/profile_image/.*)$ http://example.com/$1 [R=301,NC,L]

RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^(.*)$ http://dev.example.com/$1 [R=301,L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?%{QUERY_STRING} [NE,L]

RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]

I have used above code but couldn't get any success. Can I get any help?

Body:
I do this all the time with my localhost sites to grab the images from the online production site. In your sub domain .htaccess file use the following.

<IfModule mod_rewrite.c>
# Attempt to load files from production if
# they're not in our dev version
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule wp-content/uploads/(.*) \
http://example.com/wp-content/uploads/$1 [NC,L]
</IfModule>


问:
Differentiating background-color based on browser support of CSS properties
I have created a polka dotted background in pure CSS via:

.polka-gr{

    background-image:radial-gradient(#FAFFB3 20%, transparent 0), radial-gradient(#F1C3CB 20%, transparent 0);
    background-size: 30px 30px;
    background-position: 0 0, 15px 15px;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div class="polka-gr" style="background-color:#77FFD1;width:600px;height:200px;></div></code>```

As you can see, the background color is a greenish shade (of hex value #77FFD1).

Some of the clients this code is being served to do not support radial-gradient (e.g. those using Opera Mini browser). All such clients currently fall back to a plain #77FFD1 background without polka dots. Fair enough.

But is there any pure CSS way to get these non-supporting browsers to fall back to a different color entirely, e.g. #FFFF99?

Supporting browsers should still see the greenish background-color (#77FFD1) with polka dots.

Is such an arrangement possible? If so, an illustrative example would be great.

答:
.polka-gr{
  background: yellow;
}

@supports (background: radial-gradient(#F1C3CB 20%, transparent 0)) {
.polka-gr{

    background-image:radial-gradient(#FAFFB3 20%, transparent 0), radial-gradient(#F1C3CB 20%, transparent 0);
      background-color:#77FFD1;
      background-size: 30px 30px;
      background-position: 0 0, 15px 15px;
  }
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div class="polka-gr" style="width:600px;height:200px;></div></code>```

To target different browsers you can use @supports

https://developer.mozilla.org/en-US/docs/Web/CSS/%40supports

In your case:

```<code>@supports (background: radial-gradient(white, black)) {
  /* relevant styles here */
}
</code>```

Body:
I have created a polka dotted background in pure CSS via:

.polka-gr{

    background-image:radial-gradient(#FAFFB3 20%, transparent 0), radial-gradient(#F1C3CB 20%, transparent 0);
    background-size: 30px 30px;
    background-position: 0 0, 15px 15px;
}

As you can see, the background color is a greenish shade (of hex value #77FFD1).

Some of the clients this code is being served to do not support radial-gradient (e.g. those using Opera Mini browser). All such clients currently fall back to a plain #77FFD1 background without polka dots. Fair enough.

But is there any pure CSS way to get these non-supporting browsers to fall back to a different color entirely, e.g. #FFFF99?

Supporting browsers should still see the greenish background-color (#77FFD1) with polka dots.

Is such an arrangement possible? If so, an illustrative example would be great.

Body:
.polka-gr{
  background: yellow;
}

@supports (background: radial-gradient(#F1C3CB 20%, transparent 0)) {
.polka-gr{

    background-image:radial-gradient(#FAFFB3 20%, transparent 0), radial-gradient(#F1C3CB 20%, transparent 0);
      background-color:#77FFD1;
      background-size: 30px 30px;
      background-position: 0 0, 15px 15px;
  }
}

<div class="polka-gr" style="width:600px;height:200px;></div>

To target different browsers you can use @supports

https://developer.mozilla.org/en-US/docs/Web/CSS/%40supports

In your case:

@supports (background: radial-gradient(white, black)) {
  /* relevant styles here */
}


问:
How to generate a clean sql script using visual studio database project?
I have created an SQL Server Database Project using Visual Studio 2013. The build and Publish work fine (all changes from project are executed on database) but when I choose 'Generate Script' (instead of Publish) an .sql file is generated but it cannot be run directly (without modifying it) in SQL Server Management Studio because some of the following lines are not part of SQL language (those which starts with ":"):

```<code>GO
:setvar DatabaseName "Test_Project"
:setvar DefaultFilePrefix "Test_Project"
:setvar DefaultDataPath "<default path>"
:setvar DefaultLogPath "<default log path>"

GO
:on error exit
GO
/*
Detect SQLCMD mode and disable script execution if SQLCMD mode is not supported.
To re-enable the script after enabling SQLCMD mode, execute the following:
SET NOEXEC OFF;
*/
:setvar __IsSqlCmdEnabled "True"
GO
IF N'$(__IsSqlCmdEnabled)' NOT LIKE N'True'
    BEGIN
        PRINT N'SQLCMD mode must be enabled to successfully execute this script.';
        SET NOEXEC ON;
    END

GO
USE [$(DatabaseName)];
</code>```

How can generate a "clean" SQL file when I press Generate Script button? If it is not possible how can I transform the result into a SQL file which can be interpreted by SQL Server Management Studio?

答:
It's possible to pass the sqlcmd script into sqlcmd.exe with parameters. There's an example of this in this Microsoft blog post.

As far as I'm aware there's no way of outputting the sql file with the supplied parameters substituted in.

Body:
I have created an SQL Server Database Project using Visual Studio 2013. The build and Publish work fine (all changes from project are executed on database) but when I choose 'Generate Script' (instead of Publish) an .sql file is generated but it cannot be run directly (without modifying it) in SQL Server Management Studio because some of the following lines are not part of SQL language (those which starts with ":"):

GO
:setvar DatabaseName "Test_Project"
:setvar DefaultFilePrefix "Test_Project"
:setvar DefaultDataPath "<default path>"
:setvar DefaultLogPath "<default log path>"

GO
:on error exit
GO
/*
Detect SQLCMD mode and disable script execution if SQLCMD mode is not supported.
To re-enable the script after enabling SQLCMD mode, execute the following:
SET NOEXEC OFF;
*/
:setvar __IsSqlCmdEnabled "True"
GO
IF N'$(__IsSqlCmdEnabled)' NOT LIKE N'True'
    BEGIN
        PRINT N'SQLCMD mode must be enabled to successfully execute this script.';
        SET NOEXEC ON;
    END

GO
USE [$(DatabaseName)];

How can generate a "clean" SQL file when I press Generate Script button? If it is not possible how can I transform the result into a SQL file which can be interpreted by SQL Server Management Studio?


问:
Javascript error adding output! TypeError: tickvalues is null See your browser Javascript console for more details
I am trying to run below code in jupyter notebook.

df.groupby(['Gender'])['ApplicantIncome'].mean().plot()

But end up with the error:

Javascript error adding output! TypeError: tickvalues is null See your
  browser Javascript console for more details.

答:
I had the same problem while I was trying to include mpld3. Try excluding them if you have any.</p>

```<code># import mpld3
# mpld3.enable_notebook()
</code>```

Body:
I had the same problem while I was trying to include mpld3. Try excluding them if you have any.

# import mpld3
# mpld3.enable_notebook()


答:
We can use the rowSums based on subsetting the dataset by removing the last column, first column so that dimensions will the same and it compares the adjacent columns

```<code>rowSums(df[-length(df)] > 0.7 & df[-1] < 0.4)
</code>```

Title: Check and count conditions for following value

Body:
I have a dataframe with 18 rows and 25 variables. The values are between 0 and 1. For each row, I want to count the number of times a high value (> than 0.7) is followed by a low value (<0.4) and stored that count in a new column.

So far I have been using:
df$n_calls<-rowSums(df > 0.7)

I know it is possible to use different conditions but in my case it is very important to check that the low value is right after the high value

Here is an example of my df

            1          2          3          4          5          6          7          8          9         10          11
1   0.186158072 0.27738592 0.42165043 0.43501515 0.10918095 0.09976244 0.09571536 0.08674526 0.09239877 0.07523392 0.043679510
2   0.773469188 0.75381254 0.20389633 0.46444408 0.30433377 0.68334244 0.42105103 0.66224478 0.32412056 0.30951402 0.616658953
3   0.201245200 0.26873094 0.25892904 0.38605874 0.68438397 0.30236790 0.51493090 0.66314468 0.68910974 0.59134860 0.625550641
4   0.033746517 0.06388212 0.06978669 0.05517553 0.06032239 0.06736223 0.06514233 0.05133860 0.06034266 0.05702451 0.011144861
5   0.590297759 0.40352955 0.08106493 0.06063485 0.07780428 0.09633069 0.10882515 0.11468680 0.28375374 0.63941033 0.629284574
6   0.165001648 0.31174739 0.36955514 0.47581249 0.65349233 0.66471913 0.58004314 0.50790858 0.51298260 0.18651107 0.501195655
7   0.033164989 0.05678890 0.05941058 0.04139692 0.04660761 0.05452679 0.04939543 0.02780824 0.03680599 0.04645522 0.018496662
8   0.080893779 0.07228276 0.07473865 0.05536056 0.05732153 0.06403365 0.06139970 0.05142047 0.05698089 0.06998986 0.032598440
9   0.557273680 0.49226191 0.63900601 0.37497255 0.72114277 0.37557355 0.34360391 0.37502000 0.41622472 0.46852220 0.410656260
10 -0.004010143 0.03051558 0.04403711 0.02749514 0.04770637 0.05800898 0.05603494 0.04163723 0.04622024 0.04677767 0.007736933
11  0.280273472 0.59839662 0.74167893 0.75352655 0.75108785 0.72345468 0.65395063 0.32957749 0.08357061 0.33165070 0.731228429
12  0.107398713 0.10983041 0.13630594 0.19905651 0.47014034 0.72519345 0.69545405 0.62194265 0.49873996 0.16549282 0.087689371
13  0.164520925 0.22763832 0.50824238 0.59686660 0.68419908 0.66837348 0.62380175 0.20226234 0.11425066 0.09725765 0.078701134
14  0.076934267 0.09684586 0.10703672 0.08436558 0.10789735 0.24130640 0.36615645 0.42805115 0.42937392 0.51390288 0.584757257
15  0.055565174 0.06796064 0.07519020 0.05498454 0.05754891 0.06377643 0.06537049 0.05152625 0.05783594 0.05963775 0.022556411
16  0.126975964 0.19394191 0.53324900 0.60905758 0.67072084 0.61613836 0.55415573 0.18317823 0.13453799 0.09835233 0.067080267
17  0.730333357 0.65759923 0.59045925 0.63148539 0.36305458 0.40829673 0.48734552 0.58647457 0.66968986 0.48312152 0.453863785
18  0.196450179 0.33968393 0.51538678 0.44868341 0.22221050 0.18934329 0.19179838 0.18764290 0.22423578 0.27524872 0.608625015
            12          13         14         15         16          17         18         19         20         21         22
1  0.038553121 0.040081485 0.05358118 0.07403555 0.05091901 0.042299806 0.04322122 0.05587749 0.06881493 0.09753878 0.10462942
2  0.618447812 0.048885425 0.06231155 0.08228801 0.05963307 0.022666894 0.09384802 0.07914030 0.08549148 0.08373159 0.07404309
3  0.179434300 0.679981042 0.69176338 0.74453573 0.70937271 0.289762839 0.17956945 0.68770664 0.73864122 0.73187173 0.34604987
4  0.005094105 0.007952117 0.02076629 0.04174891 0.02129751 0.010066515 0.01454399 0.04337116 0.05259742 0.05795045 0.04533231
5  0.554122074 0.322792638 0.21839661 0.18322419 0.05764354 0.041600287 0.04692187 0.04305403 0.05762126 0.06212474 0.05289008
6  0.719147265 0.481543275 0.20168371 0.19885731 0.27223662 0.587549079 0.66694312 0.76974309 0.45266122 0.23338301 0.09435850
7  0.019041585 0.005380972 0.01856521 0.03947278 0.01221314 0.004858193 0.01322566 0.02001854 0.02755861 0.03889634 0.03102918
8  0.031368415 0.024535386 0.04031225 0.06011198 0.03558484 0.027890723 0.04100022 0.04572906 0.05465957 0.06437218 0.06308497
9  0.290487995 0.109253389 0.09076971 0.11177720 0.08365271 0.074780381 0.07845467 0.08843678 0.12696256 0.15252180 0.16108674
10 0.004599971 0.004843833 0.02327683 0.05022203 0.02867540 0.013674600 0.02376855 0.03408261 0.04563785 0.04991278 0.04216682
11 0.702763718 0.204497547 0.05554607 0.07056242 0.04561622 0.027652748 0.05185238 0.03544719 0.04735368 0.05194280 0.05193089
12 0.087884047 0.068055513 0.07587232 0.09912338 0.09637278 0.085378227 0.09348430 0.09237792 0.10785289 0.22242136 0.28522539
13 0.050134608 0.060945434 0.07203437 0.09687331 0.07316602 0.067771770 0.07634787 0.08154630 0.09157153 0.08930093 0.09904561
14 0.255098748 0.323642069 0.34568802 0.42105224 0.41797424 0.434900416 0.39764147 0.30798058 0.31269146 0.42912436 0.52562571
15 0.015262751 0.027712972 0.03813722 0.07103989 0.05202094 0.040513502 0.04066496 0.23360454 0.34666910 0.62701471 0.61683636
16 0.052436966 0.080045644 0.11447572 0.10672800 0.07924541 0.064626998 0.07234429 0.06744468 0.07878329 0.08901864 0.07953835
17 0.422132751 0.127518376 0.13062324 0.15104667 0.12490013 0.110841862 0.10892834 0.07984952 0.09097741 0.15193027 0.18654107
18 0.662904286 0.247251060 0.20583902 0.32290931 0.47391488 0.574805088 0.64776018 0.73091902 0.27798841 0.35922799 0.36333131
           23         24 n_calls
1  0.23100480 0.30027592       0
2  0.07209460 0.06670631       1
3  0.30800154 0.27452357       2
4  0.04148986 0.03842700       0
5  0.05362370 0.05018294       0
6  0.08703911 0.08242964       0
7  0.03186000 0.03233006       0
8  0.05789078 0.05637648       0
9  0.25593446 0.29909342       1
10 0.03615961 0.03356159       0
11 0.05754763 0.06368048       1
12 0.45794999 0.56138753       0
13 0.16676533 0.22718405       0
14 0.63646856 0.29169414       0
15 0.64039251 0.60901138       0
16 0.08805636 0.09688941       0
17 0.36883747 0.41561690       1
18 0.37085132 0.36292634

Any idea how to proceed?

Body:
We can use the rowSums based on subsetting the dataset by removing the last column, first column so that dimensions will the same and it compares the adjacent columns

rowSums(df[-length(df)] > 0.7 & df[-1] < 0.4)


问:
The requested resource () is not available. (when running Tomcat 7.0 after downloading of JSF 2.0 project)
I have created a new Dynamic Web Project in eclipse 3.6.

I added a Tomcat 7.0 server and choose "Run on server" on a jsf file. Working fine!

I added it to a SVN repository to share it with other.

I close Eclipse.

I create a new fresh workspace to check that everything works okey. Checking out the same project as above.

I added a Tomcat 7.0 server and choose "Run on server" on the same file as before. This result in a 404: "HTTP Status 404 .... - description The requested resource () is not available."

Why is that?? This is really strange! Don't you think? Can you please help me?

Best regards

答: Remove the dynamic web project from the Tomcat server and add it again.</p>

ContentLicense: CC BY-SA 2.5


问:
hadoop copy a local file system folder to HDFS
I need to copy a folder from local file system to HDFS. I could not find any example of moving a folder(including its all subfolders) to HDFS

$ hadoop fs -copyFromLocal /home/ubuntu/Source-Folder-To-Copy HDFS-URI

答:
In Short

hdfs dfs -put <localsrc> <dest>

In detail with an example:

Checking source and target before placing files into HDFS

```<code>[cloudera@quickstart ~]$ ll files/
total 132
-rwxrwxr-x 1 cloudera cloudera  5387 Nov 14 06:33 cloudera-manager
-rwxrwxr-x 1 cloudera cloudera  9964 Nov 14 06:33 cm_api.py
-rw-rw-r-- 1 cloudera cloudera   664 Nov 14 06:33 derby.log
-rw-rw-r-- 1 cloudera cloudera 53655 Nov 14 06:33 enterprise-deployment.json
-rw-rw-r-- 1 cloudera cloudera 50515 Nov 14 06:33 express-deployment.json

[cloudera@quickstart ~]$ hdfs dfs -ls
Found 1 items
drwxr-xr-x   - cloudera cloudera          0 2017-11-14 00:45 .sparkStaging
</code>```

Copy files HDFS using -put or -copyFromLocal command

```<code>[cloudera@quickstart ~]$ hdfs dfs -put files/ files
</code>```

Verify the result in HDFS

```<code>[cloudera@quickstart ~]$ hdfs dfs -ls
Found 2 items
drwxr-xr-x   - cloudera cloudera          0 2017-11-14 00:45 .sparkStaging
drwxr-xr-x   - cloudera cloudera          0 2017-11-14 06:34 files

[cloudera@quickstart ~]$ hdfs dfs -ls files
Found 5 items
-rw-r--r--   1 cloudera cloudera       5387 2017-11-14 06:34 files/cloudera-manager
-rw-r--r--   1 cloudera cloudera       9964 2017-11-14 06:34 files/cm_api.py
-rw-r--r--   1 cloudera cloudera        664 2017-11-14 06:34 files/derby.log
-rw-r--r--   1 cloudera cloudera      53655 2017-11-14 06:34 files/enterprise-deployment.json
-rw-r--r--   1 cloudera cloudera      50515 2017-11-14 06:34 files/express-deployment.json
</code>```

ContentLicense: CC BY-SA 4.0

Body:
In Short

hdfs dfs -put <localsrc> <dest>

In detail with an example:

Checking source and target before placing files into HDFS

[cloudera@quickstart ~]$ ll files/
total 132
-rwxrwxr-x 1 cloudera cloudera  5387 Nov 14 06:33 cloudera-manager
-rwxrwxr-x 1 cloudera cloudera  9964 Nov 14 06:33 cm_api.py
-rw-rw-r-- 1 cloudera cloudera   664 Nov 14 06:33 derby.log
-rw-rw-r-- 1 cloudera cloudera 53655 Nov 14 06:33 enterprise-deployment.json
-rw-rw-r-- 1 cloudera cloudera 50515 Nov 14 06:33 express-deployment.json

[cloudera@quickstart ~]$ hdfs dfs -ls
Found 1 items
drwxr-xr-x   - cloudera cloudera          0 2017-11-14 00:45 .sparkStaging

Copy files HDFS using -put or -copyFromLocal command

[cloudera@quickstart ~]$ hdfs dfs -put files/ files

Verify the result in HDFS

[cloudera@quickstart ~]$ hdfs dfs -ls
Found 2 items
drwxr-xr-x   - cloudera cloudera          0 2017-11-14 00:45 .sparkStaging
drwxr-xr-x   - cloudera cloudera          0 2017-11-14 06:34 files

[cloudera@quickstart ~]$ hdfs dfs -ls files
Found 5 items
-rw-r--r--   1 cloudera cloudera       5387 2017-11-14 06:34 files/cloudera-manager
-rw-r--r--   1 cloudera cloudera       9964 2017-11-14 06:34 files/cm_api.py
-rw-r--r--   1 cloudera cloudera        664 2017-11-14 06:34 files/derby.log
-rw-r--r--   1 cloudera cloudera      53655 2017-11-14 06:34 files/enterprise-deployment.json
-rw-r--r--   1 cloudera cloudera      50515 2017-11-14 06:34 files/express-deployment.json


问:
Adding new elements on ComboBox
I'm developing a Vaadin app, and I've decided to use the SuggestingComboBox idea, that allows better searches between items. This works great, but now I can't figure out how to add new elements, that aren't already in the container with the setNewItemHandler method.

For refference, here is the SuggestingComBox code:

```<code>public class SuggestingComboBox extends ComboBox {

    public SuggestingComboBox() {
        setItemCaptionMode(ItemCaptionMode.PROPERTY);
        setItemCaptionPropertyId("name");
    }

    @Override
    protected Filter buildFilter(String filterString,
            FilteringMode filteringMode) {
        return new SuggestingContainer.SuggestionFilter(filterString);
    }
}
</code>```

And the SuggestingContainer code, that comes along the combobox:

```<code>public abstract class SuggestingContainer<T> extends BeanItemContainer<T> {

    public SuggestingContainer(Class<? super T> type)
            throws IllegalArgumentException {
        super(type);
    }

    @Override
    protected void addFilter(Filter filter)
            throws UnsupportedFilterException {
        if(filter instanceof SuggestionFilter) {
            SuggestionFilter suggestionFilter = (SuggestionFilter) filter;
            filterItems(suggestionFilter.getFilterString());
        } else
            super.addFilter(filter);
    }

    //This method is to be overriden
    protected abstract void filterItems(String filterString);

   public static class SuggestionFilter implements Container.Filter {
       private String filterString;

       public SuggestionFilter(String filterString) {
           this.filterString = filterString;
       }

       public String getFilterString() {
           return filterString;
       }

       @Override
       public boolean passesFilter(Object itemId, Item item)
               throws UnsupportedOperationException {
           return false;
       }

       @Override
       public boolean appliesToProperty(Object propertyId) {
           return false;
       }
  }
</code>```

This container is used as this:

```<code>public SuggestingField extends CustomField<Model> {
    private SuggestingComboBox suggestingCB;
    private SuggestingContainer<ObjectItem> container;

    public SuggestingField() {
        suggestingCB = new SuggestingComboBox();
        container = new SuggestingContainer<ObjectItem>(ObjectItem.class) {
            @Override
            protected void filterItems(String filterString) {
                removeAllItems();

                List<Model> result; //Obtain here the results
                List<ObjectItem> lItems = result.stream()
                        .map(m -> new ObjectItem(m.getId()+"", m.toString(), m))
                        .collect(Collectors.toList());
                addAll(lItems);
            }
        };
        suggestingCB.setContainerDataSource(container);
        suggestingCB.setImmediate(true);
        suggestingCB.setItemCaptionPropertyId("text");
    }
}
</code>```

Also, I have a POJO Model and that ObjectItem class, that I have to use, beacuse I don't get to work the toString caption mode.

```<code>public class Model {
    private int id;
    private String name;
    //Getters and setters; equals/hash
}
public class ObjectItem {
    private String id;
    private String text;
    private Object o;
    //Equals/hash and getters/setters
}
</code>```

So, my problem is: I'm trying to allow creating new Model(s) in the field, using the setNewItemHandler method. This is what I've tried so far.

```<code>public SuggestingField extends CustomField<Model> {
...
    public void setNewElementsAllowed(boolean allowed) {
        this.suggestingCB.setNewItemsAllowed(allowed);
        this.suggestingCB.setImmediate(allowed);
        if(allowed) {
            suggestingCB.setNewItemHandler(caption -> {
                Model m = new Model();
                m.setNombre(caption);

                setValue(m);
            });
        }
    }
    public void setValue(Model m) {
        super.setValue(m);
        if(m == null)
            suggestingCB.setValue(null);
        else {
            ObjectItem it = new ObjectItem(""+m.getId(),
                m.getName(), m);
            if(container.size() == 0 || !container.containsId(it.getId()))
                container.addItem(it);

            suggestingCB.setValue(it);
            suggestingCB.select(it);
        }
    }
</code>```

After debuggind this code, I've found that the newElementHandler is used, and it adds a new item to the container, but nothing is shown in the ComboBox and the next handler's execution, the container is empty, as if no item was inserted.

答:
I've been able to identify the error. When you select one item in a ComboBox, the filterString becomes "", so, if you select something that isn't in the DB, and recall the query, it won't be in the List<Model> result and thus, it will be unselected.

A way to overcome this is to modify SuggestingField as here:

```<code>public SuggestingField extends CustomField<Model> {
    private Model model;
    ...
    public SuggestingField() {
        ...
        container = new SuggestingContainer<ObjectItem>(ObjectItem.class) {
            @Override
            protected void filterItems(String filterString) {
                removeAllItems();

                if("".equals(filterString)) {
                    if(model != null) {
                        ObjectItem it = new ObjectItem();
                        it.setId(model.getId()+"");
                        it.setText(model.toString());
                        it.setObject(model);

                        addItem(it);
                        return;
                    }
                }

                List<Model> result; //Obtain here the results
                List<ObjectItem> lItems = result.stream()
                    .map(m -> new ObjectItem(m.getId()+"", m.toString(), m))
                    .collect(Collectors.toList());
                addAll(lItems);
            }
        };
        suggestingCB.addValueChangeListener(ev -> {
            this.model = (Model) suggestingCB.getValue();
        });
</code>```

This allows to maintain the new item through filters.

Title: Adding new elements on ComboBox

Body:
I'm developing a Vaadin app, and I've decided to use the SuggestingComboBox idea, that allows better searches between items. This works great, but now I can't figure out how to add new elements, that aren't already in the container with the setNewItemHandler method.

For refference, here is the SuggestingComBox code:

public class SuggestingComboBox extends ComboBox {

    public SuggestingComboBox() {
        setItemCaptionMode(ItemCaptionMode.PROPERTY);
        setItemCaptionPropertyId("name");
    }

    @Override
    protected Filter buildFilter(String filterString,
            FilteringMode filteringMode) {
        return new SuggestingContainer.SuggestionFilter(filterString);
    }
}

And the SuggestingContainer code, that comes along the combobox:

public abstract class SuggestingContainer<T> extends BeanItemContainer<T> {

    public SuggestingContainer(Class<? super T> type)
            throws IllegalArgumentException {
        super(type);
    }

    @Override
    protected void addFilter(Filter filter)
            throws UnsupportedFilterException {
        if(filter instanceof SuggestionFilter) {
            SuggestionFilter suggestionFilter = (SuggestionFilter) filter;
            filterItems(suggestionFilter.getFilterString());
        } else
            super.addFilter(filter);
    }

    //This method is to be overriden
    protected abstract void filterItems(String filterString);

   public static class SuggestionFilter implements Container.Filter {
       private String filterString;

       public SuggestionFilter(String filterString) {
           this.filterString = filterString;
       }

       public String getFilterString() {
           return filterString;
       }

       @Override
       public boolean passesFilter(Object itemId, Item item)
               throws UnsupportedOperationException {
           return false;
       }

       @Override
       public boolean appliesToProperty(Object propertyId) {
           return false;
       }
  }

This container is used as this:

public SuggestingField extends CustomField<Model> {
    private SuggestingComboBox suggestingCB;
    private SuggestingContainer<ObjectItem> container;

    public SuggestingField() {
        suggestingCB = new SuggestingComboBox();
        container = new SuggestingContainer<ObjectItem>(ObjectItem.class) {
            @Override
            protected void filterItems(String filterString) {
                removeAllItems();

                List<Model> result; //Obtain here the results
                List<ObjectItem> lItems = result.stream()
                        .map(m -> new ObjectItem(m.getId()+"", m.toString(), m))
                        .collect(Collectors.toList());
                addAll(lItems);
            }
        };
        suggestingCB.setContainerDataSource(container);
        suggestingCB.setImmediate(true);
        suggestingCB.setItemCaptionPropertyId("text");
    }
}

Also, I have a POJO Model and that ObjectItem class, that I have to use, beacuse I don't get to work the toString caption mode.

public class Model {
    private int id;
    private String name;
    //Getters and setters; equals/hash
}
public class ObjectItem {
    private String id;
    private String text;
    private Object o;
    //Equals/hash and getters/setters
}

So, my problem is: I'm trying to allow creating new Model(s) in the field, using the setNewItemHandler method. This is what I've tried so far.

public SuggestingField extends CustomField<Model> {
...
    public void setNewElementsAllowed(boolean allowed) {
        this.suggestingCB.setNewItemsAllowed(allowed);
        this.suggestingCB.setImmediate(allowed);
        if(allowed) {
            suggestingCB.setNewItemHandler(caption -> {
                Model m = new Model();
                m.setNombre(caption);

                setValue(m);
            });
        }
    }
    public void setValue(Model m) {
        super.setValue(m);
        if(m == null)
            suggestingCB.setValue(null);
        else {
            ObjectItem it = new ObjectItem(""+m.getId(),
                m.getName(), m);
            if(container.size() == 0 || !container.containsId(it.getId()))
                container.addItem(it);

            suggestingCB.setValue(it);
            suggestingCB.select(it);
        }
    }

After debuggind this code, I've found that the newElementHandler is used, and it adds a new item to the container, but nothing is shown in the ComboBox and the next handler's execution, the container is empty, as if no item was inserted.

Body:
I've been able to identify the error. When you select one item in a ComboBox, the filterString becomes "", so, if you select something that isn't in the DB, and recall the query, it won't be in the List<Model> result and thus, it will be unselected.

A way to overcome this is to modify SuggestingField as here:

public SuggestingField extends CustomField<Model> {
    private Model model;
    ...
    public SuggestingField() {
        ...
        container = new SuggestingContainer<ObjectItem>(ObjectItem.class) {
            @Override
            protected void filterItems(String filterString) {
                removeAllItems();

                if("".equals(filterString)) {
                    if(model != null) {
                        ObjectItem it = new ObjectItem();
                        it.setId(model.getId()+"");
                        it.setText(model.toString());
                        it.setObject(model);

                        addItem(it);
                        return;
                    }
                }

                List<Model> result; //Obtain here the results
                List<ObjectItem> lItems = result.stream()
                    .map(m -> new ObjectItem(m.getId()+"", m.toString(), m))
                    .collect(Collectors.toList());
                addAll(lItems);
            }
        };
        suggestingCB.addValueChangeListener(ev -> {
            this.model = (Model) suggestingCB.getValue();
        });

This allows to maintain the new item through filters.


问:
Firebase Messaging - Can't receive notifications from subscriptions
Here is the situation: I have a firebase cloud function that is running on every write to a certain database collection (called "jamrooms"). The NodeJS script is as follows:

```<code>const functions = require('firebase-functions');

// The Firebase Admin SDK to access the Firebase Realtime Database.
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

exports.newJamroom = functions.database.ref('/jamrooms/{jamroomId}').onWrite(event => {

        // Grab the current value of what was written to the Realtime Database.
        var jamroomId = event.params.jamroomId;

        var topic = "new-jamroom";
        var payload = {
            data: {
                title: "New jamroom available !",
                body: String("Jamroom id = ").concat(jamroomId)
            }
        };

        // Send a message to devices subscribed to the provided topic.
        return admin.messaging().sendToTopic(topic, payload)
            .then(function (response) {
                // See the MessagingTopicResponse reference documentation for the
                // contents of response.
                console.log("Successfully sent message:", response);
            })
            .catch(function (error) {
                console.log("Error sending message:", error);
            });
});
</code>```

On the client side (Android), I've subscribed to the topic "new-jamroom":

FirebaseMessaging.getInstance().subscribeToTopic("new-jamroom");
```

The script is successfully executed each time a new key-value pair is added to the collection:

but the client never receives the notification, either in background or in foreground.

I don't know where to look at to understand what's not going right.

Update

Even sending notifications from the console (using topic "new-jamroom", that exists in the console) doesn't send it to the client (Firebase records 0 sent).

答:
Because your payload contains the data key, you are sending a data-only message, not a notification:

```<code>    var payload = {
        data: {
            title: "New jamroom available !",
            body: String("Jamroom id = ").concat(jamroomId)
        }
</code>```

Data messages and notification messages are handled differently by the receiver.  Data-only messages cause onMessageReceived() to be invoked in the receiver.  To generate a notification, build your payload with the notification key:

```<code>    var payload = {
        notification: {  // <= CHANGED
            title: "New jamroom available !",
            body: String("Jamroom id = ").concat(jamroomId)
        }
</code>```

Body:
Here is the situation: I have a firebase cloud function that is running on every write to a certain database collection (called "jamrooms"). The NodeJS script is as follows:

const functions = require('firebase-functions');

// The Firebase Admin SDK to access the Firebase Realtime Database.
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

exports.newJamroom = functions.database.ref('/jamrooms/{jamroomId}').onWrite(event => {

        // Grab the current value of what was written to the Realtime Database.
        var jamroomId = event.params.jamroomId;

        var topic = "new-jamroom";
        var payload = {
            data: {
                title: "New jamroom available !",
                body: String("Jamroom id = ").concat(jamroomId)
            }
        };

        // Send a message to devices subscribed to the provided topic.
        return admin.messaging().sendToTopic(topic, payload)
            .then(function (response) {
                // See the MessagingTopicResponse reference documentation for the
                // contents of response.
                console.log("Successfully sent message:", response);
            })
            .catch(function (error) {
                console.log("Error sending message:", error);
            });
});

On the client side (Android), I've subscribed to the topic "new-jamroom":

FirebaseMessaging.getInstance().subscribeToTopic("new-jamroom");

The script is successfully executed each time a new key-value pair is added to the collection:

but the client never receives the notification, either in background or in foreground.

I don't know where to look at to understand what's not going right.

Update

Even sending notifications from the console (using topic "new-jamroom", that exists in the console) doesn't send it to the client (Firebase records 0 sent).

Body:
Because your payload contains the data key, you are sending a data-only message, not a notification:

    var payload = {
        data: {
            title: "New jamroom available !",
            body: String("Jamroom id = ").concat(jamroomId)
        }

Data messages and notification messages are handled differently by the receiver.  Data-only messages cause onMessageReceived() to be invoked in the receiver.  To generate a notification, build your payload with the notification key:

    var payload = {
        notification: {  // <= CHANGED
            title: "New jamroom available !",
            body: String("Jamroom id = ").concat(jamroomId)
        }


问:
Why trim is not working?
I am trying to trim leading whitespaces from the string and I do not know what is wrong with my approach, any suggestions would be appreciated ?

Code:

this.poNumber = poNumber.equals("") ? poNumber : poNumber.trim();

am reading poNumber from csv file as "     IG078565 and IG083060 " and output also am getting same value with same whitespaces, not sure why ?

Updated

Adding complete method for better context:

```<code>public BillingDTO(String currency, String migrationId, String chargeId, String priceId, String poNumber, String otc,
            String billingClassId, String laborOnly) {
        super();
        this.currency = currency.equals("") ? currency : currency.trim();
        this.migrationId = migrationId.equals("") ? migrationId : migrationId.trim();
        this.chargeId = chargeId.equals("") ? chargeId : chargeId.trim();
        this.priceId = priceId.equals("") ? priceId : priceId.trim();
        this.poNumber = poNumber.equals("") ? poNumber : poNumber.trim();
            //poNumber.trim();
        //System.out.println("poNumber:"+this.poNumber.trim());
        //this.poNumber = poNumber.equals("") ? poNumber : poNumber.trim();
        this.otc = otc.equals("") ? otc : otc.trim();
        this.billingClassId = billingClassId.equals("") ? billingClassId : billingClassId.trim();
        this.laborOnly = laborOnly.equals("") ? "N" : laborOnly;
    }
</code>```

Thanks.

答:
Your file may have non-ascii whitespace which is not being trimmed. For example there is a unicode character non-breaking space (U+00A0), which displays as whitespace but is not considered by trim (this is something you might see such as in a document edited in wordpad or other editors which try to "help" you.) If you look at the definition of String.trim() it removes characters that are <= ' ' (i.e. value less than or equal to 20).

So print the byte values of your string (or look at it in a hex editor) and make sure that your spaces actually are space (i.e. decimal value 20). If you need other behavior you might need to write your own trim utility function that uses a proper unicode Character.isWhiteSpace(char) check.

Title: Why trim is not working?

Body:
I am trying to trim leading whitespaces from the string and I do not know what is wrong with my approach, any suggestions would be appreciated ?

Code:

this.poNumber = poNumber.equals("") ? poNumber : poNumber.trim();

am reading poNumber from csv file as "     IG078565 and IG083060 " and output also am getting same value with same whitespaces, not sure why ?

Updated

Adding complete method for better context:

public BillingDTO(String currency, String migrationId, String chargeId, String priceId, String poNumber, String otc,
            String billingClassId, String laborOnly) {
        super();
        this.currency = currency.equals("") ? currency : currency.trim();
        this.migrationId = migrationId.equals("") ? migrationId : migrationId.trim();
        this.chargeId = chargeId.equals("") ? chargeId : chargeId.trim();
        this.priceId = priceId.equals("") ? priceId : priceId.trim();
        this.poNumber = poNumber.equals("") ? poNumber : poNumber.trim();
            //poNumber.trim();
        //System.out.println("poNumber:"+this.poNumber.trim());
        //this.poNumber = poNumber.equals("") ? poNumber : poNumber.trim();
        this.otc = otc.equals("") ? otc : otc.trim();
        this.billingClassId = billingClassId.equals("") ? billingClassId : billingClassId.trim();
        this.laborOnly = laborOnly.equals("") ? "N" : laborOnly;
    }

Thanks.


问:
Different app versions on iOS and Android - React Native (CRNA) with Expo
Is it possible to have two different app versions (one for iOS and one for Android) within the same codebase in a React Native (CRNA) app using Expo?

There is obviously only 1 app.json as follows:

```<code>{
  "expo": {
    "name": "MyApp",
    "icon": "./assets/images/appstore-icon.png",
    "description": "This is a sample",
    "slug": "test",
    "privacy": "unlisted",
    "sdkVersion": "19.0.0",
    "version": "1.0.10",
    ......... etc
  }
}
</code>```

Is there a way to add platform-specific versioning?

答:
Unfortunately there is no direct way of doing what you ask.

Using Platform

You can define custom code for each application using the Platform react native API, which docs can be found on the RN docs. Using this API you can check the current platform and define code for each.

```<code>import { Platform, StyleSheet } from 'react-native';

const styles = StyleSheet.create({  height: (Platform.OS === 'ios') ? 200 : 100, });
</code>```

or you can also define some code for each platform using platform.select

```<code>import { Platform, StyleSheet } from 'react-native';

const styles = StyleSheet.create({
  container: {
    flex: 1,
    ...Platform.select({
      ios: {
        backgroundColor: 'red',
      },
      android: {
        backgroundColor: 'blue',
      },
    }),
  },
</code>```

Using Specific file extensions

You can name each js file using filename.ios.js or filename.android.js and they will be called in each platform automatically.

Using Environments

Besides of platform in many cases I like to define an Environment module which allows me to swap some values depending on what environment I've selected. For example:

```<code>- environment
   /environment.js
   /state.js
</code>```

In environment.js I save the available state keys and the currently selected environment:

environment.js

```<code>export const environments = {
  pre: "PRE_ENV",
  prod: "PROD_ENV",
};

export const currentEnvironment =  environments.pre;
</code>```

Then in the state.js I like to store some helpers to check which environment I'm in:

state.js

```<code>import { currentEnvironment, environments } from "./environment";

export const isProductionEnvironment = () => {
  return environments.prod === currentEnvironment;
};

export const isPreEnvironment = () => {
  return environments.pre === currentEnvironment;
};
</code>```

Now you can make some environment-dependent code in new files, like:

greeting.js

```<code>import { environments, currentEnvironment } from "./environment";

export const selectGreeting = () => {
  switch(currentEnvironment) {
    case environments.pre:
      return "Welcome to the pre environment";

    case environments.prod:
      return "Welcome to the prod environment";

    default:
      return "Unsupported Environment";
  }
};
</code>```

To manage your app.js there is no beautiful solution, you store some default app.js to some environment and copy paste it or you can use:
https://github.com/oliverbenns/expo-deploy

It is a little library written in bash which helps you deploy to multiple slugs.

Hope it helps!

Body:
Is it possible to have two different app versions (one for iOS and one for Android) within the same codebase in a React Native (CRNA) app using Expo?

There is obviously only 1 app.json as follows:

{
  "expo": {
    "name": "MyApp",
    "icon": "./assets/images/appstore-icon.png",
    "description": "This is a sample",
    "slug": "test",
    "privacy": "unlisted",
    "sdkVersion": "19.0.0",
    "version": "1.0.10",
    ......... etc
  }
}

Is there a way to add platform-specific versioning?

Body:
Unfortunately there is no direct way of doing what you ask.

Using Platform

You can define custom code for each application using the Platform react native API, which docs can be found on the RN docs. Using this API you can check the current platform and define code for each.

import { Platform, StyleSheet } from 'react-native';

const styles = StyleSheet.create({  height: (Platform.OS === 'ios') ? 200 : 100, });

or you can also define some code for each platform using platform.select

import { Platform, StyleSheet } from 'react-native';

const styles = StyleSheet.create({
  container: {
    flex: 1,
    ...Platform.select({
      ios: {
        backgroundColor: 'red',
      },
      android: {
        backgroundColor: 'blue',
      },
    }),
  },

Using Specific file extensions

You can name each js file using filename.ios.js or filename.android.js and they will be called in each platform automatically.

Using Environments

Besides of platform in many cases I like to define an Environment module which allows me to swap some values depending on what environment I've selected. For example:

- environment
   /environment.js
   /state.js

In environment.js I save the available state keys and the currently selected environment:

environment.js

export const environments = {
  pre: "PRE_ENV",
  prod: "PROD_ENV",
};

export const currentEnvironment =  environments.pre;

Then in the state.js I like to store some helpers to check which environment I'm in:

state.js

import { currentEnvironment, environments } from "./environment";

export const isProductionEnvironment = () => {
  return environments.prod === currentEnvironment;
};

export const isPreEnvironment = () => {
  return environments.pre === currentEnvironment;
};

Now you can make some environment-dependent code in new files, like:

greeting.js

import { environments, currentEnvironment } from "./environment";

export const selectGreeting = () => {
  switch(currentEnvironment) {
    case environments.pre:
      return "Welcome to the pre environment";

    case environments.prod:
      return "Welcome to the prod environment";

    default:
      return "Unsupported Environment";
  }
};

To manage your app.js there is no beautiful solution, you store some default app.js to some environment and copy paste it or you can use:
https://github.com/oliverbenns/expo-deploy

It is a little library written in bash which helps you deploy to multiple slugs.

Hope it helps!


问:
How to Open a URL in Safari from settings.bundle
How can I open a URL in Safari from Settings?

Something like in the Nike+ App

Does it need to be customized? I can't seem to find a Type for adding a URL in the Root.plist.

答:
Similar to GSiklos's answer abouve, but using the plist editor in XCode , the change would be:

Note that as default, any URL's shown in the IASK settings are NOT displayed in the standard iOS settings page (usefully)


问:
SQL search in the same order as requested and showing not found items
I want to do a special query for SQL but I'm not able to get the wanted result.

My basic query is:

```<code>select * from TABLE_NAME where COLUMN_NAME_1 in ('ABC1', 'ABC98', 'ABC97', 'ABC2', 'ABC3')
</code>```

Imagine that the item 'ABC1' is not in the table. I would like my query to show it. In addition I would like that my query shows the items in the same order I asked (ABC1, ABC98, ABC97, and so on).

I attach an image where you'll understand better what I want.

Thanks in advance

答:
You need to use an outer join or union all.  One method looks like:

```<code>select v.col1, . . .
from (select 'ABC1' as col1, 1 as ord union all
      select 'ABC98', 2  union all
      . . .
     ) left join
    TABLE_NAME t
    on t.column_name_1 = v.col1
order by ord;
</code>```

The exact syntax for the list of values varies by database.  The above works for MySQL.  Oracle would require from dual in the subqueries.

Body:
I want to do a special query for SQL but I'm not able to get the wanted result.

My basic query is:

select * from TABLE_NAME where COLUMN_NAME_1 in ('ABC1', 'ABC98', 'ABC97', 'ABC2', 'ABC3')

Imagine that the item 'ABC1' is not in the table. I would like my query to show it. In addition I would like that my query shows the items in the same order I asked (ABC1, ABC98, ABC97, and so on).

I attach an image where you'll understand better what I want.

Thanks in advance

Body:
You need to use an outer join or union all.  One method looks like:

select v.col1, . . .
from (select 'ABC1' as col1, 1 as ord union all
      select 'ABC98', 2  union all
      . . .
     ) left join
    TABLE_NAME t
    on t.column_name_1 = v.col1
order by ord;

The exact syntax for the list of values varies by database.  The above works for MySQL.  Oracle would require from dual in the subqueries.


问:
ffmpeg image and flask app in two different containers in Docker compose. How do I use ffmpeg in flask app?
Here is my docker compose yml file:

```<code>ffmpeg:
    image: jrottenberg/ffmpeg:ubuntu
    tty: true
flask_app:
  build: ./flask_app
  #image: conorquinn01/composeapp
  command: python ./flask_app/app.py
  ports:
   - "5000:5000"
  volumes:
   - .:/muse_compose2
  links:
    ['ffmpeg']
</code>```

Not sure how to do this. Thanks.

答:
I'm a noob with Docker and python isn't my language but I'm facing a similar problem. I have a rails app to save videos with shrine on docker and I don't want the transcoding in the same container because of the local resources, so, when somebody upload a video I save the ID in the BD and the video is sent to the shared folder while a thread call the ffmpeg container (jrottenberg/ffmpeg:ubuntu). If you're interested, here is the script to run the ffmpeg while saving in the shared folder:

Windows

```<code>docker run -it -v c:/Users/[your-user]/desktop/compartida:/v jrottenberg/ffmpeg -i http://archive.org/download/thethreeagesbusterkeaton/Buster.Keaton.The.Three.Ages.ogv /video.mp4
</code>```

Linux

```<code>docker run -it -v $(pwd):/v jrottenberg/ffmpeg -i http://archive.org/download/thethreeagesbusterkeaton/Buster.Keaton.The.Three.Ages.ogv  /video.mp4
</code>```

And the link to the git of the project
jrottenberg/ffmpeg

Because I make a folder with the video ID to save the videos, when I want the video I just use the id in the BD instead of the name. I'm sorry for my english.

Body:
Here is my docker compose yml file:

ffmpeg:
    image: jrottenberg/ffmpeg:ubuntu
    tty: true
flask_app:
  build: ./flask_app
  #image: conorquinn01/composeapp
  command: python ./flask_app/app.py
  ports:
   - "5000:5000"
  volumes:
   - .:/muse_compose2
  links:
    ['ffmpeg']

Not sure how to do this. Thanks.

Body:
I'm a noob with Docker and python isn't my language but I'm facing a similar problem. I have a rails app to save videos with shrine on docker and I don't want the transcoding in the same container because of the local resources, so, when somebody upload a video I save the ID in the BD and the video is sent to the shared folder while a thread call the ffmpeg container (jrottenberg/ffmpeg:ubuntu). If you're interested, here is the script to run the ffmpeg while saving in the shared folder:

Windows

docker run -it -v c:/Users/[your-user]/desktop/compartida:/v jrottenberg/ffmpeg -i http://archive.org/download/thethreeagesbusterkeaton/Buster.Keaton.The.Three.Ages.ogv /video.mp4

Linux

docker run -it -v $(pwd):/v jrottenberg/ffmpeg -i http://archive.org/download/thethreeagesbusterkeaton/Buster.Keaton.The.Three.Ages.ogv  /video.mp4

And the link to the git of the project
jrottenberg/ffmpeg

Because I make a folder with the video ID to save the videos, when I want the video I just use the id in the BD instead of the name. I'm sorry for my english.


问:
how to capture Build Info using Gradle and Spring Boot
I am trying to get access to build info values such as version in my Java main application using Spring Boot and Gradle.

I can't find any documentation / examples of how to configure the

build.gradle

application.yml (if required)

Java main class

could someone please help with a small code example for the above files.

In my build.gradle file I will have the version entry, so how to get this into Java main class using Spring Boot and Gradle.

build.gradle

```<code>version=0.0.1-SNAPSHOT
</code>```

I've tried adding

build.gradle

```<code>apply plugin: 'org.springframework.boot'

springBoot {
    buildInfo()
}
</code>```

but the buildInfo() isn't recognised as a keyword in Intellij

In my Java main class I have the following:

```<code>public class MyExampleApplication implements CommandLineRunner {
    @Autowired
    private ApplicationContext context;

    public static void main(String[] args) {
        SpringApplication.run(MyExampleApplication.class, args);
    }

    @Override
    public void run(String[] args) throws Exception{
        Environment env = (Environment) context.getBean("environment");
        displayInfo(env);
    }

    private static void displayInfo(Environment env) {
       log.info("build version is <" + env.getProperty("version")
    }
</code>```

But when I run this - the output from env.getProperty("version") is showing as null.

答:
I managed to get it working now - using the help pointer that Vampire gave below and some other sources. The key was adding the actuator class to the project dependency.
Note: Intellj doesn't seem to recognise buildInfo() in the springBoot tag - but it does run ok - so don't be put off.

build.gradle

```<code>buildscript {
   ext {
      springBootVersion = '1.5.6.RELEASE'
      gradleVersion = '3.3'
   }

   repositories {
      mavenLocal()
      maven { url "http://cft-nexus.ldn.xxxxxxxxx.com:8081/nexus/content/groups/public/" }
                }
   dependencies {
      classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
                }
            }

        apply plugin: 'application'
        apply plugin: 'java'
        apply plugin: 'eclipse'
        apply plugin: 'idea'
        apply plugin: 'org.springframework.boot'

    version = '0.0.1-SNAPSHOT'
    sourceCompatibility = 1.8

    springBoot{
        buildInfo {
            additionalProperties = [
                    'foo': 'bar'
            ]
        }
    }

  compile "org.springframework.boot:spring-boot-starter-actuator"
</code>```

MyExampleApplication

```<code>@Slf4j
@EnableIntegration
@EnableLoaderApplication
@SpringBootApplication
@EnableDiscoveryClient
public class MyExampleApplication implements CommandLineRunner {

    private static final String SYSTEM_NAME_INFO = "My Example Application";
    private static final String VERSION="0.0.1";

    @Autowired
    private ApplicationContext context;

    public static void main(String[] args) {
        SpringApplication.run(MyExampleApplication.class, args);
    }

    @Override
    public void run(String[] args) throws Exception{
        BuildProperties buildProperties = context.getBean(BuildProperties.class);
        displayInfo(buildProperties);
    }

    private static void displayInfo(BuildProperties buildProperties) {
        log.info("build version is <" + buildProperties.getVersion() + ">");
    log.info("value for custom key 'foo' is <" + buildProperties.get("foo") + ">");
    }

}
</code>```

Screenshot of Console output when running the Application in Intellj

pasting the output as well incase the image doesn't display

```<code>> 2017-11-14 14:35:47.330  INFO 22448 --- [           main]
> o.s.c.support.DefaultLifecycleProcessor  : Starting beans in phase
> 2147483647 2017-11-14 14:35:47.448  INFO 22448 --- [           main]
> s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s):
> 8780 (http) 2017-11-14 14:35:47.451  INFO 22448 --- [           main]
> c.u.o.metrics.MyExampleApplication         : build version is
> <0.0.1-SNAPSHOT> 2017-11-14 14:35:47.451  INFO 22448 --- [
> main] c.u.o.myexample.MyExampleApplication         : value for custom key
> 'foo' is <bar>
</code>```

UPDATE

After reviewing this with my colleague we decided to move the some of the build properties, e.g. version (above) out of the build.gradle file and into gradle.properties file. This gives us a cleaner separation for build details and properties. When you run Gradle build it automatically pulls these values in and they are available in the BuildProperties bean in the Java main class as shown in the example above.

gradle.properties

```<code>group=com.xxx.examplesource
version=0.0.1-SNAPSHOT
gradleVersion=3.3
</code>```

Body:
I am trying to get access to build info values such as version in my Java main application using Spring Boot and Gradle.

I can't find any documentation / examples of how to configure the

build.gradle

application.yml (if required)

Java main class

could someone please help with a small code example for the above files.

In my build.gradle file I will have the version entry, so how to get this into Java main class using Spring Boot and Gradle.

build.gradle

version=0.0.1-SNAPSHOT

I've tried adding

build.gradle

apply plugin: 'org.springframework.boot'

springBoot {
    buildInfo()
}

but the buildInfo() isn't recognised as a keyword in Intellij

In my Java main class I have the following:

public class MyExampleApplication implements CommandLineRunner {
    @Autowired
    private ApplicationContext context;

    public static void main(String[] args) {
        SpringApplication.run(MyExampleApplication.class, args);
    }

    @Override
    public void run(String[] args) throws Exception{
        Environment env = (Environment) context.getBean("environment");
        displayInfo(env);
    }

    private static void displayInfo(Environment env) {
       log.info("build version is <" + env.getProperty("version")
    }

But when I run this - the output from env.getProperty("version") is showing as null.

Body:
I managed to get it working now - using the help pointer that Vampire gave below and some other sources. The key was adding the actuator class to the project dependency.
Note: Intellj doesn't seem to recognise buildInfo() in the springBoot tag - but it does run ok - so don't be put off.

build.gradle

buildscript {
   ext {
      springBootVersion = '1.5.6.RELEASE'
      gradleVersion = '3.3'
   }

   repositories {
      mavenLocal()
      maven { url "http://cft-nexus.ldn.xxxxxxxxx.com:8081/nexus/content/groups/public/" }
                }
   dependencies {
      classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
                }
            }

        apply plugin: 'application'
        apply plugin: 'java'
        apply plugin: 'eclipse'
        apply plugin: 'idea'
        apply plugin: 'org.springframework.boot'

    version = '0.0.1-SNAPSHOT'
    sourceCompatibility = 1.8

    springBoot{
        buildInfo {
            additionalProperties = [
                    'foo': 'bar'
            ]
        }
    }

  compile "org.springframework.boot:spring-boot-starter-actuator"

MyExampleApplication

@Slf4j
@EnableIntegration
@EnableLoaderApplication
@SpringBootApplication
@EnableDiscoveryClient
public class MyExampleApplication implements CommandLineRunner {

    private static final String SYSTEM_NAME_INFO = "My Example Application";
    private static final String VERSION="0.0.1";

    @Autowired
    private ApplicationContext context;

    public static void main(String[] args) {
        SpringApplication.run(MyExampleApplication.class, args);
    }

    @Override
    public void run(String[] args) throws Exception{
        BuildProperties buildProperties = context.getBean(BuildProperties.class);
        displayInfo(buildProperties);
    }

    private static void displayInfo(BuildProperties buildProperties) {
        log.info("build version is <" + buildProperties.getVersion() + ">");
    log.info("value for custom key 'foo' is <" + buildProperties.get("foo") + ">");
    }

}

Screenshot of Console output when running the Application in Intellj

pasting the output as well incase the image doesn't display

> 2017-11-14 14:35:47.330  INFO 22448 --- [           main]
> o.s.c.support.DefaultLifecycleProcessor  : Starting beans in phase
> 2147483647 2017-11-14 14:35:47.448  INFO 22448 --- [           main]
> s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s):
> 8780 (http) 2017-11-14 14:35:47.451  INFO 22448 --- [           main]
> c.u.o.metrics.MyExampleApplication         : build version is
> <0.0.1-SNAPSHOT> 2017-11-14 14:35:47.451  INFO 22448 --- [
> main] c.u.o.myexample.MyExampleApplication         : value for custom key
> 'foo' is <bar>

UPDATE

After reviewing this with my colleague we decided to move the some of the build properties, e.g. version (above) out of the build.gradle file and into gradle.properties file. This gives us a cleaner separation for build details and properties. When you run Gradle build it automatically pulls these values in and they are available in the BuildProperties bean in the Java main class as shown in the example above.

gradle.properties

group=com.xxx.examplesource
version=0.0.1-SNAPSHOT
gradleVersion=3.3