问:
The data couldn’t be read because it isn’t in the correct format Stripe
I'm trying to create StripeEphemeralKeys within my IOS application using Stripe and Firebase but I keep getting this error when I try and print out the data. The data couldn’t be read because it isn’t in the correct format. I can't figure out why!

Fuctions:

```<code>exports.createStripeEphemeralKeys = functions.https.onCall((data, context) => {
const customerId = data.customerId;
const stripe_version = data.stripe_version;
return stripe.ephemeralKeys
    .create({
        customer: customerId,
        stripe_version: stripe_version
    })
});
</code>```

Presentation:

```<code>func choosePaymentButtonTapped() {

    guard let uid = Auth.auth().currentUser?.uid else { return }

    var paymentContext: STPPaymentContext?

    let ref = Database.database().reference().child("stripe_customers").child(uid)
    ref.observeSingleEvent(of: .value) { (snapshot) in

        guard let dict = snapshot.value as? [String: Any] else { return }
        guard let customerId = dict["customer_id"] as? String else { return }

        let customerContext = STPCustomerContext(keyProvider: StripeProvider(customerId: customerId))
        paymentContext = STPPaymentContext(customerContext: customerContext)
        paymentContext!.delegate = self
        paymentContext!.hostViewController = self
        paymentContext!.presentPaymentOptionsViewController()
    }
}
</code>```

Stripe API:

```<code>class StripeProvider: NSObject, STPCustomerEphemeralKeyProvider {
lazy var functions = Functions.functions()
let customerId: String

init(customerId: String){
    self.customerId = customerId
}

func createCustomerKey(withAPIVersion apiVersion: String, completion: @escaping STPJSONResponseCompletionBlock) {
    let data: [String: Any] = [
        "customerId": customerId,
        "stripe_version": apiVersion
    ]
    functions
        .httpsCallable("createStripeEphemeralKeys")
        .call(data) { result, error in

            if let error = error {
                print(error.localizedDescription)
                completion(nil, error)
            } else if let data = result?.data as? [String: Any] {
                completion(data, nil)
            }
    }
}
}
</code>```

答: I had the same issue. The problem was I was not running the onCall function locally. That is, although I had the emulators running locally, I had not told my client to use the emulators. That is done by calling useFunctionsEmulator(origin: [YOUR HOST]). More info here.

Body:
I'm trying to create StripeEphemeralKeys within my IOS application using Stripe and Firebase but I keep getting this error when I try and print out the data. The data couldn’t be read because it isn’t in the correct format. I can't figure out why!

Fuctions:

exports.createStripeEphemeralKeys = functions.https.onCall((data, context) => {
const customerId = data.customerId;
const stripe_version = data.stripe_version;
return stripe.ephemeralKeys
    .create({
        customer: customerId,
        stripe_version: stripe_version
    })
});

Presentation:

func choosePaymentButtonTapped() {

    guard let uid = Auth.auth().currentUser?.uid else { return }

    var paymentContext: STPPaymentContext?

    let ref = Database.database().reference().child("stripe_customers").child(uid)
    ref.observeSingleEvent(of: .value) { (snapshot) in

        guard let dict = snapshot.value as? [String: Any] else { return }
        guard let customerId = dict["customer_id"] as? String else { return }

        let customerContext = STPCustomerContext(keyProvider: StripeProvider(customerId: customerId))
        paymentContext = STPPaymentContext(customerContext: customerContext)
        paymentContext!.delegate = self
        paymentContext!.hostViewController = self
        paymentContext!.presentPaymentOptionsViewController()
    }
}

Stripe API:

class StripeProvider: NSObject, STPCustomerEphemeralKeyProvider {
lazy var functions = Functions.functions()
let customerId: String

init(customerId: String){
    self.customerId = customerId
}

func createCustomerKey(withAPIVersion apiVersion: String, completion: @escaping STPJSONResponseCompletionBlock) {
    let data: [String: Any] = [
        "customerId": customerId,
        "stripe_version": apiVersion
    ]
    functions
        .httpsCallable("createStripeEphemeralKeys")
        .call(data) { result, error in

            if let error = error {
                print(error.localizedDescription)
                completion(nil, error)
            } else if let data = result?.data as? [String: Any] {
                completion(data, nil)
            }
    }
}
}


来源: stackexchange

问:
Fireabse UI sign up without requesting user name
Using Firebase UI for sign-in and sign-up, how do I remove the option for a user to sign-up with a first & last name? In other words, only their email and password are required.

According to this github issue, the feature to do so has been implemented.

Firebase provided Kotlin code for sign-in/sign-up:

```<code>private fun createSignInIntent() {
    // Choose authentication providers
    val providers = arrayListOf(
        AuthUI.IdpConfig.EmailBuilder().build(),
        AuthUI.IdpConfig.GoogleBuilder().build())

    // Create and launch sign-in intent
    startActivityForResult(
        AuthUI.getInstance()
            .createSignInIntentBuilder()
            .setAvailableProviders(providers)
            .setLogo(R.drawable.logo)
            .setTheme(R.style.AppTheme)
            .build(),
        RC_SIGN_IN)
}

override fun onActivityResult(...
</code>```

答:
The pull request that implements this feature suggests that you call setRequireName(false) on your EmailBuilder object.

```<code>AuthUI.IdpConfig.EmailBuilder().setRequireName(false).build()
</code>```

ContentLicense: CC BY-SA 4.0

Body:
Using Firebase UI for sign-in and sign-up, how do I remove the option for a user to sign-up with a first & last name? In other words, only their email and password are required.

According to this github issue, the feature to do so has been implemented.

Firebase provided Kotlin code for sign-in/sign-up:

private fun createSignInIntent() {
    // Choose authentication providers
    val providers = arrayListOf(
        AuthUI.IdpConfig.EmailBuilder().build(),
        AuthUI.IdpConfig.GoogleBuilder().build())

    // Create and launch sign-in intent
    startActivityForResult(
        AuthUI.getInstance()
            .createSignInIntentBuilder()
            .setAvailableProviders(providers)
            .setLogo(R.drawable.logo)
            .setTheme(R.style.AppTheme)
            .build(),
        RC_SIGN_IN)
}

