{{error}}
{{(quickSearchResults.length>10)?'10+':(quickSearchResults.length)}} {{(quickSearchResults.length==1)?'result':'results'}}
{{result.title}} {{result.timeStamp | mysql2ymd }}
I am sorry, no such article was written yet.
angular ng contenteditable directive
Code for "contenteditable" directive in AngularJS.
2 files attached: myapp.js myapp.html
myapp.js myapp.html
<td>
					<span class='btn btn-xs btn-danger' ng-click='bodyContentEditable=!bodyContentEditable'><%glyphicon:edit%> Edit</span>
					<span ng-if='shadowTodo.body!=todo.body' ng-click='put("body")'><%glyphicon:ok%></span>
					<span ng-if='shadowTodo.body!=todo.body' ng-click='reset("body")'><%glyphicon:remove%></span>
					<div ng-attr-contenteditable='{{bodyContentEditable}}' ng-model='shadowTodo.body'></div>
				</td>
Converting pipe-separated values in a list of maps
1 files attached: asPsv.java
asPsv.java
public List<Map<String, String>> asPsv() {
        List<Map<String, String>> result = new ArrayList<>();
        String[] lines = Arrays.stream(this.asString().split("[\\r\\n]"))
                .map(String::trim)
                .filter(line -> line.length() > 0)
                .filter(line -> !line.startsWith("|--"))
                .filter(line -> line.charAt(0) != '#').toArray(String[]::new);
        String[] header = lines[0].split("\\|");
        for (int lineIndex = 1; lineIndex < lines.length; lineIndex++) {
            Map<String, String> currentRow = new HashMap<>();
            String[] currentCells = lines[lineIndex].split("\\|");
            for (int columnIdx = 0; columnIdx < currentCells.length; columnIdx++) {
                if (columnIdx < header.length)
                    currentRow.put(header[columnIdx].trim(), currentCells[columnIdx].trim());
            }
            result.add(currentRow);
        }
        return result;
    }
JSON report appender
1 files attached: JsonLogger.java
JsonLogger.java
import com.google.gson.Gson;
import groovy.json.JsonSlurper;

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class JsonLogger {
    private final Path path;
    private final File file;

    public JsonLogger(File file) {
        this.file = file;
        this.path = file.toPath();
    }

    public void add(Map data) {
        if (!file.exists()) {
            if (!file.getParentFile().exists())
                file.getParentFile().mkdirs();
            TryRun(file::createNewFile);
        }
        String text = new Gson().toJson(data);
        TryRun(() -> Files.write(path, Collections.singleton(text), StandardCharsets.UTF_8, StandardOpenOption.APPEND));
    }

    public List<Map> readAll() {
        return TryGet(() -> Files.readAllLines(path).stream().map(row -> (Map) new JsonSlurper().parseText(row)).collect(Collectors.toList()));
    }
}
Oracle JDBC wrapper
3 files attached: OracleJdbcConnector.java OracleJdbcRowset .java sample.groovy
OracleJdbcConnector.java OracleJdbcRowset .java sample.groovy
def conn=new OracleJdbcConnector(URL,USER,PASS);
println conn.select("select 1+? from dual where 2=?",3,4);
println conn.execute("update table where field=? and expr=?+4",value1,value2);
Digitize/dedigitize - data to image and reverse
Simple way to convert text/byte data to image and reverse.
2 files attached: Dedigitizer.java Digitizer.gsp
Dedigitizer.java Digitizer.gsp
Why you don't need a browser plugin to control online video speed
Why you don't need a browser plugin to control online video speed:
If you have an HTML 5 modern browser with proper support for media (videos in this example) you may control the speed of the videos by simple JavaScript snippets that you may put in your favourites bar.
3 files attached: decrease.js reset.js increase.js
decrease.js reset.js
javascript:Array(...document.getElementsByTagName("video")).forEach(it=>it.playbackRate=1)
increase.js
javascript:Array(...document.getElementsByTagName("video")).forEach(it=>it.playbackRate*=1.25)
Simple compression/decompression functions for byte arrays
1 files attached: Compression.java
Compression.java
package eu.sorescu.io;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.Deflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

