/** * ============================================================================= * * ORCID (R) Open Source * http://orcid.org * * Copyright (c) 2012-2014 ORCID, Inc. * Licensed under an MIT-Style License (MIT) * http://orcid.org/open-source-license * * This copyright and license information (including a link to the full license) * shall be included in its entirety in all copies or substantial portion of * the software. * * ============================================================================= */ package org.orcid.core.manager.impl; import java.util.Random; import javax.annotation.Resource; import net.sf.ehcache.Cache; import net.sf.ehcache.Element; import org.apache.commons.lang3.StringUtils; import org.orcid.core.crypto.OrcidCheckDigitGenerator; import org.orcid.core.manager.OrcidGenerationManager; import org.orcid.core.manager.ProfileEntityManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Will Simpson (will) Date: 15/02/2012 */ public class OrcidGenerationManagerImpl implements OrcidGenerationManager { private static final Logger LOGGER = LoggerFactory.getLogger(OrcidGenerationManager.class); @Resource private ProfileEntityManager profileEntityManager; @Resource(name = "recentOrcidCache") private Cache recentOrcidCache; @Override public String createNewOrcid() { String orcid = getNextOrcid(); while (isInRecentOrcidCache(orcid) || profileEntityManager.orcidExists(orcid)) { orcid = getNextOrcid(); } recentOrcidCache.put(new Element(orcid, orcid)); return orcid; } private String getNextOrcid() { String baseOrcid = StringUtils.leftPad(String.valueOf(getRandomNumber()), 15, '0'); String checkDigit = OrcidCheckDigitGenerator.generateCheckDigit(baseOrcid); return formatOrcid(baseOrcid + checkDigit); } private boolean isInRecentOrcidCache(String formattedOrcid) { LOGGER.debug("Recent ORCID cache size: {}", recentOrcidCache.getSize()); Element alreadyUsed = recentOrcidCache.get(formattedOrcid); if (alreadyUsed != null) { LOGGER.debug("Same ORCID randomly generated a few moments ago: {}", formattedOrcid); return true; } return false; } private long getRandomNumber() { Random random = new Random(); // XXX Need to test edge cases return (long) (ORCID_BASE_MIN + (random.nextDouble() * (ORCID_BASE_MAX - ORCID_BASE_MIN + 1))); } private String formatOrcid(String orcid) { return orcid.replaceAll("(.{4})(?=.)", "$1-"); } }