TypeManager.java :  » Database-ORM » JPOX » org » jpox » Java Open Source

Java Open Source » Database ORM » JPOX 
JPOX » org » jpox » TypeManager.java
/**********************************************************************
Copyright (c) 2003 Andy Jefferson and others. All rights reserved.
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.

Contributors:
2004 Erik Bengtson - added interfaces methods
    ...
**********************************************************************/
package org.jpox;

import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.jpox.api.ApiAdapter;
import org.jpox.exceptions.JPOXException;
import org.jpox.metadata.FieldPersistenceModifier;
import org.jpox.plugin.ConfigurationElement;
import org.jpox.plugin.ExtensionPoint;
import org.jpox.plugin.PluginManager;
import org.jpox.sco.SCOList;
import org.jpox.sco.SCOMap;
import org.jpox.util.JPOXLogger;
import org.jpox.util.JavaUtils;
import org.jpox.util.Localiser;
import org.jpox.util.StringUtils;

/**
 * Registry of type support within JPOX.
 * The plugin mechanism provides the registration of supported types, so that users can register
 * support for their own types and these are loaded when the TypeManager is constructed.
 *
 * @version $Revision: 1.49 $
 */
public class TypeManager
{
    private static final Localiser LOCALISER=Localiser.getInstance("org.jpox.Localisation");

    protected final ClassLoaderResolver clr;

    protected final ApiAdapter api;

    /** The types, keyed by the class name. */
    Map types = new HashMap();

    /** Shortcut for the type names which default to 'persistence-modifier="persistent"' */
    private static String[] DEFAULT_PERSISTENT_TYPE;

    /** Shortcut for the type names which default to 'default-fetch-group="true"' */
    private static String[] DEFAULT_FETCH_GROUP_TRUE;

    /** Shortcut for the type names which default to 'embedded="true"' */
    private static String[] DEFAULT_EMBEDDED_TYPE;

    /**
     * Constructor, loading JPOX's support for type mappings using the plugin mechanism.
     * @param api The API in use
     * @param clr the ClassLoader Resolver
     * @param mgr the PluginManager
     **/
    public TypeManager(ApiAdapter api, PluginManager mgr, ClassLoaderResolver clr)
    {
        this.clr = clr;
        this.api = api;
        loadUserTypes(mgr, clr);
    }

    /**
     * Convenience method returning whether the passed type is a reference type.
     * This typically means whether it is an interface or java.lang.Object.
     * @param cls The class
     * @return Whether it is a reference type
     */
    public boolean isReferenceType(Class cls)
    {
        if (cls == null)
        {
            return false;
        }
        return cls.isInterface() || cls.getName().equals("java.lang.Object");
    }

    /**
     * Accessor for whether a class is supported.
     * @param className The class name
     * @return Whether the class is supported (to some degree)
     */
    public boolean isSupportedType(String className)
    {
        if (className == null)
        {
            return false;
        }

        JPOXType type = getType(className);
        if (type == null)
        {
            try
            {
                Class cls = clr.classForName(className);
                type = findJPOXTypeForClass(cls);
                return (type.getSCOMappingType() != null);
            }
            catch (Exception e)
            {
            }
            return false;
        }
        else
        {
            return (type.getSCOMappingType() != null);
        }
    }

    /**
     * Accessor for the Supported Types.
     * @return Set of supported types (containing the fully qualified class names (String)).
     **/
    public Set getSupportedTypes()
    {
        return new HashSet(types.keySet());
    }

    /**
     * Accessor for whether a class is a supported second class mutable type
     * @param class_name The class name
     * @return Whether it is a second class mutable type
     */
    public boolean isSecondClassMutableType(String class_name)
    {
        return (getSecondClassWrapper(class_name) != null);
    }

    /**
     * Accessor for whether the type is a List type that uses a SCOList wrapper type.
     * @param c The class
     * @return if c is a List type
     */
    public boolean isSCOList(Class c)
    {
        if (c == null)
        {
            return false;
        }
        if (c.isInterface() && !isSupportedType(c.getName()))
        {
          return false;
        }

        JPOXType type = getType(c.getName());
        return type != null ? SCOList.class.isAssignableFrom(type.getSCOMutableWrapperType()) : false;
    }

