/** * Provides implementation class for the database access object * (DAO and DVO) for the database layer. */ package hk.hku.cecid.edi.sfrm.dao.ds; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.FileInputStream; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.InputStreamReader; import java.security.cert.X509Certificate; import java.security.cert.CertificateFactory; import java.sql.Timestamp; import hk.hku.cecid.edi.sfrm.spa.SFRMException; import hk.hku.cecid.edi.sfrm.spa.SFRMProperties; import hk.hku.cecid.edi.sfrm.dao.SFRMPartnershipDVO; import hk.hku.cecid.piazza.commons.io.IOHandler; import hk.hku.cecid.piazza.commons.dao.ds.DataSourceDVO; /** * The <code>SFRMPartnershipDSDVO</code> is a data value object representing * a tabular row in the <em>sfrm_partnership</em> in the persistence layer.<br/><br/> * * Creation Date: 27/9/2006<br/> * * It possesses caching automatically for most frequently fields shown below: * <ol> * <li>partnership Id</li> * <li>partnership endpoint</li> * <li>maximum retry allowed</li> * <li>retry interval</li> * <li>X509 verfication / encryption cerfiticates</li> * </ol><br/> * * So developers do not need to worry the issue of thread contention and * can freely call the <em>get</em> and <em>set</em> with no performance impact.<br/> * * Version 1.0.1 - * <ol> * <li>Added cache for hot access field, it requires extra <em>17</em> bytes + 1 soft reference * per <code>SFRMPartnershipDSDVO</code> object.</li> * * * @author Twinsen Tsang * @version 1.0.1 * @since 1.0.0 */ public class SFRMPartnershipDSDVO extends DataSourceDVO implements SFRMPartnershipDVO { /** * Backward Compatible serial version UID. */ private static final long serialVersionUID = 4453567496887231495L; /** * The cached partnership Id; [4B] */ private String partnershipId; /** * The cached partnership endpoint; [4B] */ private String partnerEndpoint; /** * The cached retry max. [4B] */ private int retryMax = Integer.MIN_VALUE; /** * The cached retry interval. [4B] */ private int retryInterval = Integer.MIN_VALUE; /** * Constructor. */ public SFRMPartnershipDSDVO(){} /** * [@GET, THREAD-SAFETY] Get the partnership sequence no from this partnership DVO. */ public int getPartnershipSeq(){ return super.getInt("partnershipSeq"); } /** * [@SET, THREAD-SAFETY] Set the partnership sequence */ public void setPartnershipSeq(int partnershipSeq){ super.setInt("partnershipSeq", partnershipSeq); } /** * [@GET, THREAD-SAFETY, CACHABLE]<br/><br/> * * Get the partnership from this partnership DVO. */ public String getPartnershipId(){ // TODO: Make it become thread-safety // Multiple access requires super.getString twice or more in order to cache it // into variable. if (this.partnershipId == null){ String partnershipId = super.getString("partnershipId"); this.partnershipId = partnershipId; } return this.partnershipId; } /** * [@SET, THREAD-SAFETY] Set the new partnership id to this partnership DVO. * * @param partnershipId The new partnership Id. */ public void setPartnershipId(String partnershipId){ super.setString("partnershipId", partnershipId); // cache value. this.partnershipId = partnershipId; } /** * [@GET, THREAD-SAFETY] Get the description of the partnership DVO. */ public String getDescription(){ return super.getString("description"); } /** * [@SET, THREAD-SAFETY] Set the new description to this partnership DVO. * * @param description The new description. */ public void setDescription(String description){ super.setString("description", description); } /** * [@GET, THREAD-SAFETY] Get the sending endpoint of the partnership. * * The endpoint in the database stores only the * address of receiver. For example, like * <strong>http://127.0.0.1:8080/</strong> or * <strong>http://sfrm.partnership.com:8080/</strong><br><br> * * But the endpoint returned here will concat a designated * conext path = "corvus/httpd/sfrm/inbound". */ public String getPartnerEndpoint() { String endPoint = super.getString("partnerEndpoint"); if (this.partnerEndpoint == null && endPoint != null){ if (!endPoint.endsWith("/")) endPoint += "/"; endPoint += CONTEXT_PATH; this.partnerEndpoint = endPoint; } return this.partnerEndpoint; } /** * Get the sending endpoint of the partnership without appended the context path */ public String getOrgPartnerEndpoint(){ return super.getString("partnerEndpoint"); } /** * [@GET, THREAD-SAFETY] Set the partnership endpoint of the partnership DVO. * * @param endpoint The new partnership endpoint. */ public void setPartnerEndPoint(String endpoint) { super.setString("partnerEndpoint", endpoint); this.partnerEndpoint = endpoint; } /** * [@GET, THREAD-SAFETY] Get the partnership endpoint of this partnership DVO. */ public String getPartnerCertFingerprint(){ return super.getString("partnerCertFingerprint"); } /** * [@SET, THREAD-SAFETY] Set the partnership endpoint of this partnership DVO. */ public void setPartnerCertFingerprint(String partnerCertFingerprint){ super.setString("partnerCertFingerprint", partnerCertFingerprint); } /** * [@GET, THREAD-SAFETY] whether the partnership requires SSL hostname verified. */ public boolean isHostnameVerified() { return super.getBoolean("isHostnameVerified"); } /** * [@SET, THREAD-SAFETY] set whether the partnership requires SSL hostname verified. */ public void setIsHostnameVerified(boolean isHostnameVerified) { super.setBoolean("isHostnameVerified", isHostnameVerified); } public String getSignAlgorithm() { return super.getString("signAlgorithm"); } public void setSignAlgorithm(String signAlgorithm) { super.setString("signAlgorithm", signAlgorithm); } public String getEncryptAlgorithm() { return super.getString("encryptAlgorithm"); } public void setEncryptAlgorithm(String encryptAlgorithm) { super.setString("encryptAlgorithm", encryptAlgorithm); } /** * [@GET, THREAD-SAFETY] Get the maximum retry allowed for this partnership DVO. */ public int getRetryMax() { if (this.retryMax == Integer.MIN_VALUE){ int ret = this.getInt("retryMax"); this.retryMax = ret; } return this.retryMax; } /** * [@SET, THREAD-SAFETY] Set the maximum retry allowed for this partnership DVO. */ public void setRetryMax(int retryMax) { this.setInt("retryMax", retryMax); this.retryMax = retryMax; } /** * [@GET, NON-THREAD-SAFETY] Get the retry interval of this partnership DVO. */ public int getRetryInterval() { if (this.retryInterval == Integer.MIN_VALUE){ int ret = this.getInt("retryInterval"); this.retryInterval = ret; } return this.retryInterval; } /** * [@SET, THREAD-SAFETY] Set the retry interval of this partnership DVO. */ public void setRetryInterval(int retryInterval) { super.setInt("retryInterval", retryInterval); this.retryInterval = retryInterval; } public boolean isDisabled() { return super.getBoolean("isDisabled"); } public void setIsDisabled(boolean isDisabled) { super.setBoolean("isDisabled", isDisabled); } /** * [@GET, THREAD-SAFETY] * * @param get the creation timestamp of this partnership record. */ public Timestamp getCreationTimestamp() { return (Timestamp)super.get("createdTimestamp"); } /** * [@SET, THREAD-SAFETY] Set the creation timestamp. * * @param creationTimestamp the new value of the creation time stamp for this partnership DVO. */ public void setCreationTimestamp(Timestamp creationTimestamp) { super.put("createdTimestamp", creationTimestamp); } /** * [@GET, THREAD-SAFETY] * * @return Get the last modified timestamp */ public Timestamp getModifiedTimestamp() { return (Timestamp)this.get("modifiedTimestamp"); } /** * [@GET, THREAD-SAFETY] Set the last modified timestamp * * @param modifiedTimestamp the last modified timestamp. */ public void setModifiedTimestamp(Timestamp modifiedTimestamp) { this.put("modifiedTimestamp", modifiedTimestamp); } /** * Get X509 certificate from trusted certificate store specified in SFRM properties * * @return X509 certificate * @throws SFRMException */ public X509Certificate getVerifyX509Certificate() throws SFRMException{ return getX509Certificate(new File(SFRMProperties.getTrustedCertStore() ,this.getPartnerCertFingerprint())); } /** * Get X509 certificate from trusted certificate store specified in SFRM properties * * @return X509 certificate * @throws SFRMException */ public X509Certificate getEncryptX509Certificate() throws SFRMException{ if(this.getPartnerCertFingerprint() != null){ return getX509Certificate(new File(SFRMProperties.getTrustedCertStore() ,this.getPartnerCertFingerprint())); } return null; } /** * Get the X509 Verification / Encryption * certificates. * * @param certFile The file with fingerprint as file name of the public certificate * @return X509 certificate */ private X509Certificate getX509Certificate(File certFile) throws SFRMException { try { X509Certificate cert; if (!certFile.exists()) throw new SFRMException("Missing certs with finger print:" + certFile); BufferedInputStream bis = new BufferedInputStream( new FileInputStream(certFile)); byte[] bs = IOHandler.readBytes(bis); InputStream certStream = new ByteArrayInputStream(bs); cert = (X509Certificate) CertificateFactory .getInstance("X.509") .generateCertificate(certStream); bis.close(); certStream.close(); return cert; } catch (Exception e){ throw new SFRMException("Unable to load the certificates with fingerprint: " + certFile, e); } } public String getEncryptX509CertificateBase64() throws FileNotFoundException, IOException{ File certFile = new File(SFRMProperties.getTrustedCertStore(), this.getPartnerCertFingerprint()); InputStreamReader certReader = new InputStreamReader(new FileInputStream(certFile)); String certContent = IOHandler.readString(certReader); return certContent; } }