问:
Android Databinding in Sub-module
I have an application module, let's say "Test". The "Test" module depends on a sub-module B. Both enable databinding. In library module B, I create a simple activity using databinding, its purpose is for reusability, for example: I can create a base Login screen and use it in many apps later. Below is sample code in Package B.

```<code>package com.test.packageb

      open class MainActivity : AppCompatActivity() {

        lateinit var binding : ActivityMainBinding

        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        }
    }
</code>```

and then in "Test" module, I can just simply inherit MainActivity class to do customize things, like this:

```<code>class MainActivity1 : MainActivity(){

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }

    fun doSomething(){
        binding.rootLayout.setBackgroundResource(R.color.colorPrimary)
    }
}
</code>```

However, when I try to run "Test" application, I got this error

Error:(17, 9) Cannot access class
   'com.test.packageb.databinding.ActivityMainBinding'. Check your module
   classpath for missing or conflicting dependencies

  Error:(17, 17)
   Unresolved reference: rootLayout

What did I miss? Is there anything else need to be implemented?

Test app build.gradle

```<code>apply plugin: 'com.android.application'

apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-android-extensions'

android {
    compileSdkVersion 26
    buildToolsVersion "26.0.1"
    defaultConfig {
        applicationId "com.test.testapplication"
        minSdkVersion 15
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }

    dataBinding{
        enabled true
    }

    buildTypes {
        debug {

        }
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    kapt 'com.android.databinding:compiler:3.0.0-beta4'
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:26.0.2'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation('com.android.support.test.espresso:espresso-core:3.0.1', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
    implementation project(':packageb')
}
</code>```

Package B build.gradle

```<code>apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
android {
    compileSdkVersion 26
    buildToolsVersion "26.0.1"

    defaultConfig {
        minSdkVersion 15
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

    }
    dataBinding{
        enabled true
    }
    buildTypes {
        debug {
            minifyEnabled false
        }
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

}

dependencies {
    kapt 'com.android.databinding:compiler:3.0.0-beta4'
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:26.0.2'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation('com.android.support.test.espresso:espresso-core:3.0.1', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
}
</code>```

答:
Not sure if the issue is relevant to you but I managed to find some kind of the solution.

To make it work base class should have generic

```<code>class A<BINDING extends ViewDataBinding> {
    protected ABinding binding;

    void init(){
        binding = (ABinding) DataBindingUtil.setContentView(this, R.layout.a);
    }
}
</code>```

and pass the same binding to the child class from the submodule

```<code>class B<ABinding> {
    // you can use instance in this class
}
</code>```

The main problem here that you can't drastically change the UI, only hiding existing elements or add new at runtime. But I suppose in such case easier create a totally new class.

Title: Android Databinding in Sub-module

Body:
I have an application module, let's say "Test". The "Test" module depends on a sub-module B. Both enable databinding. In library module B, I create a simple activity using databinding, its purpose is for reusability, for example: I can create a base Login screen and use it in many apps later. Below is sample code in Package B.

package com.test.packageb

      open class MainActivity : AppCompatActivity() {

        lateinit var binding : ActivityMainBinding

        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        }
    }

and then in "Test" module, I can just simply inherit MainActivity class to do customize things, like this:

class MainActivity1 : MainActivity(){

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }

    fun doSomething(){
        binding.rootLayout.setBackgroundResource(R.color.colorPrimary)
    }
}

However, when I try to run "Test" application, I got this error

Error:(17, 9) Cannot access class
   'com.test.packageb.databinding.ActivityMainBinding'. Check your module
   classpath for missing or conflicting dependencies

  Error:(17, 17)
   Unresolved reference: rootLayout

What did I miss? Is there anything else need to be implemented?

Test app build.gradle

apply plugin: 'com.android.application'

apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-android-extensions'