    /**
     * Accessor for whether the type is a Map type that uses a SCOMap wrapper type.
     * @param c The class
     * @return true if c is a Map type
     */
    public boolean isSCOMap(Class c)
    {
        if (c == null)
        {
            return false;
        }
        if (c.isInterface() && !isSupportedType(c.getName()))
        {
          return false;
        }

        JPOXType type = getType(c.getName());
        return type != null ? SCOMap.class.isAssignableFrom(type.getSCOMutableWrapperType()) : false;
    }

    /**
     * Accessor for the Java Mapping type class for the supplied class.
     * @param className The class name
     * @return The Java mapping type
     */
    public Class getMappingType(String className)
    {
        if (className == null)
        {
            return null;
        }

        JPOXType type = getType(className);
        if (type == null)
        {
            // Check if this is a SCO wrapper
            Collection supportedTypes = new HashSet(types.values());
            Iterator iter = supportedTypes.iterator();
            while (iter.hasNext())
            {
                type = (JPOXType)iter.next();
                if (type.scoMutableWrapperType != null &&
                    type.scoMutableWrapperType.getName().equals(className))
                {
                    // SCO wrapper with same name, so return the JavaTypeMapping for that
                    return type.getSCOMappingType();
                }
                else if (type.scoMutableSimpleWrapperType != null &&
                    type.scoMutableSimpleWrapperType.getName().equals(className))
                {
                    // SCO wrapper with same name, so return the JavaTypeMapping for that
                    return type.getSCOMappingType();
                }
            }

            // Not SCO wrapper so find a type
            try
            {
                Class cls = clr.classForName(className);
                type = findJPOXTypeForClass(cls);
                return type.getSCOMappingType();
            }
            catch (Exception e)
            {
                return null;
            }
        }
        else
        {
            return type.getSCOMappingType();
        }
    }

    /**
     * Accessor for the Second Class Wrapper class for the supplied class.
     * A type will have a SCO wrapper if it is SCO supported and is mutable.
     * @param className The class name
     * @return The second class wrapper
     */
    public Class getSecondClassWrapper(String className)
    {
        if (className == null)
        {
            return null;
        }

        JPOXType type = getType(className);
        return type == null ? null : type.getSCOMutableWrapperType();
    }

    /**
     * Accessor for the SCO "simple" wrapper class for the supplied class.
     * A type will have a SCO wrapper if it is SCO supported and is mutable.
     * The "simple" wrapper provides simple wrapping of operations and dirty detection only.
     * @param className The class name
     * @return The second class wrapper
     */
    public Class getSecondClassWrapperSimple(String className)
    {
        if (className == null)
        {
            return null;
        }

        JPOXType type = getType(className);
        return type == null ? null : type.getSCOMutableSimpleWrapperType();
    }

    /**
     * Accessor for whether a class is a Second Class Wrapper type.
     * @param className The name of the class
     * @return Whether it is a second class wrapper type
     */
    public boolean isSecondClassWrapper(String className)
    {
        if (className == null)
        {
            return false;
        }

        Iterator iter = types.values().iterator();
        while (iter.hasNext())
        {
            JPOXType type = (JPOXType)iter.next();
            if (type.getSCOMutableWrapperType() != null &&
                type.getSCOMutableWrapperType().getName().equals(className))
            {
                return true;
            }
            if (type.getSCOMutableSimpleWrapperType() != null &&
                type.getSCOMutableSimpleWrapperType().getName().equals(className))
            {
                return true;
            }
        }
        return false;
    }

    /**
     * Accessor for the default "persistence-modifier" for a field given the
     * class, its modifier and whether it is a PersistentCapable class.
     * @param c The class
     * @param modifier The modifiers for the field
     * @param isPCclass Whether it is persistence capable.
     * @return The default field PersistenceModifier.
     */
    public final FieldPersistenceModifier getDefaultFieldPersistenceModifier(Class c, int modifier, boolean isPCclass)
    {
        // Static, Transient and Final fields are all not persistent
        if (Modifier.isStatic(modifier) || Modifier.isTransient(modifier) || Modifier.isFinal(modifier))
        {
            // Static, transient and final fields are not persistent
            return FieldPersistenceModifier.NONE;
        }

        if (isPCclass)
        {
            // All PC class fields are persistent by default
            return FieldPersistenceModifier.PERSISTENT;
        }

        if (c == null)
        {
            throw new JPOXException("class is null");
        }

        if (Arrays.binarySearch(DEFAULT_PERSISTENT_TYPE, c.getName()) >= 0)
        {
            // Use the specified "jpoxtypes" default persistence modifier for this type (if specified)
            return FieldPersistenceModifier.PERSISTENT;
        }
        if (c.isArray() && api.isPersistable(c.getComponentType()))
        {
            // Arrays of PC types are, by default, persistent
            return FieldPersistenceModifier.PERSISTENT;
        }

        // Try to find a class that this class extends that is supported
        JPOXType type = findJPOXTypeForClass(c);
        if (type != null)
        {
            return (type.dftPersistent ? FieldPersistenceModifier.PERSISTENT : FieldPersistenceModifier.NONE);
        }

        return FieldPersistenceModifier.NONE;
    }

