![JAR search and dependency download from the Maven repository](/logo.png)
it.tidalwave.metadata.tiff.persistence.DirectoryBeanAccessor Maven / Gradle / Ivy
/***********************************************************************************************************************
*
* 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.tiff.persistence;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import java.beans.Introspector;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import it.tidalwave.util.logging.Logger;
import it.tidalwave.image.metadata.Directory;
import it.tidalwave.metadata.persistence.spi.CodeBasedBeanAccessor;
import it.tidalwave.metadata.persistence.spi.UnknownPropertyException;
/*******************************************************************************
*
* This BeanAccessor
works with all the classes descending from
* Mistral {@link Directory}. All properties are accessed as their numeric
* TIFF code and their value is retrieved by {@link Directory#getObject(int)}
* with no proxies. In this way, the persistence representation relying on this
* accessor will be the closest to the original thing, thus preserving fidelity
* and portability.
*
* @author Fabrizio Giudici
* @version $Id$
*
******************************************************************************/
public class DirectoryBeanAccessor extends CodeBasedBeanAccessor
{
private final static String CLASS = DirectoryBeanAccessor.class.getName();
private final static Logger logger = Logger.getLogger(CLASS);
// Used only to get tag names, would it be better if getTagName() was static.
@CheckForNull
private Bean prototype;
@Nonnull
private final Object[][] extraProperties;
/***************************************************************************
*
**************************************************************************/
public DirectoryBeanAccessor (@Nonnull final Class extends Bean> beanClass,
@Nonnull final String propertySetName)
{
this(beanClass, propertySetName, Collections.emptyList(), new Object[0][0]);
}
/***************************************************************************
*
**************************************************************************/
public DirectoryBeanAccessor (@Nonnull final Class extends Bean> beanClass,
@Nonnull final String propertySetName,
@Nonnull final List transientProperties,
@Nonnull final Object[][] extraProperties)
{
super(beanClass, propertySetName, transientProperties);
this.extraProperties = extraProperties.clone();
}
/***************************************************************************
*
**************************************************************************/
@Nonnull
public List getPersistentPropertyNames (@Nonnull final Bean item)
{
final List result = new ArrayList();
for (final int code : item.getTagCodes())
{
final String tagName = getPrototype().getTagName(code);
if (tagName == null)
{
logger.warning("Cannot find a name for #%d, assuming it is persistent", code);
result.add(String.format("#%d", code));
}
else if (isPersistent(tagName))
{
result.add(String.format("#%d", code));
}
}
for (final Object[] e : extraProperties)
{
final int code = (Integer)e[0];
final String propertyName = (String)e[1];
if (item.getObject(code) != null)
{
result.add(propertyName);
}
}
return result;
}
/***************************************************************************
*
* {@inheritDoc}. This method provides support for enumeration types by
* returning Integer.class
for them.
*
**************************************************************************/
@Override
@Nonnull
public Class> getDefaultPropertyType (@Nonnull final String propertyName)
throws UnknownPropertyException
{
final Class> type = super.getDefaultPropertyType(propertyName);
//
// if (type == null)
// {
// throw new IllegalArgumentException("Unknown default property type for " + propertyName);
// }
//
return type.isEnum() ? Integer.class : type;
}
/***************************************************************************
*
* {@inheritDoc}. This method provides for converting enumeration types by
* calling the static method getValue()
.
*
**************************************************************************/
@Override
@Nonnull
public Object convertValueToPersistence (@Nonnull final String propertyName,
@Nonnull final Object value)
throws UnknownPropertyException
{
final Class> type = super.getDefaultPropertyType(propertyName);
if (!type.isEnum())
{
return value;
}
else
{
try
{
final Method method = type.getMethod("getValue");
return method.invoke(value);
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
}
/***************************************************************************
*
* {@inheritDoc}. This method provides for converting enumeration types by
* calling the static method fromInteger()
.
*
**************************************************************************/
@Override
@Nonnull
public Object convertValueFromPersistence (@Nonnull final String propertyName,
@Nonnull Object value)
throws UnknownPropertyException
{
final Class> type = super.getDefaultPropertyType(propertyName);
if (!type.isEnum())
{
return value;
}
else
{
if (!value.getClass().equals(Integer.class))
{
value = Integer.valueOf(((Number)value).intValue());
logger.warning("Property %s, enum type is not Integer: %s", propertyName, value.getClass());
}
try
{
final Method method = type.getMethod("fromInteger", int.class);
return method.invoke(null, value);
}
catch (RuntimeException e)
{
throw e;
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
}
/***************************************************************************
*
**************************************************************************/
@CheckForNull
protected Object getProperty (@Nonnull final Bean bean, final int code)
{
return bean.getObject(code);
}
/***************************************************************************
*
**************************************************************************/
@Override
@CheckForNull
protected void setProperty (@Nonnull final Bean bean, final int code, final Object value)
{
bean.setObject(code, value);
}
/***************************************************************************
*
**************************************************************************/
@Override
protected void registerCodes()
{
final Bean prototype = getPrototype();
// FIXME: get the codes from the Directory's Registry.
for (int code = 0; code < 120000; code++)
{
String propertyName = prototype.getTagName(code);
if (propertyName != null)
{
// FIXME: simply stripping off blanks is not enough.
// We must find a way to query the TIFF structure.
propertyName = Introspector.decapitalize(propertyName.replaceAll("[ /-]", ""));
registerCode(propertyName, code);
}
}
}
/***************************************************************************
*
**************************************************************************/
@Nonnull
protected synchronized Bean getPrototype()
{
if (prototype == null)
{
try
{
prototype = getItemClass().newInstance();
}
catch (InstantiationException e)
{
throw new RuntimeException(e);
}
catch (IllegalAccessException e)
{
throw new RuntimeException(e);
}
}
return prototype;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy