/** * Copyright 2006 by Know-Center, Graz, Austria * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a * joint initiative of the Federal Chancellery Austria and Graz University of * Technology. * * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by * the European Commission - subsequent versions of the EUPL (the "Licence"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * http://www.osor.eu/eupl/ * * Unless required by applicable law or agreed to in writing, software * distributed under the Licence is distributed on an "AS IS" basis, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the Licence for the specific language governing permissions and * limitations under the Licence. * * This product combines work with different licenses. See the "NOTICE" text * file for details on the various modules and licenses. * The "NOTICE" text file is part of the distribution. Any derivative works * that you distribute must include a readable copy of the "NOTICE" text file. * * $Id: SignatureTypeDefinition.java,v 1.3 2006/08/25 17:09:41 wprinz Exp $ */ package at.knowcenter.wag.egov.egiz.sig; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Vector; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import at.knowcenter.wag.egov.egiz.cfg.SettingsReader; import at.knowcenter.wag.egov.egiz.exceptions.SignatureException; public class SignatureTypeDefinition implements Serializable { /** * SVUID. */ private static final long serialVersionUID = 1327407307346061147L; /** * The log. */ private static final Log logger_ = LogFactory.getLog(SignatureTypeDefinition.class); /** * The type of this definition */ protected String type_ = null; /** * A map of all key to caption tupls. */ private Map keyCaptionMap_ = new HashMap(); /** * A map of all key to value tupls. */ private Map keyValueMap_ = new HashMap(); /** * A list of sorted keys */ private Vector sortedKeys_ = null; /** * A list of sorted captions */ private Vector sortedCaptions_ = null; /** * A revert of sorted keys */ private Vector revertSortedKeys_ = new Vector(); /** * A revert list of sorted captions */ private Vector revertSortedCaptions_ = new Vector(); /** * The settings reader reference */ private SettingsReader settings_ = null; /** * List of (visible) field definitions. */ protected Map field_definitions_ = null; /** * List of invisible field definitions. * *

* If empty, all definitions are visible. *

*/ protected Map invisible_field_definitions = null; /** * The constructor of the signature type definition. It reads the configured * table definition of the signature block and load the type definition of a * given type. * * @param settings * a SettingsReader instance * @param type * the signature type to load * @throws SignatureException * @see SettingsReader */ public SignatureTypeDefinition(SettingsReader settings, String type) throws SignatureException { settings_ = settings; type_ = type; readSigTable(SignatureTypes.MAIN_TABLE); loadTypeDefinition(); readFieldDefinitions(); readInvisibleFieldDefinitions(); } protected void readInvisibleFieldDefinitions() { this.invisible_field_definitions = new HashMap(); for (int i = 0; i < SignatureTypes.REQUIRED_SIG_KEYS.length; i++) { String requiredKey = SignatureTypes.REQUIRED_SIG_KEYS[i]; if (!this.sortedKeys_.contains(requiredKey)) { SignatureFieldDefinition sfd = readFieldDefinition(requiredKey); this.invisible_field_definitions.put(sfd.field_name, sfd); } } } /** * Returns the List of invisible field definitions, if any. * *

* Invisible field definitions are the field definitions of required fields that are not explicitely specified in the signature profile. *

*

* Note that the concept of invisible fields can only be used by binary signatures. *

* * @return Returns the List of invisible field definitions, if any. */ public List getInvisibleFieldDefinitions() { return new ArrayList(this.invisible_field_definitions.values()); } /** * Tells, if the signature type is text-extractable, which means that all required fields are visible. * * @return Returns true, if the signature type is text-extractable. */ public boolean isTextExtractable() { if (logger_.isDebugEnabled()) { Iterator it = this.invisible_field_definitions.values().iterator(); StringBuffer buffer = new StringBuffer(); while (it.hasNext()) { SignatureFieldDefinition sfd = (SignatureFieldDefinition) it.next(); buffer.append(sfd.field_name); if (it.hasNext()) { buffer.append(", "); } } if (buffer.length() != 0) { logger_.debug("Invisible field definitions for profile \"" + this.type_ + "\" = " + buffer.toString()); } } return this.invisible_field_definitions.isEmpty(); } /** * Load the configured signature type definitions. It reads all key-captions * tupls that are used in the signature table. It also reads all key-value * tupls. * * @throws SignatureException */ private void loadTypeDefinition() throws SignatureException { if (sortedKeys_ == null) { sortKeys(); } String key_prefix = SignatureTypes.SIG_OBJ + type_ + ".key"; ArrayList keys = settings_.getKeys(key_prefix); if (keys == null) { // exthex: no exception to enable invisible signatures logger_.debug("There is no key defined for type:" + type_ +". assuming invisible signature"); return; // keep this incredible wprinz(?) lines as a puzzle: Can anyone do same thing in just one line? // SignatureException se = new SignatureException(100, "There is no key defined for type:" + type_); // ; // throw se; } for (int key_idx = 0; key_idx < keys.size(); key_idx++) { String sig_key = (String) keys.get(key_idx); String sig_key_val = settings_.getValueFromKey(key_prefix + "." + sig_key); if (sortedKeys_.contains(sig_key)) { keyCaptionMap_.put(sig_key, sig_key_val); } } String value_prefix = SignatureTypes.SIG_OBJ + type_ + ".value"; ArrayList values = settings_.getKeys(value_prefix); if (values != null) { for (int key_idx = 0; key_idx < values.size(); key_idx++) { String val_key = (String) values.get(key_idx); String val_key_val = settings_.getValueFromKey(value_prefix + "." + val_key); keyValueMap_.put(val_key, val_key_val); } } } /** * This method reads the table definition of singature type. It takes care * about the linearization of the defined key-value pairs or sub tables. The * linearisation is done reading a table from left to right and top to bottom. * A sub table is alwais a normal cell element in the linearisation prozess. * If a sub table exists therefore the linearisation of the subtable is taken * es cell element in the parent table. t This method stores a revert sorted * linearisation list of used keys in the table. This method is called * recursivley if defined nested tables. * * @param tableKey * the name of the table definition */ private void readSigTable(String tableKey) { // System.err.println("read table:" + type_ + "." + tableKey); String table_key_prefix = SignatureTypes.SIG_OBJ + type_ + "." + SignatureTypes.TABLE; String table_key = table_key_prefix + tableKey; String key_prefix = SignatureTypes.SIG_OBJ + type_ + ".key."; // ArrayList table_def_keys = settings_.getKeys(table_key); Vector table_def_keys = settings_.getSettingKeys(table_key); if (table_def_keys != null) { for (int table_key_idx = 0; table_key_idx < table_def_keys.size(); table_key_idx++) { String table_row_id = (String) table_def_keys.get(table_key_idx); String table_def_keys_name = table_key + "." + table_row_id; String table_def_string = settings_.getValueFromKey(table_def_keys_name); if (table_row_id.matches("\\D*")) { continue; } if (table_def_string != null) { // analyse the row definition String[] elems = table_def_string.split("\\|"); // ArrayList row = new ArrayList(); int elem_idx = elems.length; while (elem_idx > 0) { elem_idx--; String elem = elems[elem_idx]; String[] key_type = elem.split("-"); if (key_type.length < 2) { return; } String key = key_type[0]; String type = key_type[1]; // System.err.println("key:" + type_ + "." + tableKey + // "." + key + "=" + type); if (SignatureTypes.TYPE_TABLE.equals(key)) { // read sub table readSigTable(type); } if (SignatureTypes.TYPE_IMAGE.equals(type)) { // ignore images } if (SignatureTypes.TYPE_VALUE.equals(type)) { String sig_key_val = settings_.getValueFromKey(key_prefix + key); if (sig_key_val != null) { revertSortedKeys_.add(key); revertSortedCaptions_.add(sig_key_val); } // ignore values without caption } if ((SignatureTypes.TYPE_VALUE + SignatureTypes.TYPE_CAPTION).equals(type) || (SignatureTypes.TYPE_CAPTION + SignatureTypes.TYPE_VALUE).equals(type)) { String sig_key_val = settings_.getValueFromKey(key_prefix + key); if (sig_key_val != null) { revertSortedKeys_.add(key); revertSortedCaptions_.add(sig_key_val); } } } } } } } /** * @return Returns the keys. */ public Map getKeyCaptionMap() { return keyCaptionMap_; } /** * @return Returns the keyValueMap. */ public Map getKeyValueMap() { return keyValueMap_; } /** * Returns a caption to a given key * * @param key * @return the caption or null if the key is not found */ public String getCaptionFromKey(String key) { return (String) keyCaptionMap_.get(key); } /** * Returns a value to given key * * @param key * @return the value or null if the key is not found */ public String getValueFromKey(String key) { return (String) keyValueMap_.get(key); } /** * @return Returns the sortedKeys. */ public Vector getSortedKeys() { if (sortedKeys_ == null) { sortKeys(); } return sortedKeys_; } /** * @return Returns the sortedCaptions. */ public Vector getSortedCaptions() { if (sortedCaptions_ == null) { sortKeys(); } return sortedCaptions_; } /** * @return Returns the revertSortedCaptions. */ public Vector getRevertSortedCaptions() { return revertSortedCaptions_; } /** * @return Returns the revertSortedKeys. */ public Vector getRevertSortedKeys() { return revertSortedKeys_; } /** * This method sort the reverted sorted key-caption and key-value lists. * */ private void sortKeys() { // String key_prefix = SignatureTypes.SIG_OBJ + type_ + ".key."; sortedKeys_ = new Vector(revertSortedKeys_.size()); sortedCaptions_ = new Vector(revertSortedCaptions_.size()); for (int key_idx = revertSortedKeys_.size() - 1; key_idx >= 0; key_idx--) { sortedKeys_.add(revertSortedKeys_.get(key_idx)); sortedCaptions_.add(revertSortedCaptions_.get(key_idx)); } } /** * This method checks if a given key is defined. * * @param key * to find * @return true if the key is find false otherwise */ public boolean contains(String key) { return (keyValueMap_.get(key) != null); } /** * The standard toString method. Used for internal tests only. */ public String toString() { String strg = this.type_ + "\n"; Vector sk = getSortedKeys(); Vector sc = getSortedCaptions(); for (int i = 0; i < sk.size(); i++) { strg += sk.get(i) + "=" + sc.get(i) + "\n"; } return strg; } /** * @return Returns the signature type string. */ public String getType() { return type_; } /** * @return Returns the signature type description. */ public String getDescription() { String descr_key = SignatureTypes.SIG_OBJ + type_ + ".description"; return settings_.getValueFromKey(descr_key); } protected String getSettingsKeyBase() { return getSettingsKeyBase(type_); } /** * Gets the field definition of the given Field. * * @param field_name * The name of the field. * @return Returns the field's definition. */ public SignatureFieldDefinition readFieldDefinition(String field_name) { SignatureFieldDefinition sfd = new SignatureFieldDefinition(); sfd.field_name = field_name; sfd.caption = this.settings_.getValueFromKey(getSettingsKeyBase() + ".key." + field_name); sfd.value = this.settings_.getValueFromKey(getSettingsKeyBase() + ".value." + field_name); //sfd.value = this.settings_.getValueFromKey(getSettingsKeyBase() + type_ + ".value." + field_name); sfd.placeholder_length = -1; String phlen_str = readPhLenStringFromSettings(this.settings_, this.type_, field_name); if (phlen_str != null) { sfd.placeholder_length = Integer.parseInt(phlen_str); } return sfd; } protected static String getSettingsKeyBase (String type) { return SignatureTypes.SIG_OBJ + type; } public static String readPhLenStringFromSettings(SettingsReader settings, String profile, String field_name) { String phlen_str = settings.getValueFromKey(getSettingsKeyBase(profile) + ".phlength." + field_name); if (phlen_str == null) { phlen_str = settings.getValueFromKey("defaults.phlength." + field_name); } return phlen_str; } protected void readFieldDefinitions() { this.field_definitions_ = new HashMap(); for (int i = 0; i < this.sortedKeys_.size(); i++) { String key = (String) this.sortedKeys_.get(i); SignatureFieldDefinition sfd = readFieldDefinition(key); // sfd.brev = SignatureTypes.ALL_SIG_BREV[i]; this.field_definitions_.put(sfd.field_name, sfd); } } /** * Returns the list of field definitions of this Signature profile. * * @return Returns the list of field definitions of this Signature profile. */ public List getFieldDefinitions() { return new ArrayList(this.field_definitions_.values()); } /** * Tells if this signature profile is semantically equal to the other * signature profile. * *

* One profile is semantically equal to another one if the captions and keys * of both profiles are equal and have the same order. *

* * @param other * The other signature profile. * @return Returns true, if this profile is semantically equivalent to the * other profile. */ public boolean isSemanticallyEqual(SignatureTypeDefinition other) { List this_keys = filterOutNonRequiredFoundKeys(this.sortedKeys_); List other_keys = filterOutNonRequiredFoundKeys(other.sortedKeys_); if (this_keys.size() != other_keys.size()) { return false; } for (int i = 0; i < this_keys.size(); i++) { String this_key = (String) this_keys.get(i); String other_key = (String) other_keys.get(i); if (!this_key.equals(other_key)) { return false; } String this_caption = this.getCaptionFromKey(this_key); String other_caption = other.getCaptionFromKey(other_key); if (!this_caption.equals(other_caption)) { return false; } } return true; } /** * Filters out all non required keys from the List of keys. * * @param keys The List of keys. * * @return Returns the subset List which contains only the required keys. */ protected static List filterOutNonRequiredFoundKeys (List keys) { List required_keys = new ArrayList(keys.size()); for (int i = 0; i < keys.size(); i++) { String this_key = (String) keys.get(i); if (!SignatureTypes.isRequiredKey(this_key)) { continue; } required_keys.add(this_key); } return required_keys; } public SignatureFieldDefinition getSignatureFieldDefinition(String key) { SignatureFieldDefinition res = (SignatureFieldDefinition) this.field_definitions_.get(key); if (res == null) { res = (SignatureFieldDefinition) this.invisible_field_definitions.get(key); } return res; } }