public class Compression {
    public static byte[] compress(byte[] in) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ZipOutputStream zipOut = new java.util.zip.ZipOutputStream(baos);
        zipOut.setLevel(Deflater.BEST_COMPRESSION);
        zipOut.putNextEntry(new java.util.zip.ZipEntry("data"));
        zipOut.write(in);
        zipOut.closeEntry();
        zipOut.flush();
        zipOut.close();
        return baos.toByteArray();
    }

    public static byte[] decompress(byte[] in) throws IOException {
        ZipInputStream zis = new ZipInputStream(new ByteArrayInputStream(in));
        zis.getNextEntry();
        return zis.readAllBytes();
    }
}
simple XLSX parser in Java - returns a map with a list of rows for each sheet
1 files attached: XlsxReader.java
XlsxReader.java
package eu.sorescu.io;

import eu.sorescu.lang.Try;
import groovy.lang.Tuple2;
import groovy.util.Node;
import groovy.util.XmlParser;
import groovy.xml.QName;
import org.codehaus.groovy.runtime.ArrayUtil;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

public class XlsxReader {
    private final Map<String, byte[]> zipFiles;
    private static XmlParser XML_PARSER = Try.Throw((Try.SmartSupplier<XmlParser>) XmlParser::new);

    public XlsxReader(File file) throws IOException {
        ZipFile zip = new ZipFile(file);
        zipFiles = zip.stream().collect(Collectors.toMap(ZipEntry::getName, it -> Try.Throw(() -> zip.getInputStream(it).readAllBytes())));
    }

    private Node getXmlFile(String name) {
        return Try.Throw(() -> XML_PARSER.parse(new ByteArrayInputStream(zipFiles.get(name))));
    }

    private static Tuple2<Integer, Integer> cellName2coordinates(String cellName) {
        int row = Integer.parseInt(cellName.replaceAll("[A-Z]+", ""));
        final int[] col = {0};
        new StringBuffer(cellName.replaceAll("\\d+", "")).reverse().toString().chars()
                .forEach(c -> col[0] = col[0] * 26 + c - 'A' + 1);
        return new Tuple2<>(row - 1, col[0] - 1);
    }

    public Map<String, List<List<Object>>> getData() {
        Map<String, List<List<Object>>> result = new HashMap<>();
        Node workbook = getXmlFile("xl/workbook.xml");
        Node relations = getXmlFile("xl/_rels/workbook.xml.rels");
        Function<String, QName> q = it -> new QName("http://schemas.openxmlformats.org/spreadsheetml/2006/main", it);
        Function<String, QName> r = it -> new QName("http://schemas.openxmlformats.org/officeDocument/2006/relationships", it);
        Function<String, QName> rels = it -> new QName("http://schemas.openxmlformats.org/package/2006/relationships", it);
        Function<String, QName> s = it -> new QName("http://schemas.openxmlformats.org/spreadsheetml/2006/main", it);
        workbook.getAt(q.apply("sheets")).getAt(q.apply("sheet")).stream().forEach(workbookEntry -> {
            String sheetName = String.valueOf(((Node) workbookEntry).attribute("name"));
            result.put(sheetName, new ArrayList<>());
            String sheetId = String.valueOf(((Node) workbookEntry).attribute(r.apply("id")));
            String sheetPath = String.valueOf(relations.getAt(rels.apply("Relationship")).stream()
                    .filter(it -> ((Node) it).attribute("Id").equals(sheetId))
                    .map(it -> ((Node) it).attribute("Target"))
                    .findFirst().get());
            Node sheet = getXmlFile("xl/" + sheetPath);
            sheet.getAt(s.apply("sheetData")).getAt(s.apply("row")).forEach(row -> {
                ((Node) row).getAt(s.apply("c")).forEach(cell -> {
                    Node v = (Node) ((Node) cell).getAt(s.apply("v")).get(0);
                    String cellName = (String) ((Node) cell).attribute(("r"));
                    Tuple2<Integer, Integer> coordinates = cellName2coordinates(cellName);
                    while (result.get(sheetName).size() <= coordinates.getFirst())
                        result.get(sheetName).add(new ArrayList<>());
                    while (result.get(sheetName).get(coordinates.getFirst()).size() <= coordinates.getSecond())
                        result.get(sheetName).get(coordinates.getFirst()).add(null);
                    result.get(sheetName).get(coordinates.getFirst()).set(coordinates.getSecond(), v.text());
                });
            });
        });
        return result;
    }

    public static void main(String[] args) throws IOException {
        XlsxReader xlsx = new XlsxReader(new File("c:\\Users\\dsorescu.DBDC\\Desktop\\Book1.xlsx"));
        System.out.println(xlsx.zipFiles.keySet());
        System.out.println(new String(xlsx.zipFiles.get("xl/workbook.xml")));
        System.out.println(xlsx.getData());
    }
}
2017-08-03
Sample code that prompts when new server certificates found, and if confirmed, they are saved on disk for further usage.
1 files attached: SSLTest.java
SSLTest.java
package main;

