/** * 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."); } log.debug("Trying to get SignatureLayoutHandler for \"" + bkuIdentifier + "\"."); 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.debug("SignatureLayoutHandler has already been instantiated. Class: \"" + signatureLayoutHandler.getClass().getName() + "\""); 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); } }