/**
* 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.
*/
package at.knowcenter.wag.egov.egiz.sig.signaturelayout;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Vector;
import java.util.regex.Pattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import at.gv.egiz.pdfas.exceptions.ErrorCode;
import at.knowcenter.wag.egov.egiz.cfg.SettingsReader;
import at.knowcenter.wag.egov.egiz.exceptions.ConnectorException;
import at.knowcenter.wag.egov.egiz.exceptions.SettingNotFoundException;
import at.knowcenter.wag.egov.egiz.exceptions.SettingsException;
/**
* Returns instances of signature layout handlers based on given bku
* identifiers.
*
* @author tknall
*/
public class SignatureLayoutHandlerFactory {
/**
* Prefix of configuration keys defining bku identifiers for a signature layout.
*/
private final static String SIGNATURE_LAYOUT_CONFIG_KEY_PATTERN = "signaturelayout.pattern";
/**
* Prefix of configuration keys defining implementations of signature layout handlers.
* @see SignatureLayoutHandler
*/
private final static String SIGNATURE_LAYOUT_CONFIG_KEY_IMPL = "signaturelayout.implementation";
/**
* A map holding instantiated signature layout implementations (for performance reasons).
*/
private final static Map instances = Collections.synchronizedMap(new HashMap());
/**
* The log.
*/
private static Log log = LogFactory.getLog(SignatureLayoutHandlerFactory.class);
/**
* Returns an instance of a signature layout handler based on the given bku identifier.
* @param bkuIdentifier The bku identifier (e.g. citizen-card-environment/1.2 MOCCA/1.1.1
).
* @return An implementation of a signature layout handler.
* @throws ConnectorException Thrown in case of an error finding a match within the configuration with the given bku identifier.
* @throws SettingsException Thrown in case of an error within the configuration.
*/
public static SignatureLayoutHandler getSignatureLayoutHandlerInstance(String bkuIdentifier) throws ConnectorException, SettingsException {
if (bkuIdentifier == null) {
throw new SettingsException(ErrorCode.MISSING_HEADER_SERVER_USER_AGENT, "Unable to determine type of citizen card environment. Response header \"Server\" resp. \"user-agent\" is missing. Refer to security layer specification 1.2.2, section 3.3.2.");
}
SignatureLayoutHandler signatureLayoutHandler = (SignatureLayoutHandler) instances.get(bkuIdentifier);
if (signatureLayoutHandler == null) {
SettingsReader sr = SettingsReader.getInstance();
Vector v = sr.getSettingKeys(SIGNATURE_LAYOUT_CONFIG_KEY_PATTERN);
String implValue = null;
Iterator it = v.iterator();
try {
while (it.hasNext()) {
String subKey = (String) it.next();
String key = SIGNATURE_LAYOUT_CONFIG_KEY_PATTERN + "." + subKey;
String value = sr.getSetting(key);
Pattern p = Pattern.compile(value);
if (p.matcher(bkuIdentifier).matches()) {
String implKey = SIGNATURE_LAYOUT_CONFIG_KEY_IMPL + "." + subKey;
implValue = sr.getSetting(implKey);
}
}
} catch (SettingNotFoundException e) {
throw new SettingsException(ErrorCode.INVALID_SIGNATURE_LAYOUT_IMPL_CONFIGURED, e.getMessage());
}
if (implValue == null) {
throw new ConnectorException(ErrorCode.BKU_NOT_SUPPORTED, "Unsupported BKU: " + bkuIdentifier);
}
log.debug("Trying to instantiate SignatureLayoutHandler \"" + implValue + "\".");
try {
Class clazz = Class.forName(implValue);
Object obj = clazz.newInstance();
if (!(obj instanceof SignatureLayoutHandler)) {
throw new SettingsException(ErrorCode.INVALID_SIGNATURE_LAYOUT_IMPL_CONFIGURED, "Invalid signature layout implementation (\"" + implValue + "\") configured for bku identifier \"" + bkuIdentifier + "\".");
}
signatureLayoutHandler = (SignatureLayoutHandler) obj;
} catch (InstantiationException e) {
throw new SettingsException(ErrorCode.INVALID_SIGNATURE_LAYOUT_IMPL_CONFIGURED, "Error instantiating signature layout implementation (\"" + implValue + "\") configured for bku identifier \"" + bkuIdentifier + "\".");
} catch (IllegalAccessException e) {
throw new SettingsException(ErrorCode.INVALID_SIGNATURE_LAYOUT_IMPL_CONFIGURED, "Illegal access instantiating signature layout implementation (\"" + implValue + "\") configured for bku identifier \"" + bkuIdentifier + "\".");
} catch (ClassNotFoundException e) {
throw new SettingsException(ErrorCode.INVALID_SIGNATURE_LAYOUT_IMPL_CONFIGURED, "Unable to find signature layout implementation (\"" + implValue + "\") configured for bku identifier \"" + bkuIdentifier + "\".");
}
log.debug("SignatureLayoutHandler successfully instantiated.");
instances.put(bkuIdentifier, signatureLayoutHandler);
} else {
log.trace("SignatureLayoutHandler has already been instantiated. Returning old instance.");
}
return signatureLayoutHandler;
}
/**
* Verifies that the bku is supported trying to match the given bku identifier.
* @param bkuIdentifier The bku identifier (e.g. citizen-card-environment/1.2 MOCCA/1.1.1
).
* @throws ConnectorException Thrown in case of an error (e.g. bku not supported).
* @throws SettingsException Thrown in case of an error within the configuration.
*/
public static void verifyBKUSupport(String bkuIdentifier) throws ConnectorException, SettingsException {
getSignatureLayoutHandlerInstance(bkuIdentifier);
}
}