Package org.projectforge.xml.stream

Source Code of org.projectforge.xml.stream.XmlRegistry

/////////////////////////////////////////////////////////////////////////////
//
// Project ProjectForge Community Edition
//         www.projectforge.org
//
// Copyright (C) 2001-2014 Kai Reinhard (k.reinhard@micromata.de)
//
// ProjectForge is dual-licensed.
//
// This community edition is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
// by the Free Software Foundation; version 3 of the License.
//
// This community edition is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
// Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, see http://www.gnu.org/licenses/.
//
/////////////////////////////////////////////////////////////////////////////

package org.projectforge.xml.stream;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;

import org.projectforge.Version;
import org.projectforge.xml.stream.converter.BigDecimalConverter;
import org.projectforge.xml.stream.converter.BooleanConverter;
import org.projectforge.xml.stream.converter.ByteArrayConverter;
import org.projectforge.xml.stream.converter.ClassConverter;
import org.projectforge.xml.stream.converter.DateConverter;
import org.projectforge.xml.stream.converter.DoubleConverter;
import org.projectforge.xml.stream.converter.IConverter;
import org.projectforge.xml.stream.converter.IntConverter;
import org.projectforge.xml.stream.converter.LocaleConverter;
import org.projectforge.xml.stream.converter.LongConverter;
import org.projectforge.xml.stream.converter.ShortConverter;
import org.projectforge.xml.stream.converter.StringConverter;
import org.projectforge.xml.stream.converter.TimeZoneConverter;
import org.projectforge.xml.stream.converter.VersionConverter;

/**
* There is one singleton instance used for default mappings, aliases etc.
* @author Kai Reinhard (k.reinhard@micromata.de)
*
*/
public class XmlRegistry
{
  private static final XmlRegistry baseRegistry;

  private Map<Class< ? >, IConverter< ? >> converterRegistry;

  // private Map<Field, IConverter< ? >> fieldConverterRegistry;

  private Set<Class< ? >> asAttributeAsDefaultSet;

  private AliasMap aliasMap;

  static {
    baseRegistry = new XmlRegistry();
    baseRegistry.initializeDefaultRegistry();
  }

  /**
   * Default xml registry.
   */
  public static XmlRegistry baseRegistry()
  {
    return baseRegistry;
  }

  /**
   * For customized xml registry.
   */
  public XmlRegistry()
  {
  }

  /**
   * Only for the singleton instance.
   */
  private void initializeDefaultRegistry()
  {
    internalRegisterTypeAsAttribute(BigDecimal.class);
    internalRegisterTypeAsAttribute(Boolean.class);
    internalRegisterTypeAsAttribute(boolean.class);
    internalRegisterTypeAsAttribute(Date.class);
    internalRegisterTypeAsAttribute(Double.class);
    internalRegisterTypeAsAttribute(double.class);
    internalRegisterTypeAsAttribute(Integer.class);
    internalRegisterTypeAsAttribute(int.class);
    internalRegisterTypeAsAttribute(Long.class);
    internalRegisterTypeAsAttribute(long.class);
    internalRegisterTypeAsAttribute(Short.class);
    internalRegisterTypeAsAttribute(short.class);
    internalRegisterTypeAsAttribute(TimeZone.class);
    internalRegisterTypeAsAttribute(Locale.class);
    internalRegisterTypeAsAttribute(Version.class);

    internalRegisterAlias(BigDecimal.class, "decimal");
    internalRegisterAlias(Boolean.class, "boolean");
    internalRegisterAlias(boolean.class, "boolean");
    internalRegisterAlias(Double.class, "double");
    internalRegisterAlias(double.class, "double");
    internalRegisterAlias(Integer.class, "int");
    internalRegisterAlias(int.class, "int");
    internalRegisterAlias(Long.class, "long");
    internalRegisterAlias(long.class, "long");
    internalRegisterAlias(Short.class, "short");
    internalRegisterAlias(short.class, "short");
    internalRegisterAlias(TimeZone.class, "timeZone");
    internalRegisterAlias(Locale.class, "locale");
    internalRegisterAlias(Version.class, "version");

    IConverter< ? > conv = new BooleanConverter();
    internalRegisterConverter(Boolean.class, conv);
    internalRegisterConverter(boolean.class, conv);
    conv = new DoubleConverter();
    internalRegisterConverter(Double.class, conv);
    internalRegisterConverter(double.class, conv);
    conv = new IntConverter();
    internalRegisterConverter(Integer.class, conv);
    internalRegisterConverter(int.class, conv);
    conv = new LongConverter();
    internalRegisterConverter(Long.class, conv);
    internalRegisterConverter(long.class, conv);
    conv = new ShortConverter();
    internalRegisterConverter(Short.class, conv);
    internalRegisterConverter(short.class, conv);
    internalRegisterConverter(byte[].class, new ByteArrayConverter());

    internalRegisterConverter(BigDecimal.class, new BigDecimalConverter());
    internalRegisterConverter(Class.class, new ClassConverter());
    internalRegisterConverter(Date.class, new DateConverter());
    internalRegisterConverter(String.class, new StringConverter());
    internalRegisterConverter(TimeZone.class, new TimeZoneConverter());
    internalRegisterConverter(Locale.class, new LocaleConverter());
    internalRegisterConverter(Version.class, new VersionConverter());
  }

