package org.marketcetera.util.l10n;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.LinkedList;
import java.util.List;
import org.marketcetera.util.except.I18NException;
import org.marketcetera.util.log.I18NBoundMessage1P;
import org.marketcetera.util.log.I18NBoundMessage3P;
import org.marketcetera.util.log.I18NMessage;
import org.marketcetera.util.log.I18NMessageProvider;
import org.marketcetera.util.misc.ClassVersion;
import org.marketcetera.util.misc.ReflectUtils;
/**
* Holder of meta-information about a message container class, such as
* {@link Messages}. Note that only static, non-null fields are
* introspected.
*
* @see org.marketcetera.util.log
*
* @author tlerios@marketcetera.com
* @since 0.6.0
* @version $Id: ContainerClassInfo.java 16154 2012-07-14 16:34:05Z colin $
*/
/* $License$ */
@ClassVersion("$Id: ContainerClassInfo.java 16154 2012-07-14 16:34:05Z colin $")
public class ContainerClassInfo
implements MessageInfoProvider
{
// INSTANCE DATA.
private Class<?> mContainer;
private I18NMessageProvider mProvider;
private List<MessageInfo> mMessageInfo;
// CONSTRUCTORS.
/**
* Creates a new meta-information holder for the given message
* container class.
*
* @param container The class.
*
* @throws I18NException Thrown if introspection of the given
* class fails, or the class does not contain a message provider.
*/
public ContainerClassInfo
(Class<?> container)
throws I18NException
{
mContainer=container;
mMessageInfo=new LinkedList<MessageInfo>();
try {
for (Field field:ReflectUtils.getAllFields(getContainer())) {
String name=field.getName();
if ((field.getModifiers()&Modifier.STATIC)==0) {
Messages.NONSTATIC_FIELD_IGNORED.info(this,name);
continue;
}
Class<?> type=field.getType();
if (I18NMessage.class.isAssignableFrom(type)) {
field.setAccessible(true);
I18NMessage message=
((I18NMessage)(field.get(getContainer())));
if (message==null) {
Messages.NULL_FIELD_IGNORED.info(this,name);
continue;
}
addMessage(message);
}
if (I18NMessageProvider.class.isAssignableFrom(type)) {
setProvider
((I18NMessageProvider)(field.get(getContainer())));
}
}
} catch (IllegalAccessException ex) {
throw new I18NException
(ex,new I18NBoundMessage1P
(Messages.INTROSPECTION_FAILED,getContainer().getName()));
}
if (getProvider()==null) {
throw new I18NException
(new I18NBoundMessage1P
(Messages.MISSING_PROVIDER,getContainer().getName()));
}
}
// INSTANCE METHODS.
/**
* Adds the given message to the receiver's meta-information.
*
* @param message The message.
*
* @throws I18NException Thrown if addition of the message fails
* due to the message having a different message provider than
* other messages in the receiver's container class.
*/
protected void addMessage
(I18NMessage message)
throws I18NException
{
setProvider(message.getMessageProvider());
mMessageInfo.add
(new I18NMessageInfo
(message.getMessageId()+"."+ //$NON-NLS-1$
message.getEntryId(),message.getParamCount(),message));
}
/**
* Returns the receiver's container class.
*
* @return The class.
*/
public Class<?> getContainer()
{
return mContainer;
}
/**
* Sets the internationalized message provider declared in the
* receiver's container class to the given one.
*
* @param provider The provider.
*
* @throws I18NException Thrown if the provider has already been
* set to a different one.
*/
private void setProvider
(I18NMessageProvider provider)
throws I18NException
{
if ((getProvider()!=null) && (!getProvider().equals(provider))) {
throw new I18NException
(new I18NBoundMessage3P
(Messages.MULTIPLE_PROVIDERS,getContainer().getName(),
getProvider().getProviderId(),provider.getProviderId()));
}
mProvider=provider;
}
/**
* Returns the internationalized message provider declared in the
* receiver's container class.
*
* @return The provider.
*/
public I18NMessageProvider getProvider()
{
return mProvider;
}
// MessageInfoProvider.
@Override
public List<MessageInfo> getMessageInfo()
{
return mMessageInfo;
}
}