override fun onActivityResult(...

Body:
The pull request that implements this feature suggests that you call setRequireName(false) on your EmailBuilder object.

AuthUI.IdpConfig.EmailBuilder().setRequireName(false).build()


问:
Database Design Best Practice - Order processing database - Where updates to products could effectively change a closed invoice
just after some insight on best practice here.

I'm building an order processing database, which manages stock, orders and invoices.

In my design so far, the invoices and orders have foreign key references to a products table. If the products were to be updated after the creation of an order / invoice, then the list of items on the rder / invoice could change if it were viewed again.

I'm planning to manage this by creating an "OrderItems" table, which stores an immutable copy of the product data as it was at the point where the order / invoice was created, and have the order reference this table rather than the changeable product table.

Is this a common method of handling this problem - is there another approach?

Thanks

答:
This is related to the "Slowly Changing Dimension" problem in data warehouses.  There are a half-dozen standard solutions.

http://en.wikipedia.org/wiki/Slowly_changing_dimension

Your "freeze a copy" is like the Type 4 algorithm.

ContentLicense: CC BY-SA 3.0


问:
content Length of OutputStream
I want to to gzip when size of output stream is greater than 100 bytes .
I am trying various approaches but couldn’t get how can I get content-length from output stream .Value from
Content-length in httpheader is incorrect

Could you please help me how can I find length of output stream

```<code>@Provider
@Compress
public class GzipInterceptor implements WriterInterceptor {

  @Context
  private HttpHeaders httpHeaders;

  @Override
  public void aroundWriteTo(WriterInterceptorContext context)
      throws IOException, WebApplicationException {

    List<String> acceptEncoding = null;
    if (httpHeaders != null) {
      MultivaluedMap<String, String> requestHeaders = httpHeaders.getRequestHeaders();
      acceptEncoding = requestHeaders.get(HttpHeaders.ACCEPT_ENCODING);
    }

    if (acceptEncoding != null) {
      for (String s : acceptEncoding) {

        if (s.contains(“gzip”)) {
            MultivaluedMap<String, Object> headers = context.getHeaders();
            OutputStream os = context.getOutputStream();
            if(//content-legth greater than 100 bytes)//I need some help here {
            headers.add(HttpHeaders.CONTENT_ENCODING, “”gzip”);
            context.setOutputStream(new GZIPOutputStream(os));
           }
          break;
        }
      }
    }

    context.proceed();
  }

}
</code>```

Thanks for your help

答:
Instead of putting custom logic to enable GZip compression, you can directly enable gzip compression in your web/application server. Unless you have some other specific reason for doing the current approach.

For instance, the server is Apache Tomcat, you could do this (https://examples.javacodegeeks.com/enterprise-java/tomcat/enable-gzip-compression-apache-tomcat/).

Title: content Length of OutputStream

Body:
I want to to gzip when size of output stream is greater than 100 bytes .
I am trying various approaches but couldn’t get how can I get content-length from output stream .Value from
Content-length in httpheader is incorrect

Could you please help me how can I find length of output stream

@Provider
@Compress
public class GzipInterceptor implements WriterInterceptor {

  @Context
  private HttpHeaders httpHeaders;

  @Override
  public void aroundWriteTo(WriterInterceptorContext context)
      throws IOException, WebApplicationException {

    List<String> acceptEncoding = null;
    if (httpHeaders != null) {
      MultivaluedMap<String, String> requestHeaders = httpHeaders.getRequestHeaders();
      acceptEncoding = requestHeaders.get(HttpHeaders.ACCEPT_ENCODING);
    }

    if (acceptEncoding != null) {
      for (String s : acceptEncoding) {

        if (s.contains(“gzip”)) {
            MultivaluedMap<String, Object> headers = context.getHeaders();
            OutputStream os = context.getOutputStream();
            if(//content-legth greater than 100 bytes)//I need some help here {
            headers.add(HttpHeaders.CONTENT_ENCODING, “”gzip”);
            context.setOutputStream(new GZIPOutputStream(os));
           }
          break;
        }
      }
    }

    context.proceed();
  }

}

Thanks for your help


问:
Unable to change the value of "i" th index of an array in javascript using a function
I am writing a code where user will see a list of all issues and it has two buttons:

Close the issue

Delete the issue

So, while calling delete function, it is not changing the status of the issue.

The close() function is changing the status of the "i" th issue and calling fetchIssues() function but it is not changing the status.

Close Issue:

```<code>function close(i) {

    var issues=JSON.parse(localStorage.getItem('issues'));
    issues[i].status="Close";
    fetchissues();

}
</code>```

Fetch Issues:

```<code>function fetchIssues () {

    var issues=JSON.parse(localStorage.getItem('issues'));
    var I;
    for(i=0;i<issues.length;i++) {

        var id=issues[i].id;
        var description=issues[i].description;
        var severity=issues[i].severity;
        var assignto=issues[i].assignto;
        var status=issues[i].status;
        document.getElementById('issuesList').innerHTML +=
            '<div class="well">'+
                '<h5> Issue ID : '+ id + '</h5>' +
                '<h4><span class="label label-info">'+ status +'</span></h4>'+
                '<h3><span class="glyphicon glyphicon-paste"></span>'+"     "+  description + '</h3>'+
                '<p><span class="glyphicon glyphicon-time"></span>'+'     '+ severity+'         '+'<span class="glyphicon glyphicon-user"></span>'+'     '+ assignto + '</p>'+
                '<button type="button" class="btn btn-success" onclick="close(i)">Close</button>'+'  '+
                '<button type="button" class="btn btn-danger" onclick="delete(i)">Delete</button>'+
            '</div>';

    }

}
</code>```

Save Issue:

```<code>function saveIssue(e) {

    var id=chance.guid()
    var description = document.getElementById("issueDescInput").value;
    var severity = document.getElementById("issueSeverityInput").value;
    var assignto = document.getElementById("issueAssignedToInput").value;
    var status="Open";
    var summarized = {
        id,
        description,
        severity,
        assignto,
        status
    }

    var final=JSON.stringify(summarized);
    if(localStorage.getItem('issues')===null) {

        var issues=[];
        issues.push(summarized);
        var finalissues=JSON.stringify(issues);
        localStorage.setItem('issues', finalissues);
        alert("saved");

    } else {

        var issues = JSON.parse(localStorage.getItem('issues'));
        issues.push(summarized);
        var finalissues=JSON.stringify(issues);
        localStorage.setItem('issues', finalissues);
        alert("saved");

    }
    e.preventDefault();
    fetchIssues();

}
</code>```

答:
In the following function:

```<code>function close(i) {
   var issues=JSON.parse(localStorage.getItem('issues'));
   issues[i].status="Close";
   fetchissues();
}
</code>```

You have to save it to localstorage first, you don't simply set the issue[i].status="Close" and expect the localstorage version to be updated, you have to set it with:

```<code>localStorage.setItem("issues", JSON.stringify(issues))
</code>```

So, your close function should be:

```<code>function close(i) {
   var issues=JSON.parse(localStorage.getItem('issues'));
   issues[i].status="Close";
   localStorage.setItem("issues", JSON.stringify(issues));
   fetchissues();
}
</code>```

There is also the problem pointed by @heretic-monkey:

That's because you're using strings for HTML and onclick="close(i)"
  doesn't know what i is. You need onclick="close(' + i + ')"

Body:
I am writing a code where user will see a list of all issues and it has two buttons:

Close the issue

Delete the issue

So, while calling delete function, it is not changing the status of the issue.

The close() function is changing the status of the "i" th issue and calling fetchIssues() function but it is not changing the status.

Close Issue:

function close(i) {

    var issues=JSON.parse(localStorage.getItem('issues'));
    issues[i].status="Close";
    fetchissues();

}

Fetch Issues:

function fetchIssues () {

    var issues=JSON.parse(localStorage.getItem('issues'));
    var I;
    for(i=0;i<issues.length;i++) {

        var id=issues[i].id;
        var description=issues[i].description;
        var severity=issues[i].severity;
        var assignto=issues[i].assignto;
        var status=issues[i].status;
        document.getElementById('issuesList').innerHTML +=
            '
'+
                '
 Issue ID : '+ id + '
' +
                '
'+ status +'
'+
                '
'+"     "+  description + '
'+
                '
'+'     '+ severity+'         '+''+'     '+ assignto + '
'+
                '<button type="button" class="btn btn-success" onclick="close(i)">Close</button>'+'  '+
                '<button type="button" class="btn btn-danger" onclick="delete(i)">Delete</button>'+
            '
';

    }

}

Save Issue:

function saveIssue(e) {

    var id=chance.guid()
    var description = document.getElementById("issueDescInput").value;
    var severity = document.getElementById("issueSeverityInput").value;
    var assignto = document.getElementById("issueAssignedToInput").value;
    var status="Open";
    var summarized = {
        id,
        description,
        severity,
        assignto,
        status
    }

    var final=JSON.stringify(summarized);
    if(localStorage.getItem('issues')===null) {

        var issues=[];
        issues.push(summarized);
        var finalissues=JSON.stringify(issues);
        localStorage.setItem('issues', finalissues);
        alert("saved");

    } else {

        var issues = JSON.parse(localStorage.getItem('issues'));
        issues.push(summarized);
        var finalissues=JSON.stringify(issues);
        localStorage.setItem('issues', finalissues);
        alert("saved");

    }
    e.preventDefault();
    fetchIssues();

}

Body:
In the following function:

function close(i) {
   var issues=JSON.parse(localStorage.getItem('issues'));
   issues[i].status="Close";
   fetchissues();
}

You have to save it to localstorage first, you don't simply set the issue[i].status="Close" and expect the localstorage version to be updated, you have to set it with:

localStorage.setItem("issues", JSON.stringify(issues))

So, your close function should be:

function close(i) {
   var issues=JSON.parse(localStorage.getItem('issues'));
   issues[i].status="Close";
   localStorage.setItem("issues", JSON.stringify(issues));
   fetchissues();
}

There is also the problem pointed by @heretic-monkey:

That's because you're using strings for HTML and onclick="close(i)"
  doesn't know what i is. You need onclick="close(' + i + ')"


问:
How to use GNU mtools to extract all files from a given disk image?
I understand that GNU mtools can be used to extact files from a DOS disk image.  The example provided on the website shows how to extract a discrete number of files or directories from a disk image.

```<code>mcopy -i my-image-file.bin ::file1 ::file2 .
</code>```

This copies file1 and file2 from the image file (my-image-file.bin) to
  the /tmp directory.

How do I use this command to extract all files from an image (recursively)?

答:
According to https://www.gnu.org/software/mtools/manual/html_node/mcopy.html it should be possible

mcopy [-bspanvmQT] [-D clash_option] sourcefile [ sourcefiles… ]
  targetdirectory

...

s    Recursive copy. Also copies directories and their contents

  p    Preserves the attributes of the copied files

...

But it doesn't mention the -i in your example.

Body:
I understand that GNU mtools can be used to extact files from a DOS disk image.  The example provided on the website shows how to extract a discrete number of files or directories from a disk image.

mcopy -i my-image-file.bin ::file1 ::file2 .

This copies file1 and file2 from the image file (my-image-file.bin) to
  the /tmp directory.

How do I use this command to extract all files from an image (recursively)?


问:
Git: Cherry-pick adding code that not in the commit
I am using cherry pick to add commits from my branches on github. I have a branch with only one commit and that is related to creating a new function. when, I try to add that commit using cherry-pick, I got a conflict with 3 incoming funcitons!

```<code> git cherry-pick 15sh -- no-commit
</code>```

and the same commit in my PR on github is only adding one function, but got 3 function conflict!. It's imply adding two other funcitons from another PR!

答:
It's imply adding two other funcitons from another PR!

Not really. The content of the conflicting portion does not in any way imply that you need to copy it over. Do this: git cherry-pick --abort then run the same cherry-pick but set merge.conflictStyle to diff3 with git -c merge.conflictStyle=diff3 cherry-pick blahblah. Then see what changed between the middle block and the bottom block... that's what you need to see how to bring over into the upper block.

Body:
I am using cherry pick to add commits from my branches on github. I have a branch with only one commit and that is related to creating a new function. when, I try to add that commit using cherry-pick, I got a conflict with 3 incoming funcitons!

 git cherry-pick 15sh -- no-commit

and the same commit in my PR on github is only adding one function, but got 3 function conflict!. It's imply adding two other funcitons from another PR!


问:
Insert 2 values into MySQL, and then stop said values appearing again
I have a script, its supposed to insert a vote (either -1 or +1) to a MySQL value, it does this fine, but it's also supposed to insert the ID of the item they have just voted on, into another table, in array format, to the user who has just voted, so that it doesn't appear again for that user.

1) I don't know how to stop the values appearing again
2) It's not sending the id of the website