android {
    compileSdkVersion 26
    buildToolsVersion "26.0.1"
    defaultConfig {
        applicationId "com.test.testapplication"
        minSdkVersion 15
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }

    dataBinding{
        enabled true
    }

    buildTypes {
        debug {

        }
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    kapt 'com.android.databinding:compiler:3.0.0-beta4'
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:26.0.2'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation('com.android.support.test.espresso:espresso-core:3.0.1', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
    implementation project(':packageb')
}

Package B build.gradle

apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
android {
    compileSdkVersion 26
    buildToolsVersion "26.0.1"

    defaultConfig {
        minSdkVersion 15
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

    }
    dataBinding{
        enabled true
    }
    buildTypes {
        debug {
            minifyEnabled false
        }
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

}

dependencies {
    kapt 'com.android.databinding:compiler:3.0.0-beta4'
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:26.0.2'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation('com.android.support.test.espresso:espresso-core:3.0.1', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
}

Body:
Not sure if the issue is relevant to you but I managed to find some kind of the solution.

To make it work base class should have generic

class A<BINDING extends ViewDataBinding> {
    protected ABinding binding;

    void init(){
        binding = (ABinding) DataBindingUtil.setContentView(this, R.layout.a);
    }
}

and pass the same binding to the child class from the submodule

class B<ABinding> {
    // you can use instance in this class
}

The main problem here that you can't drastically change the UI, only hiding existing elements or add new at runtime. But I suppose in such case easier create a totally new class.


来源: stackexchange

问:
How to get the extends of single area-type geojson file?
I need the google map to zoom into the extends of single area-type geojson-file.

I can load the geojson file to google maps and make it a data layer:

```<code>var myArea = new google.maps.Data();
myArea.loadGeoJson('myArea.geojson');
</code>```

I can set its settings:

```<code>myArea.setStyle({
strokeColor:"#F00",
fillColor:"#00F"
};
</code>```

But I cannot zoom the view according to its borders.

For "map.fitBounds()" to work, I would need to get the LatLngBounds of myArea.

How to get LatLngBounds from the geoJson-google map data layer?

I have found a lot of information for many other types of data (sheets, polygons, several layers, points, lines) but not one for single geojson-data layer.

I have tried for example:

```<code>var bounds = new google.maps.LatLngBounds();
map.data.forEach(function(myArea){
   myArea.getGeometry().forEachLatLng(function(latlng){
   bounds.extend(latlng);
   });
});
map.fitBounds(bounds);
</code>```

I have also tried to find the extends manually:

```<code>var SW = myArea.getSouthWest();
var NW = myArea.getNorthEast();
var bounds = new google.maps.LatLngBounds(SW,NE);
</code>```

With no success. I think the problem is in the concept of google data layer, but I haven't found anything to go around this problem. Any ideas how to get the bounds of single geojson google map data layer?

答:
forEach is asynchronous.  You need to set the map bounds either in each function call or when all are complete. This works for me:

```<code>map.data.forEach(function(myArea) {
  myArea.getGeometry().forEachLatLng(function(latlng) {
    bounds.extend(latlng);
    map.fitBounds(bounds);
  });
});
</code>```

proof of concept fiddle

code snippet:

function initialize() {
  // Create a simple map.
  features = [];
  map = new google.maps.Map(document.getElementById('map-canvas'), {
    zoom: 4,
    center: {
      lat: -28,
      lng: 137.883
    }
  });
  google.maps.event.addListener(map, 'click', function() {
    infowindow.close();
  });
  // process the loaded GeoJSON data.
  var bounds = new google.maps.LatLngBounds();
  map.data.addGeoJson(data);
  map.data.forEach(function(myArea) {
    myArea.getGeometry().forEachLatLng(function(latlng) {
      bounds.extend(latlng);
      map.fitBounds(bounds);
    });
  });
}

google.maps.event.addDomListener(window, 'load', initialize);
var data = {
  "type": "FeatureCollection",
  "features": [{
    "type": "Feature",
    "properties": {
      "name": "test",
      "desc": "test desc",
      "inDailyProgram": true,
      "color": "red"
    },
    "geometry": {
      "type": "Polygon",
      "coordinates": [
        [
          [
            35.188327,
            31.699929,
            0
          ],
          [
            35.187895,
            31.699669,
            0
          ],
          [
            35.187014,
            31.699729,
            0
          ],
          [
            35.186867,
            31.700016,
            0
          ],
          [
            35.186783,
            31.700395,
            0
          ],
          [
            35.186921,
            31.700787,
            0
          ],
          [
            35.187232,
            31.701291,
            0
          ],
          [
            35.18763,
            31.701844,
            0
          ],
          [
            35.187442,
            31.702328,
            0
          ],
          [
            35.18692,
            31.702779,
            0
          ],
          [
            35.187064,
            31.703654,
            0
          ],
          [
            35.187433,
            31.703794,
            0
          ],
          [
            35.188155,
            31.70344,
            0
          ],
          [
            35.188921,
            31.702917,
            0
          ],
          [
            35.189348,
            31.702887,
            0
          ],
          [
            35.189828,
            31.70302,
            0
          ],
          [
            35.190313,
            31.703443,
            0
          ],
          [
            35.190359,
            31.704104,
            0
          ],
          [
            35.190224,
            31.704348,
            0
          ],
          [
            35.189797,
            31.704585,
            0
          ],
          [
            35.189753,
            31.704948,
            0
          ],
          [
            35.189847,
            31.705107,
            0
          ],
          [
            35.190187,
            31.705015,
            0
          ],
          [
            35.190604,
            31.705041,
            0
          ],
          [
            35.190931,
            31.705171,
            0
          ],
          [
            35.191435,
            31.70526,
            0
          ],
          [
            35.191861,
            31.705231,
            0
          ],
          [
            35.192482,
            31.705008,
            0
          ],
          [
            35.192945,
            31.704893,
            0
          ],
          [
            35.193564,
            31.704449,
            0
          ],
          [
            35.192869,
            31.704004,
            0
          ],
          [
            35.192256,
            31.703737,
            0
          ],
          [
            35.191754,
            31.703371,
            0
          ],
          [
            35.191306,
            31.703001,
            0
          ],
          [
            35.190838,
            31.702632,
            0
          ],
          [
            35.190546,
            31.70221,
            0
          ],
          [
            35.190348,
            31.701739,
            0
          ],
          [
            35.190323,
            31.701589,
            0
          ],
          [
            35.189814,
            31.701624,
            0
          ],
          [
            35.189443,
            31.701456,
            0
          ],
          [
            35.189108,
            31.701217,
            0
          ],
          [
            35.188509,
            31.700359,
            0
          ],
          [
            35.188327,
            31.699929,
            0
          ]
        ]
      ]
    }
  }, {
    "type": "Feature",
    "properties": {
      "name": "test",
      "desc": "test desc",
      "inDailyProgram": true,
      "color": "red"
    },
    "geometry": {
      "type": "Polygon",
      "coordinates": [
        [
          [
            35.209224,
            31.718497,
            0
          ],
          [
            35.209775,
            31.718459,
            0
          ],
          [
            35.210282,
            31.717788,
            0
          ],
          [
            35.210741,
            31.71723,
            0
          ],
          [
            35.21132,
            31.716803,
            0
          ],
          [
            35.211748,
            31.716193,
            0
          ],
          [
            35.212124,
            31.715632,
            0
          ],
          [
            35.212315,
            31.714798,
            0
          ],
          [
            35.21227,
            31.714137,
            0
          ],
          [
            35.212647,
            31.713599,
            0
          ],
          [
            35.21316,
            31.713412,
            0
          ],
          [
            35.214134,
            31.713095,
            0
          ],
          [
            35.215018,
            31.712675,
            0
          ],
          [
            35.215822,
            31.7119,
            0
          ],
          [
            35.21577,
            31.711156,
            0
          ],
          [
            35.215564,
            31.710175,
            0
          ],
          [
            35.215104,
            31.709128,
            0
          ],
          [
            35.21473,
            31.708518,
            0
          ],
          [
            35.214301,
            31.707911,
            0
          ],
          [
            35.214086,
            31.707207,
            0
          ],
          [
            35.213709,
            31.706154,
            0
          ],
          [
            35.213519,
            31.705807,
            0
          ],
          [
            35.212415,
            31.705441,
            0
          ],
          [
            35.211313,
            31.705103,
            0
          ],
          [
            35.210114,
            31.704964,
            0
          ],
          [
            35.20915,
            31.705031,
            0
          ],
          [
            35.208402,
            31.704612,
            0
          ],
          [
            35.207939,
            31.704119,
            0
          ],
          [
            35.207657,
            31.704636,
            0
          ],
          [
            35.207123,
            31.704922,
            0
          ],
          [
            35.206421,
            31.705164,
            0
          ],
          [
            35.205969,
            31.70529,
            0
          ],
          [
            35.205926,
            31.705613,
            0
          ],
          [
            35.205553,
            31.705808,
            0
          ],
          [
            35.205577,
            31.706157,
            0
          ],
          [
            35.205694,
            31.706459,
            0
          ],
          [
            35.205902,
            31.70686,
            0
          ],
          [
            35.206285,
            31.707193,
            0
          ],
          [
            35.206113,
            31.707375,
            0
          ],
          [
            35.206005,
            31.707544,
            0
          ],
          [
            35.206139,
            31.707746,
            0
          ],
          [
            35.206713,
            31.708194,
            0
          ],
          [
            35.207228,
            31.708428,
            0
          ],
          [
            35.207474,
            31.708798,
            0
          ],
          [
            35.207463,
            31.709435,
            0
          ],
          [
            35.207359,
            31.709878,
            0
          ],
          [
            35.207255,
            31.710418,
            0
          ],
          [
            35.207232,
            31.71089,
            0
          ],
          [
            35.20712,
            31.711257,
            0
          ],
          [
            35.206802,
            31.711473,
            0
          ],
          [
            35.206408,
            31.711645,
            0
          ],
          [
            35.206061,
            31.711753,
            0
          ],
          [
            35.205639,
            31.711857,
            0
          ],
          [
            35.205398,
            31.711766,
            0
          ],
          [
            35.205213,
            31.711698,
            0
          ],
          [
            35.205289,
            31.711992,
            0
          ],
          [
            35.205266,
            31.712464,
            0
          ],
          [
            35.205096,
            31.712808,
            0
          ],
          [
            35.204885,
            31.713348,
            0
          ],
          [
            35.204829,
            31.71414,
            0
          ],
          [
            35.204947,
            31.714644,
            0
          ],
          [
            35.205089,
            31.715104,
            0
          ],
          [
            35.205489,
            31.715687,
            0
          ],
          [
            35.205906,
            31.716113,
            0
          ],
          [
            35.206464,
            31.716586,
            0
          ],
          [
            35.20684,
            31.716421,
            0
          ],
          [
            35.207254,
            31.716005,
            0
          ],
          [
            35.207524,
            31.715517,
            0
          ],
          [
            35.207901,
            31.714965,
            0
          ],
          [
            35.207949,
            31.714464,
            0
          ],
          [
            35.208022,
            31.713919,
            0
          ],
          [
            35.20835,
            31.713855,
            0
          ],
          [
            35.208542,
            31.714229,
            0
          ],
          [
            35.208847,
            31.71465,
            0
          ],
          [
            35.209151,
            31.715044,
            0
          ],
          [
            35.20929,
            31.71545,
            0
          ],
          [
            35.209362,
            31.715694,
            0
          ],
          [
            35.209315,
            31.716214,
            0
          ],
          [
            35.209177,
            31.716619,
            0
          ],
          [
            35.209031,
            31.716906,
            0
          ],
          [
            35.208958,
            31.717132,
            0
          ],
          [
            35.208853,
            31.717333,
            0
          ],
          [
            35.208878,
            31.717691,
            0
          ],
          [
            35.209224,
            31.718497,
            0
          ]
        ]
      ]
    }
  }]
};```
<pre class="snippet-code-css lang-css prettyprint-override"><code>html,
body,
#map-canvas {
  height: 100%;
  margin: 0px;
  padding: 0px;
  width: 100%;
}</code>```

```

ContentLicense: CC BY-SA 3.0

Body:
I need the google map to zoom into the extends of single area-type geojson-file.

I can load the geojson file to google maps and make it a data layer:

var myArea = new google.maps.Data();
myArea.loadGeoJson('myArea.geojson');

I can set its settings:

myArea.setStyle({
strokeColor:"#F00",
fillColor:"#00F"
};

But I cannot zoom the view according to its borders.

For "map.fitBounds()" to work, I would need to get the LatLngBounds of myArea.

How to get LatLngBounds from the geoJson-google map data layer?

I have found a lot of information for many other types of data (sheets, polygons, several layers, points, lines) but not one for single geojson-data layer.

I have tried for example:

var bounds = new google.maps.LatLngBounds();
map.data.forEach(function(myArea){
   myArea.getGeometry().forEachLatLng(function(latlng){
   bounds.extend(latlng);
   });
});
map.fitBounds(bounds);

I have also tried to find the extends manually:

var SW = myArea.getSouthWest();
var NW = myArea.getNorthEast();
var bounds = new google.maps.LatLngBounds(SW,NE);

With no success. I think the problem is in the concept of google data layer, but I haven't found anything to go around this problem. Any ideas how to get the bounds of single geojson google map data layer?

Body:
forEach is asynchronous.  You need to set the map bounds either in each function call or when all are complete. This works for me:

map.data.forEach(function(myArea) {
  myArea.getGeometry().forEachLatLng(function(latlng) {
    bounds.extend(latlng);
    map.fitBounds(bounds);
  });
});

proof of concept fiddle

code snippet:

function initialize() {
  // Create a simple map.
  features = [];
  map = new google.maps.Map(document.getElementById('map-canvas'), {
    zoom: 4,
    center: {
      lat: -28,
      lng: 137.883
    }
  });
  google.maps.event.addListener(map, 'click', function() {
    infowindow.close();
  });
  // process the loaded GeoJSON data.
  var bounds = new google.maps.LatLngBounds();
  map.data.addGeoJson(data);
  map.data.forEach(function(myArea) {
    myArea.getGeometry().forEachLatLng(function(latlng) {
      bounds.extend(latlng);
      map.fitBounds(bounds);
    });
  });
}

google.maps.event.addDomListener(window, 'load', initialize);
var data = {
  "type": "FeatureCollection",
  "features": [{
    "type": "Feature",
    "properties": {
      "name": "test",
      "desc": "test desc",
      "inDailyProgram": true,
      "color": "red"
    },
    "geometry": {
      "type": "Polygon",
      "coordinates": [
        [
          [
            35.188327,
            31.699929,
            0
          ],
          [
            35.187895,
            31.699669,
            0
          ],
          [
            35.187014,
            31.699729,
            0
          ],
          [
            35.186867,
            31.700016,
            0
          ],
          [
            35.186783,
            31.700395,
            0
          ],
          [
            35.186921,
            31.700787,
            0
          ],
          [
            35.187232,
            31.701291,
            0
          ],
          [
            35.18763,
            31.701844,
            0
          ],
          [
            35.187442,
            31.702328,
            0
          ],
          [
            35.18692,
            31.702779,
            0
          ],
          [
            35.187064,
            31.703654,
            0
          ],
          [
            35.187433,
            31.703794,
            0
          ],
          [
            35.188155,
            31.70344,
            0
          ],
          [
            35.188921,
            31.702917,
            0
          ],
          [
            35.189348,
            31.702887,
            0
          ],
          [
            35.189828,
            31.70302,
            0
          ],
          [
            35.190313,
            31.703443,
            0
          ],
          [
            35.190359,
            31.704104,
            0
          ],
          [
            35.190224,
            31.704348,
            0
          ],
          [
            35.189797,
            31.704585,
            0
          ],
          [
            35.189753,
            31.704948,
            0
          ],
          [
            35.189847,
            31.705107,
            0
          ],
          [
            35.190187,
            31.705015,
            0
          ],
          [
            35.190604,
            31.705041,
            0
          ],
          [
            35.190931,
            31.705171,
            0
          ],
          [
            35.191435,
            31.70526,
            0
          ],
          [
            35.191861,
            31.705231,
            0
          ],
          [
            35.192482,
            31.705008,
            0
          ],
          [
            35.192945,
            31.704893,
            0
          ],
          [
            35.193564,
            31.704449,
            0
          ],
          [
            35.192869,
            31.704004,
            0
          ],
          [
            35.192256,
            31.703737,
            0
          ],
          [
            35.191754,
            31.703371,
            0
          ],
          [
            35.191306,
            31.703001,
            0
          ],
          [
            35.190838,
            31.702632,
            0
          ],
          [
            35.190546,
            31.70221,
            0
          ],
          [
            35.190348,
            31.701739,
            0
          ],
          [
            35.190323,
            31.701589,
            0
          ],
          [
            35.189814,
            31.701624,
            0
          ],
          [
            35.189443,
            31.701456,
            0
          ],
          [
            35.189108,
            31.701217,
            0
          ],
          [
            35.188509,
            31.700359,
            0
          ],
          [
            35.188327,
            31.699929,
            0
          ]
        ]
      ]
    }
  }, {
    "type": "Feature",
    "properties": {
      "name": "test",
      "desc": "test desc",
      "inDailyProgram": true,
      "color": "red"
    },
    "geometry": {
      "type": "Polygon",
      "coordinates": [
        [
          [
            35.209224,
            31.718497,
            0
          ],
          [
            35.209775,
            31.718459,
            0
          ],
          [
            35.210282,
            31.717788,
            0
          ],
          [
            35.210741,
            31.71723,
            0
          ],
          [
            35.21132,
            31.716803,
            0
          ],
          [
            35.211748,
            31.716193,
            0
          ],
          [
            35.212124,
            31.715632,
            0
          ],
          [
            35.212315,
            31.714798,
            0
          ],
          [
            35.21227,
            31.714137,
            0
          ],
          [
            35.212647,
            31.713599,
            0
          ],
          [
            35.21316,
            31.713412,
            0
          ],
          [
            35.214134,
            31.713095,
            0
          ],
          [
            35.215018,
            31.712675,
            0
          ],
          [
            35.215822,
            31.7119,
            0
          ],
          [
            35.21577,
            31.711156,
            0
          ],
          [
            35.215564,
            31.710175,
            0
          ],
          [
            35.215104,
            31.709128,
            0
          ],
          [
            35.21473,
            31.708518,
            0
          ],
          [
            35.214301,
            31.707911,
            0
          ],
          [
            35.214086,
            31.707207,
            0
          ],
          [
            35.213709,
            31.706154,
            0
          ],
          [
            35.213519,
            31.705807,
            0
          ],
          [
            35.212415,
            31.705441,
            0
          ],
          [
            35.211313,
            31.705103,
            0
          ],
          [
            35.210114,
            31.704964,
            0
          ],
          [
            35.20915,
            31.705031,
            0
          ],
          [
            35.208402,
            31.704612,
            0
          ],
          [
            35.207939,
            31.704119,
            0
          ],
          [
            35.207657,
            31.704636,
            0
          ],
          [
            35.207123,
            31.704922,
            0
          ],
          [
            35.206421,
            31.705164,
            0
          ],
          [
            35.205969,
            31.70529,
            0
          ],
          [
            35.205926,
            31.705613,
            0
          ],
          [
            35.205553,
            31.705808,
            0
          ],
          [
            35.205577,
            31.706157,
            0
          ],
          [
            35.205694,
            31.706459,
            0
          ],
          [
            35.205902,
            31.70686,
            0
          ],
          [
            35.206285,
            31.707193,
            0
          ],
          [
            35.206113,
            31.707375,
            0
          ],
          [
            35.206005,
            31.707544,
            0
          ],
          [
            35.206139,
            31.707746,
            0
          ],
          [
            35.206713,
            31.708194,
            0
          ],
          [
            35.207228,
            31.708428,
            0
          ],
          [
            35.207474,
            31.708798,
            0
          ],
          [
            35.207463,
            31.709435,
            0
          ],
          [
            35.207359,
            31.709878,
            0
          ],
          [
            35.207255,
            31.710418,
            0
          ],
          [
            35.207232,
            31.71089,
            0
          ],
          [
            35.20712,
            31.711257,
            0
          ],
          [
            35.206802,
            31.711473,
            0
          ],
          [
            35.206408,
            31.711645,
            0
          ],
          [
            35.206061,
            31.711753,
            0
          ],
          [
            35.205639,
            31.711857,
            0
          ],
          [
            35.205398,
            31.711766,
            0
          ],
          [
            35.205213,
            31.711698,
            0
          ],
          [
            35.205289,
            31.711992,
            0
          ],
          [
            35.205266,
            31.712464,
            0
          ],
          [
            35.205096,
            31.712808,
            0
          ],
          [
            35.204885,
            31.713348,
            0
          ],
          [
            35.204829,
            31.71414,
            0
          ],
          [
            35.204947,
            31.714644,
            0
          ],
          [
            35.205089,
            31.715104,
            0
          ],
          [
            35.205489,
            31.715687,
            0
          ],
          [
            35.205906,
            31.716113,
            0
          ],
          [
            35.206464,
            31.716586,
            0
          ],
          [
            35.20684,
            31.716421,
            0
          ],
          [
            35.207254,
            31.716005,
            0
          ],
          [
            35.207524,
            31.715517,
            0
          ],
          [
            35.207901,
            31.714965,
            0
          ],
          [
            35.207949,
            31.714464,
            0
          ],
          [
            35.208022,
            31.713919,
            0
          ],
          [
            35.20835,
            31.713855,
            0
          ],
          [
            35.208542,
            31.714229,
            0
          ],
          [
            35.208847,
            31.71465,
            0
          ],
          [
            35.209151,
            31.715044,
            0
          ],
          [
            35.20929,
            31.71545,
            0
          ],
          [
            35.209362,
            31.715694,
            0
          ],
          [
            35.209315,
            31.716214,
            0
          ],
          [
            35.209177,
            31.716619,
            0
          ],
          [
            35.209031,
            31.716906,
            0
          ],
          [
            35.208958,
            31.717132,
            0
          ],
          [
            35.208853,
            31.717333,
            0
          ],
          [
            35.208878,
            31.717691,
            0
          ],
          [
            35.209224,
            31.718497,
            0
          ]
        ]
      ]
    }
  }]
};

html,
body,
#map-canvas {
  height: 100%;
  margin: 0px;
  padding: 0px;
  width: 100%;
}

<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="map-canvas"></div>

ContentLicense: CC BY-SA 4.0


问:
How to generate the similar folding effect as Gmail in JavaScript
I assume Gmail used JavaScript to implement the folding effect for a particular email thread. The effect I am talking about is: after you choose a particular email thread by clicking on it, then you will see that only the latest email is shown, with all the previous emails in a folded state. Only when you click on the folding section, they will expand, but still only showing a snippet of them. Then you click on each individual section, you can read the full message. How can one do this? Many thanks.</p>

答:
I'm assuming you're talking about the effect where previous messages in a thread are collapsed so just the sender's name and the first few words of the message are shown.

How I would do it: For every message other than unread ones, load the sender's name and the first n characters of the body. Display all the previous messages in a table with an onclick listener on each row. When the row is clicked, use Ajax to retrieve the full message from the server and replace the truncated message with the full one. If the user clicks the row again, hide the full message except for the first n characters. In GMail's case, the unread and/or most recent messages are loaded in full when you click on an e-mail thread.

A simpler way to do it would be: Load all messages in full when the page loads, but hide all but n characters of the full message until the row is clicked. This will make the coding easier since you don't have to mess with Ajax and saving space on the screen, but wont give you the other benefits of less bandwidth usage.

ContentLicense: CC BY-SA 2.5


问:
how to convert the passed in price value to cents before saving to database?
I have create action that will create a karaoke object.

```<code>  def create
    @user = current_user
    @karaoke = @user.karaokes.build(karaoke_params)

    respond_to do |format|
      if @karaoke.save
        format.html { redirect_to @karaoke, notice: 'Karaoke was successfully created.' }
        format.json { render :show, status: :created, location: @karaoke }
      else
        format.html { render :new }
        format.json { render json: @karaoke.errors, status: :unprocessable_entity }
      end
    end
  end
</code>```

i have allowed the following parameters to bind

```<code># Never trust parameters from the scary internet, only allow the white list through.
def karaoke_params
  params.require(:karaoke).permit(:name, :audio, :price)
end
</code>```

Now what i want to do is in database the price field is of type integers because i am saving money as cents in database. So, in create action, before saving the user parameter for price, i want to multiply by 100 to convert it to cents. How can i multiply the passed in price form value by 100 and assign it to price field of Karaoke object? I appreciate any help! Thanks!

The form to accept the karaoke parameters are as follows

```<code><%= form_for(@karaoke) do |f| %>
  <% if @karaoke.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@karaoke.errors.count, "error") %> prohibited this karaoke from being saved:</h2>

      <ul>
      <% @karaoke.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :name %><br>
    <%= f.text_field :name %>
  </div>

  <div class="field">
    <%= f.label :price %><br>
    <%= f.text_field :price %>
  </div>

  <div class="field">
    <%= f.label :audio %><br>
    <%= f.file_field :audio %>
  </div>

  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>
</code>```

答:
If what you want is to convert the price passed in from the controller to an Integer (or a float in your case) when you save it to the database, you can use money-rails gem:

https://github.com/RubyMoney/money-rails

Body:
I have create action that will create a karaoke object.

  def create
    @user = current_user
    @karaoke = @user.karaokes.build(karaoke_params)

    respond_to do |format|
      if @karaoke.save
        format.html { redirect_to @karaoke, notice: 'Karaoke was successfully created.' }
        format.json { render :show, status: :created, location: @karaoke }
      else
        format.html { render :new }
        format.json { render json: @karaoke.errors, status: :unprocessable_entity }
      end
    end
  end

i have allowed the following parameters to bind

# Never trust parameters from the scary internet, only allow the white list through.
def karaoke_params
  params.require(:karaoke).permit(:name, :audio, :price)
end

Now what i want to do is in database the price field is of type integers because i am saving money as cents in database. So, in create action, before saving the user parameter for price, i want to multiply by 100 to convert it to cents. How can i multiply the passed in price form value by 100 and assign it to price field of Karaoke object? I appreciate any help! Thanks!

The form to accept the karaoke parameters are as follows

<%= form_for(@karaoke) do |f| %>
  <% if @karaoke.errors.any? %>

<%= pluralize(@karaoke.errors.count, "error") %> prohibited this karaoke from being saved:

      <% @karaoke.errors.full_messages.each do |message| %>

<%= message %>

      <% end %>

  <% end %>

    <%= f.label :name %>

    <%= f.text_field :name %>

    <%= f.label :price %>

    <%= f.text_field :price %>

    <%= f.label :audio %>

    <%= f.file_field :audio %>

    <%= f.submit %>

<% end %>


问:
AWS SNS, Apple Push Services, I get invalid platform credentials errors even after renewing certs and uploading associated .p12 creds
I'm running into an issue where I'm seeing delivery failures to iOS endpoints only with the "Platform application credentials are not valid" error.  This is for our app that's been in the app store for years.  I've cleaned out all my certs, renewed them, uploaded them, and updated my AWS SNS platform creds to the new .p12 file .  I have double confirmed all the certs expire 1 year from now. I've also confirmed that I created certs for production level push notifications and app distribution.

This week, I managed to get push notifications working twice.  On Day 1, I go through the renewing certs, etc., test push notifications on a variety of iphones, then wait until the next day and notice delivery failures due to bad platform credentials.  On Day 2, I go through the same steps to the point where push notifications are working again.  Then, the next day I see delivery failures due to the same reason. After that happens the platform is disabled and push notifications fail to be delivered.

In both cases, something has happened overnight that causes AWS SNS to think the APNS certs are invalid. Has someone experienced the same thing?

Thanks for your help!

dzincolorado

答:
I figured out that my APS certificate wasn't the correct one.  After revoking it and using the correct .certSigningRequest file, I re-downloaded the .cer file, double clicked it and noticed that it created a new item in Keychain Access 'My Certificates' section.  Removing the other APS certs and using this new one, I exported it as a .p12 and updated my AWS SNS creds and it's now working.

Edit: Using a bad cert, it is odd that notifications worked for about a day before they started failing.

Thanks.


问:
Load external jar with system class loader in Jetty
I'm using Jetty (both 8 and 9) along with LZ4 compression and I'd like to use the native implementation of LZ4 which is a native binding to a C library. To accomplish this the LZ4 classes should be loaded with the system class loader.

So my question is, how to load an external jar with the system class loader in Jetty.

Placing the lib into $jetty.home/lib/ext didn't help as it was loaded with the extension class loader instead of the system one.

答:
When Jetty starts, it instantiates a custom ClassLoader to conform to the various spec requirements (JSP, CDI, OSGi, Java9, etc.)

The System ClassLoader basically only exists to hold the JVM (and optionally the XBootClasspath and JVM extension) related jars.

The Jetty lib/ext is not related to the JVM extension mechanisms, don't get those 2 confused.

Perhaps your LZ4 compression jars need to be loaded via the various extension mechanisms of the JVM, before Jetty gets involved with the ClassLoaders.

Something like ...

$ java <load_LZ4_jars_via_ext_stuff> -jar start.jar
# example
$ java -Djava.ext.dirs=/full/path/to/lz4.jar -jar start.jar
```

Note: Java 9 changes everything again, so whatever you learn now will have to be forgotten and you'll need to use the new Java 9 techniques (see JEP 220 and its deprecation/replacement of JVM extension behaviors and near elimination of the concept of a System ClassLoader)

Body:
When Jetty starts, it instantiates a custom ClassLoader to conform to the various spec requirements (JSP, CDI, OSGi, Java9, etc.)

The System ClassLoader basically only exists to hold the JVM (and optionally the XBootClasspath and JVM extension) related jars.

The Jetty lib/ext is not related to the JVM extension mechanisms, don't get those 2 confused.

Perhaps your LZ4 compression jars need to be loaded via the various extension mechanisms of the JVM, before Jetty gets involved with the ClassLoaders.

Something like ...

$ java <load_LZ4_jars_via_ext_stuff> -jar start.jar
# example
$ java -Djava.ext.dirs=/full/path/to/lz4.jar -jar start.jar

Note: Java 9 changes everything again, so whatever you learn now will have to be forgotten and you'll need to use the new Java 9 techniques (see JEP 220 and its deprecation/replacement of JVM extension behaviors and near elimination of the concept of a System ClassLoader)


问:
Sqlite encryption for Android
I have an Android app that has been already developed using SQLite.
The DB is quite large (over 100 Megs) so it can be deployed only on the SD card.
The data inside the DB is sensitive so for this reason we need to encrypt the DB.
The default SQLite binary on the phone does not allow encryption or to add a plug in (extensions).
I manage to compile the SQLite using NDK with the encryption extension (I am calling this SQLiteS - from secure) but I still need to figure out how to copy the Sqlite API and bind it to the new SQLiteS binary.
The idea is to not change the already developed code using the SQLite default API excepting the package name.
Any idea of how can I accomplish this ?</p>

答:
Tryp getting a native jdbcsqlite driver onto Android.
which makes sqlite3_* calls(JNI).

Use the aapt tool to link the library(sqliteS) into the .apk file.

Also, you can change the sqlite3_* names(in SQLiteS.so you built) so that it doesnt refer to sqlite.so file provided by android.

Let me know the solution.

Title: Sqlite encryption for Android


问:
neo4j : quick search of a type of relationship between nodes in a list
We have a graph with different relationships and a list of nodes. We would like to know the relationships of type "E" between the nodes of this list.

Presently we do like this :

```<code>With ["0","1","2","10"] as list1
MATCH p=(x)-[:E]-(y)
WHERE (x.frag IN list1) AND (y.frag IN list1)
RETURN p
</code>```

It  works for a few nodes but it becomes very slow even with only 100 nodes.

Is there a method to get quicker this result with APOC for example ?

Sincerely.

答:
You may see a big performance boost simply by using labels and indexing your params.

MATCH p=(x:NODE_LABELX)-[:E]-(y:NODE_LABELY)

 Also check out : https://graphaware.com/neo4j/2015/01/16/neo4j-graph-model-design-labels-versus-indexed-properties.html

Body:
We have a graph with different relationships and a list of nodes. We would like to know the relationships of type "E" between the nodes of this list.

Presently we do like this :

With ["0","1","2","10"] as list1
MATCH p=(x)-[:E]-(y)
WHERE (x.frag IN list1) AND (y.frag IN list1)
RETURN p

It  works for a few nodes but it becomes very slow even with only 100 nodes.

Is there a method to get quicker this result with APOC for example ?

Sincerely.


问:
Joining 2 tables with limited joining conditions
I am quite new to SQL and I am trying to join two tables,

Table A:

```<code>ID  Amount    Bank
123  50        Barclays
123  50        tesco
123  50        HSBC
123  100       LLyods
123  200       MBNA
</code>```

Table B:

```<code>ID  Amount    Bank
123  50        aa
123  50        bb
123  50        cc
123  100       dd
123  200       ee
</code>```

Note that: in table B the bank name is the same as table A but it is written in a different format, so I can't join on this.

the script i am running is:

```<code>Select A.*, B.*
FROM TableA  A
Left Join TableB B
on A.ID = B.ID AND A.AMOUNT = B.AMOUNT
;
</code>```

The result i get is,

```<code>ID  Amount  Bank    ID  AMOUNT  BANK
123 50  Barclays    123 50      aa
123 50  Barclays    123 50      bb
123 50  Barclays    123 50      cc
123 50  tesco       123 50      aa
123 50  tesco       123 50      bb
123 50  tesco       123 50      cc
123 50  HSBC        123 50      aa
123 50  HSBC        123 50      bb
123 50  HSBC        123 50      cc
123 100 LLyods      123 100     dd
123 200 MBNA        123 200     ee
</code>```

what i want to get is,

```<code>ID  Amount  Bank    ID  AMOUNT  BANK
123 50  Barclays    123 50      aa
123 50  tesco       123 50      bb
123 50  HSBC        123 50      cc
123 100 LLyods      123 100     dd
123 200 MBNA        123 200     ee
</code>```

I get the issue is that it joining each row of table A to the rows of table B which meet the join conditions; unfortunately the table B has no other unique values that I can use as a join condition;

Can the community please see if you can think of something, I would very much appreciate it. Thank you :)

