package uk.ac.bbsrc.tgac.miso.core.service.naming; import net.sourceforge.fluxion.spi.ServiceProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import uk.ac.bbsrc.tgac.miso.core.data.Sample; import uk.ac.bbsrc.tgac.miso.core.exception.MisoNamingException; import uk.ac.bbsrc.tgac.miso.core.manager.RequestManager; import uk.ac.bbsrc.tgac.miso.core.util.LimsUtils; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * uk.ac.bbsrc.tgac.miso.core.service.naming * <p/> * Info * * @author Rob Davey * @date 29/08/12 * @since 0.1.7 */ @ServiceProvider public class DefaultSampleNamingScheme implements RequestManagerAwareNamingScheme<Sample> { protected static final Logger log = LoggerFactory.getLogger(DefaultSampleNamingScheme.class); private Map<String, Boolean> allowDuplicateMap = new HashMap<String, Boolean>(); private Map<String, Pattern> validationMap = new HashMap<String, Pattern>(); private Map<String, NameGenerator<Sample>> customNameGeneratorMap = new HashMap<String, NameGenerator<Sample>>(); private RequestManager requestManager; public DefaultSampleNamingScheme() { allowDuplicateMap.put("name", false); allowDuplicateMap.put("alias", false); validationMap.put("name", Pattern.compile("([A-Z]{3})([0-9]+)")); validationMap.put("alias", Pattern.compile("([A-z0-9]+)_S([A-z0-9]+)_(.*)")); } @Override public void setValidationRegex(String fieldName, String regex) throws MisoNamingException { if (fieldCheck(fieldName) != null) { if (validationMap.get(fieldName) != null) { log.warn("Setting validation regex from '" +validationMap.get(fieldName).pattern()+ "' to '"+regex+"'. This usually doesn't happen at " + "runtime unless a custom regex is specified at MISO startup!"); validationMap.put(fieldName, Pattern.compile(regex)); } } else { throw new MisoNamingException("Cannot set validation regex for a field (via 'get"+ LimsUtils.capitalise(fieldName)+"') that doesn't exist in " + namingSchemeFor().getCanonicalName()); } } @Override public Class<Sample> namingSchemeFor() { return Sample.class; } @Override public String getSchemeName() { return "DefaultSampleNamingScheme"; } @Override public String generateNameFor(String fieldName, Sample s) throws MisoNamingException { if (customNameGeneratorMap.get(fieldName) != null) { NameGenerator<Sample> sng = customNameGeneratorMap.get(fieldName); String customName = sng.generateName(s); if (validateField(fieldName, customName)) { return customName; } else { throw new MisoNamingException("Custom naming generator '"+sng.getGeneratorName()+"' supplied for Sample field '"+fieldName+"' generated an invalid name according to the validation scheme '"+validationMap.get(fieldName)+"'"); } } else { if ("alias".equals(fieldName)) { throw new MisoNamingException("Alias generation not available. Validation via validateName is available."); } else { if (validationMap.keySet().contains(fieldName)) { Method m = fieldCheck(fieldName); if (m != null) { log.info("Generating name for '"+fieldName+"' :: " + DefaultMisoEntityPrefix.get(Sample.class.getSimpleName()).name() + s.getId()); return DefaultMisoEntityPrefix.get(Sample.class.getSimpleName()).name() + s.getId(); } else { throw new MisoNamingException("No such nameable field."); } } else { throw new MisoNamingException("Generation of names on field '"+fieldName+"' not available."); } } } } @Override public String getValidationRegex(String fieldName) throws MisoNamingException { Pattern p = validationMap.get(fieldName); if (p != null) { return validationMap.get(fieldName).pattern(); } else { throw new MisoNamingException("No such field registered for validation"); } } @Override public boolean validateField(String fieldName, String entityName) throws MisoNamingException { if (fieldCheck(fieldName) != null) { Pattern p = validationMap.get(fieldName); if (p != null) { Matcher mat = p.matcher(entityName); return mat.matches(); } } return false; } @Override public void registerCustomNameGenerator(String fieldName, NameGenerator<Sample> sampleNameGenerator) { this.customNameGeneratorMap.put(fieldName, sampleNameGenerator); } @Override public void unregisterCustomNameGenerator(String fieldName) { this.customNameGeneratorMap.remove(fieldName); } @Override public boolean allowDuplicateEntityNameFor(String fieldName) { return fieldCheck(fieldName) != null && allowDuplicateMap.get(fieldName); } @Override public void setAllowDuplicateEntityName(String fieldName, boolean allow) { if (allowDuplicateMap.containsKey(fieldName) && fieldCheck(fieldName) != null) { allowDuplicateMap.put(fieldName, allow); } } private Method fieldCheck(String fieldName) { try { return namingSchemeFor().getMethod("get"+LimsUtils.capitalise(fieldName)); } catch (NoSuchMethodException e) { log.error("No such field '"+fieldName+"' on class " + namingSchemeFor().getCanonicalName()); e.printStackTrace(); } return null; } @Override public RequestManager getRequestManager() { return requestManager; } @Override public void setRequestManager(RequestManager requestManager) { this.requestManager = requestManager; } }