The code:

```<code>    $sql = "SELECT * FROM webmash ORDER BY RAND() LIMIT 1";
    $result = mysql_query($sql) or print ("Can't select entry from table webmash.<br />" . $sql . "<br />" . mysql_error());

    while($row = mysql_fetch_array($result)) {
    $name = stripslashes($row['name']);
    $description = stripslashes($row['description']);
    $link =($row['link']);
    $votes = ($row['votes']);
    $id = $row['id'];
    }

    $sql2 = "SELECT * FROM webmashusers";
    $result2 = mysql_query($sql) or print ("Can't select entry from table webmashusers.<br />" . $sql . "<br />" . mysql_error());

    while($row = mysql_fetch_array($result2)) {
    $username = stripslashes($row['username']);
    $likes = ($row['likes']);
    $dislikes = ($row['dislikes']);
    }

    if(isset($_POST['like'])) {
    $votes += 1;
    $sql = "UPDATE webmash SET votes = $votes WHERE id = ".$_POST['id'];
    mysql_query($sql);

    $sqllikes = array (serialize($id));
    $sql2 = "INSERT '$sqllikes' INTO webmashusers (likes) WHERE 'username' = '$376770'";
    mysql_query($sql2);
    }

    if(isset($_POST['dislike'])) {
    $votes -= 1;
    $sql = "UPDATE webmash SET votes = $votes WHERE id = ".$_POST['id'];
    mysql_query($sql);

    $sqldislikes = array (serialize($id));
    $sql2 = "INSERT '$sqldislikes' INTO webmashusers (dislikes) WHERE 'username' = '$376770'";
    mysql_query($sql2);

    }
</code>```

EDIT: $376770 is my username cookie.

答:
Side note, you use $_POST['id'] in raw query.. way vulnerable for sql injections.

```<code>$sql = "UPDATE webmash SET votes = $votes WHERE id = ".$_POST['id'];
</code>```

As for your question, you use INSERT, even if there is already such user in the second table. UPDATE should be useful in the case. Overall, you could google for "INSERT ... ON DUPLICATE UPDATE" Mysql syntax for $sql2 queries and use it (together with making user name unique index in second table).

Body:
I have a script, its supposed to insert a vote (either -1 or +1) to a MySQL value, it does this fine, but it's also supposed to insert the ID of the item they have just voted on, into another table, in array format, to the user who has just voted, so that it doesn't appear again for that user.

1) I don't know how to stop the values appearing again
2) It's not sending the id of the website

The code:

    $sql = "SELECT * FROM webmash ORDER BY RAND() LIMIT 1";
    $result = mysql_query($sql) or print ("Can't select entry from table webmash.
" . $sql . "
" . mysql_error());

    while($row = mysql_fetch_array($result)) {
    $name = stripslashes($row['name']);
    $description = stripslashes($row['description']);
    $link =($row['link']);
    $votes = ($row['votes']);
    $id = $row['id'];
    }

    $sql2 = "SELECT * FROM webmashusers";
    $result2 = mysql_query($sql) or print ("Can't select entry from table webmashusers.
" . $sql . "
" . mysql_error());

    while($row = mysql_fetch_array($result2)) {
    $username = stripslashes($row['username']);
    $likes = ($row['likes']);
    $dislikes = ($row['dislikes']);
    }

    if(isset($_POST['like'])) {
    $votes += 1;
    $sql = "UPDATE webmash SET votes = $votes WHERE id = ".$_POST['id'];
    mysql_query($sql);

    $sqllikes = array (serialize($id));
    $sql2 = "INSERT '$sqllikes' INTO webmashusers (likes) WHERE 'username' = '$376770'";
    mysql_query($sql2);
    }

    if(isset($_POST['dislike'])) {
    $votes -= 1;
    $sql = "UPDATE webmash SET votes = $votes WHERE id = ".$_POST['id'];
    mysql_query($sql);

    $sqldislikes = array (serialize($id));
    $sql2 = "INSERT '$sqldislikes' INTO webmashusers (dislikes) WHERE 'username' = '$376770'";
    mysql_query($sql2);

    }

EDIT: $376770 is my username cookie.

Body:
Side note, you use $_POST['id'] in raw query.. way vulnerable for sql injections.

$sql = "UPDATE webmash SET votes = $votes WHERE id = ".$_POST['id'];

As for your question, you use INSERT, even if there is already such user in the second table. UPDATE should be useful in the case. Overall, you could google for "INSERT ... ON DUPLICATE UPDATE" Mysql syntax for $sql2 queries and use it (together with making user name unique index in second table).


问:
Files.delete does not delete empty directory
I am trying to delete file from file system, and check whether are directory and its parent directories containing it are empty to delete them also:

```<code>Path filePath = Paths.get(document.getUrl());
Files.delete(filePath);

Path directory = filePath.getParent();

// check if is it necessary to delete any parent dirs

while(!Files.list(directory).findAny().isPresent() && !directory.endsWith(DOCUMENT_ROOT)){
    Files.delete(directory);
    directory = directory.getParent();
}
</code>```

When I try to delete file that is only one in directory it deletes it but fails to delete directory that is containing it without throwing java.ioIOException. After that when I try to save another file to that directory I get java.nio.file.AccessDeniedException:

```<code>java.nio.file.AccessDeniedException: C:\Users\mjo\git\attendo5\media\doc\2020\6\1
at java.base/sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:89)
at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:103)
at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:108)
at java.base/sun.nio.fs.WindowsFileSystemProvider.createDirectory(WindowsFileSystemProvider.java:506)
at java.base/java.nio.file.Files.createDirectory(Files.java:693)
at java.base/java.nio.file.Files.createAndCheckIsDirectory(Files.java:800)
at java.base/java.nio.file.Files.createDirectories(Files.java:786)
at com.attendo.server.webapp.common.DocumentManagerServiceImpl.saveDocument(DocumentManagerServiceImpl.java:46)
at com.attendo.server.webapp.app.panel.humanresources.service.ContractServiceImpl.addDocuments_aroundBody4(ContractServiceImpl.java:222)
at com.attendo.server.webapp.app.panel.humanresources.service.ContractServiceImpl$AjcClosure5.run(ContractServiceImpl.java:1)
at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96cproceed(AbstractTransactionAspect.aj:66)
at org.springframework.transaction.aspectj.AbstractTransactionAspect$AbstractTransactionAspect$1.proceedWithInvocation(AbstractTransactionAspect.aj:72)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:366)
at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96c(AbstractTransactionAspect.aj:70)
at com.attendo.server.webapp.app.panel.humanresources.service.ContractServiceImpl.addDocuments(ContractServiceImpl.java:211)
at com.attendo.server.webapp.app.panel.humanresources.service.ContractServiceImpl$$FastClassBySpringCGLIB$$2fa3d507.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:69)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
at com.attendo.server.webapp.app.panel.humanresources.service.ContractServiceImpl$$EnhancerBySpringCGLIB$$1de4496.addDocuments(<generated>)
at com.attendo.server.webapp.app.panel.humanresources.api.controller.general.ContractController.addDocument(ContractController.java:143)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:879)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:126)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:118)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:158)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:152)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:92)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:92)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:77)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:830)
</code>```

I can't figure out what is going on and any help would be welcomed.

Edit: It works perfectly well if I use java.io and apache.commons.io:

```<code>    File file = new File(document.getUrl());
    if(!file.delete()){
        throw new AttendoException("error.file_could_not_be_deleted");
    }

    File directory = new File(file.getParent());

    // check if is it necessary to delete any parent dirs
    while((directory.isDirectory()) && (directory.list().length == 0) && !directory.getAbsolutePath().endsWith(DOCUMENT_ROOT)){
        FileUtils.deleteDirectory(directory);
        directory = new File(directory.getParent());
    }
</code>```

答:
Unlike File.list() which is self contained scan of the directory, note that Javadoc for Files.list(directory) says its should be used with "try-with-resources statement or similar control structure". So see if rewrite with the Files.list(directory) in try() block changes whether there is a lingering lock/access to a sub-directory which stops the Files.delete higher up, something like:</p>

```<code>while(!directory.endsWith(DOCUMENT_ROOT)) {
    try(var stream = Files.list(directory))  {
        if (stream.findAny().isPresent()) {
            // do the delete you want here
        }
    }
}
</code>```

Body:
I am trying to delete file from file system, and check whether are directory and its parent directories containing it are empty to delete them also:

Path filePath = Paths.get(document.getUrl());
Files.delete(filePath);

Path directory = filePath.getParent();

// check if is it necessary to delete any parent dirs

while(!Files.list(directory).findAny().isPresent() && !directory.endsWith(DOCUMENT_ROOT)){
    Files.delete(directory);
    directory = directory.getParent();
}

When I try to delete file that is only one in directory it deletes it but fails to delete directory that is containing it without throwing java.ioIOException. After that when I try to save another file to that directory I get java.nio.file.AccessDeniedException:

java.nio.file.AccessDeniedException: C:\Users\mjo\git\attendo5\media\doc\2020\6\1
at java.base/sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:89)
at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:103)
at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:108)
at java.base/sun.nio.fs.WindowsFileSystemProvider.createDirectory(WindowsFileSystemProvider.java:506)
at java.base/java.nio.file.Files.createDirectory(Files.java:693)
at java.base/java.nio.file.Files.createAndCheckIsDirectory(Files.java:800)
at java.base/java.nio.file.Files.createDirectories(Files.java:786)
at com.attendo.server.webapp.common.DocumentManagerServiceImpl.saveDocument(DocumentManagerServiceImpl.java:46)
at com.attendo.server.webapp.app.panel.humanresources.service.ContractServiceImpl.addDocuments_aroundBody4(ContractServiceImpl.java:222)
at com.attendo.server.webapp.app.panel.humanresources.service.ContractServiceImpl$AjcClosure5.run(ContractServiceImpl.java:1)
at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96cproceed(AbstractTransactionAspect.aj:66)
at org.springframework.transaction.aspectj.AbstractTransactionAspect$AbstractTransactionAspect$1.proceedWithInvocation(AbstractTransactionAspect.aj:72)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:366)
at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96c(AbstractTransactionAspect.aj:70)
at com.attendo.server.webapp.app.panel.humanresources.service.ContractServiceImpl.addDocuments(ContractServiceImpl.java:211)
at com.attendo.server.webapp.app.panel.humanresources.service.ContractServiceImpl$$FastClassBySpringCGLIB$$2fa3d507.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:69)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
at com.attendo.server.webapp.app.panel.humanresources.service.ContractServiceImpl$$EnhancerBySpringCGLIB$$1de4496.addDocuments(<generated>)
at com.attendo.server.webapp.app.panel.humanresources.api.controller.general.ContractController.addDocument(ContractController.java:143)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:879)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:126)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:118)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:158)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:152)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:92)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:92)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:77)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:830)

I can't figure out what is going on and any help would be welcomed.

Edit: It works perfectly well if I use java.io and apache.commons.io:

    File file = new File(document.getUrl());
    if(!file.delete()){
        throw new AttendoException("error.file_could_not_be_deleted");
    }

    File directory = new File(file.getParent());

    // check if is it necessary to delete any parent dirs
    while((directory.isDirectory()) && (directory.list().length == 0) && !directory.getAbsolutePath().endsWith(DOCUMENT_ROOT)){
        FileUtils.deleteDirectory(directory);
        directory = new File(directory.getParent());
    }

Body:
Unlike File.list() which is self contained scan of the directory, note that Javadoc for Files.list(directory) says its should be used with "try-with-resources statement or similar control structure". So see if rewrite with the Files.list(directory) in try() block changes whether there is a lingering lock/access to a sub-directory which stops the Files.delete higher up, something like:

while(!directory.endsWith(DOCUMENT_ROOT)) {
    try(var stream = Files.list(directory))  {
        if (stream.findAny().isPresent()) {
            // do the delete you want here
        }
    }
}


问:
Edit Distance in Python
I'm programming a spellcheck program in Python. I have a list of valid words (the dictionary) and I need to output a list of words from this dictionary that have an edit distance of 2 from a given invalid word.

I know I need to start by generating a list with an edit distance of one from the invalid word(and then run that again on all the generated words). I have three methods, inserts(...), deletions(...) and changes(...) that should output a list of words with an edit distance of 1, where inserts outputs all valid words with one more letter than the given word, deletions outputs all valid words with one less letter, and changes outputs all valid words with one different letter.

I've checked a bunch of places but I can't seem to find an algorithm that describes this process. All the ideas I've come up with involve looping through the dictionary list multiple times, which would be extremely time consuming. If anyone could offer some insight, I'd be extremely grateful.

答:
Using the SequenceMatcher from Python built-in difflib is another way of doing it, but (as correctly pointed out in the comments), the result does not match the definition of an edit distance exactly. Bonus: it supports ignoring "junk" parts (e.g. spaces or punctuation).

```<code>from difflib import SequenceMatcher

a = 'kitten'
b = 'sitting'

required_edits = [
    code
    for code in (
        SequenceMatcher(a=a, b=b, autojunk=False)
        .get_opcodes()
    )
    if code[0] != 'equal'
]
required_edits
# [
#    # (tag, i1, i2, j1, j2)
#    ('replace', 0, 1, 0, 1), # replace a[0:1]="k" with b[0:1]="s"
#    ('replace', 4, 5, 4, 5), # replace a[4:5]="e" with b[4:5]="i"
#    ('insert', 6, 6, 6, 7),  # insert b[6:7]="g" after a[6:6]="n"
# ]

# the edit distance:
len(required_edits)  # == 3
</code>```

Title: Edit Distance in Python

Body:
Using the SequenceMatcher from Python built-in difflib is another way of doing it, but (as correctly pointed out in the comments), the result does not match the definition of an edit distance exactly. Bonus: it supports ignoring "junk" parts (e.g. spaces or punctuation).

from difflib import SequenceMatcher

a = 'kitten'
b = 'sitting'

required_edits = [
    code
    for code in (
        SequenceMatcher(a=a, b=b, autojunk=False)
        .get_opcodes()
    )
    if code[0] != 'equal'
]
required_edits
# [
#    # (tag, i1, i2, j1, j2)
#    ('replace', 0, 1, 0, 1), # replace a[0:1]="k" with b[0:1]="s"
#    ('replace', 4, 5, 4, 5), # replace a[4:5]="e" with b[4:5]="i"
#    ('insert', 6, 6, 6, 7),  # insert b[6:7]="g" after a[6:6]="n"
# ]