答:
you can use inner join for your desired result</p>

```<code>Select A.*
B.*
FROM TableA  A
 INNER JOIN TableB B
   on A.ID = B.ID
    AND A.AMOUNT = B.AMOUNT
;
</code>```

Body:
I am quite new to SQL and I am trying to join two tables,

Table A:

ID  Amount    Bank
123  50        Barclays
123  50        tesco
123  50        HSBC
123  100       LLyods
123  200       MBNA

Table B:

ID  Amount    Bank
123  50        aa
123  50        bb
123  50        cc
123  100       dd
123  200       ee

Note that: in table B the bank name is the same as table A but it is written in a different format, so I can't join on this.

the script i am running is:

Select A.*, B.*
FROM TableA  A
Left Join TableB B
on A.ID = B.ID AND A.AMOUNT = B.AMOUNT
;

The result i get is,

ID  Amount  Bank    ID  AMOUNT  BANK
123 50  Barclays    123 50      aa
123 50  Barclays    123 50      bb
123 50  Barclays    123 50      cc
123 50  tesco       123 50      aa
123 50  tesco       123 50      bb
123 50  tesco       123 50      cc
123 50  HSBC        123 50      aa
123 50  HSBC        123 50      bb
123 50  HSBC        123 50      cc
123 100 LLyods      123 100     dd
123 200 MBNA        123 200     ee

