org.bitsofinfo.util.address.usps.ais.DefaultIdGenerator.java Source code

Java tutorial

Introduction

Here is the source code for org.bitsofinfo.util.address.usps.ais.DefaultIdGenerator.java

Source

/*****************************************************************************
* Copyright 2012  bitsofinfo.g [at] gmail [dot] com 
* 
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* 
* http://www.apache.org/licenses/LICENSE-2.0 
* 
* Unless required by applicable law or agreed to in writing, software 
* distributed under the License is distributed on an "AS IS" BASIS, 
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and 
* limitations under the License
* 
* Author: bitsofinfo.g [at] gmail [dot] com 
* @see bitsofinfo.wordpress.com
*****************************************************************************/
package org.bitsofinfo.util.address.usps.ais;

import java.security.MessageDigest;
import java.util.Hashtable;
import java.util.Map;
import java.util.Set;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.codec.binary.Hex;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;

import org.bitsofinfo.util.address.usps.ais.annotations.USPSRecordContext;

/**
 * DefaultIDGenerator is a USPSIdGenerator.
 * 
 * For USPSRecord types a unique String ID will be created consisting of:
 * 
 * [USPSProductType.id]-[Values from properties on the record annotated with USPSKeyField]
 * 
 * @author bitsofinfo.g [at] gmail [dot] com
 *
 */
public class DefaultIdGenerator implements USPSIdGenerator {

    private Map<Class<? extends USPSRecord>, String> typeCache = new Hashtable<Class<? extends USPSRecord>, String>();
    private Map<String, Class<? extends USPSRecord>> prefixCache = new Hashtable<String, Class<? extends USPSRecord>>();
    private MessageDigest digest = null;

    @Autowired
    private USPSUtils uspsUtils;

    public void setUspsUtils(USPSUtils uspsUtils) {
        this.uspsUtils = uspsUtils;
    }

    public void initialize() throws Exception {
        this.buildCaches();

        digest = MessageDigest.getInstance("MD5");
    }

    @Override
    public String generateId(USPSRecord record) throws Exception {

        String idPrefix = getPrefix(record);
        String[] keyFieldNames = uspsUtils.getIdentifierFieldNames(record);

        StringBuffer tmp = new StringBuffer();
        for (String fieldName : keyFieldNames) {
            try {
                Object value = PropertyUtils.getProperty(record, fieldName);
                if (value != null) {
                    tmp.append(value);
                }
                tmp.append("|");

            } catch (NoSuchMethodException e) {
                throw new Exception("Error in generating id for USPSRecord... no getter defined for USPSKeyField "
                        + fieldName + " within class " + record.getClass().getName());
            }
        }

        String toReturn = tmp.toString();

        synchronized (digest) {
            digest.reset();
            byte[] digested = digest.digest(toReturn.getBytes());
            toReturn = new String(Hex.encodeHex(digested));
        }

        return idPrefix + "-" + toReturn;
    }

    private String getPrefix(USPSRecord record) {
        Class<? extends USPSRecord> clazz = record.getClass();
        String prefix = typeCache.get(clazz);
        return prefix;
    }

    private synchronized void buildCaches() throws Exception {
        if (typeCache.size() == 0) {
            Set<Class> clazzes = uspsUtils.getUSPSRecordClasses();
            for (Class clazz : clazzes) {
                USPSRecordContext context = (USPSRecordContext) clazz.getAnnotation(USPSRecordContext.class);
                StringBuffer tmp = new StringBuffer();
                for (USPSProductType pt : context.productTypes()) {
                    tmp.append(pt.getId());
                }
                String prefix = tmp.toString() + context.copyrightDetailCode();
                typeCache.put(clazz, prefix);
                prefixCache.put(prefix, clazz);
            }
        }
    }

    @Override
    public Class<? extends USPSRecord> getRecordType(String identifier) {
        String prefix = StringUtils.split(identifier, "-")[0];
        Class clazz = prefixCache.get(prefix);
        return clazz;
    }

}