    /**
     * Accessor for whether the class is by default in the default fetch group.
     * @param c The class
     * @return return true if is part of default fetch group by default
     */
    public boolean isDefaultFetchGroup(Class c)
    {
        if (c == null)
        {
            return false;
        }
        if (Arrays.binarySearch(DEFAULT_FETCH_GROUP_TRUE, c.getName()) >= 0)
        {
            return true;
        }

        // Try to find a class that this class extends that is supported
        JPOXType type = findJPOXTypeForClass(c);
        if (type != null)
        {
            return type.dfg;
        }

        return false;
    }

    /**
     * Utility to return whether a type defaults to embedded or not.
     * See JDO 2 Section 18.14 <field> for definition. This only provides for the
     * basic types, and ignores arrays/collections.
     * @param c The type
     * @return Whether it defaults to embedded or not.
     */
    public boolean isDefaultEmbeddedType(Class c)
    {
        if (c == null)
        {
            return false;
        }
        if (Arrays.binarySearch(DEFAULT_EMBEDDED_TYPE, c.getName()) >= 0)
        {
            return true;
        }

        // Try to find a class that this class extends that is supported
        JPOXType type = findJPOXTypeForClass(c);
        if (type != null)
        {
            return type.dftEmbedded;
        }

        return false;
    }

    /**
     * Utility class to retrieve a supported type
     * @param className The class name
     * @return The internal type information for the class
     */
    protected JPOXType getType(String className)
    {
        if (className == null)
        {
            return null;
        }

        return (JPOXType)types.get(className);
    }

    protected JPOXType findJPOXTypeForClass(Class cls)
    {
        JPOXType type = getType(cls.getName());
        if (type != null)
        {
            return type;
        }

        // Not supported so try to find one that is supported that this class derives from
        Class componentCls = (cls.isArray() ? cls.getComponentType() : null);
        Collection supportedTypes = new HashSet(types.values());
        Iterator iter = supportedTypes.iterator();
        while (iter.hasNext())
        {
            type = (JPOXType)iter.next();
            if (type.cls == cls)
            {
                return type;
            }
            if (!type.cls.getName().equals("java.lang.Object") && !type.cls.getName().equals("java.io.Serializable"))
            {
                if (componentCls != null)
                {
                    // Array type
                    if (type.cls.isArray() && type.cls.getComponentType().isAssignableFrom(componentCls))
                    {
                        addTypeInternal(cls, type);
                        return type;
                    }
                }
                else
                {
                    // Basic type
                    if (type.cls.isAssignableFrom(cls))
                    {
                        // Copy the mapping of this type
                        addTypeInternal(cls, type);
                        return type;
                    }
                }
            }
        }

        // Not supported
        return null;
    }

    /**
     * Inner class defining a supported type. 
     * The type is supported to some degree by JPOX, maybe as FCO or maybe as SCO.
     * Only has SCO wrapper class if is SCO mutable.
     */
    static class JPOXType
    {
        /** supported class. */
        final Class cls;

        /** mapping class. An extension of {@link org.jpox.store.mapping.JavaTypeMapping}*/
        final Class scoMappingType;
        /** sco wrapper for mutable types. An implementation of {@link org.jpox.sco.SCO} */
        final Class scoMutableWrapperType;
        /** sco wrapper for mutable types. An implementation of {@link org.jpox.sco.SCO} */
        final Class scoMutableSimpleWrapperType;
        /** default-fetch-group */
        final boolean dfg;
        /** minimum required java version **/
        final String javaVersion;
        /** if this type is persistent by default. If not, the metadata must explicitily set persistent-modifier="persistent" **/
        final boolean dftPersistent;
        /** if this type is embedded by default. If not, the metadata must explicitily set embedded="true" **/
        final boolean dftEmbedded;
        /** if this type is restricted only to the specified java version */
        final boolean javaRestricted;