what i want to get is,

ID  Amount  Bank    ID  AMOUNT  BANK
123 50  Barclays    123 50      aa
123 50  tesco       123 50      bb
123 50  HSBC        123 50      cc
123 100 LLyods      123 100     dd
123 200 MBNA        123 200     ee

I get the issue is that it joining each row of table A to the rows of table B which meet the join conditions; unfortunately the table B has no other unique values that I can use as a join condition;

Can the community please see if you can think of something, I would very much appreciate it. Thank you :)

Body:
you can use inner join for your desired result

Select A.*
B.*
FROM TableA  A
 INNER JOIN TableB B
   on A.ID = B.ID
    AND A.AMOUNT = B.AMOUNT
;


问:
Android project hangs on deploy
I'm attempting a very novice Xamarin Forms app and it builds in an instant, but then seems to hang when deploying to the emulator, i.e. I aborted after well over 20 minutes. In the output window, under Xamarin Diagnostics, I get the following last few entries:

```<code>[I:]:                     Found Android SDK. API levels: 22, 26
[I:]:                     Tracking android devices started
[D:]:                     TrackDeviceTask got: emulator-5554    device
[I:]:                     Got new device list from adb with 1 devices
[D:RunShellCommand]:      emulator-5554 getprop
[D:]:                     Tracking avd started
[D:]:                     avd watcher *.ini path: 'C:\Users\brady\.android\avd'
[D:RunShellCommand]:      emulator-5554 getprop
[D:]:                     avd watcher: got device list from avd with 1 devices
</code>```