  public IConverter< ? > getConverter(final Class< ? > clazz)
  {
    if (converterRegistry != null) {
      final IConverter< ? > converter = converterRegistry.get(clazz);
      if (converter != null) {
        return converter;
      }
      for (final Class< ? > cls : converterRegistry.keySet()) {
        if (cls.isAssignableFrom(clazz) == true) {
          final IConverter< ? > conv = converterRegistry.get(cls);
          if (conv != null) {
            // Register so every type must only be checked once.
            internalRegisterConverter(clazz, conv);
            return conv;
          }
        }
      }
    }
    if (this == baseRegistry) {
      return null;
    }
    return baseRegistry.getConverter(clazz);
  }

  public boolean asAttributeAsDefault(final Class< ? > type)
  {
    if (asAttributeAsDefaultSet != null) {
      if (asAttributeAsDefaultSet.contains(type) == true) {
        return true;
      }
    }
    if (this == baseRegistry) {
      return false;
    }
    return baseRegistry.asAttributeAsDefault(type);
  }

  public String getAliasForClass(final Class< ? > type)
  {
    if (aliasMap != null) {
      final String alias = aliasMap.getAliasForClass(type);
      if (alias != null) {
        return alias;
      }
    }
    if (this == baseRegistry) {
      return null;
    }
    return baseRegistry.getAliasForClass(type);
  }

  public Class< ? > getClassForAlias(final String alias)
  {
    if (aliasMap != null) {
      final Class< ? > clazz = aliasMap.getClassForAlias(alias);
      if (clazz != null) {
        return clazz;
      }
    }
    if (this == baseRegistry) {
      return null;
    }
    return baseRegistry.getClassForAlias(alias);
  }

  public XmlRegistry registerConverter(final Class< ? > type, final IConverter< ? > converter)
  {
    if (this == baseRegistry) {
      throw new IllegalStateException("Couldn't register type as attribute for base registry (singleton). This registry is unmodifiable");
    }
    internalRegisterConverter(type, converter);
    return this;
  }

  private void internalRegisterConverter(final Class< ? > type, final IConverter< ? > converter)
  {
    if (this.converterRegistry == null) {
      this.converterRegistry = new HashMap<Class< ? >, IConverter< ? >>();
    }
    this.converterRegistry.put(type, converter);
  }

  public XmlRegistry registerAlias(final Class< ? > type, final String alias)
  {
    if (this == baseRegistry) {
      throw new IllegalStateException("Couldn't register type as attribute for base registry (singleton). This registry is unmodifiable");
    }
    internalRegisterAlias(type, alias);
    return this;
  }

  private void internalRegisterAlias(final Class< ? > type, final String alias)
  {
    if (this.aliasMap == null) {
      this.aliasMap = new AliasMap();
    }
    this.aliasMap.put(type, alias);
  }

  public XmlRegistry registerTypeAsAttribute(final Class< ? > type)
  {
    if (this == baseRegistry) {
      throw new IllegalStateException("Couldn't register type as attribute for base registry (singleton). This registry is unmodifiable");
    }
    internalRegisterTypeAsAttribute(type);
    return this;
  }

  private void internalRegisterTypeAsAttribute(final Class< ? > type)
  {
    if (this.asAttributeAsDefaultSet == null) {
      this.asAttributeAsDefaultSet = new HashSet<Class< ? >>();
    }
    this.asAttributeAsDefaultSet.add(type);
  }
}
TOP

Related Classes of org.projectforge.xml.stream.XmlRegistry

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.