# the edit distance:
len(required_edits)  # == 3


问:
Mathjax strangely render back-tick in code blocks
I have a TCL code gist embedded in my own website. This page uses MathJax 2.7.5 configed with "TeX-MML-AM_CHTML". However, Mathjax strangely rendered the code between back-ticks in the comments of the code. For example, one line in the source code is (can be found here in gist):

```<code>#   `testPrintFlag`  : integer
</code>```

The letters "int" were rendered by MathJax to a integration symbol (see here).

The gist code block appears like this., but the correct one should be like this. I'm wondering how I can fix this.

Thanks!

答:
The configuration file TeX-MML-AM_CHTML includes the AsciiMath input processor, and AsciiMath uses back-ticks as its math delimiters.  So all your back-tacks will cause AsciiMath to process their contents as math.  If you aren't using AsciiMath input, you probably want to use a different configuration format, like just TeX-AMS_CHTML which only does TeX input (not MathML and AsciiMath, as in your original).  That will be faster as well as it is a smaller file.

If you are using AsciiMath input, then you could configure it to use a different delimiter.  See the documentation for details.

You could also configure MathJax to skip containers with certain class names (e.g., class="gist").  See the ignoreClass option for the asciimath2jax preprocessor at the link above.  There is a similar one for the tex2jax preprocessor.

Body:
I have a TCL code gist embedded in my own website. This page uses MathJax 2.7.5 configed with "TeX-MML-AM_CHTML". However, Mathjax strangely rendered the code between back-ticks in the comments of the code. For example, one line in the source code is (can be found here in gist):

#   `testPrintFlag`  : integer

The letters "int" were rendered by MathJax to a integration symbol (see here).

The gist code block appears like this., but the correct one should be like this. I'm wondering how I can fix this.

Thanks!


问:
In Apex 19.2, is it possible to display an interactive grid pagination on the left side top and bottom like you can with an interactive report?
I originally created an IR but ran into an issue I can't resolve so I tried another approach
using an IG.  See the screenshots below for reference.

image.Interactive Reportpng

On the above IR, I want the column General Notes to display only 30 characters and not wrap.
I have used the td[headers=xx] code to set the column width and a myriad of CSS, Inline, etc.
If I use any no wrap options, it sizes to the length of the data in the column.  I just want to display
30 characters no matter the data length.  I have tried using the SUBSTR in my SELECT query to
limit the column to 30 characters, but then the Search function can only search on those 30
characters.

Consequently, I created an IG that looks similar and disabled the editing.  The General Notes
column can be sized to 30 characters.  This approach works great, but the pagination is on
the right side bottom of the page!  If I could move the pagination to the left top and bottom,
then this approach will work great!  (The users are accustomed to and desire to keep displaying
the record counts on the left top and bottom.)

image.Interactive Gridpng

So I basically have 2 issues, 1 with the IR and 1 with the IG! Any suggestions will be much
appreciated!

答:
Sizing by characters is difficult (at least I find it to be). If you're okay sizing by pixels, you can try the following for the IR. First, assign a static id to the column (I'll use 'my-class' in this example). Right-click the IR region and select Create Dynamic Action. That will create a DA that fires on the refresh of the report region. For the Action, set Type to Execute JavaScript Code and enter the following in the Code field:

```<code>$('td[headers="mgr"]').wrapInner('<span></span>');
</code>```

Ensure that the Fire on Initialization attribute is enabled. Next, add the following CSS to the page:

```<code>td[headers="my-test"] {
  max-width: 60px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
</code>```

If you'd rather move the pagination in an IG, use the following steps. Add this code to the Execute when Page Loads attribute of the page (under JavaScript).

```<code>$('.a-GV-footer').prepend($('.a-GV-pagination'))
</code>```

And the following to the Inline attribute (under CSS):

```<code>.a-GV-pagination, .a-GV-stateIcons, .a-GV-status {
  text-align: left;
  display: inline;
}

.a-GV-pagination {
  margin-right: 20px;
}
</code>```

Body:
Sizing by characters is difficult (at least I find it to be). If you're okay sizing by pixels, you can try the following for the IR. First, assign a static id to the column (I'll use 'my-class' in this example). Right-click the IR region and select Create Dynamic Action. That will create a DA that fires on the refresh of the report region. For the Action, set Type to Execute JavaScript Code and enter the following in the Code field:

$('td[headers="mgr"]').wrapInner('<span></span>');

Ensure that the Fire on Initialization attribute is enabled. Next, add the following CSS to the page:

td[headers="my-test"] {
  max-width: 60px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

If you'd rather move the pagination in an IG, use the following steps. Add this code to the Execute when Page Loads attribute of the page (under JavaScript).

$('.a-GV-footer').prepend($('.a-GV-pagination'))

And the following to the Inline attribute (under CSS):

.a-GV-pagination, .a-GV-stateIcons, .a-GV-status {
  text-align: left;
  display: inline;
}

.a-GV-pagination {
  margin-right: 20px;
}


问:
Change image source dynamically (StaticResource)
I want to change the image displayed in a grid depending on a certain condition (e.g. an enum value). The problem is that the image sources are DrawingImage (provided from xaml file).

```<code><Grid>
        <Image Source="{StaticResource BodyDrawingImage}"></Image>
</Grid>
</code>```

I want that BodyDrawingImage (which is a key for DrawingImage) to be selected at run-time (by a binding i guess) from a list of DrawingImage keys but I can't figure out how to do this.

答:
The way I've handled this is using a value converter class, with a property corresponding to each element of the Enum type.

```<code>public class perDialogIconConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (!(value is perDialogIcon))
        {
            return null;
        }

        switch ((perDialogIcon) value)
        {
            case perDialogIcon.Asterisk:
                return AsteriskIcon;
            case perDialogIcon.Error:
                return ErrorIcon;
            case perDialogIcon.Exclamation:
                return ExclamationIcon;
            case perDialogIcon.Hand:
                return HandIcon;
            case perDialogIcon.Information:
                return InformationIcon;
            case perDialogIcon.Question:
                return QuestionIcon;
            case perDialogIcon.Stop:
                return StopIcon;
            case perDialogIcon.Warning:
                return WarningIcon;
            default:
                return null;
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    public UIElement AsteriskIcon { get; set; }
    public UIElement ErrorIcon { get; set; }
    public UIElement ExclamationIcon { get; set; }
    public UIElement HandIcon { get; set; }
    public UIElement InformationIcon { get; set; }
    public UIElement QuestionIcon { get; set; }
    public UIElement StopIcon { get; set; }
    public UIElement WarningIcon { get; set; }
}
</code>```

This is instantuated as a resource within the window, along with each image required

```<code><Window.Resources>
    <Image x:Key="AsteriskIcon"
           Source="Images/Asterisk.png"
           Stretch="None" />
    <Image x:Key="ErrorIcon"
           Source="Images/Error.png"
           Stretch="None" />
    <Image x:Key="ExclamationIcon"
           Source="Images/Exclamation.png"
           Stretch="None" />
    <Image x:Key="HandIcon"
           Source="Images/Hand.png"
           Stretch="None" />
    <Image x:Key="InformationIcon"
           Source="Images/Information.png"
           Stretch="None" />
    <Image x:Key="QuestionIcon"
           Source="Images/Question.png"
           Stretch="None" />
    <Image x:Key="StopIcon"
           Source="Images/Stop.png"
           Stretch="None" />
    <Image x:Key="WarningIcon"
           Source="Images/Warning.png"
           Stretch="None" />

    <dlg:perDialogIconConverter x:Key="DialogIconConverter"
                                AsteriskIcon="{StaticResource AsteriskIcon}"
                                ErrorIcon="{StaticResource ErrorIcon}"
                                ExclamationIcon="{StaticResource ExclamationIcon}"
                                HandIcon="{StaticResource HandIcon}"
                                InformationIcon="{StaticResource InformationIcon}"
                                QuestionIcon="{StaticResource QuestionIcon}"
                                StopIcon="{StaticResource StopIcon}"
                                WarningIcon="{StaticResource WarningIcon}" />
</Window.Resources>
</code>```

and then used as required as part of the binding statement - DialogIcon is an enum property on the ViewModel

```<code><ContentPresenter Grid.Row="0"
                  Grid.Column="0"
                  VerticalAlignment="Center"
                  Content="{Binding DialogIcon, Converter={StaticResource DialogIconConverter}}" />
</code>```

Body:
I want to change the image displayed in a grid depending on a certain condition (e.g. an enum value). The problem is that the image sources are DrawingImage (provided from xaml file).

<Grid>
        <Image Source="{StaticResource BodyDrawingImage}"></Image>
</Grid>

I want that BodyDrawingImage (which is a key for DrawingImage) to be selected at run-time (by a binding i guess) from a list of DrawingImage keys but I can't figure out how to do this.

Body:
The way I've handled this is using a value converter class, with a property corresponding to each element of the Enum type.

public class perDialogIconConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (!(value is perDialogIcon))
        {
            return null;
        }

        switch ((perDialogIcon) value)
        {
            case perDialogIcon.Asterisk:
                return AsteriskIcon;
            case perDialogIcon.Error:
                return ErrorIcon;
            case perDialogIcon.Exclamation:
                return ExclamationIcon;
            case perDialogIcon.Hand:
                return HandIcon;
            case perDialogIcon.Information:
                return InformationIcon;
            case perDialogIcon.Question:
                return QuestionIcon;
            case perDialogIcon.Stop:
                return StopIcon;
            case perDialogIcon.Warning:
                return WarningIcon;
            default:
                return null;
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    public UIElement AsteriskIcon { get; set; }
    public UIElement ErrorIcon { get; set; }
    public UIElement ExclamationIcon { get; set; }
    public UIElement HandIcon { get; set; }
    public UIElement InformationIcon { get; set; }
    public UIElement QuestionIcon { get; set; }
    public UIElement StopIcon { get; set; }
    public UIElement WarningIcon { get; set; }
}

This is instantuated as a resource within the window, along with each image required

<Window.Resources>
    <Image x:Key="AsteriskIcon"
           Source="Images/Asterisk.png"
           Stretch="None" />
    <Image x:Key="ErrorIcon"
           Source="Images/Error.png"
           Stretch="None" />
    <Image x:Key="ExclamationIcon"
           Source="Images/Exclamation.png"
           Stretch="None" />
    <Image x:Key="HandIcon"
           Source="Images/Hand.png"
           Stretch="None" />
    <Image x:Key="InformationIcon"
           Source="Images/Information.png"
           Stretch="None" />
    <Image x:Key="QuestionIcon"
           Source="Images/Question.png"
           Stretch="None" />
    <Image x:Key="StopIcon"
           Source="Images/Stop.png"
           Stretch="None" />
    <Image x:Key="WarningIcon"
           Source="Images/Warning.png"
           Stretch="None" />

    <dlg:perDialogIconConverter x:Key="DialogIconConverter"
                                AsteriskIcon="{StaticResource AsteriskIcon}"
                                ErrorIcon="{StaticResource ErrorIcon}"
                                ExclamationIcon="{StaticResource ExclamationIcon}"
                                HandIcon="{StaticResource HandIcon}"
                                InformationIcon="{StaticResource InformationIcon}"
                                QuestionIcon="{StaticResource QuestionIcon}"
                                StopIcon="{StaticResource StopIcon}"
                                WarningIcon="{StaticResource WarningIcon}" />
</Window.Resources>

and then used as required as part of the binding statement - DialogIcon is an enum property on the ViewModel

<ContentPresenter Grid.Row="0"
                  Grid.Column="0"
                  VerticalAlignment="Center"
                  Content="{Binding DialogIcon, Converter={StaticResource DialogIconConverter}}" />


问:
How to emit the result of a subscription
I have the following situation:

I am using the RxKotlin extensions for detecting clicks in the buttons of my activity

I am using Room for inserting records in a database

This is the code related in my activity:

```<code>button.clicks()
            .flatMap {
                val list = mutableListOf<Answer>()
                val date = Date()
                list.add(Answer("some placeholder info"))
                list.add(Answer("Another placeholder info"))
                Observable.fromArray(list)
            }
            .map {
                upsertStatusQuestionsViewModel.insertMultipleAnswers(it)
            }.subscribe {
                // it here is an object Maybe<Answer>
            }
</code>```

And this is the code of the ViewModel:

```<code>fun insertMultipleAnswers(answers: List<Answer>) = database.answerDao()
                                                      .createMultiple(answers.toList())
                                                      .subscribeOn(Schedulers.io())
                                                      .observeOn(AndroidSchedulers.mainThread())
</code>```

I would like to show some information about the answer inserted in the database, for that reason, I need to get the Answer object in my subscription. However, I don't know which operator can I use for achieving that the it object in the subscription is of class Answer, instead of Maybe<Answer>.

Thanks a lot for your help!

答:
If anyone stumbles with this, the solution is to parse the Maybe to an Observable, as Observable implements ObservableSource, so my code is now something like this:

```<code>upsert_status_questions_confirm.clicks()
            .map {
                val list = mutableListOf<Answer>()
                list.add(Answer("Some placeholder"))
                list.add(Answer("Another placeholder"))
                list
            }.flatMap {
                upsertStatusQuestionsViewModel.insertMultipleAnswers(*it.toTypedArray())
            }.subscribe({
                // Success...
            }, {
                // Error...
            })
</code>```

And in the ViewModel:

```<code>fun insertMultipleAnswers(vararg answers: Answer) = database.answerDao()
                                               .createMultiple(answers.toList())
                                               .toObservable()
                                               .subscribeOn(Schedulers.io())
                                               .observeOn(AndroidSchedulers.mainThread())
</code>```

Body:
I have the following situation:

I am using the RxKotlin extensions for detecting clicks in the buttons of my activity

I am using Room for inserting records in a database

This is the code related in my activity:

button.clicks()
            .flatMap {
                val list = mutableListOf<Answer>()
                val date = Date()
                list.add(Answer("some placeholder info"))
                list.add(Answer("Another placeholder info"))
                Observable.fromArray(list)
            }
            .map {
                upsertStatusQuestionsViewModel.insertMultipleAnswers(it)
            }.subscribe {
                // it here is an object Maybe<Answer>
            }

And this is the code of the ViewModel:

fun insertMultipleAnswers(answers: List<Answer>) = database.answerDao()
                                                      .createMultiple(answers.toList())
                                                      .subscribeOn(Schedulers.io())
                                                      .observeOn(AndroidSchedulers.mainThread())

I would like to show some information about the answer inserted in the database, for that reason, I need to get the Answer object in my subscription. However, I don't know which operator can I use for achieving that the it object in the subscription is of class Answer, instead of Maybe<Answer>.

Thanks a lot for your help!

Body:
If anyone stumbles with this, the solution is to parse the Maybe to an Observable, as Observable implements ObservableSource, so my code is now something like this:

upsert_status_questions_confirm.clicks()
            .map {
                val list = mutableListOf<Answer>()
                list.add(Answer("Some placeholder"))
                list.add(Answer("Another placeholder"))
                list
            }.flatMap {
                upsertStatusQuestionsViewModel.insertMultipleAnswers(*it.toTypedArray())
            }.subscribe({
                // Success...
            }, {
                // Error...
            })

And in the ViewModel:

fun insertMultipleAnswers(vararg answers: Answer) = database.answerDao()
                                               .createMultiple(answers.toList())
                                               .toObservable()
                                               .subscribeOn(Schedulers.io())
                                               .observeOn(AndroidSchedulers.mainThread())


问:
How can I clear strange spacing of listviewitem in Xamarin.WPF?
Here is the code in XAML of Xamarin project:

```<code><?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="App1.MainPage">

    <ListView ItemsSource="{Binding TestList}" SeparatorVisibility="None" HasUnevenRows="True">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <ViewCell.View>
                        <ContentView BackgroundColor="Red">
                            <Label Text="{Binding TestName}"></Label>
                        </ContentView>
                    </ViewCell.View>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</ContentPage>
</code>```

Here is code-behind of Xamarin project:

```<code>using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace App1
{
    // Learn more about making custom code visible in the Xamarin.Forms previewer
    // by visiting https://aka.ms/xamarinforms-previewer
    [DesignTimeVisible(false)]
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
            this.BindingContext = this;
            TestList.Add(new Test() { TestName = "aaa" });
            TestList.Add(new Test() { TestName = "bbb" });
            TestList.Add(new Test() { TestName = "ccc" });
            TestList.Add(new Test() { TestName = "ddd" });
        }
        public ObservableCollection<Test> TestList { get; set; } = new ObservableCollection<Test>();
        public class Test
        {
            public string TestName { get; set; }
        }
    }
}
</code>```

Here is the Style of WPF project:

```<code><Application x:Class="App1.WPF.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:App1.WPF"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <Style x:Key="LvItemStyle" TargetType="ListViewItem">
            <Setter Property="Margin" Value="0"></Setter>
            <Setter Property="Padding" Value="0"></Setter>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListViewItem">
                        <ContentPresenter Margin="0"/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

        <Style TargetType="ListView" x:Key="LvStyle">
            <Setter Property="BorderBrush" Value="Transparent"/>
            <Setter Property="BorderThickness" Value="0"/>
            <Setter Property="Foreground" Value="Transparent"/>
            <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
            <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
            <Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
            <Setter Property="ScrollViewer.PanningMode" Value="Both"/>
            <Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
            <Setter Property="VerticalContentAlignment" Value="Center"/>
            <Setter Property="Padding" Value="0"></Setter>
            <Setter Property="Margin" Value="0"></Setter>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListView">
                        <ScrollViewer Focusable="false" Padding="0" Margin="0" Background="Green">
                            <ItemsPresenter Margin="0"/>
                        </ScrollViewer>
                        <ControlTemplate.Triggers>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="IsGrouping" Value="true"/>
                                    <Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false"/>
                                </MultiTrigger.Conditions>
                                <Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
                            </MultiTrigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Application.Resources>
</Application>
</code>```

And here is the MyListView.cs in WPF project:

```<code>using App1.WPF;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using Xamarin.Forms.Platform.WPF;

[assembly: ExportRenderer(typeof(Xamarin.Forms.ListView), typeof(MyListView))]
namespace App1.WPF
{
    class MyListView : ListViewRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.ListView> e)
        {
            base.OnElementChanged(e);
            foreach (var item in Control.Children)
            {
                if (item is ListView)
                {
                    var list = item as ListView;
                    list.Style = App.Current.Resources["LvStyle"] as System.Windows.Style;
                    list.ItemContainerStyle = App.Current.Resources["LvItemStyle"] as System.Windows.Style;
                }
            }
        }
    }
}
</code>```

Here is the screen capture in Android, it fits well.

And here is the screen capture in WPF. There is a strange spacing in the left of each listviewitem.

As you see, in spite I have added so many margin="0" and padding="0" above in the ListView/ListViewItem style of the WPF project, it doesn't work at all.

What's the problem? How can I solve this? Thank you.

答:
Not 100% sure the root cause of the issue, but I suspect it has something to do with how the System.Windows.ListViewItem's style is trying to present the Xamarin.Forms.ViewCell's content, and the presenter is adding some margin.

I was able to fix it by editing the ContentPresenter of your ListViewItem's style (btw, remove all your other margins and paddings to make sure none of them override this setting):

```<code>        <Style x:Key="LvItemStyle" TargetType="ListViewItem">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListViewItem">
                        <ContentPresenter Margin="-5,0,0,0"/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
</code>```

Body:
Here is the code in XAML of Xamarin project:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="App1.MainPage">

    <ListView ItemsSource="{Binding TestList}" SeparatorVisibility="None" HasUnevenRows="True">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <ViewCell.View>
                        <ContentView BackgroundColor="Red">

                        </ContentView>
                    </ViewCell.View>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</ContentPage>

Here is code-behind of Xamarin project:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace App1
{
    // Learn more about making custom code visible in the Xamarin.Forms previewer
    // by visiting https://aka.ms/xamarinforms-previewer
    [DesignTimeVisible(false)]
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
            this.BindingContext = this;
            TestList.Add(new Test() { TestName = "aaa" });
            TestList.Add(new Test() { TestName = "bbb" });
            TestList.Add(new Test() { TestName = "ccc" });
            TestList.Add(new Test() { TestName = "ddd" });
        }
        public ObservableCollection<Test> TestList { get; set; } = new ObservableCollection<Test>();
        public class Test
        {
            public string TestName { get; set; }
        }
    }
}