This is my debugging target:

My Xamarin Forms projects were working about a month ago, but since then I experimented with nearly every other Android enabled IDE and maybe that somehow affected my AVD.

What can I look at or change to correct this problem?

I have since learnt I must use the Emulator Manager to create an emulator. Now when I try and open the Emulator Manager, it says I must use the SDK Manager to downgrade the SDK tools to v25.x. When I open the SDK Manager, it says it must be updated, and presents an Update button. Pressing the button directs me to a download page with no download button:

The Get Started button takes me to the docs page for the SDK Manager. Now how am I supposed to update this problem child SDK Manager?

答:
If your project compiles but won't deploy, then Visual Studio is probably not connected to your emulator.

I would recommend using Visual Studio Emulator for Android as it is much faster and has worked on every device I have used it on.

On some computers Visual Studio does not connect to the emulator when it starts. A workaround is to find the devices IP address and connect to it manually:

First open Visual Studio Emulator for Android and start one of the emulators

Next in the emulator select tools, a popup window will open, select the 'Network' tab and under the list of network adaptors note down the preferred IP address. Here my one is 169.254.160.177.

Then in Visual Studio open 'Android Adb Command Prommpt' and enter adb connect 169.254.160.177

Now that Visual Studio is connected to the emulator the application will be deployed to the device. You will need to connect to the emulator every time you restart it (don't close it while your programming).

Note: On some computers, Visual Studio will connect to the emulator automatically.

Title: Android project hangs on deploy

Body:
I'm attempting a very novice Xamarin Forms app and it builds in an instant, but then seems to hang when deploying to the emulator, i.e. I aborted after well over 20 minutes. In the output window, under Xamarin Diagnostics, I get the following last few entries:

[I:]:                     Found Android SDK. API levels: 22, 26
[I:]:                     Tracking android devices started
[D:]:                     TrackDeviceTask got: emulator-5554    device
[I:]:                     Got new device list from adb with 1 devices
[D:RunShellCommand]:      emulator-5554 getprop
[D:]:                     Tracking avd started
[D:]:                     avd watcher *.ini path: 'C:\Users\brady\.android\avd'
[D:RunShellCommand]:      emulator-5554 getprop
[D:]:                     avd watcher: got device list from avd with 1 devices

This is my debugging target:

My Xamarin Forms projects were working about a month ago, but since then I experimented with nearly every other Android enabled IDE and maybe that somehow affected my AVD.

What can I look at or change to correct this problem?

I have since learnt I must use the Emulator Manager to create an emulator. Now when I try and open the Emulator Manager, it says I must use the SDK Manager to downgrade the SDK tools to v25.x. When I open the SDK Manager, it says it must be updated, and presents an Update button. Pressing the button directs me to a download page with no download button:

The Get Started button takes me to the docs page for the SDK Manager. Now how am I supposed to update this problem child SDK Manager?


问:
Issue with recycler view inside constraint layout
I'm trying to create a bottom sheet dialog based on a complex layout.
What I have to achieve is a dialog with an header layout, a recycler view with a list of element and a bottom bar with a couple of buttons.
Here is my code:

```<code><?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <!-- Layout injected inside this linear layout container programmatically -->
        <LinearLayout
            android:id="@+id/header_dialog_container"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintBottom_toTopOf="@id/form_dialog_recycler_view"
            app:layout_constraintTop_toTopOf="parent" />

        <android.support.v7.widget.RecyclerView
            android:id="@+id/form_dialog_recycler_view"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:scrollbars="vertical"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            app:layout_constraintBottom_toTopOf="@id/bottom_sheet_container_buttons"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/header_dialog_container" />

        <LinearLayout
            android:id="@+id/bottom_sheet_container_buttons"
            android:layout_width="match_parent"
            android:layout_height="60dp"
            android:orientation="horizontal"
            app:layout_constraintBottom_toBottomOf="parent">

            <Button
                android:id="@+id/dialog_sheet_button_reset"
                style="@style/ActionSheetTitle"
                android:layout_width="0dp"
                android:layout_height="60dp"
                android:layout_weight="0.5"
                android:background="@color/bottomBarContainerColor"
                android:text="@string/general_reset"
                android:textColor="@color/dangerColor" />

            <Button
                android:id="@+id/dialog_sheet_button_close"
                style="@style/ActionSheetTitle"
                android:layout_width="0dp"
                android:layout_height="60dp"
                android:layout_weight="0.5"
                android:background="@color/bottomBarContainerColor"
                android:text="@string/general_close" />

        </LinearLayout>
    </android.support.constraint.ConstraintLayout>
</layout>
</code>```

Unfortunately my recycler view height is always equal to zero. I tried to change android:layout_height="0dp" to android:layout_height="wrap_content" but as expected it goes below the bottom container. Am I missing something?

答:
Try this code:</p>

```<code><?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <!-- Layout injected inside this linear layout container programmatically -->
        <LinearLayout
            android:id="@+id/header_dialog_container"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintBottom_toTopOf="@id/form_dialog_recycler_view"
            app:layout_constraintTop_toTopOf="parent" />

        <android.support.v7.widget.RecyclerView
            android:id="@+id/form_dialog_recycler_view"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:scrollbars="vertical"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            app:layout_constraintBottom_toTopOf="@id/bottom_sheet_container_buttons"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/header_dialog_container" />

        <LinearLayout
            android:id="@+id/bottom_sheet_container_buttons"
            android:layout_width="match_parent"
            android:layout_height="60dp"
            android:orientation="horizontal"
            app:layout_constraintBottom_toBottomOf="parent">

            <Button
                android:id="@+id/dialog_sheet_button_reset"
                style="@style/ActionSheetTitle"
                android:layout_width="0dp"
                android:layout_height="60dp"
                android:layout_weight="0.5"
                android:background="@color/bottomBarContainerColor"
                android:text="@string/general_reset"
                android:textColor="@color/dangerColor" />

            <Button
                android:id="@+id/dialog_sheet_button_close"
                style="@style/ActionSheetTitle"
                android:layout_width="0dp"
                android:layout_height="60dp"
                android:layout_weight="0.5"
                android:background="@color/bottomBarContainerColor"
                android:text="@string/general_close" />

        </LinearLayout>
    </android.support.constraint.ConstraintLayout>
</layout>
</code>```

Body:
I'm trying to create a bottom sheet dialog based on a complex layout.
What I have to achieve is a dialog with an header layout, a recycler view with a list of element and a bottom bar with a couple of buttons.
Here is my code:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <LinearLayout
            android:id="@+id/header_dialog_container"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintBottom_toTopOf="@id/form_dialog_recycler_view"
            app:layout_constraintTop_toTopOf="parent" />

        <android.support.v7.widget.RecyclerView
            android:id="@+id/form_dialog_recycler_view"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:scrollbars="vertical"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            app:layout_constraintBottom_toTopOf="@id/bottom_sheet_container_buttons"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/header_dialog_container" />

        <LinearLayout
            android:id="@+id/bottom_sheet_container_buttons"
            android:layout_width="match_parent"
            android:layout_height="60dp"
            android:orientation="horizontal"
            app:layout_constraintBottom_toBottomOf="parent">

            <Button
                android:id="@+id/dialog_sheet_button_reset"
                style="@style/ActionSheetTitle"
                android:layout_width="0dp"
                android:layout_height="60dp"
                android:layout_weight="0.5"
                android:background="@color/bottomBarContainerColor"
                android:text="@string/general_reset"
                android:textColor="@color/dangerColor" />

            <Button
                android:id="@+id/dialog_sheet_button_close"
                style="@style/ActionSheetTitle"
                android:layout_width="0dp"
                android:layout_height="60dp"
                android:layout_weight="0.5"
                android:background="@color/bottomBarContainerColor"
                android:text="@string/general_close" />

        </LinearLayout>
    </android.support.constraint.ConstraintLayout>
</layout>

Unfortunately my recycler view height is always equal to zero. I tried to change android:layout_height="0dp" to android:layout_height="wrap_content" but as expected it goes below the bottom container. Am I missing something?

Body:
Try this code:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <!-- Layout injected inside this linear layout container programmatically -->
        <LinearLayout
            android:id="@+id/header_dialog_container"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintBottom_toTopOf="@id/form_dialog_recycler_view"
            app:layout_constraintTop_toTopOf="parent" />

        <android.support.v7.widget.RecyclerView
            android:id="@+id/form_dialog_recycler_view"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:scrollbars="vertical"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            app:layout_constraintBottom_toTopOf="@id/bottom_sheet_container_buttons"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/header_dialog_container" />

        <LinearLayout
            android:id="@+id/bottom_sheet_container_buttons"
            android:layout_width="match_parent"
            android:layout_height="60dp"
            android:orientation="horizontal"
            app:layout_constraintBottom_toBottomOf="parent">

            <Button
                android:id="@+id/dialog_sheet_button_reset"
                style="@style/ActionSheetTitle"
                android:layout_width="0dp"
                android:layout_height="60dp"
                android:layout_weight="0.5"
                android:background="@color/bottomBarContainerColor"
                android:text="@string/general_reset"
                android:textColor="@color/dangerColor" />

            <Button
                android:id="@+id/dialog_sheet_button_close"
                style="@style/ActionSheetTitle"
                android:layout_width="0dp"
                android:layout_height="60dp"
                android:layout_weight="0.5"
                android:background="@color/bottomBarContainerColor"
                android:text="@string/general_close" />

        </LinearLayout>
    </android.support.constraint.ConstraintLayout>
</layout>


问:
Liferay Service is not overriding journalArticle is not calling restoreArticleFromTrash?
This method is not calling while restore article from recycle bin.</p>

```<code>@Override
public void restoreArticleFromTrash(long groupId, String articleId) throws PortalException {
    // TODO Auto-generated method stub
    System.out.println(":::::::::::::restote article from the trash::::::::::::");
    super.restoreArticleFromTrash(groupId, articleId);
}
</code>```

答: JournalArticleTrashHandler calls the JournalArticleLocalService's retoreArticleFromTrash method. I'm assuming this is the entry point into the Journal Article's service layer for the action you're taking in the portal. Because the call is directly to the Local Service, I think you need to create a service wrapper for JournalArticleLocalService rather than JournalArticleService.

Body:
This method is not calling while restore article from recycle bin.

@Override
public void restoreArticleFromTrash(long groupId, String articleId) throws PortalException {
    // TODO Auto-generated method stub
    System.out.println(":::::::::::::restote article from the trash::::::::::::");
    super.restoreArticleFromTrash(groupId, articleId);
}


问:
Blueprism - Not able to spy elements
I am using Blueprism to launch a URL in browser to spy it. I am able to launch the URL using the application modeller, but not able to spy it. The "Identify" option itself does not appear in blue prism. What is the problem and what is the solution ?</p>

答: If you launch application from Google Chrome, then you can get this error because in Google Chrome it's not possible to Spy and launch the applications. Any RPA Tools will support only Internet Explorer</p>

Title: Blueprism - Not able to spy elements


问:
How to add a focus to an editable ComboBox in WPF
I am using an editable ComboBox in wpf but when i try to set focus from C# code, it is only shows selection. but i want to go for edit option (cursor should display for user input).</p>

答:
Based on Rikker Serg's answer, you can use that code in your constructor (after InitializeComponent) and dispatch it instead of needing to create custom controls or event handlers.</p>

```<code>public NewMessageWindow()
{
    InitializeComponent();

    Dispatcher.BeginInvoke(new Action(() =>
    {
        var textBox = myComboBox.Template.FindName("PART_EditableTextBox", cbUsers) as TextBox;
        if (textBox != null)
        {
            textBox.Focus();
            textBox.SelectionStart = textBox.Text.Length;
        }
    }));

}
</code>```

Body:
Based on Rikker Serg's answer, you can use that code in your constructor (after InitializeComponent) and dispatch it instead of needing to create custom controls or event handlers.

public NewMessageWindow()
{
    InitializeComponent();

    Dispatcher.BeginInvoke(new Action(() =>
    {
        var textBox = myComboBox.Template.FindName("PART_EditableTextBox", cbUsers) as TextBox;
        if (textBox != null)
        {
            textBox.Focus();
            textBox.SelectionStart = textBox.Text.Length;
        }
    }));

}


问:
Volley GET JsonObjectRequest with JSONObjectParameter doesn't work at all
I've got a problem with Volley request - I want to send GET (another similiar POST also) request with JSONObject param (user having password and login) to authorize user and send back full user data. Although I can see during debugging that mRequestBody is correct JSON but I cannot receive it by my controller -

```<code>private void processLogin() throws JSONException {
    this.user.setLogin(this.loginText.getText().toString());
    this.user.setPassword(this.passwordText.getText().toString());
    final JSONObject jsonObject = new JSONObject(new Gson().toJson(this.user));

    final JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, UrlHelper.loginUrl, jsonObject, new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {
            user = new Gson().fromJson(response.toString(), User.class);
            if (user.getUserId().equals(getResources().getString(R.string.ERROR))) {
                onLoginFailed();
            } else {
                onLoginSuccess(user);
            }
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Log.d(TAG, error.toString());
        }
    }) {
        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
            HashMap<String, String> headers = new HashMap<String, String>();
            headers.put("Content-Type", "application/json");
            return headers;
        }
    };
    VolleySingleton.getInstance(this).addToRequestQueue(request);
}
</code>```

Controller method:

```<code>@RequestMapping(value = "/loginTest", method = RequestMethod.GET, produces = {MediaType.APPLICATION_JSON_UTF8_VALUE})
public User someMethod(@RequestBody User user) throws SQLException {
    return userService.authenticateUser(user.getLogin(), user.getPassword());
}
</code>```

Without annotation @RequestBody I it process but User in param is empty, so I process User with null password and login. Recently I did it by StringRequest Please, help me. :)