import sun.misc.BASE64Encoder;
import sun.misc.IOUtils;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.security.auth.callback.ConfirmationCallback;
import javax.swing.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.security.SecureRandom;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.stream.Stream;

public class SSLTest{
    interface FlexSupplier<T>{
        T get() throws Throwable;
    }

    private static <T> T Try(FlexSupplier<T> function){
        try{
            return function.get();
        }catch(Throwable throwable){
            throw new RuntimeException(throwable);
        }
    }

    private static X509Certificate[] getSavedCertificates(){
        CertificateFactory x509=Try(()->CertificateFactory.getInstance("X.509"));
        return Stream.of(new File("c:\\workingFolder").listFiles())
                       .filter(it->it.getName().endsWith(".cer"))
                       .map(it->Try(()->new FileInputStream(it)))
                       .map(file->Try(()->x509.generateCertificate(file)))
                       .toArray(X509Certificate[]::new);
    }

    private static void saveCertificate(X509Certificate certificate){
        Try(()->Files.write(new File("c:\\workingFolder\\"+certificate.getSerialNumber()+".cer").toPath(),certificate.getEncoded()));
    }

    private static boolean matches(X509Certificate savedCertificate,X509Certificate newCertificate){
        if(savedCertificate.getSerialNumber().equals(newCertificate.getSerialNumber()))
            return true;
        try{
            newCertificate.verify(savedCertificate.getPublicKey());
            return true;
        }catch(Throwable t){
            return false;
        }
    }

    private static void validateCertificate(X509Certificate it){
        System.out.println("Checking certificate: "+it.getSubjectDN());
        for(X509Certificate saved : getSavedCertificates())
            if(matches(saved,it)){
                System.out.println("Matched by: "+saved.getSubjectDN()+" by "+saved.getIssuerDN());
                return;
            }
        System.out.println("Not matched!!!");
        if(promptFor(it))
            saveCertificate(it);
        else throw new RuntimeException("Certificate rejected");
    }

    private static boolean promptFor(Certificate it){
        X509Certificate x=(X509Certificate)it;
        String message=x.getNotBefore()+"-"+x.getNotAfter()+"\r\n";
        message+=x.getIssuerDN()+" by "+x.getIssuerX500Principal()+"\r\n";
        message+=x.getSerialNumber()+"\r\n";
        message+=new BASE64Encoder().encode(x.getSignature());
        return JOptionPane.showConfirmDialog(null,message)==ConfirmationCallback.YES;
    }

    public static void main(String[] args) throws IOException{
        trustSavedCertificates();
        URL url;
        url=new URL("https://host/domain");
        HttpsURLConnection con=(HttpsURLConnection)url.openConnection();
        System.out.println(new String(IOUtils.readFully(con.getInputStream(),-1,true)));
    }


    public static void trustSavedCertificates(){
        TrustManager[] trustAllCerts=new TrustManager[]{
                new X509TrustManager(){
                    public X509Certificate[] getAcceptedIssuers(){
                        return null;
                    }

                    public void checkClientTrusted(X509Certificate[] certs,String authType){
                    }

                    public void checkServerTrusted(X509Certificate[] certs,String authType){
                        for(X509Certificate cert : certs)
                            validateCertificate(cert);
                    }
                }
        };
        try{
            SSLContext sslContext=SSLContext.getInstance("SSL");
            sslContext.init(null,trustAllCerts,new SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
        }catch(Exception e){
            e.printStackTrace();
        }

    }
}
How to retrieve server certificates, save them, and use their public keys to validate new connections
How to retrieve server certificates, save them, and use their public keys to validate new connections
3 files attached: SSLTest.java findCertificates.java validateUsingCertificates.java
SSLTest.java findCertificates.java
URL url = new URL("https://server/");
List<String> certificateStrings = getAllCertificateStrings(url);
// save the relevant certificates on your disk
validateUsingCertificates.java
URL url = new URL("https://server/");
List<String> certificateStrings = getAllCertificateStrings(url);// or load them from disk
List<PublicKey> publicKeys = certificateStrings.stream().map(it -> Try(() -> base64certificate2publicKey(it))).collect(Collectors.toList());
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
con.setHostnameVerifier(verifier(publicKeys));
System.out.println(new String(IOUtils.readFully(con.getInputStream(), -1, true)));