        /**
         * Constructor.
         * @param cls the java type class being supported
         * @param sco_mapping_type the mapping class. An extension of {@link org.jpox.store.mapping.JavaTypeMapping}
         * @param sco_wrapper_type the SCO wrapper class name. An implementation of {@link org.jpox.sco.SCO}
         * @param sco_simple_wrapper_type the SCO "simple" wrapper class name. An implementation of {@link org.jpox.sco.SCO}
         * @param dfg default fetch group
         * @param dftPersistent if this type is persistent by default
         * @param dftEmbedded if this type is embedded by default
         * @param javaVersion minimum required java version
         * @param javaRestricted if this type is restricted only to the specified java version by
         *     <code>javaVersion</code>
         */
        public JPOXType(Class cls,
                        Class sco_mapping_type,
                        Class sco_wrapper_type,
                        Class sco_simple_wrapper_type,
                        boolean dfg,
                        boolean dftPersistent,
                        boolean dftEmbedded,
                        String javaVersion,
                        boolean javaRestricted)
        {
            this.cls = cls;
            this.scoMappingType = sco_mapping_type;
            this.scoMutableWrapperType = sco_wrapper_type;
            this.scoMutableSimpleWrapperType = sco_simple_wrapper_type;
            this.dfg = dfg;
            this.javaVersion = javaVersion;
            this.dftPersistent = dftPersistent;
            this.javaRestricted = javaRestricted;
            this.dftEmbedded = dftEmbedded;
        }

        /**
         * Accessor for the mapping class. An extension of {@link org.jpox.store.mapping.JavaTypeMapping}
         * @return the mapping class. An extension of {@link org.jpox.store.mapping.JavaTypeMapping}
         */
        public Class getSCOMappingType()
        {
            return scoMappingType;
        }

        /**
         * Accessor for the SCO wrapper class name. An implementation of {@link org.jpox.sco.SCO}
         * @return the SCO wrapper class name. An implementation of {@link org.jpox.sco.SCO}
         */
        public Class getSCOMutableWrapperType()
        {
            return scoMutableWrapperType;
        }

        /**
         * Accessor for the SCO "simple" wrapper class name. An implementation of {@link org.jpox.sco.SCO}
         * @return the SCO wrapper class name. An implementation of {@link org.jpox.sco.SCO}
         */
        public Class getSCOMutableSimpleWrapperType()
        {
            return scoMutableSimpleWrapperType;
        }

        public String toString()
        {
            StringBuffer str = new StringBuffer(cls.getName() + " [");
            if (scoMappingType != null)
            {
                str.append(" SCO : mapping=" + scoMappingType);
            }
            if (scoMutableWrapperType != null)
            {
                str.append(" SCO : mutable wrapper=" + scoMutableWrapperType);
            }
            if (scoMutableSimpleWrapperType != null)
            {
                str.append(" SCO : simple wrapper=" + scoMutableSimpleWrapperType);
            }
            str.append(" default-fetch-group : " + dfg);
            str.append(" java version : " + javaVersion + (javaRestricted ? " restricted" : ""));
            str.append(" default persisted : " + dftPersistent);
            str.append(" default embedded : " + dftEmbedded);
            str.append("]");
            return str.toString();
        }
    }