Here is the Style of WPF project:

<Application x:Class="App1.WPF.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:App1.WPF"
             StartupUri="MainWindow.xaml">
    <Application.Resources>

    </Application.Resources>
</Application>

And here is the MyListView.cs in WPF project:

using App1.WPF;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using Xamarin.Forms.Platform.WPF;

[assembly: ExportRenderer(typeof(Xamarin.Forms.ListView), typeof(MyListView))]
namespace App1.WPF
{
    class MyListView : ListViewRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.ListView> e)
        {
            base.OnElementChanged(e);
            foreach (var item in Control.Children)
            {
                if (item is ListView)
                {
                    var list = item as ListView;
                    list.Style = App.Current.Resources["LvStyle"] as System.Windows.Style;
                    list.ItemContainerStyle = App.Current.Resources["LvItemStyle"] as System.Windows.Style;
                }
            }
        }
    }
}

Here is the screen capture in Android, it fits well.

And here is the screen capture in WPF. There is a strange spacing in the left of each listviewitem.

As you see, in spite I have added so many margin="0" and padding="0" above in the ListView/ListViewItem style of the WPF project, it doesn't work at all.

What's the problem? How can I solve this? Thank you.

Body:
Not 100% sure the root cause of the issue, but I suspect it has something to do with how the System.Windows.ListViewItem's style is trying to present the Xamarin.Forms.ViewCell's content, and the presenter is adding some margin.

I was able to fix it by editing the ContentPresenter of your ListViewItem's style (btw, remove all your other margins and paddings to make sure none of them override this setting):

        <Style x:Key="LvItemStyle" TargetType="ListViewItem">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListViewItem">
                        <ContentPresenter Margin="-5,0,0,0"/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>


问:
Firing javascript on button click sharepoint
All I am trying to accomplish is to call a javascript function when a button is clicked in sharepoint. This is the extent of my 'code' in sharepoint designer 2007...

```<code><%@ Page masterpagefile="~masterurl/default.master" language="C#" title="|" inherits="Microsoft.SharePoint.WebPartPages.WebPartPage, Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bxe2111e8529c" meta:webpartpageexpansion="full" meta:progid="SharePoint.WebPartPage.Document" %>
<asp:Content id="Content1" runat="server" contentplaceholderid="PlaceHolderMain">
<script type="javascript">

function tellme() {
    alert('yep yep yep');
}

</script>
<p></p>
<asp:Button runat="server" Text="Button" id="Button1" onclientclick="tellme()" />
</asp:Content>
</code>```

Can anyone tell me why the function is not called? When I save the page, view it and click the button, it just acts as a submit button. I'm perfectly happy with JS/HTML and PHP but I'm dabbling in SharePoint / .net and struggling slightly.

Thanks

Tom

答:
The Button you've added in your Sharepoint page is a ASP.Net button. it's default behaviour is postback.

If you want to do something client side, use :

```<code><input type="button" id="ClientSideBtn" value="Click ME" onclick="javascript:tellme()" />
</code>```

If you want to do something server-side, use:

```<code><asp:Button Text="Click ME" id="Button1" runat="server" onclick="Button1_Click"/>
</code>```

For the server side button , you would need to write some c# or vb.net code:

```<code>    protected void Button1_Click(object sender, EventArgs e)
    {
        //Do something here

        //Such as
        this.Response.Redirect("http://www.google.com");
    }
</code>```

You can read more here: http://support.microsoft.com/kb/306459

Body:
All I am trying to accomplish is to call a javascript function when a button is clicked in sharepoint. This is the extent of my 'code' in sharepoint designer 2007...

<%@ Page masterpagefile="~masterurl/default.master" language="C#" title="|" inherits="Microsoft.SharePoint.WebPartPages.WebPartPage, Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bxe2111e8529c" meta:webpartpageexpansion="full" meta:progid="SharePoint.WebPartPage.Document" %>
<asp:Content id="Content1" runat="server" contentplaceholderid="PlaceHolderMain">

<asp:Button runat="server" Text="Button" id="Button1" onclientclick="tellme()" />
</asp:Content>

Can anyone tell me why the function is not called? When I save the page, view it and click the button, it just acts as a submit button. I'm perfectly happy with JS/HTML and PHP but I'm dabbling in SharePoint / .net and struggling slightly.