答: As a part of the HTTP specs, GET requests have no body. You can create and send GET requests with a body though, but that's meaningless since the body has no semantic meaning in the GET method specification. I don't know too much about Spring, but my guess is that Spring is probably ignoring the body of the request because it's a GET method. You should send and receive the request as POST if your intention is to put something inside the body.</p>

Body:
I've got a problem with Volley request - I want to send GET (another similiar POST also) request with JSONObject param (user having password and login) to authorize user and send back full user data. Although I can see during debugging that mRequestBody is correct JSON but I cannot receive it by my controller -

private void processLogin() throws JSONException {
    this.user.setLogin(this.loginText.getText().toString());
    this.user.setPassword(this.passwordText.getText().toString());
    final JSONObject jsonObject = new JSONObject(new Gson().toJson(this.user));

    final JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, UrlHelper.loginUrl, jsonObject, new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {
            user = new Gson().fromJson(response.toString(), User.class);
            if (user.getUserId().equals(getResources().getString(R.string.ERROR))) {
                onLoginFailed();
            } else {
                onLoginSuccess(user);
            }
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Log.d(TAG, error.toString());
        }
    }) {
        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
            HashMap<String, String> headers = new HashMap<String, String>();
            headers.put("Content-Type", "application/json");
            return headers;
        }
    };
    VolleySingleton.getInstance(this).addToRequestQueue(request);
}

Controller method:

@RequestMapping(value = "/loginTest", method = RequestMethod.GET, produces = {MediaType.APPLICATION_JSON_UTF8_VALUE})
public User someMethod(@RequestBody User user) throws SQLException {
    return userService.authenticateUser(user.getLogin(), user.getPassword());
}

Without annotation @RequestBody I it process but User in param is empty, so I process User with null password and login. Recently I did it by StringRequest Please, help me. :)


问:
stragety of the name lookup about full specialization of function?
Here is two-phase name lookup for template from iso-standard:

When looking for the declaration of a name used in a template definition, the usual lookup rules (6.4.1, 6.4.2) are used for non-dependent names.

The lookup of names dependent on the template parameters is postponed until the actual template argument is known

Sample codes:

```<code>#include <iostream>

void WithoutTemplate(int) {std::cout << "NonTemplate: int\n";}

template<typename T>
void WithTemplate(T) {std::cout << "no match\n";}

template<>
void WithTemplate(int) {std::cout <<"Template: int\n";}

template<typename T>
void test(T)
{
    WithTemplate(1.1);
    WithoutTemplate(1.1);
}

void WithoutTemplate(double) {std::cout << "nontemplate: double\n";}

template<>
void WithTemplate(double) {std::cout << "template: double\n";}

int main()
{
    test(1.1);
}
</code>```

output:

template: double
  NonTemplate: int