    /**
     * Method to load the user type mappings that are currently registered in the PluginManager.
     * @param mgr the PluginManager
     * @param clr the ClassLoaderResolver
     */
    private void loadUserTypes(PluginManager mgr, ClassLoaderResolver clr)
    {
        ExtensionPoint exPoint = mgr.getExtensionPoint("org.jpox.store_mapping");
        for (int i = 0; i < exPoint.getExtensions().length; i++)
        {
            ConfigurationElement[] elms = exPoint.getExtensions()[i].getConfigurationElements();
            for (int e = 0; e < elms.length; e++)
            {
                String javaName = elms[e].getAttribute("java-type").trim();
                String mappingClassName = elms[e].getAttribute("mapping-class");
                String fullWrapperClassName = elms[e].getAttribute("sco-wrapper");
                String simpleWrapperClassName = elms[e].getAttribute("sco-wrapper-simple");
                String defaultFetchGroup = elms[e].getAttribute("default-fetch-group");
                String defaultPersistent = elms[e].getAttribute("default-persistent");
                String defaultEmbedded = elms[e].getAttribute("default-embedded");
                String javaVersionRestrict = elms[e].getAttribute("java-version-restrict");
                if (simpleWrapperClassName == null)
                {
                    // No simple wrapper specified so fallback to the full wrapper
                    simpleWrapperClassName = fullWrapperClassName;
                }
                boolean dfg = false;
                if (defaultFetchGroup != null)
                {
                    if (defaultFetchGroup.equalsIgnoreCase("true"))
                    {
                        dfg = Boolean.TRUE.booleanValue();
                    }
                }
                boolean dftPersistent = false;
                if (defaultPersistent != null)
                {
                    if (defaultPersistent.equalsIgnoreCase("true"))
                    {
                        dftPersistent = Boolean.TRUE.booleanValue();
                    }
                }
                boolean dftEmbedded = false;
                if (defaultEmbedded != null)
                {
                    if (defaultEmbedded.equalsIgnoreCase("true"))
                    {
                        dftEmbedded = Boolean.TRUE.booleanValue();
                    }
                }
                boolean javaRestricted = false;
                if (javaVersionRestrict != null)
                {
                    if (javaVersionRestrict.equalsIgnoreCase("true"))
                    {
                        javaRestricted = Boolean.TRUE.booleanValue();
                    }
                }
                String javaVersion = elms[e].getAttribute("java-version");
                if (javaVersion == null || javaVersion.length() < 1)
                {
                    javaVersion = "1.3";
                }

                addType(mgr, elms[e].getExtension().getPlugin().getSymbolicName(), javaName, mappingClassName, 
                    fullWrapperClassName, simpleWrapperClassName, dfg, dftPersistent,
                    dftEmbedded, javaVersion, javaRestricted, clr);
            }
        }
    }

    /**
     * Method to add support for a Java class (to some degree).
     * @param mgr The PluginManager
     * @param pluginId the plug-in id
     * @param className Name of the class to add
     * @param mappingClassName The Java mapping type
     * @param fullWrapperClassName The SCO wrapper type (for mutable SCOs)
     * @param simpleWrapperClassName The SCO "simple" wrapper type (for mutable SCOs)
     * @param dfg whether this type should be on the default fetch group
     * @param dftPersistent if this type is persistent by default. If not, the metadata must explicitily set persistent-modifier="persistent"
     * @param dftEmbedded If this type is by default embedded
     * @param javaVersion the minimum java version required at runtime to add this type
     * @param javaRestricted if this type is restricted only to the specified java version
     * @param clr the ClassLoaderResolver
     */
    private void addType(PluginManager mgr, String pluginId,
                        String className,
                        String mappingClassName,
                        String fullWrapperClassName,
                        String simpleWrapperClassName,
                        boolean dfg,
                        boolean dftPersistent,
                        boolean dftEmbedded,
                        String javaVersion,
                        boolean javaRestricted,
                        ClassLoaderResolver clr)
    {
        if (className == null)
        {
            return;
        }

        if ((JavaUtils.isGreaterEqualsThan(javaVersion) && !javaRestricted) ||
            (JavaUtils.isEqualsThan(javaVersion) && javaRestricted))
        {
            Class fullWrapperType = null;
            Class simpleWrapperType = null;
            Class mappingType = null;
            if (!StringUtils.isWhitespace(mappingClassName))
            {
                try
                {
                    mappingType = mgr.loadClass(pluginId,mappingClassName);
                }
                catch (JPOXException jpe)
                {
                    JPOXLogger.PERSISTENCE.error(LOCALISER.msg("016004", mappingClassName));
                    return;
                }
            }
            if (!StringUtils.isWhitespace(fullWrapperClassName))
            {
                try
                {
                    fullWrapperType = mgr.loadClass(pluginId,fullWrapperClassName);
                }
                catch (JPOXException jpe)
                {
                    JPOXLogger.PERSISTENCE.error(LOCALISER.msg("016005", fullWrapperClassName));
                    return;
                }
            }
            if (!StringUtils.isWhitespace(simpleWrapperClassName))
            {
                try
                {
                    simpleWrapperType = mgr.loadClass(pluginId,simpleWrapperClassName);
                }
                catch (JPOXException jpe)
                {
                    JPOXLogger.PERSISTENCE.error(LOCALISER.msg("016005", simpleWrapperClassName));
                    return;
                }
            }

            Class cls = null;
            try
            {
                cls = clr.classForName(className);
            }
            catch (Exception e)
            {
                // Class not found so ignore. Should log this
            }
            if (cls != null)
            {
                JPOXType type = new JPOXType(cls, mappingType, fullWrapperType, simpleWrapperType, 
                    dfg, dftPersistent, dftEmbedded, javaVersion, javaRestricted);
                if (dftPersistent)
                {
                    addDefaultPersistent(className);
                }
                if (dfg)
                {
                    addDefaultFetchGroup(className);
                }
                if (dftEmbedded)
                {
                    addDefaultEmbedded(className);
                }
                types.put(className, type);
                if (JPOXLogger.PERSISTENCE.isDebugEnabled())
                {
                    JPOXLogger.PERSISTENCE.debug(LOCALISER.msg("016000", className, 
                        "" + dftPersistent, "" + dfg, "" + dftEmbedded));
                }
            }
        }
    }