Thanks

Tom

Body:
The Button you've added in your Sharepoint page is a ASP.Net button. it's default behaviour is postback.

If you want to do something client side, use :

<input type="button" id="ClientSideBtn" value="Click ME" onclick="javascript:tellme()" />

If you want to do something server-side, use:

<asp:Button Text="Click ME" id="Button1" runat="server" onclick="Button1_Click"/>

For the server side button , you would need to write some c# or vb.net code:

    protected void Button1_Click(object sender, EventArgs e)
    {
        //Do something here

        //Such as
        this.Response.Redirect("http://www.google.com");
    }

You can read more here: http://support.microsoft.com/kb/306459


问:
SQL Server 2019 BDC deployment on AKS stuck at Check controller logs for more details
I setup a 3 node kubernetes cluster on AKS for the purpose of deploying SQL Server 2019 BDC.

The installation went smooth for sometime and got stuck at "Cluster 'mssql-cluster' is not ready after 15.0 minutes. Check controller logs for more details".

This is the complete output:

```<code>Starting cluster deployment.
Waiting for cluster controller to start.
Waiting for cluster controller to start.
Waiting for cluster controller to start.
Waiting for cluster controller to start.
Waiting for cluster controller to start.
Cluster controller endpoint is available at XX.6X.2X.1XY:3X0X0.
Cluster control plane is ready.
Compute pool is ready.
Master pool is ready.
Data pool is ready.
Storage pool is ready.
Cluster 'mssql-cluster' is not ready after 15.0 minutes. Check controller logs for more details.
</code>```

I'm new to both AKS and BDC so I don't know where to locate the controller logs. Can someone point me in the right direction. The deployment uses the AKS-Dev-Test profile without any change.

At this point, how can I access the available controller endpoint and what will it give me at this juncture?

Update:-

I ran azdata bdc status show and the error seems to be in HDFS/Spark.

```<code>hdfs           waiting  unhealthy       StatefulSet sparkhead is not ready with 0 ready pods and 1 unready pods
spark          waiting  unhealthy       StatefulSet sparkhead is not ready with 0 ready pods and 1 unready pods
</code>```

Thanks,
rgn

答:
The issue seems to be with resources as I had picked VMs with limited resources which is not appropriate for BDC.

Thanks,
rgn

```<code>Warning  FailedScheduling  12s (x107 over 154m)  default-scheduler  0/3 nodes are available: 3 node(s) exceed max volume count.
</code>```

Body:
I setup a 3 node kubernetes cluster on AKS for the purpose of deploying SQL Server 2019 BDC.

The installation went smooth for sometime and got stuck at "Cluster 'mssql-cluster' is not ready after 15.0 minutes. Check controller logs for more details".

This is the complete output:

Starting cluster deployment.
Waiting for cluster controller to start.
Waiting for cluster controller to start.
Waiting for cluster controller to start.
Waiting for cluster controller to start.
Waiting for cluster controller to start.
Cluster controller endpoint is available at XX.6X.2X.1XY:3X0X0.
Cluster control plane is ready.
Compute pool is ready.
Master pool is ready.
Data pool is ready.
Storage pool is ready.
Cluster 'mssql-cluster' is not ready after 15.0 minutes. Check controller logs for more details.

I'm new to both AKS and BDC so I don't know where to locate the controller logs. Can someone point me in the right direction. The deployment uses the AKS-Dev-Test profile without any change.

At this point, how can I access the available controller endpoint and what will it give me at this juncture?

Update:-

I ran azdata bdc status show and the error seems to be in HDFS/Spark.

hdfs           waiting  unhealthy       StatefulSet sparkhead is not ready with 0 ready pods and 1 unready pods
spark          waiting  unhealthy       StatefulSet sparkhead is not ready with 0 ready pods and 1 unready pods

Thanks,
rgn

Body:
The issue seems to be with resources as I had picked VMs with limited resources which is not appropriate for BDC.

Thanks,
rgn

Warning  FailedScheduling  12s (x107 over 154m)  default-scheduler  0/3 nodes are available: 3 node(s) exceed max volume count.


问:
Join statement in multiple thread
I have a program that starts 2 threads and use Join.My understanding says that  joins blocks the calling operation till it is finished executing .So,the below program should give 2 Million as answer since both the threads blocks till execution is completed but I am always getting the different value.This might be because first thread is completed but second thread is not run completely.
Can someone please explain the output.

Reference -Multithreading: When would I use a Join?

```<code>namespace ThreadSample
{
    class Program
    {
        static int Total = 0;
        public static void Main()
        {
            Thread thread1 = new Thread(Program.AddOneMillion);
            Thread thread2 = new Thread(Program.AddOneMillion);

            thread1.Start();
            thread2.Start();

            thread1.Join();
            thread2.Join();

            Console.WriteLine("Total = " + Total);
            Console.ReadLine();
        }
        public static void AddOneMillion()
        {
            for (int i = 1; i <= 1000000; i++)
            {
                Total++;
            }
        }
    }
}
</code>```

答:
When you call start method of thread, it starts immediately. hence by the time u call join on the thread1, thread2 would also have started. As a result variable 'Total' will be accessed by both threads simultaneously. Hence you will not get correct result as one thread operation is overwriting the value of 'Total' value causing data lose.

```<code>    public static void Main()
    {
        Thread thread1 = new Thread(Program.AddOneMillion);
        Thread thread2 = new Thread(Program.AddOneMillion);

        thread1.Start(); //starts immediately
        thread2.Start();//starts immediately

        thread1.Join(); //By the time this line executes, both threads have accessed the Total varaible causing data loss or corruption.
        thread2.Join();

        Console.WriteLine("Total = " + Total);
        Console.ReadLine();
    }
</code>```

Inorder to correct results either u can lock the Total variable as follows

```<code>    static object _l = new object();

    public static void AddOneMillion()
    {
        for (int i = 0; i < 1000000; i++)
        {
            lock(_l)
                ii++;
        }
    }
</code>```

U can use Interlocked.Increment which atomically updates the variable.
Please refer the link posted by @Emanuel Vintilă in the comment for more insight.

```<code>    public static void AddOneMillion()
    {
        for (int i = 0; i < 1000000; i++)
        {
            Interlocked.Increment(ref Total);
        }
    }
</code>```

Title: Join statement in multiple thread

Body:
I have a program that starts 2 threads and use Join.My understanding says that  joins blocks the calling operation till it is finished executing .So,the below program should give 2 Million as answer since both the threads blocks till execution is completed but I am always getting the different value.This might be because first thread is completed but second thread is not run completely.
Can someone please explain the output.

Reference -Multithreading: When would I use a Join?

namespace ThreadSample
{
    class Program
    {
        static int Total = 0;
        public static void Main()
        {
            Thread thread1 = new Thread(Program.AddOneMillion);
            Thread thread2 = new Thread(Program.AddOneMillion);

            thread1.Start();
            thread2.Start();

            thread1.Join();
            thread2.Join();

            Console.WriteLine("Total = " + Total);
            Console.ReadLine();
        }
        public static void AddOneMillion()
        {
            for (int i = 1; i <= 1000000; i++)
            {
                Total++;
            }
        }
    }
}

Body:
When you call start method of thread, it starts immediately. hence by the time u call join on the thread1, thread2 would also have started. As a result variable 'Total' will be accessed by both threads simultaneously. Hence you will not get correct result as one thread operation is overwriting the value of 'Total' value causing data lose.

    public static void Main()
    {
        Thread thread1 = new Thread(Program.AddOneMillion);
        Thread thread2 = new Thread(Program.AddOneMillion);

        thread1.Start(); //starts immediately
        thread2.Start();//starts immediately

        thread1.Join(); //By the time this line executes, both threads have accessed the Total varaible causing data loss or corruption.
        thread2.Join();

        Console.WriteLine("Total = " + Total);
        Console.ReadLine();
    }

Inorder to correct results either u can lock the Total variable as follows

    static object _l = new object();

    public static void AddOneMillion()
    {
        for (int i = 0; i < 1000000; i++)
        {
            lock(_l)
                ii++;
        }
    }

U can use Interlocked.Increment which atomically updates the variable.
Please refer the link posted by @Emanuel Vintilă in the comment for more insight.

    public static void AddOneMillion()
    {
        for (int i = 0; i < 1000000; i++)
        {
            Interlocked.Increment(ref Total);
        }
    }