/**
*
*/
package net.conselldemallorca.helium.applet.signatura;
import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Locale;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.UIManager;
import netscape.javascript.JSObject;
import org.jdesktop.layout.GroupLayout;
/**
* Applet per a la signatura de documents digitals
*
* @author Limit Tecnologies <limit@limit.es>
*/
public abstract class SignaturaApplet extends Applet {
private JPanel jPanel = new JPanel();
private JButton jButtonSignar;
private JComboBox jComboBoxCertificats;
private JLabel jLabelCertificat;
private JLabel jLabelContrasenya;
private JPasswordField jPasswordField;
private PropertyResourceBundle missatges;
public void init() {
String lang = getParameter("locale");
try {
if (lang != null)
missatges = (PropertyResourceBundle)ResourceBundle.getBundle("net.conselldemallorca.helium.integracio.plugins.signatura.applet.missatges_signatura", new Locale(lang));
else
missatges = (PropertyResourceBundle)ResourceBundle.getBundle("net.conselldemallorca.helium.integracio.plugins.signatura.applet.missatges_signatura");
} catch(Exception e) {
e.printStackTrace();
}
}
public void start() {
initComponents();
initSignature();
}
private void initComponents() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ignored) {}
jComboBoxCertificats = new JComboBox();
jLabelCertificat = new JLabel();
jLabelContrasenya = new JLabel();
jPasswordField = new JPasswordField();
jButtonSignar = new JButton();
jComboBoxCertificats.setModel(
new DefaultComboBoxModel(
new String[] {missatges.getString("msg.info.carregant")}));
jComboBoxCertificats.setEnabled(false);
jLabelCertificat.setText(missatges.getString("label.certificat"));
jLabelContrasenya.setText(missatges.getString("label.contrasenya"));
jPasswordField.setEnabled(false);
jButtonSignar.setText(missatges.getString("accio.signar"));
jButtonSignar.setEnabled(false);
GroupLayout layout = new GroupLayout(jPanel);
jPanel.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(layout.createSequentialGroup()
.addContainerGap()
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(layout.createSequentialGroup()
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
.add(jLabelContrasenya)
.add(jLabelCertificat))
.add(18, 18, 18)
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(jPasswordField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 194, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.add(jComboBoxCertificats, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 194, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))
.add(jButtonSignar))
.addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(layout.createSequentialGroup()
.addContainerGap()
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
.add(jLabelCertificat)
.add(jComboBoxCertificats, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
.add(jLabelContrasenya)
.add(jPasswordField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(jButtonSignar)
.addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
jButtonSignar.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {jButtonSignarActionPerformed(e);}
});
add(jPanel, BorderLayout.CENTER);
String bgColor = getParameter("bgColor");
if (bgColor == null) {
setBackground(Color.WHITE);
jPanel.setBackground(Color.WHITE);
} else {
setBackground(new Color(Integer.valueOf(bgColor, 16).intValue(), true));
jPanel.setBackground(new Color(Integer.valueOf(bgColor, 16).intValue()));
}
}
private void initSignature() {
try {
initSigner();
String[] certList = null;
try {
certList = getCertList(getSignaturaParams());
} catch (Exception ex) {
missatgeError("msg.error.certlist");
ex.printStackTrace();
return;
}
if (certList != null) {
jComboBoxCertificats.setModel(
new DefaultComboBoxModel(certList));
} else {
jComboBoxCertificats.setModel(
new DefaultComboBoxModel(new String[] {}));
}
jComboBoxCertificats.setEnabled(true);
jButtonSignar.setEnabled(true);
jPasswordField.setEnabled(true);
} catch (NecessitaActualitzarException ex) {
ex.printStackTrace();
missatgeError("msg.error.upgrade", ex.getLocalizedMessage());
getAppletContext().showDocument(ex.getUrl());
}
}
private void jButtonSignarActionPerformed(ActionEvent evt) {
if (confirm("msg.configrm.firmar")) {
String certName = (String)jComboBoxCertificats.getSelectedItem();
if (certName != null) {
try {
HttpURLConnection conn = (HttpURLConnection)new URL(getSourceUrl()).openConnection();
conn.connect();
String filename = getFileNameFromHttpUtlConnection(conn);
InputStream connInputStream = conn.getInputStream();
if (connInputStream != null) {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] tmp = new byte[1024];
while ((nRead = connInputStream.read(tmp, 0, tmp.length)) != -1) {
buffer.write(tmp, 0, nRead);
}
buffer.flush();
if (signarDocument(buffer.toByteArray(), filename, certName)) {
JSObject win = JSObject.getWindow(this);
win.eval("location.reload()");
}
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
} catch (Exception ex) {
missatgeError("msg.error.download", ex.getLocalizedMessage());
}
} else {
missatgeError("msg.error.nosel");
}
}
}
private void missatgeError(String missatge) {
missatgeError(missatge, null);
}
private void missatgeError(String missatge, String afegit) {
String text = missatges.getString(missatge) + ((afegit != null) ? ": " + afegit : "");
JOptionPane.showMessageDialog(
jPanel,
text,
missatges.getString("msg.titol"),
JOptionPane.ERROR_MESSAGE);
}
private boolean confirm(String missatge) {
String text = missatges.getString(missatge);
return JOptionPane.showConfirmDialog(
jPanel,
text,
missatges.getString("msg.titol"),
JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION;
}
private boolean signarDocument(byte[] inputDocument, String filename, String certName) {
Object[] resposta = new Object[3];
resposta[0] = getParameter("token");
try {
Object signatura = sign(
inputDocument,
certName,
new String(jPasswordField.getPassword()),
getSignaturaParams());
resposta[1] = filename;
resposta[2] = signatura;
return enviarDocumentSignat(resposta);
} catch (ContrasenyaIncorrectaException ex) {
missatgeError("msg.error.contrasenya");
} catch (SignaturaException ex) {
missatgeError("msg.error.firma", ex.getLocalizedMessage());
}
return false;
}
private boolean enviarDocumentSignat(Object resposta) {
String TWOHYPHENS = "--";
String NEWLINE = "\r\n";
try {
HttpURLConnection conn = (HttpURLConnection)new URL(getTargetUrl()).openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setDefaultUseCaches(false);
String boundary = "------" + Long.toString(System.currentTimeMillis(), 16);
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
DataOutputStream out = new DataOutputStream(conn.getOutputStream());
out.writeBytes(TWOHYPHENS + boundary + NEWLINE);
out.writeBytes("Content-Disposition: form-data; name=\"data\"; filename=\"data.bin\"" + NEWLINE);
out.writeBytes("Content-Type: application/octet-stream" + NEWLINE + NEWLINE);
ObjectOutputStream oout = new ObjectOutputStream(conn.getOutputStream());
oout.writeObject(resposta);
out.writeBytes(NEWLINE);
out.writeBytes(TWOHYPHENS + boundary + TWOHYPHENS + NEWLINE);
out.flush();
out.close();
conn.getInputStream().close();
return true;
} catch (Exception ex) {
missatgeError("msg.error.upload", ex.getLocalizedMessage());
return false;
}
}
private String getSourceUrl() throws Exception {
return getParameter("sourceUrl");
}
private String getTargetUrl() {
return getParameter("targetUrl");
}
private String getSignaturaParams() {
String signaturaParams = getParameter("signaturaParams");
return signaturaParams;
}
private String getFileNameFromHttpUtlConnection(HttpURLConnection conn) {
String filenameToken = "filename=\"";
String contentType = conn.getContentType();
String contentDisposition = conn.getHeaderField("Content-Disposition");
if (contentDisposition != null) {
int filenameIndex = contentDisposition.indexOf(filenameToken);
if (filenameIndex != -1)
return contentDisposition.substring(
filenameIndex + filenameToken.length(),
contentDisposition.indexOf("\"", filenameIndex + filenameToken.length()));
}
if (contentType.contains("pdf") || contentType.contains("PDF"))
return "unknown.pdf";
else
return "unknown.bin";
}
public abstract void initSigner() throws NecessitaActualitzarException;
public abstract String[] getCertList(String params) throws ObtencioCertificatsException;
public abstract Object sign(
byte[] inputDocument,
String certName,
String password,
String params) throws SignaturaException, ContrasenyaIncorrectaException;
private static final long serialVersionUID = 1L;
}