Home » apache-openjpa-1.1.0-source » org.apache.openjpa.jdbc » meta » [javadoc | source]
    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one
    3    * or more contributor license agreements.  See the NOTICE file
    4    * distributed with this work for additional information
    5    * regarding copyright ownership.  The ASF licenses this file
    6    * to you under the Apache License, Version 2.0 (the
    7    * "License"); you may not use this file except in compliance
    8    * with the License.  You may obtain a copy of the License at
    9    *
   10    * http://www.apache.org/licenses/LICENSE-2.0
   11    *
   12    * Unless required by applicable law or agreed to in writing,
   13    * software distributed under the License is distributed on an
   14    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   15    * KIND, either express or implied.  See the License for the
   16    * specific language governing permissions and limitations
   17    * under the License.    
   18    */
   19   package org.apache.openjpa.jdbc.meta;
   20   
   21   import java.lang.reflect.Modifier;
   22   import java.security.AccessController;
   23   import java.security.PrivilegedActionException;
   24   import java.sql.Types;
   25   import java.util.Collection;
   26   import java.util.HashMap;
   27   import java.util.List;
   28   import java.util.Map;
   29   
   30   import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
   31   import org.apache.openjpa.jdbc.meta.strats.BlobValueHandler;
   32   import org.apache.openjpa.jdbc.meta.strats.ByteArrayValueHandler;
   33   import org.apache.openjpa.jdbc.meta.strats.CharArrayStreamValueHandler;
   34   import org.apache.openjpa.jdbc.meta.strats.CharArrayValueHandler;
   35   import org.apache.openjpa.jdbc.meta.strats.ClassNameDiscriminatorStrategy;
   36   import org.apache.openjpa.jdbc.meta.strats.ClobValueHandler;
   37   import org.apache.openjpa.jdbc.meta.strats.ElementEmbedValueHandler;
   38   import org.apache.openjpa.jdbc.meta.strats.EmbedFieldStrategy;
   39   import org.apache.openjpa.jdbc.meta.strats.EmbeddedClassStrategy;
   40   import org.apache.openjpa.jdbc.meta.strats.FlatClassStrategy;
   41   import org.apache.openjpa.jdbc.meta.strats.FullClassStrategy;
   42   import org.apache.openjpa.jdbc.meta.strats.HandlerCollectionTableFieldStrategy;
   43   import org.apache.openjpa.jdbc.meta.strats.HandlerFieldStrategy;
   44   import org.apache.openjpa.jdbc.meta.strats.HandlerHandlerMapTableFieldStrategy;
   45   import org.apache.openjpa.jdbc.meta.strats.HandlerRelationMapTableFieldStrategy;
   46   import org.apache.openjpa.jdbc.meta.strats.ImmutableValueHandler;
   47   import org.apache.openjpa.jdbc.meta.strats.LobFieldStrategy;
   48   import org.apache.openjpa.jdbc.meta.strats.MaxEmbeddedBlobFieldStrategy;
   49   import org.apache.openjpa.jdbc.meta.strats.MaxEmbeddedByteArrayFieldStrategy;
   50   import org.apache.openjpa.jdbc.meta.strats.MaxEmbeddedCharArrayFieldStrategy;
   51   import org.apache.openjpa.jdbc.meta.strats.MaxEmbeddedClobFieldStrategy;
   52   import org.apache.openjpa.jdbc.meta.strats.NanoPrecisionTimestampVersionStrategy;
   53   import org.apache.openjpa.jdbc.meta.strats.NoneClassStrategy;
   54   import org.apache.openjpa.jdbc.meta.strats.NoneDiscriminatorStrategy;
   55   import org.apache.openjpa.jdbc.meta.strats.NoneFieldStrategy;
   56   import org.apache.openjpa.jdbc.meta.strats.NoneVersionStrategy;
   57   import org.apache.openjpa.jdbc.meta.strats.NumberVersionStrategy;
   58   import org.apache.openjpa.jdbc.meta.strats.ObjectIdClassStrategy;
   59   import org.apache.openjpa.jdbc.meta.strats.ObjectIdValueHandler;
   60   import org.apache.openjpa.jdbc.meta.strats.PrimitiveFieldStrategy;
   61   import org.apache.openjpa.jdbc.meta.strats.RelationCollectionInverseKeyFieldStrategy;
   62   import org.apache.openjpa.jdbc.meta.strats.RelationCollectionTableFieldStrategy;
   63   import org.apache.openjpa.jdbc.meta.strats.RelationFieldStrategy;
   64   import org.apache.openjpa.jdbc.meta.strats.RelationHandlerMapTableFieldStrategy;
   65   import org.apache.openjpa.jdbc.meta.strats.RelationMapInverseKeyFieldStrategy;
   66   import org.apache.openjpa.jdbc.meta.strats.RelationMapTableFieldStrategy;
   67   import org.apache.openjpa.jdbc.meta.strats.RelationRelationMapTableFieldStrategy;
   68   import org.apache.openjpa.jdbc.meta.strats.StateComparisonVersionStrategy;
   69   import org.apache.openjpa.jdbc.meta.strats.StringFieldStrategy;
   70   import org.apache.openjpa.jdbc.meta.strats.SubclassJoinDiscriminatorStrategy;
   71   import org.apache.openjpa.jdbc.meta.strats.SuperclassDiscriminatorStrategy;
   72   import org.apache.openjpa.jdbc.meta.strats.SuperclassVersionStrategy;
   73   import org.apache.openjpa.jdbc.meta.strats.TimestampVersionStrategy;
   74   import org.apache.openjpa.jdbc.meta.strats.UntypedPCValueHandler;
   75   import org.apache.openjpa.jdbc.meta.strats.ValueMapDiscriminatorStrategy;
   76   import org.apache.openjpa.jdbc.meta.strats.VerticalClassStrategy;
   77   import org.apache.openjpa.jdbc.schema.Column;
   78   import org.apache.openjpa.jdbc.schema.SchemaGroup;
   79   import org.apache.openjpa.jdbc.sql.DBDictionary;
   80   import org.apache.openjpa.jdbc.sql.JoinSyntaxes;
   81   import org.apache.openjpa.lib.conf.Configurable;
   82   import org.apache.openjpa.lib.conf.Configurations;
   83   import org.apache.openjpa.lib.util.J2DoPrivHelper;
   84   import org.apache.openjpa.lib.util.JavaVersions;
   85   import org.apache.openjpa.lib.util.Localizer;
   86   import org.apache.openjpa.meta.ClassMetaData;
   87   import org.apache.openjpa.meta.FieldMetaData;
   88   import org.apache.openjpa.meta.JavaTypes;
   89   import org.apache.openjpa.meta.MetaDataRepository;
   90   import org.apache.openjpa.meta.Order;
   91   import org.apache.openjpa.meta.SequenceMetaData;
   92   import org.apache.openjpa.meta.ValueMetaData;
   93   import org.apache.openjpa.util.MetaDataException;
   94   
   95   /**
   96    * Repository of object/relational mapping information.
   97    *
   98    * @author Abe White
   99    */
  100   public class MappingRepository
  101       extends MetaDataRepository {
  102   
  103       private static final Localizer _loc = Localizer.forPackage
  104           (MappingRepository.class);
  105   
  106       private transient DBDictionary _dict = null;
  107       private transient MappingDefaults _defaults = null;
  108       
  109       private Map _results = new HashMap(); // object->queryresultmapping
  110       private SchemaGroup _schema = null;
  111       private StrategyInstaller _installer = null;
  112   
  113       /**
  114        * Default constructor.  Configure via 
  115        * {@link org.apache.openjpa.lib.conf.Configurable}.
  116        */
  117       public MappingRepository() {
  118           setValidate(VALIDATE_MAPPING, true);
  119       }
  120   
  121       /**
  122        * Convenient access to dictionary for mappings.
  123        */
  124       public DBDictionary getDBDictionary() {
  125           return _dict;
  126       }
  127   
  128       /**
  129        * Mapping defaults.
  130        */
  131       public MappingDefaults getMappingDefaults() {
  132           return _defaults;
  133       }
  134   
  135       /**
  136        * Mapping default.
  137        */
  138       public void setMappingDefaults(MappingDefaults defaults) {
  139           _defaults = defaults;
  140       }
  141   
  142       /**
  143        * Representation of the database schema.
  144        */
  145       public synchronized SchemaGroup getSchemaGroup() {
  146           if (_schema == null)
  147               _schema = ((JDBCConfiguration) getConfiguration()).
  148                   getSchemaFactoryInstance().readSchema();
  149           return _schema;
  150       }
  151   
  152       /**
  153        * Representation of the database schema.
  154        */
  155       public synchronized void setSchemaGroup(SchemaGroup schema) {
  156           _schema = schema;
  157       }
  158   
  159       /**
  160        * Installs mapping strategies on components.
  161        */
  162       public synchronized StrategyInstaller getStrategyInstaller() {
  163           if (_installer == null)
  164               _installer = new RuntimeStrategyInstaller(this);
  165           return _installer;
  166       }
  167   
  168       /**
  169        * Installs mapping strategies on components.
  170        */
  171       public synchronized void setStrategyInstaller(StrategyInstaller installer) {
  172           _installer = installer;
  173       }
  174   
  175       /**
  176        * Return the query result mapping for the given name.
  177        */
  178       public synchronized QueryResultMapping getQueryResultMapping(Class cls,
  179           String name, ClassLoader envLoader, boolean mustExist) {
  180           QueryResultMapping res = getQueryResultMappingInternal(cls, name,
  181               envLoader);
  182           if (res == null && mustExist)
  183               throw new MetaDataException(_loc.get("no-query-res", cls, name));
  184           return res;
  185       }
  186   
  187       /**
  188        * Returned the query result mapping with the given name.
  189        */
  190       private QueryResultMapping getQueryResultMappingInternal(Class cls,
  191           String name, ClassLoader envLoader) {
  192           if (name == null)
  193               return null;
  194   
  195           // check cache
  196           Object key = getQueryResultKey(cls, name);
  197           QueryResultMapping res = (QueryResultMapping) _results.get(key);
  198           if (res != null)
  199               return res;
  200   
  201           // get metadata for class, which will find results in metadata file
  202           if (cls != null && getMetaData(cls, envLoader, false) != null) {
  203               res = (QueryResultMapping) _results.get(key);
  204               if (res != null)
  205                   return res;
  206           }
  207           if ((getSourceMode() & MODE_QUERY) == 0)
  208               return null;
  209   
  210           if (cls == null)
  211               cls = getMetaDataFactory()
  212                       .getResultSetMappingScope(name, envLoader);
  213           // not in cache; load
  214           getMetaDataFactory().load(cls, MODE_META | MODE_MAPPING, envLoader);
  215           return (QueryResultMapping) _results.get(key);
  216       }
  217   
  218       /**
  219        * Return all cached query result mappings.
  220        */
  221       public synchronized QueryResultMapping[] getQueryResultMappings() {
  222           Collection values = _results.values();
  223           return (QueryResultMapping[]) values.toArray
  224               (new QueryResultMapping[values.size()]);
  225       }
  226   
  227       /**
  228        * Return the cached query result mapping with the given name, or null if
  229        * none.
  230        */
  231       public synchronized QueryResultMapping getCachedQueryResultMapping
  232           (Class cls, String name) {
  233           return (QueryResultMapping) _results.get(getQueryResultKey(cls, name));
  234       }
  235   
  236       /**
  237        * Add a query result mapping.
  238        */
  239       public synchronized QueryResultMapping addQueryResultMapping(Class cls,
  240           String name) {
  241           QueryResultMapping res = new QueryResultMapping(name, this);
  242           res.setDefiningType(cls);
  243           _results.put(getQueryResultKey(res), res);
  244           return res;
  245       }
  246   
  247       /**
  248        * Remove a query result mapping.
  249        */
  250       public synchronized boolean removeQueryResultMapping
  251           (QueryResultMapping res) {
  252           return _results.remove(getQueryResultKey(res)) != null;
  253       }
  254   
  255       /**
  256        * Remove a query result mapping.
  257        */
  258       public synchronized boolean removeQueryResultMapping(Class cls,
  259           String name) {
  260           if (name == null)
  261               return false;
  262           return _results.remove(getQueryResultKey(cls, name)) != null;
  263       }
  264   
  265       /**
  266        * Return a unique key for the given mapping.
  267        */
  268       private static Object getQueryResultKey(QueryResultMapping res) {
  269           if (res == null)
  270               return null;
  271           return getQueryResultKey(res.getDefiningType(), res.getName());
  272       }
  273   
  274       /**
  275        * Return a unique key for the given class / name. The class argument
  276        * can be null.
  277        */
  278       private static Object getQueryResultKey(Class cls, String name) {
  279           return getQueryKey(cls, name);
  280       }
  281   
  282       public ClassMapping getMapping(Class cls, ClassLoader envLoader,
  283           boolean mustExist) {
  284           return (ClassMapping) super.getMetaData(cls, envLoader, mustExist);
  285       }
  286   
  287       public ClassMapping[] getMappings() {
  288           return (ClassMapping[]) super.getMetaDatas();
  289       }
  290   
  291       public ClassMapping getMapping(Object oid, ClassLoader envLoader,
  292           boolean mustExist) {
  293           return (ClassMapping) super.getMetaData(oid, envLoader, mustExist);
  294       }
  295   
  296       public ClassMapping[] getImplementorMappings(Class cls,
  297           ClassLoader envLoader, boolean mustExist) {
  298           return (ClassMapping[]) super.getImplementorMetaDatas(cls, envLoader,
  299               mustExist);
  300       }
  301   
  302       public synchronized void clear() {
  303           super.clear();
  304           _schema = null;
  305           _results.clear();
  306       }
  307   
  308       protected void prepareMapping(ClassMetaData meta) {
  309           // make sure superclass resolved first; resolving superclass may have
  310           // resolved this mapping
  311           ClassMapping mapping = (ClassMapping) meta;
  312           ClassMapping sup = mapping.getPCSuperclassMapping();
  313           if (sup != null && (mapping.getResolve() & MODE_MAPPING) != 0)
  314               return;
  315   
  316           // define superclass fields after mapping class, so we can tell whether
  317           // the class is mapped and needs to redefine abstract superclass fields
  318           getStrategyInstaller().installStrategy(mapping);
  319           mapping.defineSuperclassFields(mapping.getJoinablePCSuperclassMapping()
  320               == null);
  321   
  322           // resolve everything that doesn't involve relations to allow relation
  323           // mappings to use the others as joinables
  324           mapping.resolveNonRelationMappings();
  325       }
  326   
  327       protected ClassMetaData newClassMetaData(Class type) {
  328           return new ClassMapping(type, this);
  329       }
  330   
  331       protected ClassMetaData[] newClassMetaDataArray(int length) {
  332           return new ClassMapping[length];
  333       }
  334   
  335       protected FieldMetaData newFieldMetaData(String name, Class type,
  336           ClassMetaData owner) {
  337           return new FieldMapping(name, type, (ClassMapping) owner);
  338       }
  339   
  340       protected FieldMetaData[] newFieldMetaDataArray(int length) {
  341           return new FieldMapping[length];
  342       }
  343   
  344       protected ClassMetaData newEmbeddedClassMetaData(ValueMetaData owner) {
  345           return new ClassMapping(owner);
  346       }
  347   
  348       protected ValueMetaData newValueMetaData(FieldMetaData owner) {
  349           return new ValueMappingImpl((FieldMapping) owner);
  350       }
  351   
  352       protected SequenceMetaData newSequenceMetaData(String name) {
  353           return new SequenceMapping(name, this);
  354       }
  355   
  356       protected Order newValueOrder(FieldMetaData owner, boolean asc) {
  357           return new JDBCValueOrder((FieldMapping) owner, asc);
  358       }
  359   
  360       protected Order newRelatedFieldOrder(FieldMetaData owner,
  361           FieldMetaData rel, boolean asc) {
  362           return new JDBCRelatedFieldOrder((FieldMapping) owner,
  363               (FieldMapping) rel, asc);
  364       }
  365   
  366       protected Order[] newOrderArray(int size) {
  367           return new JDBCOrder[size];
  368       }
  369   
  370       /**
  371        * Create version metadata for the given class.
  372        */
  373       protected Version newVersion(ClassMapping cls) {
  374           return new Version(cls);
  375       }
  376   
  377       /**
  378        * Create discriminator metadata for the given class.
  379        */
  380       protected Discriminator newDiscriminator(ClassMapping cls) {
  381           return new Discriminator(cls);
  382       }
  383   
  384       /**
  385        * Create raw mapping info for the given instance.
  386        */
  387       protected ClassMappingInfo newMappingInfo(ClassMapping cls) {
  388           ClassMappingInfo info = new ClassMappingInfo();
  389           info.setClassName(cls.getDescribedType().getName());
  390           return info;
  391       }
  392   
  393       /**
  394        * Create raw mapping info for the given instance.
  395        */
  396       protected FieldMappingInfo newMappingInfo(FieldMapping fm) {
  397           return new FieldMappingInfo();
  398       }
  399   
  400       /**
  401        * Create raw mapping info for the given instance.
  402        */
  403       protected ValueMappingInfo newMappingInfo(ValueMapping vm) {
  404           return new ValueMappingInfo();
  405       }
  406   
  407       /**
  408        * Create raw mapping info for the given instance.
  409        */
  410       protected VersionMappingInfo newMappingInfo(Version version) {
  411           return new VersionMappingInfo();
  412       }
  413   
  414       /**
  415        * Create raw mapping info for the given instance.
  416        */
  417       protected DiscriminatorMappingInfo newMappingInfo(Discriminator disc) {
  418           return new DiscriminatorMappingInfo();
  419       }
  420   
  421       /**
  422        * Instantiate the given class' named strategy, or return null if no
  423        * named strategy.
  424        */
  425       protected ClassStrategy namedStrategy(ClassMapping cls) {
  426           String name = cls.getMappingInfo().getStrategy();
  427           return instantiateClassStrategy(name, cls);
  428       }
  429   
  430       /**
  431        * Return the strategy for the given name.
  432        */
  433       protected ClassStrategy instantiateClassStrategy(String name,
  434           ClassMapping cls) {
  435           if (name == null)
  436               return null;
  437           if (NoneClassStrategy.ALIAS.equals(name))
  438               return NoneClassStrategy.getInstance();
  439   
  440           String props = Configurations.getProperties(name);
  441           name = Configurations.getClassName(name);
  442           Class strat = null;
  443   
  444           // base and vertical strategies use same alias; differentiate on join
  445           if (FullClassStrategy.ALIAS.equals(name))
  446               strat = FullClassStrategy.class;
  447           else if (FlatClassStrategy.ALIAS.equals(name))
  448               strat = FlatClassStrategy.class;
  449           else if (VerticalClassStrategy.ALIAS.equals(name))
  450               strat = VerticalClassStrategy.class;
  451           try {
  452               if (strat == null)
  453                   strat = JavaTypes.classForName(name, cls,
  454                       (ClassLoader) AccessController.doPrivileged(
  455                           J2DoPrivHelper.getClassLoaderAction(
  456                               ClassStrategy.class)));
  457               ClassStrategy strategy = 
  458                   (ClassStrategy) AccessController.doPrivileged(
  459                       J2DoPrivHelper.newInstanceAction(strat));
  460               Configurations.configureInstance(strategy, getConfiguration(),
  461                   props);
  462               return strategy;
  463           } catch (Exception e) {
  464               if (e instanceof PrivilegedActionException)
  465                   e = ((PrivilegedActionException) e).getException();
  466               throw new MetaDataException(_loc.get("bad-cls-strategy",
  467                   cls, name), e);
  468           }
  469       }
  470   
  471       /**
  472        * Instantiate the given field's named strategy, or return null if no
  473        * named strategy.
  474        */
  475       protected FieldStrategy namedStrategy(FieldMapping field,
  476           boolean installHandlers) {
  477           String name = field.getMappingInfo().getStrategy();
  478           if (name == null)
  479               return null;
  480   
  481           if (NoneFieldStrategy.ALIAS.equals(name))
  482               return NoneFieldStrategy.getInstance();
  483   
  484           String props = Configurations.getProperties(name);
  485           name = Configurations.getClassName(name);
  486           try {
  487               Class c = JavaTypes.classForName(name, field,
  488                   (ClassLoader) AccessController.doPrivileged(
  489                       J2DoPrivHelper.getClassLoaderAction(FieldStrategy.class)));
  490               if (FieldStrategy.class.isAssignableFrom(c)) {
  491                   FieldStrategy strat = (FieldStrategy)
  492                       AccessController.doPrivileged(
  493                           J2DoPrivHelper.newInstanceAction(c));
  494                   Configurations.configureInstance(strat, getConfiguration(),
  495                       props);
  496                   return strat;
  497               }
  498   
  499               // must be named handler
  500               if (installHandlers) {
  501                   ValueHandler vh = (ValueHandler) AccessController.doPrivileged(
  502                       J2DoPrivHelper.newInstanceAction(c));
  503                   Configurations.configureInstance(vh, getConfiguration(),
  504                       props);
  505                   field.setHandler(vh);
  506               }
  507               return new HandlerFieldStrategy();
  508           } catch (Exception e) {
  509               if (e instanceof PrivilegedActionException)
  510                   e = ((PrivilegedActionException) e).getException();
  511               throw new MetaDataException(_loc.get("bad-field-strategy",
  512                   field, name), e);
  513           }
  514       }
  515   
  516       /**
  517        * Instantiate the given discriminator's named strategy, or return null
  518        * if no named strategy.
  519        */
  520       protected DiscriminatorStrategy namedStrategy(Discriminator discrim) {
  521           String name = discrim.getMappingInfo().getStrategy();
  522           if (name == null)
  523               return null;
  524   
  525           // if there is a named strategy present, discard it if it matches
  526           // the base strategy, so that we won't create an independent instance
  527           ClassMapping cls = discrim.getClassMapping();
  528           while (cls.getJoinablePCSuperclassMapping() != null)
  529               cls = cls.getJoinablePCSuperclassMapping();
  530           Discriminator base = cls.getDiscriminator();
  531           if (base != discrim && base.getStrategy() != null
  532               && name.equals(base.getStrategy().getAlias()))
  533               return null;
  534   
  535           return instantiateDiscriminatorStrategy(name, discrim);
  536       }
  537   
  538       /**
  539        * Instantiate the given discriminator strategy.
  540        */
  541       protected DiscriminatorStrategy instantiateDiscriminatorStrategy
  542           (String name, Discriminator discrim) {
  543           if (NoneDiscriminatorStrategy.ALIAS.equals(name))
  544               return NoneDiscriminatorStrategy.getInstance();
  545   
  546           String props = Configurations.getProperties(name);
  547           name = Configurations.getClassName(name);
  548           Class strat = null;
  549   
  550           if (ClassNameDiscriminatorStrategy.ALIAS.equals(name))
  551               strat = ClassNameDiscriminatorStrategy.class;
  552           else if (ValueMapDiscriminatorStrategy.ALIAS.equals(name))
  553               strat = ValueMapDiscriminatorStrategy.class;
  554           else if (SubclassJoinDiscriminatorStrategy.ALIAS.equals(name))
  555               strat = SubclassJoinDiscriminatorStrategy.class;
  556   
  557           try {
  558               if (strat == null)
  559                   strat = JavaTypes.classForName(name,
  560                       discrim.getClassMapping(),
  561                       (ClassLoader) AccessController.doPrivileged(
  562                           J2DoPrivHelper.getClassLoaderAction(
  563                               DiscriminatorStrategy.class)));
  564               DiscriminatorStrategy strategy = (DiscriminatorStrategy)
  565                   AccessController.doPrivileged(
  566                       J2DoPrivHelper.newInstanceAction(strat));
  567               Configurations.configureInstance(strategy, getConfiguration(),
  568                   props);
  569               return strategy;
  570           } catch (Exception e) {
  571               if (e instanceof PrivilegedActionException)
  572                   e = ((PrivilegedActionException) e).getException();
  573               throw new MetaDataException(_loc.get("bad-discrim-strategy",
  574                   discrim.getClassMapping(), name), e);
  575           }
  576       }
  577   
  578       /**
  579        * Instantiate the given version's named strategy, or return null
  580        * if no named strategy.
  581        */
  582       protected VersionStrategy namedStrategy(Version version) {
  583           String name = version.getMappingInfo().getStrategy();
  584           if (name == null)
  585               return null;
  586   
  587           // if there is a named strategy present, discard it if it matches
  588           // the base strategy, so that we won't create an independent instance
  589           ClassMapping cls = version.getClassMapping();
  590           while (cls.getJoinablePCSuperclassMapping() != null)
  591               cls = cls.getJoinablePCSuperclassMapping();
  592           Version base = cls.getVersion();
  593           if (base != version && base.getStrategy() != null
  594               && name.equals(base.getStrategy().getAlias()))
  595               return null;
  596   
  597           return instantiateVersionStrategy(name, version);
  598       }
  599   
  600       /**
  601        * Instantiate the given version strategy.
  602        */
  603       protected VersionStrategy instantiateVersionStrategy(String name,
  604           Version version) {
  605           if (NoneVersionStrategy.ALIAS.equals(name))
  606               return NoneVersionStrategy.getInstance();
  607   
  608           String props = Configurations.getProperties(name);
  609           name = Configurations.getClassName(name);
  610           Class strat = null;
  611   
  612           if (NumberVersionStrategy.ALIAS.equals(name))
  613               strat = NumberVersionStrategy.class;
  614           else if (TimestampVersionStrategy.ALIAS.equals(name))
  615               strat = TimestampVersionStrategy.class;
  616           else if (NanoPrecisionTimestampVersionStrategy.ALIAS.equals(name))
  617               strat = NanoPrecisionTimestampVersionStrategy.class;
  618           else if (StateComparisonVersionStrategy.ALIAS.equals(name))
  619               strat = StateComparisonVersionStrategy.class;
  620   
  621           try {
  622               if (strat == null)
  623                   strat = JavaTypes.classForName(name,
  624                       version.getClassMapping(),
  625                       (ClassLoader) AccessController.doPrivileged(
  626                           J2DoPrivHelper.getClassLoaderAction(
  627                               VersionStrategy.class)));
  628           } catch (Exception e) {
  629               throw new MetaDataException(_loc.get("bad-version-strategy",
  630                   version.getClassMapping(), name), e);
  631           }
  632   
  633           return instantiateVersionStrategy(strat, version, props);
  634       }
  635   
  636       /**
  637        * Instantiate the given version strategy.
  638        */
  639       protected VersionStrategy instantiateVersionStrategy(Class strat,
  640           Version version, String props) {
  641           try {
  642               VersionStrategy strategy = (VersionStrategy)
  643                   AccessController.doPrivileged(
  644                       J2DoPrivHelper.newInstanceAction(strat));
  645               Configurations.configureInstance(strategy, getConfiguration(),
  646                   props);
  647               return strategy;
  648           } catch (Exception e) {
  649               if (e instanceof PrivilegedActionException)
  650                   e = ((PrivilegedActionException) e).getException();
  651               throw new MetaDataException(_loc.get("bad-version-strategy",
  652                   version.getClassMapping(), strat + ""), e);
  653           }
  654       }
  655   
  656       /**
  657        * Determine the default strategy to use for the given class. Does
  658        * not take into account the current strategy, if any.
  659        */
  660       protected ClassStrategy defaultStrategy(ClassMapping cls) {
  661           return defaultStrategy(cls, getStrategyInstaller().isAdapting());
  662       }
  663   
  664       /**
  665        * Determine the default strategy to use for the given class. Does
  666        * not take into account the current strategy, if any.
  667        */
  668       protected ClassStrategy defaultStrategy(ClassMapping cls,
  669           boolean adapting) {
  670           ValueMapping embed = cls.getEmbeddingMapping();
  671           if (embed != null) {
  672               // superclass of embedded class isn't mapped
  673               if (embed.getType() != cls.getDescribedType()
  674                   || embed.getFieldMapping().getStrategy()
  675                   == NoneFieldStrategy.getInstance())
  676                   return NoneClassStrategy.getInstance();
  677               if (embed.getTypeCode() == JavaTypes.OID)
  678                   return new ObjectIdClassStrategy();
  679               return new EmbeddedClassStrategy();
  680           }
  681           if (cls.isEmbeddedOnly())
  682               return NoneClassStrategy.getInstance();
  683   
  684           Object strat = _defaults.getStrategy(cls, adapting);
  685           if (strat instanceof String)
  686               return instantiateClassStrategy((String) strat, cls);
  687           if (strat != null)
  688               return (ClassStrategy) strat;
  689           
  690           // see if there is a declared hierarchy strategy
  691           ClassStrategy hstrat = null;
  692           for (ClassMapping base = cls; base != null && hstrat == null;) {
  693               hstrat = instantiateClassStrategy(base.getMappingInfo().
  694                   getHierarchyStrategy(), cls);
  695               base = base.getMappedPCSuperclassMapping();
  696           }
  697   
  698           // the full strategy as applied to a hierarchy is a
  699           // table-per-concrete-class strategy, so don't map abstract types
  700           if (hstrat instanceof FullClassStrategy
  701               && !cls.isManagedInterface()
  702               && Modifier.isAbstract(cls.getDescribedType().getModifiers()))
  703               return NoneClassStrategy.getInstance();
  704           
  705           ClassMapping sup = cls.getMappedPCSuperclassMapping();
  706           if (sup == null)
  707               return new FullClassStrategy();
  708           if (hstrat != null)
  709               return hstrat;
  710           return new FlatClassStrategy();
  711       }
  712   
  713       /**
  714        * Determine the default strategy to use for the given field. Does
  715        * not take into account the named or current strategy, if any. If a
  716        * non-null strategy is returned, this method may as a side effect install
  717        * value handlers on the field's value mappings.
  718        */
  719       protected FieldStrategy defaultStrategy(FieldMapping field,
  720           boolean installHandlers) {
  721           return defaultStrategy(field, installHandlers,
  722               getStrategyInstaller().isAdapting());
  723       }
  724   
  725       /**
  726        * Determine the default strategy to use for the given field. Does
  727        * not take into account the named or current strategy, if any. If a
  728        * non-null strategy is returned, this method may as a side effect install
  729        * value handlers on the field's value mappings.
  730        */
  731       protected FieldStrategy defaultStrategy(FieldMapping field,
  732           boolean installHandlers, boolean adapting) {
  733           // not persistent?
  734           if (field.getManagement() != field.MANAGE_PERSISTENT
  735               || field.isVersion())
  736               return NoneFieldStrategy.getInstance();
  737           if (field.getDefiningMapping().getStrategy() ==
  738               NoneClassStrategy.getInstance())
  739               return NoneFieldStrategy.getInstance();
  740   
  741           // check for named handler first
  742           ValueHandler handler = namedHandler(field);
  743           if (handler != null) {
  744               if (installHandlers)
  745                   field.setHandler(handler);
  746               return new HandlerFieldStrategy();
  747           }
  748   
  749           if (field.isSerialized()) {
  750               if (_dict.maxEmbeddedBlobSize != -1)
  751                   return new MaxEmbeddedBlobFieldStrategy();
  752           } else {
  753               // check for mapped strategy
  754               Object strat = mappedStrategy(field, field.getType(), adapting);
  755               if (strat instanceof FieldStrategy)
  756                   return (FieldStrategy) strat;
  757               if (strat != null) {
  758                   if (installHandlers)
  759                       field.setHandler((ValueHandler) strat);
  760                   return new HandlerFieldStrategy();
  761               }
  762           }
  763   
  764           // check for known field strategies
  765           if (!field.isSerialized() && (field.getType() == byte[].class
  766               || field.getType() == Byte[].class)) {
  767               if (_dict.maxEmbeddedBlobSize != -1)
  768                   return new MaxEmbeddedByteArrayFieldStrategy();
  769           } else if (!field.isSerialized()
  770               && (field.getType() == char[].class
  771               || field.getType() == Character[].class)) {
  772               if (_dict.maxEmbeddedClobSize != -1 && isClob(field, false))
  773                   return new MaxEmbeddedCharArrayFieldStrategy();
  774           } else if (!field.isSerialized()) {
  775               FieldStrategy strat = defaultTypeStrategy(field, installHandlers,
  776                   adapting);
  777               if (strat != null)
  778                   return strat;
  779           }
  780   
  781           // check for default handler
  782           handler = defaultHandler(field, adapting);
  783           if (handler != null) {
  784               if (installHandlers)
  785                   field.setHandler(handler);
  786               return new HandlerFieldStrategy();
  787           }
  788   
  789           // default to blob
  790           if (installHandlers) {
  791               if (getLog().isWarnEnabled())
  792                   getLog().warn(_loc.get("no-field-strategy", field));
  793               field.setSerialized(true);
  794           }
  795           if (_dict.maxEmbeddedBlobSize == -1) {
  796               if (installHandlers)
  797                   field.setHandler(BlobValueHandler.getInstance());
  798               return new HandlerFieldStrategy();
  799           }
  800           return new MaxEmbeddedBlobFieldStrategy();
  801       }
  802   
  803       /**
  804        * Return the built-in strategy for the field's type, or null if none.
  805        */
  806       protected FieldStrategy defaultTypeStrategy(FieldMapping field,
  807           boolean installHandlers, boolean adapting) {
  808           switch (field.getTypeCode()) {
  809               case JavaTypes.BOOLEAN:
  810               case JavaTypes.BYTE:
  811               case JavaTypes.CHAR:
  812               case JavaTypes.DOUBLE:
  813               case JavaTypes.FLOAT:
  814               case JavaTypes.INT:
  815               case JavaTypes.LONG:
  816               case JavaTypes.SHORT:
  817                   return new PrimitiveFieldStrategy();
  818               case JavaTypes.STRING:
  819                   if (!isClob(field, false))
  820                       return new StringFieldStrategy();
  821                   if (_dict.maxEmbeddedClobSize != -1)
  822                       return new MaxEmbeddedClobFieldStrategy();
  823                   break;
  824               case JavaTypes.PC:
  825                   if (field.isEmbeddedPC())
  826                       return new EmbedFieldStrategy();
  827                   if (field.getTypeMapping().isMapped()
  828                       || !useUntypedPCHandler(field))
  829                       return new RelationFieldStrategy();
  830                   break;
  831               case JavaTypes.ARRAY:
  832               case JavaTypes.COLLECTION:
  833                   ValueMapping elem = field.getElementMapping();
  834                   ValueHandler ehandler = namedHandler(elem);
  835                   if (ehandler == null)
  836                       ehandler = defaultHandler(elem);
  837                   if (ehandler != null)
  838                       return handlerCollectionStrategy(field, ehandler, 
  839                           installHandlers);
  840                   if (elem.getTypeCode() == JavaTypes.PC
  841                       && !elem.isSerialized() && !elem.isEmbeddedPC()) {
  842                       if (useInverseKeyMapping(field))
  843                           return new RelationCollectionInverseKeyFieldStrategy();
  844                       return new RelationCollectionTableFieldStrategy();
  845                   }
  846                   break;
  847               case JavaTypes.MAP:
  848                   ValueMapping key = field.getKeyMapping();
  849                   ValueHandler khandler = namedHandler(key);
  850                   if (khandler == null)
  851                       khandler = defaultHandler(key);
  852                   ValueMapping val = field.getElementMapping();
  853                   ValueHandler vhandler = namedHandler(val);
  854                   if (vhandler == null)
  855                       vhandler = defaultHandler(val);
  856                   boolean krel = khandler == null 
  857                       && key.getTypeCode() == JavaTypes.PC
  858                       && !key.isSerialized() && !key.isEmbeddedPC();
  859                   boolean vrel = vhandler == null 
  860                       && val.getTypeCode() == JavaTypes.PC
  861                       && !val.isSerialized() && !val.isEmbeddedPC();
  862                   if (!krel && vrel && key.getValueMappedBy() != null) {
  863                       if (useInverseKeyMapping(field))
  864                           return new RelationMapInverseKeyFieldStrategy();
  865                       return new RelationMapTableFieldStrategy();
  866                   }
  867                   if (!krel && khandler == null)
  868                       break;
  869                   if (!vrel && vhandler == null)
  870                       break;
  871                   return handlerMapStrategy(field, khandler, vhandler, krel,
  872                       vrel, installHandlers);
  873               case JavaTypes.INPUT_STREAM:
  874               case JavaTypes.INPUT_READER:
  875                   return new LobFieldStrategy();
  876           }
  877           return null;
  878       }
  879   
  880       /**
  881        * Return the collection strategy for the given element handler, or null
  882        * if none.
  883        */
  884       protected FieldStrategy handlerCollectionStrategy(FieldMapping field, 
  885           ValueHandler ehandler, boolean installHandlers) {
  886           if (getConfiguration().getCompatibilityInstance()
  887               .getStoreMapCollectionInEntityAsBlob())
  888               return null;
  889           if (installHandlers)
  890               field.getElementMapping().setHandler(ehandler);
  891           return new HandlerCollectionTableFieldStrategy();
  892       }
  893   
  894       /**
  895        * Return the map strategy for the given key and value handlers / relations,
  896        * or null if none.
  897        */
  898       protected FieldStrategy handlerMapStrategy(FieldMapping field, 
  899           ValueHandler khandler, ValueHandler vhandler, boolean krel, 
  900           boolean vrel,  boolean installHandlers) {
  901           if (getConfiguration().getCompatibilityInstance()
  902               .getStoreMapCollectionInEntityAsBlob())
  903               return null;
  904           if (installHandlers) {
  905               field.getKeyMapping().setHandler(khandler);
  906               field.getElementMapping().setHandler(vhandler);
  907           }
  908           if (!krel && !vrel)
  909               return new HandlerHandlerMapTableFieldStrategy();
  910           if (!krel && vrel)
  911               return new HandlerRelationMapTableFieldStrategy();
  912           if (krel && !vrel)
  913               return new RelationHandlerMapTableFieldStrategy();
  914           return new RelationRelationMapTableFieldStrategy();
  915       }
  916   
  917       /**
  918        * Use hints in mapping data to figure out whether the given relation
  919        * field should use an inverse foreign key or an association table mapping.
  920        */
  921       private boolean useInverseKeyMapping(FieldMapping field) {
  922           FieldMapping mapped = field.getMappedByMapping();
  923           if (mapped != null) {
  924               if (mapped.getTypeCode() == JavaTypes.PC)
  925                   return true;
  926               if (mapped.getElement().getTypeCode() == JavaTypes.PC)
  927                   return false;
  928               throw new MetaDataException(_loc.get("bad-mapped-by", field,
  929                   mapped));
  930           }
  931   
  932           // without a mapped-by, we have to look for clues as to the mapping.
  933           // we assume that anything with element foreign key columns but no join
  934           // columns or table uses an inverse foreign key, and anything else uses
  935           // an association table
  936           FieldMappingInfo info = field.getMappingInfo();
  937           ValueMapping elem = field.getElementMapping();
  938           return info.getTableName() == null && info.getColumns().isEmpty()
  939               && !elem.getValueInfo().getColumns().isEmpty();
  940       }
  941   
  942       /**
  943        * Check the given value against mapped strategies.
  944        */
  945       private Object mappedStrategy(ValueMapping val, Class type,
  946           boolean adapting) {
  947           if (type == null || type == Object.class)
  948               return null;
  949   
  950           Object strat = _defaults.getStrategy(val, type, adapting);
  951   
  952           // recurse on superclass so that, for example, a registered handler
  953           // for java.lang.Enum will work on all enums
  954           if (strat == null)
  955               return mappedStrategy(val, type.getSuperclass(), adapting);
  956           if (!(strat instanceof String))
  957               return strat;
  958   
  959           String name = (String) strat;
  960           if (NoneFieldStrategy.ALIAS.equals(name))
  961               return NoneFieldStrategy.getInstance();
  962   
  963           String props = Configurations.getProperties(name);
  964           name = Configurations.getClassName(name);
  965           try {
  966               Class c = JavaTypes.classForName(name, val,
  967                   (ClassLoader) AccessController.doPrivileged(
  968                       J2DoPrivHelper.getClassLoaderAction(FieldStrategy.class)));
  969               Object o = AccessController.doPrivileged(
  970                   J2DoPrivHelper.newInstanceAction(c));
  971               Configurations.configureInstance(o, getConfiguration(), props);
  972               return o;
  973           } catch (Exception e) {
  974               if (e instanceof PrivilegedActionException)
  975                   e = ((PrivilegedActionException) e).getException();
  976               throw new MetaDataException(_loc.get("bad-mapped-strategy",
  977                   val, name), e);
  978           }
  979       }
  980   
  981       /**
  982        * Instantiate the given value's named handler, or return null if no
  983        * named handler.
  984        */
  985       protected ValueHandler namedHandler(ValueMapping val) {
  986           String name = val.getValueInfo().getStrategy();
  987           if (name == null)
  988               return null;
  989   
  990           String props = Configurations.getProperties(name);
  991           name = Configurations.getClassName(name);
  992           try {
  993               Class c = JavaTypes.classForName(name, val,
  994                   (ClassLoader) AccessController.doPrivileged(
  995                       J2DoPrivHelper.getClassLoaderAction(ValueHandler.class)));
  996               if (ValueHandler.class.isAssignableFrom(c)) {
  997                   ValueHandler vh = (ValueHandler) AccessController.doPrivileged(
  998                       J2DoPrivHelper.newInstanceAction(c));
  999                   Configurations.configureInstance(vh, getConfiguration(),
 1000                       props);
 1001                   return vh;
 1002               }
 1003               return null; // named field strategy
 1004           } catch (Exception e) {
 1005               if (e instanceof PrivilegedActionException)
 1006                   e = ((PrivilegedActionException) e).getException();
 1007               throw new MetaDataException(_loc.get("bad-value-handler",
 1008                   val, name), e);
 1009           }
 1010       }
 1011   
 1012       /**
 1013        * Determine the default handler to use for the given value. Does
 1014        * not take into account the named handler, if any.
 1015        */
 1016       protected ValueHandler defaultHandler(ValueMapping val) {
 1017           return defaultHandler(val, getStrategyInstaller().isAdapting());
 1018       }
 1019   
 1020       /**
 1021        * Determine the default handler to use for the given value. Does
 1022        * not take into account the named handler, if any.
 1023        */
 1024       protected ValueHandler defaultHandler(ValueMapping val, boolean adapting) {
 1025           if (val.isSerialized()) {
 1026               if (_dict.maxEmbeddedBlobSize != -1)
 1027                   warnMaxEmbedded(val, _dict.maxEmbeddedBlobSize);
 1028               return BlobValueHandler.getInstance();
 1029           }
 1030   
 1031           Object handler = mappedStrategy(val, val.getType(), adapting);
 1032           if (handler instanceof ValueHandler)
 1033               return (ValueHandler) handler;
 1034   
 1035           if (val.getType() == byte[].class 
 1036               || val.getType() == Byte[].class) {
 1037               if (_dict.maxEmbeddedBlobSize != -1)
 1038                   warnMaxEmbedded(val, _dict.maxEmbeddedBlobSize);
 1039               return ByteArrayValueHandler.getInstance();
 1040           }
 1041           if (val.getType() == char[].class
 1042               || val.getType() == Character[].class) {
 1043               if (isClob(val, true))
 1044                   return CharArrayStreamValueHandler.getInstance();
 1045               return CharArrayValueHandler.getInstance();
 1046           }
 1047   
 1048           switch (val.getTypeCode()) {
 1049               case JavaTypes.BOOLEAN:
 1050               case JavaTypes.BYTE:
 1051               case JavaTypes.CHAR:
 1052               case JavaTypes.DOUBLE:
 1053               case JavaTypes.FLOAT:
 1054               case JavaTypes.INT:
 1055               case JavaTypes.LONG:
 1056               case JavaTypes.SHORT:
 1057               case JavaTypes.BOOLEAN_OBJ:
 1058               case JavaTypes.BYTE_OBJ:
 1059               case JavaTypes.CHAR_OBJ:
 1060               case JavaTypes.DOUBLE_OBJ:
 1061               case JavaTypes.FLOAT_OBJ:
 1062               case JavaTypes.INT_OBJ:
 1063               case JavaTypes.LONG_OBJ:
 1064               case JavaTypes.SHORT_OBJ:
 1065               case JavaTypes.BIGINTEGER:
 1066               case JavaTypes.BIGDECIMAL:
 1067               case JavaTypes.NUMBER:
 1068               case JavaTypes.DATE:
 1069               case JavaTypes.CALENDAR:
 1070               case JavaTypes.LOCALE:
 1071                   return ImmutableValueHandler.getInstance();
 1072               case JavaTypes.STRING:
 1073                   if (isClob(val, true))
 1074                       return ClobValueHandler.getInstance();
 1075                   return ImmutableValueHandler.getInstance();
 1076               case JavaTypes.PC:
 1077                   if (!val.getTypeMapping().isMapped()
 1078                       && useUntypedPCHandler(val)) 
 1079                       return UntypedPCValueHandler.getInstance();
 1080                   break;
 1081               case JavaTypes.PC_UNTYPED:
 1082                   return UntypedPCValueHandler.getInstance();
 1083               case JavaTypes.OID:
 1084                   return new ObjectIdValueHandler();
 1085           }
 1086           if (!getConfiguration().getCompatibilityInstance()
 1087               .getStoreMapCollectionInEntityAsBlob()
 1088               && val.isEmbeddedPC())
 1089               return new ElementEmbedValueHandler();
 1090           return null;
 1091       }
 1092   
 1093       /**
 1094        * Return true if we should use the generic untyped PC handler for the
 1095        * given unmapped relation.
 1096        */
 1097       private boolean useUntypedPCHandler(ValueMapping val) {
 1098           ClassMapping rel = val.getTypeMapping();
 1099           return rel.getIdentityType() == ClassMapping.ID_UNKNOWN
 1100               || (rel.getIdentityType() == ClassMapping.ID_APPLICATION
 1101               && (rel.getPrimaryKeyFields().length == 0
 1102               || (!rel.isOpenJPAIdentity() && Modifier.isAbstract
 1103               (rel.getObjectIdType().getModifiers()))));
 1104       }
 1105   
 1106       /**
 1107        * Checks for hints as to whether the given column is a CLOB.
 1108        */
 1109       private boolean isClob(ValueMapping val, boolean warn) {
 1110           List cols = val.getValueInfo().getColumns();
 1111           if (cols.size() != 1)
 1112               return false;
 1113   
 1114           Column col = (Column) cols.get(0);
 1115           if (col.getSize() != -1 && col.getType() != Types.CLOB)
 1116               return false;
 1117   
 1118           if (_dict.getPreferredType(Types.CLOB) != Types.CLOB)
 1119               return false;
 1120   
 1121           if (warn && _dict.maxEmbeddedClobSize != -1)
 1122               warnMaxEmbedded(val, _dict.maxEmbeddedClobSize);
 1123           return true;
 1124       }
 1125   
 1126       /**
 1127        * Warn that the given value is being mapped to a handler that will not
 1128        * be able to store large lobs.
 1129        */
 1130       private void warnMaxEmbedded(ValueMapping val, int size) {
 1131           if (getLog().isWarnEnabled())
 1132               getLog().warn(_loc.get("max-embed-lob", val,
 1133                   String.valueOf(size)));
 1134       }
 1135   
 1136       /**
 1137        * Determine the default strategy to use for the given discriminator.
 1138        * Does not take into account the current strategy, if any.
 1139        */
 1140       protected DiscriminatorStrategy defaultStrategy(Discriminator discrim) {
 1141           return defaultStrategy(discrim, getStrategyInstaller().isAdapting());
 1142       }
 1143   
 1144       /**
 1145        * Determine the default strategy to use for the given discriminator.
 1146        * Does not take into account the current strategy, if any.
 1147        */
 1148       protected DiscriminatorStrategy defaultStrategy(Discriminator discrim,
 1149           boolean adapting) {
 1150           ClassMapping cls = discrim.getClassMapping();
 1151           if (cls.getEmbeddingMetaData() != null)
 1152               return NoneDiscriminatorStrategy.getInstance();
 1153           if (cls.getJoinablePCSuperclassMapping() == null
 1154               && (cls.getStrategy() == NoneClassStrategy.getInstance()
 1155               || Modifier.isFinal(discrim.getClassMapping().getDescribedType().
 1156               getModifiers())))
 1157               return NoneDiscriminatorStrategy.getInstance();
 1158   
 1159           Object strat = _defaults.getStrategy(discrim, adapting);
 1160           if (strat instanceof String)
 1161               return instantiateDiscriminatorStrategy((String) strat, discrim);
 1162           if (strat != null)
 1163               return (DiscriminatorStrategy) strat;
 1164   
 1165           if (cls.getJoinablePCSuperclassMapping() != null)
 1166               return new SuperclassDiscriminatorStrategy();
 1167           if (discrim.getMappingInfo().getValue() != null)
 1168               return new ValueMapDiscriminatorStrategy();
 1169           if (cls.getMappedPCSuperclassMapping() != null)
 1170               return NoneDiscriminatorStrategy.getInstance();
 1171           if (adapting || _defaults.defaultMissingInfo())
 1172               return new ClassNameDiscriminatorStrategy();
 1173           DBDictionary dict = ((JDBCConfiguration) getConfiguration()).
 1174               getDBDictionaryInstance();
 1175           if (dict.joinSyntax == JoinSyntaxes.SYNTAX_TRADITIONAL)
 1176               return NoneDiscriminatorStrategy.getInstance();
 1177           return new SubclassJoinDiscriminatorStrategy();
 1178       }
 1179   
 1180       /**
 1181        * Determine the default strategy to use for the given version.
 1182        * Does not take into account the current strategy, if any.
 1183        */
 1184       protected VersionStrategy defaultStrategy(Version version) {
 1185           return defaultStrategy(version, getStrategyInstaller().isAdapting());
 1186       }
 1187   
 1188       /**
 1189        * Determine the default strategy to use for the given version.
 1190        * Does not take into account the current strategy, if any.
 1191        */
 1192       protected VersionStrategy defaultStrategy(Version version,
 1193           boolean adapting) {
 1194           ClassMapping cls = version.getClassMapping();
 1195           if (cls.getEmbeddingMetaData() != null)
 1196               return NoneVersionStrategy.getInstance();
 1197           if (cls.getJoinablePCSuperclassMapping() == null
 1198               && cls.getStrategy() == NoneClassStrategy.getInstance())
 1199               return NoneVersionStrategy.getInstance();
 1200   
 1201           Object strat = _defaults.getStrategy(version, adapting);
 1202           if (strat instanceof String)
 1203               return instantiateVersionStrategy((String) strat, version);
 1204           if (strat != null)
 1205               return (VersionStrategy) strat;
 1206   
 1207           if (cls.getJoinablePCSuperclassMapping() != null)
 1208               return new SuperclassVersionStrategy();
 1209   
 1210           FieldMapping vfield = version.getClassMapping().
 1211               getVersionFieldMapping();
 1212           if (vfield != null)
 1213               return defaultStrategy(version, vfield);
 1214           if (adapting || _defaults.defaultMissingInfo())
 1215               return new NumberVersionStrategy();
 1216           return NoneVersionStrategy.getInstance();
 1217       }
 1218   
 1219       /**
 1220        * Return the default version strategy, given a version field.
 1221        */
 1222       protected VersionStrategy defaultStrategy(Version vers,
 1223           FieldMapping vfield) {
 1224           switch (vfield.getTypeCode()) {
 1225               case JavaTypes.DATE:
 1226               case JavaTypes.CALENDAR:
 1227                   return (JavaVersions.VERSION >= 5) 
 1228                       ? new NanoPrecisionTimestampVersionStrategy()
 1229                       : new TimestampVersionStrategy();
 1230               case JavaTypes.BYTE:
 1231               case JavaTypes.INT:
 1232               case JavaTypes.LONG:
 1233               case JavaTypes.SHORT:
 1234               case JavaTypes.BYTE_OBJ:
 1235               case JavaTypes.INT_OBJ:
 1236               case JavaTypes.LONG_OBJ:
 1237               case JavaTypes.SHORT_OBJ:
 1238               case JavaTypes.NUMBER:
 1239                   return new NumberVersionStrategy();
 1240               default:
 1241                   return NoneVersionStrategy.getInstance();
 1242           }
 1243       }
 1244       
 1245       public void endConfiguration()
 1246       {
 1247           super.endConfiguration();
 1248   
 1249           JDBCConfiguration conf = (JDBCConfiguration) getConfiguration();
 1250           _dict = conf.getDBDictionaryInstance();
 1251           if (_defaults == null)
 1252               _defaults = conf.getMappingDefaultsInstance();
 1253           if (_schema != null && _schema instanceof Configurable) {
 1254               ((Configurable) _schema).setConfiguration(conf);
 1255               ((Configurable) _schema).startConfiguration();
 1256               ((Configurable) _schema).endConfiguration();
 1257           }            
 1258       }
 1259   }

Save This Page
Home » apache-openjpa-1.1.0-source » org.apache.openjpa.jdbc » meta » [javadoc | source]