    /**
     * Method to add support for a type when it is derived from a type we already support hence shortcutting
     * the check process.
     * @param cls The class
     * @param type JPOXType that we already support that we want to use for this types support also
     */
    private void addTypeInternal(Class cls, JPOXType type)
    {
        if (cls == null)
        {
            return;
        }

        String className = cls.getName();
        types.put(className, type);
        if (type.dftPersistent)
        {
            addDefaultPersistent(className);
        }
        if (type.dfg)
        {
            addDefaultFetchGroup(className);
        }
        if (type.dftEmbedded)
        {
            addDefaultEmbedded(className);
        }
        if (JPOXLogger.PERSISTENCE.isDebugEnabled())
        {
            JPOXLogger.PERSISTENCE.debug(LOCALISER.msg("016001", className, type.cls.getName()));
        }
    }

    /**
     * Add a default persistent type
     * @param className the type name
     */
    private synchronized void addDefaultPersistent(String className)
    {
        if (DEFAULT_PERSISTENT_TYPE == null)
        {
            DEFAULT_PERSISTENT_TYPE = new String[1];
            DEFAULT_PERSISTENT_TYPE[0] = className;
        }
        else
        {
            String[] temp = new String[DEFAULT_PERSISTENT_TYPE.length+1];
            System.arraycopy(DEFAULT_PERSISTENT_TYPE,0,temp,0,DEFAULT_PERSISTENT_TYPE.length);
            temp[temp.length-1] = className;
            Arrays.sort(temp);
            DEFAULT_PERSISTENT_TYPE = temp;
        }
    }

    /**
     * Add a default fetch group type
     * @param className the type name
     */
    private synchronized void addDefaultFetchGroup(String className)
    {
        if (DEFAULT_FETCH_GROUP_TRUE == null)
        {
            DEFAULT_FETCH_GROUP_TRUE = new String[1];
            DEFAULT_FETCH_GROUP_TRUE[0] = className;
        }
        else
        {
            String[] temp = new String[DEFAULT_FETCH_GROUP_TRUE.length+1];
            System.arraycopy(DEFAULT_FETCH_GROUP_TRUE,0,temp,0,DEFAULT_FETCH_GROUP_TRUE.length);
            temp[temp.length-1] = className;
            Arrays.sort(temp);
            DEFAULT_FETCH_GROUP_TRUE = temp;
        }
    }

    /**
     * Add a default embedded type
     * @param className the type name
     */
    private synchronized void addDefaultEmbedded(String className)
    {
        if (DEFAULT_EMBEDDED_TYPE == null)
        {
            DEFAULT_EMBEDDED_TYPE = new String[1];
            DEFAULT_EMBEDDED_TYPE[0] = className;
        }
        else
        {
            String[] temp = new String[DEFAULT_EMBEDDED_TYPE.length+1];
            System.arraycopy(DEFAULT_EMBEDDED_TYPE,0,temp,0,DEFAULT_EMBEDDED_TYPE.length);
            temp[temp.length-1] = className;
            Arrays.sort(temp);
            DEFAULT_EMBEDDED_TYPE = temp;
        }
    }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.