All Downloads are FREE. Search and download functionalities are using the official Maven repository.

it.tidalwave.metadata.persistence.spi.CodeBasedBeanAccessor Maven / Gradle / Ivy

The newest version!
/***********************************************************************************************************************
 *
 * blueMarine Metadata - open source media workflow
 * Copyright (C) 2007-2011 by Tidalwave s.a.s. (http://www.tidalwave.it)
 *
 ***********************************************************************************************************************
 *
 * 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.
 *
 ***********************************************************************************************************************
 *
 * WWW: http://bluemarine.tidalwave.it
 * SCM: https://kenai.com/hg/bluemarine~metadata-src
 *
 **********************************************************************************************************************/
package it.tidalwave.metadata.persistence.spi;

import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/*******************************************************************************
 *
 * A specialization of {@link IntrospectionBeanAccessor} where all or a part of
 * the properties are represented with numerical codes. 
 * 
 * @author  Fabrizio Giudici
 * @version $Id$
 *
 ******************************************************************************/
public abstract class CodeBasedBeanAccessor extends IntrospectionBeanAccessor
  {
    private final List transientProperties = new ArrayList();
    
    private final Map codeMap = new HashMap();
    
    private final Map reverseMap = new HashMap();
    
    /***************************************************************************
     *
     * @param  beanClass
     * @param  propertySetName
     * @param  transientProperties
     * 
     **************************************************************************/
    public CodeBasedBeanAccessor (@Nonnull final Class beanClass,
                                  @Nonnull final String propertySetName, 
                                  @Nonnull final Collection transientProperties)
      {
        super(beanClass, propertySetName);
        this.transientProperties.addAll(transientProperties);
        registerCodes();
      }

    /***************************************************************************
     *
     * {@inheritDoc} 
     * 
     **************************************************************************/
    @Override
    public boolean isPersistent (@Nonnull final String propertyName) 
      {
        if (propertyName == null)
          {
            throw new IllegalArgumentException("propertyName is mandatory");
          }
        
        return !transientProperties.contains(propertyName);
      }

    /***************************************************************************
     *
     * {@inheritDoc} 
     * 
     **************************************************************************/
    @Override
    @Nonnull
    public Class getDefaultPropertyType (@Nonnull String propertyName)
      throws UnknownPropertyException
      {
        if (propertyName == null)
          {
            throw new IllegalArgumentException("propertyName is mandatory");
          }
        
        if (isCode(propertyName))
          {
            propertyName = convertPropertyNameFromPersistence(propertyName);
          }
        
        if (isCode(propertyName)) // still unknown
          {
            throw new UnknownPropertyException(getItemClass(), propertyName);
          }

        return super.getDefaultPropertyType(propertyName);  
      }
    
    /***************************************************************************
     *
     * {@inheritDoc} 
     * 
     **************************************************************************/
    @Override
    @CheckForNull
    public Object getProperty (@Nonnull final String propertyName, 
                               @Nonnull final Bean bean) 
      throws UnknownPropertyException
      {
        if (bean == null)
          {
            throw new IllegalArgumentException("bean is mandatory");
          }
        
        if (propertyName == null)
          {
            throw new IllegalArgumentException("propertyName is mandatory");
          }
        
        if (isCode(propertyName))
          {
            // Don't call the method which specifies the type - no type
            // conversion, stay close to the original.
            return getProperty(bean, toCode(propertyName));
//            return convertValueToPersistence(propertyName, getProperty(bean, toCode(propertyName)));
          }
        else
          {
            return super.getProperty(propertyName, bean);
          }
      }

    /***************************************************************************
     *
     * {@inheritDoc} 
     * 
     **************************************************************************/
    @Override
    public void setProperty (@Nonnull final Bean bean, 
                             @Nonnull final String propertyName, 
                             @CheckForNull final Object value) 
      throws UnknownPropertyException
      {
        if (bean == null)
          {
            throw new IllegalArgumentException("bean is mandatory");
          }
        
        if (propertyName == null)
          {
            throw new IllegalArgumentException("propertyName is mandatory");
          }
        
        if (isCode(propertyName))
          {
            setProperty(bean, toCode(propertyName), value);
//            setProperty(bean, toCode(propertyName), convertValueFromPersistence(propertyName, value));
          }
        else
          {
            super.setProperty(bean, propertyName, value);
          }
      }
    
    /***************************************************************************
     *
     * {@inheritDoc} The result is based on the mappings registered by the method
     * {@link #registerCodes()}; if no mapping is found, the passed argument is
     * returned.
     * 
     **************************************************************************/
    @Override
    @Nonnull
    public final String convertPropertyNameFromPersistence (@Nonnull final String propertyName)
      {
        if (propertyName == null)
          {
            throw new IllegalArgumentException("propertyName is mandatory");
          }
        
        final String result = reverseMap.get(propertyName);
        return (result != null) ? result : propertyName;
      }

    /***************************************************************************
     *
     * {@inheritDoc} The result is based on the mappings registered by the method
     * {@link #registerCodes()}; if no mapping is found, the passed argument is
     * returned.
     * 
     **************************************************************************/
    @Override
    @Nonnull
    public final String convertPropertyNameToPersistence (@Nonnull final String propertyName) 
      {
        if (propertyName == null)
          {
            throw new IllegalArgumentException("propertyName is mandatory");
          }
        
        final String result = codeMap.get(propertyName);
        return (result != null) ? result : propertyName;
      }
    
    /***************************************************************************
     *
     * This method must be ovverriden by concrete implementations to register
     * the mappings between property names and codes. See 
     * {@link #registerCode(java.lang.String, int)}.
     * 
     **************************************************************************/
    protected abstract void registerCodes();
    
    /***************************************************************************
     *
     * Register a mapping between the given property namd and code.
     * 
     * @param  propertyName   the property name
     * @param  code           the property code
     * 
     **************************************************************************/
    protected void registerCode (@Nonnull final String propertyName, final int code)
      {
        if (propertyName == null)
          {
            throw new IllegalArgumentException("propertyName is mandatory");
          }
        
        final String sCode = String.format("#%d", code);
        codeMap.put(propertyName, sCode);
        reverseMap.put(sCode, propertyName);
      }
    
    /***************************************************************************
     *
     * This method must be ovverriden by concrete implementations to read the
     * property with the given code on the given bean.
     * 
     * @param  bean  the bean
     * @param  code  the property code
     * @return       the property value
     * 
     **************************************************************************/
    @CheckForNull
    protected abstract Object getProperty (@Nonnull Bean bean, int code);
    
    /***************************************************************************
     *
     * This method must be ovverriden by concrete implementations to write the
     * property with the given code on the given bean.
     * 
     * @param  bean  the bean
     * @param  code  the property code
     * 
     **************************************************************************/
    protected abstract void setProperty (@Nonnull Bean bean, int code, @CheckForNull Object value);

    /***************************************************************************
     *
     **************************************************************************/
    protected static int toCode (@Nonnull final String propertyName)
      {
        return Integer.valueOf(propertyName.substring(1));
      }

    /***************************************************************************
     *
     **************************************************************************/
    private boolean isCode (@Nonnull final String propertyName) 
      {
        return propertyName.startsWith("#");
      }
  }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy