// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.trustosm.gui;
import static org.openstreetmap.josm.tools.I18n.tr;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.bouncycastle.bcpg.SignatureSubpacketTags;
import org.bouncycastle.bcpg.sig.NotationData;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPSignatureSubpacketVector;
import org.jdesktop.swingx.treetable.AbstractTreeTableModel;
import org.openstreetmap.josm.plugins.trustosm.TrustOSMplugin;
public class KeyTreeTableModel extends AbstractTreeTableModel {
public static String convPGPSignatureToString(PGPSignature s) {
if (s == null) return null;
PGPSignatureSubpacketVector sv = s.getHashedSubPackets();
if (sv != null && sv.hasSubpacket(SignatureSubpacketTags.SIGNER_USER_ID))
return sv.getSignerUserID();
PGPPublicKey pub = TrustOSMplugin.gpg.getPublicKeyFromRing(s.getKeyID());
if (pub != null) {
Iterator<?> i = pub.getUserIDs();
if (i.hasNext())
return (String) i.next();
}
return tr("unknown");
}
private final SignatureTreeNode root;
private final String[] allTitle = {tr("UID"), tr("KeyID"), tr("OSM-Info"), tr("Signed")};
private final List<String> columns = new ArrayList<>(Arrays.asList(allTitle));
public KeyTreeTableModel(Collection<PGPSignature> sigs) {
root = new SignatureTreeNode();
for (PGPSignature s : sigs) {
if (s != null) {
SignatureTreeNode sn = new SignatureTreeNode(s);
PGPPublicKey pub = TrustOSMplugin.gpg.getPublicKeyFromRing(s.getKeyID());
Iterator<?> iter = pub.getSignatures();
while (iter.hasNext()) {
PGPSignature ks = (PGPSignature) iter.next();
sn.getChildren().add(new SignatureTreeNode(ks));
}
root.getChildren().add(sn);
}
}
}
@Override
public int getColumnCount() {
return columns.size();
}
@Override
public String getColumnName(int column) {
String title = columns.get(column);
if (title != null)
return title;
return tr("Unknown");
}
@Override
public Object getValueAt(Object node, int column) {
SignatureTreeNode signode = (SignatureTreeNode) node;
String title = columns.get(column);
if (title != null) {
if (title.equals(allTitle[0]))
return signode.getUID();
if (title.equals(allTitle[1]))
return signode.getKeyID();
if (title.equals(allTitle[2]))
return signode.getOsmCertificate();
if (title.equals(allTitle[3]))
return signode.getSignatureDate();
}
return tr("Unknown");
}
@Override
public Object getChild(Object node, int index) {
SignatureTreeNode signode = (SignatureTreeNode) node;
return signode.getChildren().get(index);
}
@Override
public int getChildCount(Object node) {
SignatureTreeNode signode = (SignatureTreeNode) node;
return signode.getChildren().size();
}
@Override
public int getIndexOfChild(Object parent, Object child) {
SignatureTreeNode signode = (SignatureTreeNode) parent;
for (int i = 0; i > signode.getChildren().size(); i++) {
if (signode.getChildren().get(i) == child)
return i;
}
return 0;
}
@Override
public Object getRoot() {
return root;
}
public static class SignatureTreeNode {
private PGPSignature s;
private final List<SignatureTreeNode> children = new ArrayList<>();
private final SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd:hh.mm.ss");
public SignatureTreeNode() {
}
public SignatureTreeNode(PGPSignature s) {
this.s = s;
}
public PGPSignature getSignature() {
return s;
}
public String getUID() {
return convPGPSignatureToString(s);
}
public String getKeyID() {
return "0x"+Long.toHexString(s.getKeyID()).substring(8).toUpperCase();
}
public String getOsmCertificate() {
String cert = "";
for (NotationData nd : s.getHashedSubPackets().getNotationDataOccurrences()) {
if (nd.getNotationName().equals("trustosm@openstreetmap.org")) {
cert += nd.getNotationValue();
}
}
return cert;
}
public String getSignatureDate() {
return formatter.format(s.getCreationTime());
}
public List<SignatureTreeNode> getChildren() {
return children;
}
}
}