/* * Copyright (c) 2014 Data Harmonisation Panel * * All rights reserved. This program and the accompanying materials are made * available under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution. If not, see <http://www.gnu.org/licenses/>. * * Contributors: * Data Harmonisation Panel <http://www.dhpanel.eu> */ package eu.esdihumboldt.hale.common.schema.model.validate.factory.extension; import java.util.HashMap; import java.util.Map; import org.eclipse.core.runtime.IConfigurationElement; import de.fhg.igd.eclipse.util.extension.simple.IdentifiableExtension; import de.fhg.igd.slf4jplus.ALogger; import de.fhg.igd.slf4jplus.ALoggerFactory; import eu.esdihumboldt.hale.common.core.io.Value; import eu.esdihumboldt.hale.common.schema.model.validate.factory.ValidatorFactory; import eu.esdihumboldt.util.Pair; import eu.esdihumboldt.util.validator.Validator; /** * Extension point for {@link ValidatorFactory}ies. * * @author Simon Templer */ public class ValidatorFactoryExtension extends IdentifiableExtension<ValidatorFactoryDescriptor> { private static final ALogger log = ALoggerFactory.getLogger(ValidatorFactoryExtension.class); /** * Extension point ID. */ public static final String ID = "eu.esdihumboldt.hale.schema.validatorfactory"; /** * The extension instance. */ public static final ValidatorFactoryExtension INSTANCE = new ValidatorFactoryExtension(); /** * Maps constraint types to descriptors. */ private final Map<Class<?>, ValidatorFactoryDescriptor> typeToDescriptor = new HashMap<>(); /** * Create a {@link Validator} from its {@link Value} representation. * * @param value the value * @param validatorId the validator identifier * @return the validator or <code>null</code> * @throws Exception if the creation fails */ public static Validator fromValue(Value value, String validatorId) throws Exception { ValidatorFactoryDescriptor descriptor = INSTANCE.get(validatorId); if (descriptor != null && descriptor.getFactory() != null) { return descriptor.getFactory().restore(value); } return null; } /** * Create a {@link Value} representation of a {@link Validator}. * * @param validator the validator * @return a pair of the validator ID and the validator's value * representation, or <code>null</code> * @throws Exception if creating the value representation fails */ @SuppressWarnings("unchecked") public static Pair<String, Value> toValue(Validator validator) throws Exception { ValidatorFactoryDescriptor descriptor = INSTANCE.getForValidator(validator); if (descriptor != null && descriptor.getFactory() != null) { @SuppressWarnings("rawtypes") ValidatorFactory factory = descriptor.getFactory(); return new Pair<>(descriptor.getId(), factory.store(validator)); } return null; } /** * Default constructor. */ private ValidatorFactoryExtension() { super(ID); } @Override protected ValidatorFactoryDescriptor create(String id, IConfigurationElement conf) { try { ValidatorFactoryDescriptor desc = new ValidatorFactoryDescriptor(id, conf); synchronized (typeToDescriptor) { typeToDescriptor.put(desc.getValidatorType(), desc); } return desc; } catch (Exception e) { log.error("Could not create validator factory with id " + id, e); return null; } } @Override protected String getIdAttributeName() { return "id"; } /** * Get the validator descriptor applicable for the given validator object. * * @param validator the validator object * @return the descriptor or <code>null</code> if none is available */ @SuppressWarnings("unchecked") public ValidatorFactoryDescriptor getForValidator(Validator validator) { if (validator == null) return null; Class<? extends Validator> validatorType = validator.getClass(); while (validatorType != null) { ValidatorFactoryDescriptor desc = getForType(validatorType); if (desc != null) { return desc; } // check superclass if (validatorType.getSuperclass() != null && Validator.class.isAssignableFrom(validatorType.getSuperclass())) { validatorType = (Class<? extends Validator>) validatorType.getSuperclass(); } else { validatorType = null; } } return null; } /** * Get the validator descriptor directly associated to the given validator * type. * * @param validatorType the constraint type * @return the descriptor or <code>null</code> if none is registered for the * constraint type */ private ValidatorFactoryDescriptor getForType(Class<? extends Validator> validatorType) { synchronized (typeToDescriptor) { ValidatorFactoryDescriptor desc = typeToDescriptor.get(validatorType); if (desc != null) return desc; } // look for eventually not yet loaded definitions with the type for (ValidatorFactoryDescriptor desc : getElements()) { if (validatorType.equals(desc.getValidatorType())) { return desc; } } return null; } }