There are two functions: WithTemplate and WithoutTemplate. The parameter 1.1 is non-dependent(though it is prvalue, which has no name? I assume it still obey non-dependent name's rules)

name lookup of WithoutTemplate meets 2-phase lookup, because when calling WithoutTemplate(1.1), void WithoutTemplate(double) is not visible. So the output NonTemplate: int is easy to understand.

However, the case which invokes full specialization function quite confuses me. its behaviour is opposite to the standard's rules(2-phase lookup). I thought it should output template: int

So, is there other name lookup rules for specialization? Or something else I misunderstand?

Here is what I have read:

Difference between instantiation and specialization in c++ templates

Name lookups in C++ templates

答:
Your program has undefined behaviour, because you define the explicit specialization of WithTemplate<double> after it has been implicitly instantiated through the call WithTemplate(1.1). Explicit specializations must appear before any use of them that would cause instantiation - see e.g. http://en.cppreference.com/w/cpp/language/template_specialization.

So there's no point trying to reconcile the behaviour with what the standard says; the standard explicitly says nothing about what should happen here.

Body:
Here is two-phase name lookup for template from iso-standard:

When looking for the declaration of a name used in a template definition, the usual lookup rules (6.4.1, 6.4.2) are used for non-dependent names.

The lookup of names dependent on the template parameters is postponed until the actual template argument is known

Sample codes:

#include <iostream>

void WithoutTemplate(int) {std::cout << "NonTemplate: int\n";}

template<typename T>
void WithTemplate(T) {std::cout << "no match\n";}

template<>
void WithTemplate(int) {std::cout <<"Template: int\n";}

template<typename T>
void test(T)
{
    WithTemplate(1.1);
    WithoutTemplate(1.1);
}

void WithoutTemplate(double) {std::cout << "nontemplate: double\n";}

template<>
void WithTemplate(double) {std::cout << "template: double\n";}

int main()
{
    test(1.1);
}

output:

template: double
  NonTemplate: int

There are two functions: WithTemplate and WithoutTemplate. The parameter 1.1 is non-dependent(though it is prvalue, which has no name? I assume it still obey non-dependent name's rules)

name lookup of WithoutTemplate meets 2-phase lookup, because when calling WithoutTemplate(1.1), void WithoutTemplate(double) is not visible. So the output NonTemplate: int is easy to understand.

However, the case which invokes full specialization function quite confuses me. its behaviour is opposite to the standard's rules(2-phase lookup). I thought it should output template: int

So, is there other name lookup rules for specialization? Or something else I misunderstand?

Here is what I have read:

Difference between instantiation and specialization in c++ templates

Name lookups in C++ templates


问:
Getting IIS 7 Site properties
I have a C++ application that needs to retrieve an IIS 7 site's properties (such as metabase properties similar to those in IIS6 - Path, AppFriendlyName etc).

With IIS 7, my code does this:

Get the AppHostWritableAdminManager and commit the path MACHINE/WEBROOT/APPHOST/Default Web Site/.

Call GetAdminSection with the section name appSettings.

Then look at the returned collection and look for the property (Path for example).

This works in IIS 6 but not on IIS7/7.5.

What changes do I need to make in order to make this work?

答:
In IIS7 the configuration data is not stored in a "metabase" and also the metabase properties that we're accustomed to in IIS6 aren't the same. IIS7 stores the bulk of its configuration data in the following file:

%systemroot%\System32\InetSrv\Config\applicationHost.config

There are other files, but for the purposes of answering this question, this is the file we're interested in.

The documentation for applicationHost.config can be found here:

<system.applicationHost> - IIS.NET

  configuration Element [IIS 7 Settings Schema]

  system.applicationHost Section Group [IIS 7 Settings Schema]

You can find a list of IIS6 metabase -> IIS7 XML configuration mappings here:

Converting Metabase Properties to Configuration Settings [IIS 7]

For example in IIS6 the path to a site's /root is stored in the Path attribute of IIsWebVirtualDir. i.e.:

```<code><IIsWebServer Location="/LM/W3SVC/67793744" AuthFlags="0" ServerAutoStart="TRUE"
              ServerBindings="217.69.47.170:80:app2.dev" ServerComment="app2" />
<IIsWebVirtualDir Location="/LM/W3SVC/67793744/root"
    AccessFlags="AccessRead | AccessScript"
    AppFriendlyName="Default Application"
    AppIsolated="2"
    AppRoot="/LM/W3SVC/67793744/Root"
    AuthFlags="AuthAnonymous | AuthNTLM"
    DirBrowseFlags="DirBrowseShowDate | DirBrowseShowTime | DirBrowseShowSize |
            DirBrowseShowExtension | DirBrowseShowLongDate | EnableDefaultDoc"
    Path="D:\websites\ssl-test\www\kerboom"
    ScriptMaps="...">
</code>```

But in IIS7 it's stored differently:

```<code><sites>
    <site name="Default Web Site" id="1" serverAutoStart="true">
        <!-- this is the functional equivalent of the /root app in IIS6 -->
        <application path="/">
            <virtualDirectory path="/"
                              physicalPath="%SystemDrive%\inetpub\wwwroot" />
        </application>
    </site>
<sites>
</code>```

However, if your code must work with both IIS6 and IIS7 then you can install the IIS6 Management Compatibility components. This will allow you to access IIS7 site properties using traditional IIS6 metabase API's such as ADSI, System.DirectoryServices etc. The compatibility layer will map these properties to the new IIS7 schema for you.

The first part of this article explains how to install this on Vista/Windows7/Windows 2008:

How to install ASP.NET 1.1 with IIS7 on Vista and Windows 2008 - see step #1

Update:

Unfortunately C++ isn't my strong point. However I put together an example in C# using COM Interop to demonstrate using the AppHostWritableAdminManager:

```<code>IAppHostWritableAdminManager wam = new AppHostWritableAdminManager();
IAppHostElement sites =
   wam.GetAdminSection("system.applicationHost/sites", "MACHINE/WEBROOT/APPHOST");
IAppHostElementCollection sitesCollection = sites.Collection;

long index = FindSiteIndex(sitesCollection, "MySite");
if(index == -1) throw new Exception("Site not found");

IAppHostElement site = sitesCollection[index];
IAppHostElementCollection bindings = site.ChildElements["bindings"].Collection;

for (int i = 0; i < bindings.Count; i++)
{
  IAppHostElement binding = bindings[i];
  IAppHostProperty protocolProp = binding.GetPropertyByName("protocol");
  IAppHostProperty bindingInformationProp =
      binding.GetPropertyByName("bindingInformation");

  string protocol = protocolProp.Value;
  string bindingInformation = bindingInformationProp.Value;

  Debug.WriteLine("{0} - {1}", protocol, bindingInformation);

}

static long FindSiteIndex(IAppHostElementCollection sites, string siteName)
{
  for (int i = 0; i < sites.Count; i++)
  {
    IAppHostElement site = sites[i];
    Debug.WriteLine(site.Name);
    IAppHostProperty prop = site.GetPropertyByName("name");
    if(prop.Value == siteName)
    {
      return i;
    }
  }
  return -1;
}
</code>```

The code above locates a site named "MySite" in the <sites> collection. It then retrieves the site's <bindings> collection and print's each bindings protocol and bindingInformation attributes.

Your should be able to convert this to C++ fairly easily.

To answer the question in your comment -

For example, the path
  system.applicationHost/Sites will get
  me to the list of sites. Is there an
  absolute way to get to my server
  bindings like this (for example by
  doing
  system.applicationHost/Sites/Default
  Web Site/Bindings

When using the AppHostWritableAdminManager there isn't a shortcut to getting directly to the site you want to inspect/modify or it's properties. In the example above, you'll see that I need to loop through the sites collection to find the site I'm interested in. The reason for this is that AppHostWritableAdminManager sees everything as elements and collections of elements. It's a fairly basic API. Even when using the managed Microsoft.Web.Administration API you find that whilst there are some nice properties such as Site.Bindings, these are thinly disguised wrappers around AppHostWritableAdminManager.

In fact if I want to find a site I still have to search the Sites collection either in a for loop or by adding some LINQ sugar if I'm using C#3.5 or later:

```<code>using(ServerManager serverManager = new ServerManager())
{
    Site x = serverManager.Sites.FirstOrDefault(s => s.Name == "MySite");
}
</code>```

Site's base class is ConfigurationElement which under the bonnet wraps access to IAppHostElement.

Once you're past some basic shortcut wrapper properties much of what we do in managed code to configure IIS (for example IIS FTP) is elements, attributes and collections of elements.

Update 2:

Please bear in mind I've never written a line of C++ in my life. There's no cleanup of strings or objects:

```<code>#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <ahadmin.h>
#include <crtdbg.h>

static IAppHostElement*
   FindSite(IAppHostElementCollection *pCollection, BSTR bstrSiteName);

int _tmain(int argc, _TCHAR* argv[])
{
  CoInitialize(NULL);

  IAppHostWritableAdminManager *pMgr = NULL;
  IAppHostElement *pElem = NULL;
  IAppHostElementCollection *pSitesCollection = NULL;
  IAppHostElement *pSite = NULL;
  IAppHostElement *pBindings = NULL;
  IAppHostElement *pBinding = NULL;
  IAppHostElementCollection *pBindingsCollection = NULL;
  IAppHostChildElementCollection *pChildElements = NULL;
  IAppHostProperty *pProtocol = NULL;
  IAppHostProperty *pBindingInformation = NULL;

  BSTR bstrSectionName = SysAllocString( L"system.applicationHost/sites" );
  BSTR bstrConfigCommitPath = SysAllocString( L"MACHINE/WEBROOT/APPHOST" );
  BSTR bstrSiteName = SysAllocString( L"MySite" );
  BSTR bstrBindingsConst = SysAllocString( L"bindings" );
  BSTR bstrBindingProtocol = SysAllocString( L"protocol" );
  BSTR bstrBindingInformation = SysAllocString( L"bindingInformation" );

  VARIANT vtPropertyName;
  VARIANT vtIndex;

  HRESULT hr = S_OK;

  hr = CoCreateInstance( __uuidof(AppHostWritableAdminManager), NULL,
      CLSCTX_INPROC_SERVER, __uuidof(IAppHostWritableAdminManager), (void**) &pMgr);

  hr = pMgr->GetAdminSection(bstrSectionName, bstrConfigCommitPath, &pElem);
  hr = pElem->get_Collection(&pSitesCollection);

  pSite = FindSite(pSitesCollection, bstrSiteName);

  hr = pSite->get_ChildElements(&pChildElements);

  vtPropertyName.vt = VT_BSTR;
  vtPropertyName.bstrVal = bstrBindingsConst;

  hr = pChildElements->get_Item(vtPropertyName, &pBindings);
  hr = pBindings->get_Collection(&pBindingsCollection);

  DWORD bindingsCount;
  hr = pBindingsCollection->get_Count(&bindingsCount);

  for(int i = 0; i < bindingsCount; i++)
  {
    vtIndex.lVal = i;
    vtIndex.vt = VT_I4;
    hr = pBindingsCollection->get_Item(vtIndex, &pBinding);

    hr = pBinding->GetPropertyByName(bstrBindingProtocol, &pProtocol);
    hr = pBinding->GetPropertyByName(bstrBindingInformation, &pBindingInformation);

    BSTR bstrProtocol;
    BSTR bstrBindingInformation;

    hr = pProtocol->get_StringValue(&bstrProtocol);
    hr = pBindingInformation->get_StringValue(&bstrBindingInformation);

    _tprintf(_T("Protocol: %s, BindingInfo: %s\n"), bstrProtocol, bstrBindingInformation);
  }

  CoUninitialize();
  return 0;
}

IAppHostElement* FindSite(IAppHostElementCollection *pCollection, BSTR bstrSiteName)
{
  DWORD count = -1;
  pCollection->get_Count(&count);

  BSTR bstrPropName = SysAllocString( L"name");

  for(DWORD i = 0; i < count; i++)
  {
    IAppHostElement *site = NULL;
    IAppHostProperty *prop = NULL;
    BSTR bstrPropValue;

    HRESULT hr = S_OK;

    VARIANT vtCount;
    VariantInit(&vtCount);
    vtCount.lVal = i;
    vtCount.vt = VT_I4;

    hr = pCollection->get_Item(vtCount, &site);
    hr = site->GetPropertyByName(bstrPropName, &prop);
    hr = prop->get_StringValue(&bstrPropValue);

    if(wcscmp(bstrPropValue, bstrSiteName) == 0)
    {
      return site;
    }
  }

  return NULL;
}
</code>```

Title: Getting IIS 7 Site properties

Body:
In IIS7 the configuration data is not stored in a "metabase" and also the metabase properties that we're accustomed to in IIS6 aren't the same. IIS7 stores the bulk of its configuration data in the following file:

%systemroot%\System32\InetSrv\Config\applicationHost.config

There are other files, but for the purposes of answering this question, this is the file we're interested in.

The documentation for applicationHost.config can be found here:

<system.applicationHost> - IIS.NET

  configuration Element [IIS 7 Settings Schema]

  system.applicationHost Section Group [IIS 7 Settings Schema]

You can find a list of IIS6 metabase -> IIS7 XML configuration mappings here:

Converting Metabase Properties to Configuration Settings [IIS 7]

For example in IIS6 the path to a site's /root is stored in the Path attribute of IIsWebVirtualDir. i.e.:

<IIsWebServer Location="/LM/W3SVC/67793744" AuthFlags="0" ServerAutoStart="TRUE"
              ServerBindings="217.69.47.170:80:app2.dev" ServerComment="app2" />
<IIsWebVirtualDir Location="/LM/W3SVC/67793744/root"
    AccessFlags="AccessRead | AccessScript"
    AppFriendlyName="Default Application"
    AppIsolated="2"
    AppRoot="/LM/W3SVC/67793744/Root"
    AuthFlags="AuthAnonymous | AuthNTLM"
    DirBrowseFlags="DirBrowseShowDate | DirBrowseShowTime | DirBrowseShowSize |
            DirBrowseShowExtension | DirBrowseShowLongDate | EnableDefaultDoc"
    Path="D:\websites\ssl-test\www\kerboom"
    ScriptMaps="...">

But in IIS7 it's stored differently:

<sites>
    <site name="Default Web Site" id="1" serverAutoStart="true">
        <!-- this is the functional equivalent of the /root app in IIS6 -->
        <application path="/">
            <virtualDirectory path="/"
                              physicalPath="%SystemDrive%\inetpub\wwwroot" />
        </application>
    </site>
<sites>

However, if your code must work with both IIS6 and IIS7 then you can install the IIS6 Management Compatibility components. This will allow you to access IIS7 site properties using traditional IIS6 metabase API's such as ADSI, System.DirectoryServices etc. The compatibility layer will map these properties to the new IIS7 schema for you.

The first part of this article explains how to install this on Vista/Windows7/Windows 2008:

How to install ASP.NET 1.1 with IIS7 on Vista and Windows 2008 - see step #1

Update:

Unfortunately C++ isn't my strong point. However I put together an example in C# using COM Interop to demonstrate using the AppHostWritableAdminManager:

IAppHostWritableAdminManager wam = new AppHostWritableAdminManager();
IAppHostElement sites =
   wam.GetAdminSection("system.applicationHost/sites", "MACHINE/WEBROOT/APPHOST");
IAppHostElementCollection sitesCollection = sites.Collection;

long index = FindSiteIndex(sitesCollection, "MySite");
if(index == -1) throw new Exception("Site not found");

IAppHostElement site = sitesCollection[index];
IAppHostElementCollection bindings = site.ChildElements["bindings"].Collection;

for (int i = 0; i < bindings.Count; i++)
{
  IAppHostElement binding = bindings[i];
  IAppHostProperty protocolProp = binding.GetPropertyByName("protocol");
  IAppHostProperty bindingInformationProp =
      binding.GetPropertyByName("bindingInformation");

  string protocol = protocolProp.Value;
  string bindingInformation = bindingInformationProp.Value;

  Debug.WriteLine("{0} - {1}", protocol, bindingInformation);

}

static long FindSiteIndex(IAppHostElementCollection sites, string siteName)
{
  for (int i = 0; i < sites.Count; i++)
  {
    IAppHostElement site = sites[i];
    Debug.WriteLine(site.Name);
    IAppHostProperty prop = site.GetPropertyByName("name");
    if(prop.Value == siteName)
    {
      return i;
    }
  }
  return -1;
}

The code above locates a site named "MySite" in the <sites> collection. It then retrieves the site's <bindings> collection and print's each bindings protocol and bindingInformation attributes.

Your should be able to convert this to C++ fairly easily.

To answer the question in your comment -

For example, the path
  system.applicationHost/Sites will get
  me to the list of sites. Is there an
  absolute way to get to my server
  bindings like this (for example by
  doing
  system.applicationHost/Sites/Default
  Web Site/Bindings

When using the AppHostWritableAdminManager there isn't a shortcut to getting directly to the site you want to inspect/modify or it's properties. In the example above, you'll see that I need to loop through the sites collection to find the site I'm interested in. The reason for this is that AppHostWritableAdminManager sees everything as elements and collections of elements. It's a fairly basic API. Even when using the managed Microsoft.Web.Administration API you find that whilst there are some nice properties such as Site.Bindings, these are thinly disguised wrappers around AppHostWritableAdminManager.

In fact if I want to find a site I still have to search the Sites collection either in a for loop or by adding some LINQ sugar if I'm using C#3.5 or later:

using(ServerManager serverManager = new ServerManager())
{
    Site x = serverManager.Sites.FirstOrDefault(s => s.Name == "MySite");
}

Site's base class is ConfigurationElement which under the bonnet wraps access to IAppHostElement.

Once you're past some basic shortcut wrapper properties much of what we do in managed code to configure IIS (for example IIS FTP) is elements, attributes and collections of elements.

Update 2:

Please bear in mind I've never written a line of C++ in my life. There's no cleanup of strings or objects:

#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <ahadmin.h>
#include <crtdbg.h>

static IAppHostElement*
   FindSite(IAppHostElementCollection *pCollection, BSTR bstrSiteName);

int _tmain(int argc, _TCHAR* argv[])
{
  CoInitialize(NULL);

  IAppHostWritableAdminManager *pMgr = NULL;
  IAppHostElement *pElem = NULL;
  IAppHostElementCollection *pSitesCollection = NULL;
  IAppHostElement *pSite = NULL;
  IAppHostElement *pBindings = NULL;
  IAppHostElement *pBinding = NULL;
  IAppHostElementCollection *pBindingsCollection = NULL;
  IAppHostChildElementCollection *pChildElements = NULL;
  IAppHostProperty *pProtocol = NULL;
  IAppHostProperty *pBindingInformation = NULL;

  BSTR bstrSectionName = SysAllocString( L"system.applicationHost/sites" );
  BSTR bstrConfigCommitPath = SysAllocString( L"MACHINE/WEBROOT/APPHOST" );
  BSTR bstrSiteName = SysAllocString( L"MySite" );
  BSTR bstrBindingsConst = SysAllocString( L"bindings" );
  BSTR bstrBindingProtocol = SysAllocString( L"protocol" );
  BSTR bstrBindingInformation = SysAllocString( L"bindingInformation" );

  VARIANT vtPropertyName;
  VARIANT vtIndex;

  HRESULT hr = S_OK;

  hr = CoCreateInstance( __uuidof(AppHostWritableAdminManager), NULL,
      CLSCTX_INPROC_SERVER, __uuidof(IAppHostWritableAdminManager), (void**) &pMgr);

  hr = pMgr->GetAdminSection(bstrSectionName, bstrConfigCommitPath, &pElem);
  hr = pElem->get_Collection(&pSitesCollection);

  pSite = FindSite(pSitesCollection, bstrSiteName);

  hr = pSite->get_ChildElements(&pChildElements);

  vtPropertyName.vt = VT_BSTR;
  vtPropertyName.bstrVal = bstrBindingsConst;

  hr = pChildElements->get_Item(vtPropertyName, &pBindings);
  hr = pBindings->get_Collection(&pBindingsCollection);

  DWORD bindingsCount;
  hr = pBindingsCollection->get_Count(&bindingsCount);

  for(int i = 0; i < bindingsCount; i++)
  {
    vtIndex.lVal = i;
    vtIndex.vt = VT_I4;
    hr = pBindingsCollection->get_Item(vtIndex, &pBinding);

    hr = pBinding->GetPropertyByName(bstrBindingProtocol, &pProtocol);
    hr = pBinding->GetPropertyByName(bstrBindingInformation, &pBindingInformation);

    BSTR bstrProtocol;
    BSTR bstrBindingInformation;

    hr = pProtocol->get_StringValue(&bstrProtocol);
    hr = pBindingInformation->get_StringValue(&bstrBindingInformation);

    _tprintf(_T("Protocol: %s, BindingInfo: %s\n"), bstrProtocol, bstrBindingInformation);
  }

  CoUninitialize();
  return 0;
}

IAppHostElement* FindSite(IAppHostElementCollection *pCollection, BSTR bstrSiteName)
{
  DWORD count = -1;
  pCollection->get_Count(&count);

  BSTR bstrPropName = SysAllocString( L"name");

  for(DWORD i = 0; i < count; i++)
  {
    IAppHostElement *site = NULL;
    IAppHostProperty *prop = NULL;
    BSTR bstrPropValue;

    HRESULT hr = S_OK;

    VARIANT vtCount;
    VariantInit(&vtCount);
    vtCount.lVal = i;
    vtCount.vt = VT_I4;

    hr = pCollection->get_Item(vtCount, &site);
    hr = site->GetPropertyByName(bstrPropName, &prop);
    hr = prop->get_StringValue(&bstrPropValue);

    if(wcscmp(bstrPropValue, bstrSiteName) == 0)
    {
      return site;
    }
  }

  return NULL;
}